From 138703663616442da98401796fcb5b9fd99369b1 Mon Sep 17 00:00:00 2001 From: ckm007 Date: Wed, 11 Sep 2024 05:39:16 +0530 Subject: [PATCH] [MOSIP-35367] updated changes for java 21 comparison Signed-off-by: ckm007 --- .../charts/admin/templates/ui-configmap.yaml | 2 +- deployment/sandbox-v2/podconfig.yml | 324 ++++++++--------- .../templates/mosip-context.yml.j2 | 10 +- .../nginx/templates/nginx_https_conf.yml.j2 | 4 + deployment/sandbox-v2/site.yml | 4 +- deployment/sandbox-v2/utils/ports.yml | 47 +++ .../utils/prop_comparator/prop_comparator.py | 10 +- .../sandbox-v2/utils/reprocess/config.py | 4 +- deployment/sandbox-v2/versions.yml | 132 +++---- .../v3/docs/create-gmail-app-password.md | 5 +- deployment/v3/docs/digitalcardcert.md | 101 ++++++ .../docs/external services configuration.md | 6 +- deployment/v3/docs/images/gc-util.png | Bin 0 -> 42469 bytes deployment/v3/docs/images/mailserver-1.png | Bin 0 -> 30929 bytes deployment/v3/docs/images/mailserver-2.png | Bin 0 -> 30662 bytes deployment/v3/docs/images/mailserver-3.png | Bin 0 -> 37291 bytes deployment/v3/docs/images/mailserver-4.png | Bin 0 -> 13587 bytes deployment/v3/docs/images/mailserver-5.png | Bin 0 -> 41984 bytes deployment/v3/docs/images/mailserver-6.png | Bin 0 -> 28928 bytes deployment/v3/docs/images/mailserver-7.png | Bin 0 -> 52565 bytes deployment/v3/docs/images/mailserver-8.png | Bin 0 -> 51531 bytes deployment/v3/docs/images/mailserver-9.png | Bin 0 -> 40297 bytes .../v3/docs/install-gui-desktop-on-ubuntu.md | 42 +++ .../v3/docs/rancher-view-only-user/README.MD | 25 ++ .../img/rancher_role.png | Bin 0 -> 81071 bytes .../setup-email-server-via-apache-james.md | 87 +++++ deployment/v3/external/README.md | 1 - deployment/v3/external/all/install-all.sh | 6 +- .../v3/external/antivirus/clamav/install.sh | 4 +- .../v3/external/antivirus/clamav/values.yaml | 8 +- deployment/v3/external/data-archive/README.md | 62 ++++ deployment/v3/external/data-archive/delete.sh | 30 ++ .../v3/external/data-archive/install.sh | 82 +++++ .../v3/external/data-archive/values.yaml | 281 +++++++++++++++ .../v3/external/docker-secrets/delete.sh | 4 +- .../v3/external/docker-secrets/install.sh | 4 +- deployment/v3/external/hsm/softhsm/README.md | 3 +- deployment/v3/external/hsm/softhsm/delete.sh | 1 + deployment/v3/external/iam/export.sh | 2 +- .../v3/external/iam/import-init-values.yaml | 14 +- deployment/v3/external/iam/install.sh | 2 +- deployment/v3/external/iam/keycloak_init.sh | 2 +- .../v3/external/iam/upgrade-init-values.yaml | 3 + deployment/v3/external/iam/upgrade-init.sh | 6 +- deployment/v3/external/iam/values.yaml | 2 +- deployment/v3/external/kafka/backup.sh | 178 ++++++++++ deployment/v3/external/kafka/restore.sh | 223 ++++++++++++ .../v3/external/landing-page/copy_cm.sh | 2 +- deployment/v3/external/landing-page/delete.sh | 2 +- .../v3/external/landing-page/install.sh | 9 +- .../v3/external/landing-page/restart.sh | 3 +- .../landing-page/template/landing.html | 230 ++++++------ deployment/v3/external/msg-gateway/README.md | 4 + deployment/v3/external/msg-gateway/install.sh | 1 - deployment/v3/external/oauth2-proxy/README.md | 46 ++- .../v3/external/oauth2-proxy/apply_policy.sh | 6 +- deployment/v3/external/oauth2-proxy/delete.sh | 21 ++ .../v3/external/oauth2-proxy/install.sh | 72 ++-- .../v3/external/oauth2-proxy/istio-realm.json | 24 ++ .../external/oauth2-proxy/oauth2-proxy.yaml | 173 ++++----- .../oauth2-proxy/sample-auth-policy.yaml | 334 +++++++++++++++--- deployment/v3/external/object-store/cred.sh | 15 +- .../v3/external/object-store/minio/delete.sh | 2 +- .../minio/images/minio-dashboard.png | Bin 0 -> 73396 bytes .../v3/external/object-store/minio/install.sh | 2 +- .../external/object-store/minio/values.yaml | 9 + deployment/v3/external/postgres/README.md | 2 - deployment/v3/external/postgres/init_db.sh | 2 +- .../v3/external/postgres/init_values.yaml | 34 +- deployment/v3/external/postgres/install.sh | 3 +- deployment/v3/external/postgres/values.yaml | 1 - deployment/v3/mosip/README.md | 10 +- deployment/v3/mosip/admin/README.md | 1 - deployment/v3/mosip/admin/delete.sh | 4 +- deployment/v3/mosip/all/delete-all.sh | 3 + deployment/v3/mosip/all/install-all.sh | 7 +- deployment/v3/mosip/artifactory/delete.sh | 2 +- deployment/v3/mosip/artifactory/install.sh | 4 +- deployment/v3/mosip/artifactory/restart.sh | 4 +- deployment/v3/mosip/biosdk/delete.sh | 2 +- deployment/v3/mosip/biosdk/install.sh | 5 +- deployment/v3/mosip/bqatsdk/install.sh | 4 +- deployment/v3/mosip/captcha/README.md | 11 + deployment/v3/mosip/captcha/copy_cm.sh | 21 ++ deployment/v3/mosip/captcha/copy_cm_func.sh | 32 ++ deployment/v3/mosip/captcha/delete.sh | 23 ++ deployment/v3/mosip/captcha/get_logs.sh | 3 + deployment/v3/mosip/captcha/install.sh | 63 ++++ deployment/v3/mosip/captcha/restart.sh | 25 ++ deployment/v3/mosip/conf-secrets/install.sh | 2 +- deployment/v3/mosip/config-server/README.md | 15 +- deployment/v3/mosip/config-server/copy_cm.sh | 3 +- deployment/v3/mosip/config-server/install.sh | 36 +- deployment/v3/mosip/config-server/restart.sh | 3 +- deployment/v3/mosip/config-server/values.yaml | 9 + .../v3/mosip/credential-feeder/.gitignore | 1 + .../v3/mosip/credential-feeder/.helmignore | 21 ++ .../v3/mosip/credential-feeder/README.md | 6 + .../v3/mosip/credential-feeder/copy_cm.sh | 21 ++ .../v3/mosip/credential-feeder/delete.sh | 30 ++ .../v3/mosip/credential-feeder/install.sh | 38 ++ .../v3/mosip/databreachdetector/copy_cm.sh | 22 ++ .../mosip/databreachdetector/copy_secrets.sh | 19 + .../v3/mosip/databreachdetector/delete.sh | 30 ++ .../v3/mosip/databreachdetector/install.sh | 50 +++ deployment/v3/mosip/datashare/delete.sh | 2 +- deployment/v3/mosip/datashare/install.sh | 1 - deployment/v3/mosip/datashare/restart.sh | 3 +- deployment/v3/mosip/ida/delete.sh | 2 +- deployment/v3/mosip/ida/install.sh | 47 ++- deployment/v3/mosip/ida/restart.sh | 2 +- deployment/v3/mosip/idrepo/copy_cm.sh | 2 +- deployment/v3/mosip/idrepo/delete.sh | 2 +- deployment/v3/mosip/idrepo/install.sh | 3 +- .../v3/mosip/image-compressor/install.sh | 4 +- deployment/v3/mosip/kernel/copy_cm.sh | 2 +- deployment/v3/mosip/kernel/delete.sh | 3 +- deployment/v3/mosip/kernel/install.sh | 2 +- deployment/v3/mosip/kernel/restart.sh | 2 +- .../v3/mosip/key-migration-utility/README.md | 9 + .../v3/mosip/key-migration-utility/copy_cm.sh | 31 ++ .../v3/mosip/key-migration-utility/delete.sh | 36 ++ .../v3/mosip/key-migration-utility/install.sh | 54 +++ deployment/v3/mosip/keymanager/delete.sh | 2 +- .../keymanager/idle_timeout_envoyfilter.yaml | 2 +- deployment/v3/mosip/keymanager/install.sh | 40 ++- deployment/v3/mosip/keymanager/restart.sh | 2 +- .../v3/mosip/masterdata-loader/README.md | 7 + .../mosip/masterdata-loader/copy_secrets.sh | 2 +- .../v3/mosip/masterdata-loader/install.sh | 10 +- deployment/v3/mosip/mock-abis/delete.sh | 2 +- deployment/v3/mosip/mock-abis/install.sh | 2 +- deployment/v3/mosip/mock-abis/restart.sh | 4 +- deployment/v3/mosip/mock-mv/delete.sh | 3 +- deployment/v3/mosip/mock-mv/install.sh | 6 +- deployment/v3/mosip/mock-mv/restart.sh | 2 +- deployment/v3/mosip/mock-smtp/README.md | 2 +- deployment/v3/mosip/mock-smtp/delete.sh | 2 +- deployment/v3/mosip/mock-smtp/install.sh | 4 +- deployment/v3/mosip/mock-smtp/restart.sh | 3 +- .../v3/mosip/mosip-file-server/delete.sh | 2 +- .../v3/mosip/mosip-file-server/install.sh | 2 +- .../v3/mosip/mosip-file-server/restart.sh | 2 +- .../v3/mosip/mosip-file-server/values.yaml | 24 ++ .../v3/mosip/mosipcertmanager/README.md | 17 + .../v3/mosip/mosipcertmanager/copy_cm.sh | 22 ++ .../v3/mosip/mosipcertmanager/copy_secrets.sh | 20 ++ .../v3/mosip/mosipcertmanager/delete.sh | 30 ++ .../v3/mosip/mosipcertmanager/install.sh | 40 +++ deployment/v3/mosip/packetmanager/delete.sh | 2 +- deployment/v3/mosip/packetmanager/restart.sh | 3 +- .../v3/mosip/partner-onboarder/README.md | 3 - .../v3/mosip/partner-onboarder/copy_cm.sh | 2 +- .../mosip/partner-onboarder/copy_secrets.sh | 2 +- .../v3/mosip/partner-onboarder/install.sh | 16 +- .../v3/mosip/pms-migration-utility/copy_cm.sh | 2 +- deployment/v3/mosip/pms/copy_cm.sh | 2 +- deployment/v3/mosip/pms/delete.sh | 3 +- deployment/v3/mosip/pms/install.sh | 32 +- deployment/v3/mosip/pms/restart.sh | 2 +- deployment/v3/mosip/prereg/delete.sh | 4 +- deployment/v3/mosip/prereg/install.sh | 3 - deployment/v3/mosip/prereg/restart.sh | 3 +- deployment/v3/mosip/print/delete.sh | 2 +- deployment/v3/mosip/print/install.sh | 1 - deployment/v3/mosip/print/restart.sh | 2 +- deployment/v3/mosip/regclient/README.md | 3 + deployment/v3/mosip/regclient/install.sh | 2 +- .../v3/mosip/regclient/values.yaml.sample | 3 + deployment/v3/mosip/regproc/delete.sh | 4 +- deployment/v3/mosip/regproc/install.sh | 5 +- deployment/v3/mosip/regproc/restart.sh | 3 +- .../v3/mosip/regproc/topic/create_topics.sh | 24 ++ deployment/v3/mosip/resident/copy_cm.sh | 2 +- deployment/v3/mosip/resident/delete.sh | 2 +- deployment/v3/mosip/resident/install.sh | 7 +- deployment/v3/mosip/resident/restart.sh | 4 +- deployment/v3/mosip/restart-cron/README.md | 8 +- deployment/v3/mosip/restart-cron/install.sh | 20 +- deployment/v3/mosip/restart-cron/values.yaml | 7 +- deployment/v3/mosip/tusd/copy_cm.sh | 3 - deployment/v3/mosip/tusd/install.sh | 2 +- deployment/v3/mosip/websub/delete.sh | 2 +- deployment/v3/mosip/websub/restart.sh | 4 +- deployment/v3/terraform/aws/README.md | 100 ++++++ deployment/v3/terraform/aws/env.tfvars | 9 + deployment/v3/terraform/aws/locals.tf | 80 +++++ deployment/v3/terraform/aws/main.tf | 42 +++ .../modules/aws-resource-creation/README.md | 98 +++++ .../certbot-ssl-certgen.tf | 48 +++ .../aws/modules/aws-resource-creation/main.tf | 134 +++++++ .../modules/aws-resource-creation/outputs.tf | 27 ++ .../aws-resource-creation/variables.tf | 205 +++++++++++ .../aws/modules/nginx-setup/README.md | 77 ++++ .../terraform/aws/modules/nginx-setup/main.tf | 62 ++++ .../aws/modules/nginx-setup/nginx-setup.sh | 42 +++ deployment/v3/terraform/aws/outputs.tf | 24 ++ deployment/v3/terraform/aws/variables.tf | 46 +++ deployment/v3/testrig/apitestrig/copy_cm.sh | 2 +- .../v3/testrig/apitestrig/copy_secrets.sh | 2 +- deployment/v3/testrig/apitestrig/delete.sh | 2 +- deployment/v3/testrig/apitestrig/install.sh | 41 ++- deployment/v3/testrig/apitestrig/values.yaml | 19 +- deployment/v3/testrig/dslrig/copy_cm.sh | 2 +- deployment/v3/testrig/dslrig/copy_secrets.sh | 2 +- deployment/v3/testrig/dslrig/install.sh | 10 +- deployment/v3/testrig/packetcreator/README.md | 9 +- .../v3/testrig/packetcreator/install.sh | 10 +- deployment/v3/testrig/uitestrig/install.sh | 2 +- .../v3/utils/bqatsdk_jar_build/README.md | 90 +++++ deployment/v3/utils/info/README.md | 9 + deployment/v3/utils/info/delete.sh | 30 ++ deployment/v3/utils/info/install.sh | 35 ++ deployment/v3/utils/info/restart.sh | 25 ++ deployment/v3/utils/prop_migrator/Overview.md | 2 - deployment/v3/utils/prop_migrator/README.md | 3 - .../v3/utils/prop_migrator/file_comparator.py | 2 +- .../knowledge/latest-Value-takes-priority.csv | 122 +++++++ ...new-property-with-decent-default-value.csv | 288 +++++++++++++++ .../knowledge/old-value-takes-priority.csv | 7 + deployment/v3/utils/readuser-util/README.md | 39 ++ deployment/v3/utils/readuser-util/copy_cm.sh | 19 + .../v3/utils/readuser-util/copy_secrets.sh | 19 + deployment/v3/utils/readuser-util/delete.sh | 31 ++ deployment/v3/utils/readuser-util/install.sh | 39 ++ .../readuser-util/readuser-init-values.yaml | 25 ++ deployment/v3/utils/readuser-util/values.yaml | 32 ++ 227 files changed, 4999 insertions(+), 811 deletions(-) create mode 100644 deployment/sandbox-v2/utils/ports.yml create mode 100644 deployment/v3/docs/digitalcardcert.md create mode 100644 deployment/v3/docs/images/gc-util.png create mode 100644 deployment/v3/docs/images/mailserver-1.png create mode 100644 deployment/v3/docs/images/mailserver-2.png create mode 100644 deployment/v3/docs/images/mailserver-3.png create mode 100644 deployment/v3/docs/images/mailserver-4.png create mode 100644 deployment/v3/docs/images/mailserver-5.png create mode 100644 deployment/v3/docs/images/mailserver-6.png create mode 100644 deployment/v3/docs/images/mailserver-7.png create mode 100644 deployment/v3/docs/images/mailserver-8.png create mode 100644 deployment/v3/docs/images/mailserver-9.png create mode 100644 deployment/v3/docs/install-gui-desktop-on-ubuntu.md create mode 100644 deployment/v3/docs/rancher-view-only-user/README.MD create mode 100644 deployment/v3/docs/rancher-view-only-user/img/rancher_role.png create mode 100644 deployment/v3/docs/setup-email-server-via-apache-james.md create mode 100644 deployment/v3/external/data-archive/README.md create mode 100755 deployment/v3/external/data-archive/delete.sh create mode 100755 deployment/v3/external/data-archive/install.sh create mode 100644 deployment/v3/external/data-archive/values.yaml create mode 100755 deployment/v3/external/kafka/backup.sh create mode 100755 deployment/v3/external/kafka/restore.sh create mode 100755 deployment/v3/external/oauth2-proxy/delete.sh create mode 100644 deployment/v3/external/object-store/minio/images/minio-dashboard.png create mode 100755 deployment/v3/external/object-store/minio/values.yaml create mode 100644 deployment/v3/mosip/captcha/README.md create mode 100755 deployment/v3/mosip/captcha/copy_cm.sh create mode 100755 deployment/v3/mosip/captcha/copy_cm_func.sh create mode 100755 deployment/v3/mosip/captcha/delete.sh create mode 100755 deployment/v3/mosip/captcha/get_logs.sh create mode 100755 deployment/v3/mosip/captcha/install.sh create mode 100755 deployment/v3/mosip/captcha/restart.sh create mode 100644 deployment/v3/mosip/credential-feeder/.gitignore create mode 100644 deployment/v3/mosip/credential-feeder/.helmignore create mode 100644 deployment/v3/mosip/credential-feeder/README.md create mode 100755 deployment/v3/mosip/credential-feeder/copy_cm.sh create mode 100755 deployment/v3/mosip/credential-feeder/delete.sh create mode 100755 deployment/v3/mosip/credential-feeder/install.sh create mode 100755 deployment/v3/mosip/databreachdetector/copy_cm.sh create mode 100755 deployment/v3/mosip/databreachdetector/copy_secrets.sh create mode 100755 deployment/v3/mosip/databreachdetector/delete.sh create mode 100755 deployment/v3/mosip/databreachdetector/install.sh create mode 100644 deployment/v3/mosip/key-migration-utility/README.md create mode 100755 deployment/v3/mosip/key-migration-utility/copy_cm.sh create mode 100755 deployment/v3/mosip/key-migration-utility/delete.sh create mode 100755 deployment/v3/mosip/key-migration-utility/install.sh create mode 100644 deployment/v3/mosip/masterdata-loader/README.md create mode 100644 deployment/v3/mosip/mosip-file-server/values.yaml create mode 100644 deployment/v3/mosip/mosipcertmanager/README.md create mode 100755 deployment/v3/mosip/mosipcertmanager/copy_cm.sh create mode 100755 deployment/v3/mosip/mosipcertmanager/copy_secrets.sh create mode 100755 deployment/v3/mosip/mosipcertmanager/delete.sh create mode 100755 deployment/v3/mosip/mosipcertmanager/install.sh create mode 100644 deployment/v3/mosip/regclient/values.yaml.sample create mode 100755 deployment/v3/mosip/regproc/topic/create_topics.sh create mode 100644 deployment/v3/terraform/aws/README.md create mode 100644 deployment/v3/terraform/aws/env.tfvars create mode 100644 deployment/v3/terraform/aws/locals.tf create mode 100644 deployment/v3/terraform/aws/main.tf create mode 100644 deployment/v3/terraform/aws/modules/aws-resource-creation/README.md create mode 100644 deployment/v3/terraform/aws/modules/aws-resource-creation/certbot-ssl-certgen.tf create mode 100644 deployment/v3/terraform/aws/modules/aws-resource-creation/main.tf create mode 100644 deployment/v3/terraform/aws/modules/aws-resource-creation/outputs.tf create mode 100644 deployment/v3/terraform/aws/modules/aws-resource-creation/variables.tf create mode 100644 deployment/v3/terraform/aws/modules/nginx-setup/README.md create mode 100644 deployment/v3/terraform/aws/modules/nginx-setup/main.tf create mode 100644 deployment/v3/terraform/aws/modules/nginx-setup/nginx-setup.sh create mode 100644 deployment/v3/terraform/aws/outputs.tf create mode 100644 deployment/v3/terraform/aws/variables.tf create mode 100644 deployment/v3/utils/bqatsdk_jar_build/README.md create mode 100644 deployment/v3/utils/info/README.md create mode 100644 deployment/v3/utils/info/delete.sh create mode 100644 deployment/v3/utils/info/install.sh create mode 100644 deployment/v3/utils/info/restart.sh create mode 100644 deployment/v3/utils/readuser-util/README.md create mode 100755 deployment/v3/utils/readuser-util/copy_cm.sh create mode 100755 deployment/v3/utils/readuser-util/copy_secrets.sh create mode 100755 deployment/v3/utils/readuser-util/delete.sh create mode 100755 deployment/v3/utils/readuser-util/install.sh create mode 100644 deployment/v3/utils/readuser-util/readuser-init-values.yaml create mode 100644 deployment/v3/utils/readuser-util/values.yaml diff --git a/deployment/sandbox-v2/helm/charts/admin/templates/ui-configmap.yaml b/deployment/sandbox-v2/helm/charts/admin/templates/ui-configmap.yaml index 3fc2322d4..815996520 100644 --- a/deployment/sandbox-v2/helm/charts/admin/templates/ui-configmap.yaml +++ b/deployment/sandbox-v2/helm/charts/admin/templates/ui-configmap.yaml @@ -1,6 +1,6 @@ apiVersion: v1 data: - config.json: '{"baseUrl":"{{ tpl .Values.services.ui.apiHost . }}", "adminUrl" : "/admin-ui/", "primaryLangCode": "eng", "secondaryLangCode": "ara", "validateToken": "authmanager/authorize/admin/validateToken", "login": "admin/login/", "logout": "admin/logout/user","templateRepoUrl":"/admin-ui/templates/"}' + config.json: '{"baseUrl":"{{ tpl .Values.services.ui.apiHost . }}", "adminUrl" : "/admin-ui/", "primaryLangCode": "eng", "secondaryLangCode": "ara", "validateToken": "authmanager/authorize/admin/validateToken", "login": "admin/login/", "logout": "admin/logout/user", "templateRepoUrl":"/admin-ui/templates/"}' kind: ConfigMap metadata: name: {{ .Values.services.ui.configName }} diff --git a/deployment/sandbox-v2/podconfig.yml b/deployment/sandbox-v2/podconfig.yml index b87551af7..1ee282dcf 100644 --- a/deployment/sandbox-v2/podconfig.yml +++ b/deployment/sandbox-v2/podconfig.yml @@ -5,154 +5,154 @@ podconfig: minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi masterdata: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms2000M -Xmx2000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi idgen: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi prid: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi sync: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms2000M -Xmx2000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi audit : replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi key: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi notifier: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi otp: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi rid: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi keyMigrator: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi regproc: camel: @@ -160,21 +160,21 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi group2: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms2000M -Xmx2000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 300m @@ -188,7 +188,7 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms2000M -Xmx2000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 300m @@ -202,21 +202,21 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi group5: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1500M -Xmx1500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 300m @@ -230,84 +230,84 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1500M -Xmx1500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi group7: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms2000M -Xmx2000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi trans: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi workflow: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi reprocess: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi notificationService: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi dmzregproc: group1: @@ -315,56 +315,56 @@ podconfig: minReadySeconds: 10 maxUnavailable: 1 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi camel: replicas: 1 minReadySeconds: 10 maxUnavailable: 1 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi status: replicas: 1 minReadySeconds: 10 maxUnavailable: 1 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi pktserver: replicas: 1 minReadySeconds: 10 maxUnavailable: 1 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi prereg: application: @@ -372,83 +372,83 @@ podconfig: minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi batch: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi booking: replicas: 1 minReadySeconds: 10 maxUnavailable: 1 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi datasync: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi captcha: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi ui: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi ida: auth: @@ -456,42 +456,42 @@ podconfig: minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1500M -Xmx1500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi internal: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1500M -Xmx1500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi otp: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi idrepo: identity: @@ -499,56 +499,56 @@ podconfig: minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi vid: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi credentialreq: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi credentialservice: replicas: 1 minReadySeconds: 10 maxUnavailable: 0 maxSurge: 1 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi pms: partner: @@ -556,28 +556,28 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms2000M -Xmx2000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi policy: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi packetmanager: service: @@ -585,28 +585,28 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1500M -Xmx1500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi resident: service: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1000M -Xmx1000M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi activemq: service: @@ -617,38 +617,38 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi admin: service: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi hotlist: replicas: 1 maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi artifactory: service: @@ -659,10 +659,10 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi clamav: service: @@ -673,10 +673,10 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi config_server: service: @@ -687,10 +687,10 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi datashare: service: @@ -698,14 +698,14 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1500M -Xmx1500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi docker_service: service: @@ -723,10 +723,10 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 600m - memory: 3Gi + memory: 1.5Gi mockabis: service: replicas: 1 @@ -778,10 +778,10 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 1000m - memory: 6Gi + memory: 1.5Gi print: service: replicas: 1 @@ -791,10 +791,10 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi reg_client_downloader: service: @@ -802,14 +802,14 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms1500M -Xmx1500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 300m - memory: 1Gi + memory: 1.5Gi limits: cpu: 500m - memory: 3Gi + memory: 1.5Gi websub: service: @@ -820,10 +820,10 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi consolidator: replicas: 1 @@ -833,10 +833,10 @@ podconfig: resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi mosip_file_server: service: @@ -844,14 +844,14 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 1Gi + memory: 1.5Gi tusd: service: @@ -859,14 +859,14 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 3Gi + memory: 1.5Gi resident_app_server: service: @@ -874,14 +874,14 @@ podconfig: maxSurge: 1 maxUnavailable: 0 minReadySeconds: 10 - java_opts: "-Xms500M -Xmx500M" + java_opts: "-Xms750M -Xmx750M" resources: requests: cpu: 200m - memory: 1Gi + memory: 1.5Gi limits: cpu: 300m - memory: 1Gi + memory: 1.5Gi ingress: nginx: diff --git a/deployment/sandbox-v2/roles/mosip-file-server/templates/mosip-context.yml.j2 b/deployment/sandbox-v2/roles/mosip-file-server/templates/mosip-context.yml.j2 index 919c63d83..24a1b080e 100644 --- a/deployment/sandbox-v2/roles/mosip-file-server/templates/mosip-context.yml.j2 +++ b/deployment/sandbox-v2/roles/mosip-file-server/templates/mosip-context.yml.j2 @@ -35,8 +35,12 @@ }, "phone": "mosip:phone", "postalCode": { - "@id": "{{site.sandbox_public_url}}/mosip#postalCode", - "@context": {"value": "rdf:value", "lang": "@language"} + "@id": "{{site.sandbox_public_url}}/mosip#postalCode", + "@context": {"value": "rdf:value", "lang": "@language"} + }, + "province": { + "@id": "{{site.sandbox_public_url}}/mosip#province", + "@context": {"value": "rdf:value", "lang": "@language"} }, "region": { "@id": "{{site.sandbox_public_url}}/mosip#region", @@ -44,4 +48,4 @@ }, "biometrics": "mosip:biometrics" }] -} \ No newline at end of file +} diff --git a/deployment/sandbox-v2/roles/nginx/templates/nginx_https_conf.yml.j2 b/deployment/sandbox-v2/roles/nginx/templates/nginx_https_conf.yml.j2 index 602923a0b..be3a7e23a 100644 --- a/deployment/sandbox-v2/roles/nginx/templates/nginx_https_conf.yml.j2 +++ b/deployment/sandbox-v2/roles/nginx/templates/nginx_https_conf.yml.j2 @@ -306,6 +306,10 @@ http { location /registration-client/ { proxy_pass {{clusters.dmz.ingress.base_url}}/registration-client/; } + + location /resident-ui/ { + proxy_pass {{clusters.dmz.ingress.base_url}}/resident-ui/; + } location /.well-known/ { if ($request_method = 'OPTIONS') { diff --git a/deployment/sandbox-v2/site.yml b/deployment/sandbox-v2/site.yml index 6b5557b5d..b2f71614b 100644 --- a/deployment/sandbox-v2/site.yml +++ b/deployment/sandbox-v2/site.yml @@ -47,7 +47,9 @@ - import_playbook: playbooks/mock-mv.yml - import_playbook: playbooks/tusd.yml - import_playbook: playbooks/resident-app.yml +# Regclient downloader - import_playbook: playbooks/reg-client-downloader.yml +# Mosip-file-server - import_playbook: playbooks/mosip-file-server.yml -# Certificates Upload +# upload Certificates - import_playbook: playbooks/uploadCerts.yml diff --git a/deployment/sandbox-v2/utils/ports.yml b/deployment/sandbox-v2/utils/ports.yml new file mode 100644 index 000000000..1ab69fdb8 --- /dev/null +++ b/deployment/sandbox-v2/utils/ports.yml @@ -0,0 +1,47 @@ +#This is used for enabling ports in sandbox installation with firewall enabled +##usage: ansible-playbook -i hosts.ini ports.yml +- name: FirewallD installation and ports addition to the nodes + hosts: cluster + vars: + port_list: + - { port: 8080/tcp, state: enabled } + - { port: 22/tcp, state: enabled } + - { port: 25/tcp, state: enabled } + - { port: 111/tcp, state: enabled } + - { port: 80/tcp, state: enabled } + - { port: 601/tcp, state: enabled } + - { port: 443/tcp, state: enabled } + - { port: 53/udp, state: enabled } + - { port: 7703-7726/tcp, state: enabled } + - { port: 2376/tcp, state: enabled } + - { port: 2379-2380/tcp, state: enabled } + - { port: 30000-32767/udp, state: enabled } + - { port: 10250-10252/tcp, state: enabled } + - { port: 6443/tcp, state: enabled } + - { port: 9100/tcp, state: enabled } + - { port: 2049/tcp, state: enabled } + - { port: 2048/tcp, state: enabled } + - { port: 41497-43774/tcp, state: enabled } + - { port: 25654-29933/tcp, state: enabled } + tasks: + - name: Install firewalld + yum: + name: firewalld + state: latest + notify: + - start firewalld + - name: start firewalld + service: + name: firewalld + state: started + enabled: yes + become: yes + - name: enable ports + firewalld: + zone: public + port: "{{ item.port }}" + permanent: true + state: "{{ item.state }}" + loop: + "{{ port_list }}" + become: yes diff --git a/deployment/sandbox-v2/utils/prop_comparator/prop_comparator.py b/deployment/sandbox-v2/utils/prop_comparator/prop_comparator.py index 61fff6795..c3d670a33 100755 --- a/deployment/sandbox-v2/utils/prop_comparator/prop_comparator.py +++ b/deployment/sandbox-v2/utils/prop_comparator/prop_comparator.py @@ -47,11 +47,17 @@ def diff_report(fname1, fname2): print('') print('=======================================================') print('\nNEW PROPERTIES in %s' % fname1) - pp.pprint(set1 - set2) + print('') + diff = set1 - set2 + for p in list(diff): + print('%s: %s' % (p, props1[p])) print('') print('=======================================================') print('\nNEW PROPERITES in %s' % fname2) - pp.pprint(set2 - set1) + print('') + diff = set2 - set1 + for p in list(diff): + print('%s: %s' % (p, props2[p])) print('') def main(): diff --git a/deployment/sandbox-v2/utils/reprocess/config.py b/deployment/sandbox-v2/utils/reprocess/config.py index bbfdcc449..9e5eb2744 100644 --- a/deployment/sandbox-v2/utils/reprocess/config.py +++ b/deployment/sandbox-v2/utils/reprocess/config.py @@ -12,5 +12,5 @@ db_host = os.getenv('DB_HOST') db_port = os.getenv('DB_PORT') -query="select reg_id,process,workflow_instance_id from registration where latest_trn_status_code in ('SUCCESS', 'REPROCESS', 'IN_PROGRESS') and reg_process_retry_count<=500 and latest_trn_dtimes < (SELECT NOW() - INTERVAL '1 DAY') and status_code NOT IN ('PROCESSED', 'FAILED', 'REJECTED') LIMIT 1000" -delay = 1 # seconds +query="select reg_id,process,workflow_instance_id from registration where latest_trn_status_code in ('SUCCESS', 'REPROCESS', 'IN_PROGRESS') and reg_process_retry_count<=500 and latest_trn_dtimes < (SELECT NOW() - INTERVAL '1 DAY') and status_code NOT IN ('PROCESSED', 'FAILED', 'REJECTED') LIMIT 100" +delay = 2 # seconds diff --git a/deployment/sandbox-v2/versions.yml b/deployment/sandbox-v2/versions.yml index 2169b3280..89d8f9c89 100644 --- a/deployment/sandbox-v2/versions.yml +++ b/deployment/sandbox-v2/versions.yml @@ -4,174 +4,174 @@ versions: kernel: auth: - 'kernel-auth-service': 'mosipqa/kernel-auth-service:1.2.0.1' + 'kernel-auth-service': 'mosipdev/kernel-auth-service:1.2.0.1' masterdata: - 'kernel-masterdata-service': 'mosipqa/kernel-masterdata-service:1.2.0.1' + 'kernel-masterdata-service': 'mosipdev/kernel-masterdata-service:1.2.0.1' idgen: - 'kernel-idgenerator-service': 'mosipqa/kernel-idgenerator-service:1.2.0.1' + 'kernel-idgenerator-service': 'mosipdev/kernel-idgenerator-service:1.2.0.1' prid: - 'kernel-pridgenerator-service': 'mosipqa/kernel-pridgenerator-service:1.2.0.1' + 'kernel-pridgenerator-service': 'mosipdev/kernel-pridgenerator-service:1.2.0.1' sync: - 'kernel-syncdata-service': 'mosipqa/kernel-syncdata-service:1.2.0.1' + 'kernel-syncdata-service': 'mosipdev/kernel-syncdata-service:1.2.0.1' audit : - 'kernel-auditmanager-service': 'mosipqa/kernel-auditmanager-service:1.2.0.1' + 'kernel-auditmanager-service': 'mosipdev/kernel-auditmanager-service:1.2.0.1' key: - 'kernel-keymanager-service': 'mosipqa/kernel-keymanager-service:1.2.0.1' + 'kernel-keymanager-service': 'mosipdev/kernel-keymanager-service:1.2.0.1' notifier: - 'kernel-notification-service': 'mosipqa/kernel-notification-service:1.2.0.1' + 'kernel-notification-service': 'mosipdev/kernel-notification-service:1.2.0.1' otp: - 'kernel-otpmanager-service': 'mosipqa/kernel-otpmanager-service:1.2.0.1' + 'kernel-otpmanager-service': 'mosipdev/kernel-otpmanager-service:1.2.0.1' rid: - 'kernel-ridgenerator-service': 'mosipqa/kernel-ridgenerator-service:1.2.0.1' + 'kernel-ridgenerator-service': 'mosipdev/kernel-ridgenerator-service:1.2.0.1' keygen: - 'kernel-keys-generator': 'mosipqa/keys-generator:1.2.0.1' + 'kernel-keys-generator': 'mosipdev/keys-generator:1.2.0.1' keymigrator: - 'keymigrator': 'mosipqa/keys-migrator:1.2.0.1' + 'keymigrator': 'mosipdev/keys-migrator:1.2.0.1' prereg: application: - 'prereg-application-service': 'mosipqa/pre-registration-application-service:1.2.0.1' + 'prereg-application-service': 'mosipdev/pre-registration-application-service:1.2.0.1' batch: - 'prereg-batchjob-service': 'mosipqa/pre-registration-batchjob:1.2.0.1' + 'prereg-batchjob-service': 'mosipdev/pre-registration-batchjob:1.2.0.1' booking: - 'prereg-booking-service': 'mosipqa/pre-registration-booking-service:1.2.0.1' + 'prereg-booking-service': 'mosipdev/pre-registration-booking-service:1.2.0.1' datasync: - 'prereg-datasync-service': 'mosipqa/pre-registration-datasync-service:1.2.0.1' + 'prereg-datasync-service': 'mosipdev/pre-registration-datasync-service:1.2.0.1' captcha: - 'prereg-captcha-service': 'mosipqa/pre-registration-captcha-service:1.2.0.1' + 'prereg-captcha-service': 'mosipdev/pre-registration-captcha-service:1.2.0.1' ui: - 'prereg-ui': 'mosipqa/pre-registration-ui:1.2.0.1' + 'prereg-ui': 'mosipdev/pre-registration-ui:1.2.0.1' registration_client: downloader: - 'reg-client-downloader': 'mosipqa/registration-client:1.2.0.1' + 'reg-client-downloader': 'mosipdev/registration-client:1.2.0.1' version: '1.2.0.1-SNAPSHOT' regproc: group1: - 'regproc-stage-group-1': 'mosipqa/registration-processor-stage-group-1:1.2.0.1' + 'regproc-stage-group-1': 'mosipdev/registration-processor-stage-group-1:1.2.0.1' group2: - 'regproc-stage-group-2': 'mosipqa/registration-processor-stage-group-2:1.2.0.1' + 'regproc-stage-group-2': 'mosipdev/registration-processor-stage-group-2:1.2.0.1' group3: - 'regproc-stage-group-3': 'mosipqa/registration-processor-stage-group-3:1.2.0.1' + 'regproc-stage-group-3': 'mosipdev/registration-processor-stage-group-3:1.2.0.1' group4: - 'regproc-stage-group-4': 'mosipqa/registration-processor-stage-group-4:1.2.0.1' + 'regproc-stage-group-4': 'mosipdev/registration-processor-stage-group-4:1.2.0.1' group5: - 'regproc-stage-group-5': 'mosipqa/registration-processor-stage-group-5:1.2.0.1' + 'regproc-stage-group-5': 'mosipdev/registration-processor-stage-group-5:1.2.0.1' group6: - 'regproc-stage-group-6': 'mosipqa/registration-processor-stage-group-6:1.2.0.1' + 'regproc-stage-group-6': 'mosipdev/registration-processor-stage-group-6:1.2.0.1' group7: - 'regproc-stage-group-7': 'mosipqa/registration-processor-stage-group-7:1.2.0.1' + 'regproc-stage-group-7': 'mosipdev/registration-processor-stage-group-7:1.2.0.1' camel: - 'regproc-camel-stage': 'mosipqa/registration-processor-common-camel-bridge:1.2.0.1' + 'regproc-camel-stage': 'mosipdev/registration-processor-common-camel-bridge:1.2.0.1' trans: - 'regproc-registration-transaction-service': 'mosipqa/registration-processor-registration-transaction-service:1.2.0.1' + 'regproc-registration-transaction-service': 'mosipdev/registration-processor-registration-transaction-service:1.2.0.1' reprocess: - 'regproc-reprocessor': 'mosipqa/registration-processor-reprocessor:1.2.0.1' + 'regproc-reprocessor': 'mosipdev/registration-processor-reprocessor:1.2.0.1' notificationService: - 'regproc-notification-service': 'mosipqa/registration-processor-notification-service:1.2.0.1' + 'regproc-notification-service': 'mosipdev/registration-processor-notification-service:1.2.0.1' salt: - 'regproc-salt-generator': 'mosipqa/kernel-salt-generator:1.2.0.1' + 'regproc-salt-generator': 'mosipdev/kernel-salt-generator:1.2.0.1' workflow: - 'regproc-workflowmanager': 'mosipqa/registration-processor-workflow-manager-service:1.2.0.1' + 'regproc-workflowmanager': 'mosipdev/registration-processor-workflow-manager-service:1.2.0.1' dmzregproc: group1: - 'regproc-stage-group-1': 'mosipqa/registration-processor-stage-group-1:1.2.0.1' + 'regproc-stage-group-1': 'mosipdev/registration-processor-stage-group-1:1.2.0.1' camel: - 'regproc-camel-stage': 'mosipqa/registration-processor-common-camel-bridge:1.2.0.1' + 'regproc-camel-stage': 'mosipdev/registration-processor-common-camel-bridge:1.2.0.1' status: - 'regproc-registration-status-service': 'mosipqa/registration-processor-registration-status-service:1.2.0.1' + 'regproc-registration-status-service': 'mosipdev/registration-processor-registration-status-service:1.2.0.1' pktserver: - 'regproc-dmz-packet-server': 'mosipqa/registration-processor-dmz-packet-server:1.0.9' + 'regproc-dmz-packet-server': 'mosipdev/registration-processor-dmz-packet-server:1.0.9' ida: auth: - 'ida-auth-service': 'mosipqa/authentication-service:1.2.0.1' + 'ida-auth-service': 'mosipdev/authentication-service:1.2.0.1' internal: - 'ida-internal-service': 'mosipqa/authentication-internal-service:1.2.0.1' + 'ida-internal-service': 'mosipdev/authentication-internal-service:1.2.0.1' otp: - 'ida-otp-service': 'mosipqa/authentication-otp-service:1.2.0.1' + 'ida-otp-service': 'mosipdev/authentication-otp-service:1.2.0.1' keygen: - 'ida-key-generator': 'mosipqa/keys-generator:1.2.0.1' + 'ida-key-generator': 'mosipdev/keys-generator:1.2.0.1' idrepo: identity: - 'idrepo-identity-service': 'mosipqa/id-repository-identity-service:1.2.0.1' + 'idrepo-identity-service': 'mosipdev/id-repository-identity-service:1.2.0.1' vid: - 'idrepo-vid-service': 'mosipqa/id-repository-vid-service:1.2.0.1' + 'idrepo-vid-service': 'mosipdev/id-repository-vid-service:1.2.0.1' credentialreq: - 'idrepo-credential-request-generator': 'mosipqa/credential-request-generator:1.2.0.1' + 'idrepo-credential-request-generator': 'mosipdev/credential-request-generator:1.2.0.1' credentialservice: - 'idrepo-credential-service': 'mosipqa/credential-service:1.2.0.1' + 'idrepo-credential-service': 'mosipdev/credential-service:1.2.0.1' salt: - 'idrepo-salt-generator': 'mosipqa/id-repository-salt-generator:1.2.0.1' + 'idrepo-salt-generator': 'mosipdev/id-repository-salt-generator:1.2.0.1' feeder: - 'idrepo-credential-feeder': 'mosipqa/id-repository-credentials-feeder:1.2.0.1' + 'idrepo-credential-feeder': 'mosipdev/id-repository-credentials-feeder:1.2.0.1' pms: partner: - 'pms-partner-manager-service': 'mosipqa/partner-management-service:1.2.0.1' + 'pms-partner-manager-service': 'mosipdev/partner-management-service:1.2.0.1' policy: - 'pms-policy-manager-service': 'mosipqa/policy-management-service:1.2.0.1' + 'pms-policy-manager-service': 'mosipdev/policy-management-service:1.2.0.1' ui: - 'pms-ui': 'mosipqa/pmp-ui:1.2.0.1' + 'pms-ui': 'mosipdev/pmp-ui:1.2.0.1' resident: resident: - 'resident-service': 'mosipqa/resident-service:1.2.0.1' + 'resident-service': 'mosipdev/resident-service:1.2.0.1' admin: service: - 'admin-service': 'mosipqa/admin-service:1.2.0.1' + 'admin-service': 'mosipdev/admin-service:1.2.0.1' ui: - 'admin-ui': 'mosipqa/admin-ui:1.2.0.1' + 'admin-ui': 'mosipdev/admin-ui:1.2.0.1' hotlist: - 'admin-hotlist-service': 'mosipqa/hotlist-service:1.2.0.1' + 'admin-hotlist-service': 'mosipdev/hotlist-service:1.2.0.1' packetmanager: service: - 'packetmanager-service': 'mosipqa/commons-packet-service:1.2.0.1' + 'packetmanager-service': 'mosipdev/commons-packet-service:1.2.0.1' datashare: service: - 'datashare-service': 'mosipqa/data-share-service:1.2.0.1' + 'datashare-service': 'mosipdev/data-share-service:1.2.0.1' print: service: - 'print-service': 'mosipqa/print:1.2.0.1' + 'print-service': 'mosipdev/print:1.2.0.1' websub: service: - 'websub-service': 'mosipqa/websub-service:1.2.0.1' + 'websub-service': 'mosipdev/websub-service:1.2.0.1' consolidator: - 'consolidator-websub-service': 'mosipqa/consolidator-websub-service:1.2.0.1' + 'consolidator-websub-service': 'mosipdev/consolidator-websub-service:1.2.0.1' mock: abis: # Please don't change this image - 'mock-abis': 'mosipqa/mock-abis:develop' + 'mock-abis': 'mosipdev/mock-abis:develop' mv: - 'mock-mv': 'mosipqa/mock-mv:1.1.5' + 'mock-mv': 'mosipdev/mock-mv:1.1.5' biosdk: - 'mock-biosdk-service': 'mosipqa/biosdk-server:1.2.0.1' + 'mock-biosdk-service': 'mosipdev/biosdk-server:1.2.0.1' artifactory: service: - 'artifactory-service': 'mosipqa/artifactory-server:1.2.0.1' + 'artifactory-service': 'mosipdev/artifactory-server:1.2.0.1' keycloak: service: - 'keycloak': 'mosipqa/mosip-keycloak:1.2.0.1' + 'keycloak': 'mosipdev/mosip-keycloak:1.2.0.1' mosip_file_server: service: - 'mosip_file_server': 'mosipqa/mosip-file-server:1.2.0.1' + 'mosip_file_server': 'mosipdev/mosip-file-server:1.2.0.1' tusd: service: - 'tusd-server': 'mosipqa/tusd-server:1.2.0.1' + 'tusd-server': 'mosipdev/tusd-server:1.2.0.1' resident_app_server: service: - 'resident-app-server': 'mosipqa/mimoto:develop' + 'resident-app-server': 'mosipdev/mimoto:develop' diff --git a/deployment/v3/docs/create-gmail-app-password.md b/deployment/v3/docs/create-gmail-app-password.md index 98d710d16..9c602f039 100644 --- a/deployment/v3/docs/create-gmail-app-password.md +++ b/deployment/v3/docs/create-gmail-app-password.md @@ -29,11 +29,12 @@ 1. Make sure below listed properties from `kernel-default.properties` or `kernel-*.properties` file in config set to false. ``` - management.health.mail.enabled=false + # uncomment if SMTP mail health check not required + #management.health.mail.enabled=false mosip.kernel.sms.proxy-sms=false mosip.kernel.mail.proxy-mail=false ``` # References -1. [support.teamgate.com](https://support.teamgate.com/hc/en-us/articles/115002064229-How-to-create-a-password-to-connect-email-while-using-2-step-verification-in-Gmail-) \ No newline at end of file +1. [support.teamgate.com](https://support.teamgate.com/hc/en-us/articles/115002064229-How-to-create-a-password-to-connect-email-while-using-2-step-verification-in-Gmail-) diff --git a/deployment/v3/docs/digitalcardcert.md b/deployment/v3/docs/digitalcardcert.md new file mode 100644 index 000000000..4ecad31ae --- /dev/null +++ b/deployment/v3/docs/digitalcardcert.md @@ -0,0 +1,101 @@ +# DIGITALCARD Module certificate exchange guide + +- Below are the steps needed to be performed for the certificate exchange of DIGITALCARD + + * 1. Authenticate yourself and get authorization token from authmanager swagger. Also adding the request after that which can be used.. please update the domain name in the request. + + SWAGGER URL:- ```https://minibox.mosip.net/v1/authmanager/swagger-ui.html#/authmanager/clientIdSecretKeyUsingPOST ``` hit authmanager section in try-out section. + ``` + { + "id": "string", + "metadata": {}, + "request": { + "appId": "ida", + "clientId": "mosip-ida-client", + "secretKey": "abc123" + }, + "requesttime": "2018-12-10T06:12:52.994Z", + "version": "string" + } + ``` + * 2. Get the ROOT certificate data from the below URL, Copy it and use it for certificate exchange in the next step. + ```https://minibox.mosip.net/v1/keymanager/getCertificate?applicationId=ROOT``` + + * 3. Upload ROOT certificate from the above request in the below SWAGGER URL:- ```https://minibox.mosip.net/v1/partnermanager/swagger-ui.html#/Partner%20Service%20Controller/uploadCACertificateUsingPOST``` Partner_Service_Controller --> /partners/certificate/ca/upload --> with below request + ``` + { + "id": "string", + "metadata": {}, + "request": { + "certificateData": "-----BEGIN CERTIFICATE-----\nMIIDTjCCAjagAwIBAgIEYFrxXTANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJJ\nTjESMBAGA1UECAwJS2FybmF0YWthMRIwEAYDVQQHDAlCYW5nYWxvcmUxHjAcBgNV\nBAoMFW1wYXJ0bmVyLWRlZmF1bHQtYWJpczESMBAGA1UEAwwJYWJpcy1yb290MB4X\nDTIxMDMyNDA3NTkyNVoXDTIyMDMyNDA3NTkyNVowaTELMAkGA1UEBhMCSU4xEjAQ\nBgNVBAgMCUthcm5hdGFrYTESMBAGA1UEBwwJQmFuZ2Fsb3JlMR4wHAYDVQQKDBVt\ncGFydG5lci1kZWZhdWx0LWFiaXMxEjAQBgNVBAMMCWFiaXMtcm9vdDCCASIwDQYJ\nKoZIhvcNAQEBBQADggEPADCCAQoCggEBANkwlDzNZTBi1fBF4GU4qFAJ3S+Ca0Kf\ngfvg93rQlZ5LBTnZFwAxpCZtGHYb7vkqM9e7adYGC48EPWI0A+48QmF3Z6vSBXg9\nKckINa/vFCTEYrctMHS8CcBjWBf9agJq4+wWqNu8sYHD9pOzDf1uMbQJTI5VvgGx\nv890pZrXdIrR4MPTLB0rkl2sVOqbG7bts0Eqh8TO86126CDzoDrtBCj3RBP/j/dg\nBmz7LWFkG6/by+mXzdZcS46v7P/Q366WrDbMCCtjKIRAA0HQD3vdKT0V03Eiw/EU\nVxVh9sdbkO5h/T8VWI7ghEjr4PpJXPYWRbVlt6uPDpbX+yEiOWG/SsMCAwEAATAN\nBgkqhkiG9w0BAQsFAAOCAQEAEj42FlN8LnNPv3iWttydxm9kEJemyJdw8nPLCC4y\nxigXrcxPgNcoJiDBXLIAwhTmPK1hdn/BndAeUsX8mauuzf4V7Ydw1a999s8Vsj8S\nOLa8voXAE2sjdYZm0cYID0y/ak3+ZrKqCXP6bcmPOLz2plnGJB7TUQ+d8gZXsLA6\nCoopaJOlNM4jPNbX/k30vfFmyrXm2++5stErrSOix25J79DGdmJH896/pmGmB60/\nXGnpyESrVTbhTE+cx0gDHdq5T47qHcXM6CVuH/uYNy5iLCaBRzVQ043gFj3ioym1\nnZ60dsvdG8nEENBu9SzN3Mn24pz0BQ99Qn5ymsQwYAEeDQ==\n-----END CERTIFICATE-----\n", + "partnerDomain": "AUTH" + }, + "requesttime": "2021-03-24T08:24:13.349Z", + "version": "string" + } + ``` + * 4. Get the IDA certificate data from the below URL, Copy it and use it for certificate exchange in the next step. + ```https://minibox.mosip.net/v1/keymanager/getCertificate?applicationId=DIGITAL_CARD``` + + * 5. Upload IDA certificate from the above request in the below SWAGGER URL:- ```https://minibox.mosip.net/v1/partnermanager/swagger-ui.html#/Partner%20Service%20Controller/uploadCACertificat$ ``` + { + "id": "string", + "metadata": {}, + "request": { + "certificateData": "-----BEGIN CERTIFICATE-----\nMIIDTjCCAjagAwIBAgIEYFrxXTANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJJ\nTjESMBAGA1UECAwJS2FybmF0YWthMRIwEAYDVQQHDA$ + "partnerDomain": "AUTH" + }, + "requesttime": "2021-03-24T08:24:13.349Z", + "version": "string" + } + ``` + * 6. Get the mpartner-default-digitalcard partner certificate data from the below URL, Copy it and use it for certificate exchange in the next step. + ```https://minibox.mosip.net/v1/keymanager/getCertificate?applicationId=DIGITAL_CARD&referenceId=mpartner-default-digitalcard``` + + + * 7. Upload mpartner-default-auth Partner certificate in the below SWAGGER URL:- ```https://minibox.mosip.net/v1/partnermanager/swagger-ui.html#/Partner%20Service%20Controller/uploadPartnerCertificateUsingPOST_1``` Partner_Service_Controller --> /partners/certificate/upload --> with below request + ``` + { + "id": "string", + "metadata": {}, + "request": { + "certificateData": "-----BEGIN CERTIFICATE-----\nMIIDWjCCAkKgAwIBAgIEYFrz6DANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJJ\nTjESMBAGA1UECAwJS2FybmF0YWthMRIwEAYDVQQHDAlCYW5nYWxvcmUxHjAcBgNV\nBAoMFW1wYXJ0bmVyLWRlZmF1bHQtYWJpczESMBAGA1UEAwwJYWJpcy1yb290MB4X\nDTIxMDMyNDA4MTAxNloXDTIyMDMyNDA4MTAxNlowdTELMAkGA1UEBhMCSU4xEjAQ\nBgNVBAgMCUthcm5hdGFrYTESMBAGA1UEBwwJQmFuZ2Fsb3JlMR4wHAYDVQQKDBVt\ncGFydG5lci1kZWZhdWx0LWFiaXMxHjAcBgNVBAMMFW1wYXJ0bmVyLWRlZmF1bHQt\nYWJpczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKuA8CuDIRQCUCl9\nyVh/dGOb/CiMnbcL/lsLq+VeYo51yyycj5kH2wuTlnXRZAOJklCvhAIJP68q799S\nW+aMr+pOLm4rCgMfPD30UVdcmza+dPfl7A3/YZ5UjALOqjVMmwcUxmh1k5yL9QRo\n1LNLCGkwd0hfgT35Y9sC0CDxD3aOesaz0oP9dkGETpcv8nMW4VxWHvOekup1gqAi\nEn1VBat6qVGjwBNKAVkq75Q8P477DyT+t9NRs9IW68ZQXvR+VQvofDNDk8PshXVQ\nMjesEgQHs7bIhTb6hAmGJsQM97yBAA6+EEGGqvLTZDDXjTAtdNZpjml0jaaMnURl\nzF+qh08CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAjdfHjKlrt7mV0MomYO7KkuCc\naCscPAN74UZaCMRE5pXixeQVctsWE/KI7KdmJwZWqZvQrb/AX4VwZu5A1zcDNOJ6\nB7UaDePCMBXRPcyUAAWWwr0AtV0JkEei3d2TbqiPXqlCM1fvvkKQqGZxa61CvSdN\nz2XmY9W09gbAgkMx3svv6MHpZlJuWY8OZVr0ID1hW+ajEoCf5Adv2Iwuogg/Hs9D\nlhhvYg4GzU/qWE9vFYO52UqtVPfrzQZTPBQE5Hrg0a32HBOwL3vu0ms2gf1lEt23\nEf/8TZA5kT/0bMYlB6heGjIKEC90tEv645jbkgJoCI+GgazTTe9wYHXmgz9oPw==\n-----END CERTIFICATE-----\n", + "partnerDomain": "Auth", + "partnerId": "mpartner-default-digitalcard" + }, + "requesttime": "", + "version": "string" + } + + * 8. Upload the response signinng certificate obtained from the reponse of the above api into the keymanager for mpartner-default-digitalcard partner in keymanager using below Swagger URL: https://minbox.mosip.net/v1/keymanager/swagger-ui.html#/keymanager/uploadCertificateUsingPOST``` keymanager --> /uploadCertificate with below request + ``` + { + "id": "string", + "metadata": {}, + "request": { + "applicationId": "DIGITAL_CARD", + "certificateData": "certficate data fom the responce of step 7", + "referenceId": "mpartner-dafault-digitalcard" + }, + "requesttime": "2018-12-10T06:12:52.994Z", + "version": "string" + } + ``` + +# Troubleshooting + +- Please check if the domain name is correctly replaced. +- In case of errors related to timestamp please update the latest timestamp in the request. +- If the Swagger links are not available check if the services are running fine. + swagger 1:- kernel-Auth-service. + swagger 2:- pms services. + swagger 3:- pms services. + get certificate request :- keymanager services. +- In case you gett error in certifacte upload for either of ROOT, IDA, mpartner-default-digitalcard reponse as ```certificate data already exist``` pls ignore as the certifcate exchange is done once. +- As of now this is WIP on this document. +- For other descrepencies raise a github issue. +- Below is the example of how to get the get the certificate data from the response. + ``` + {"id":null,"version":null,"responsetime":"2021-04-18T10:03:20.606Z","metadata":null,"response":{"certificate":"~~~-----BEGIN CERTIFICATE-----\nMIIDkDCCAnigAwIBAgIIzui2vr6fKUMwDQYJKoZIhvcNAQELBQAwbjELMAkGA1UE\nBhMCSU4xCzAJBgNVBAgMAktBMRIwEAYDVQQHDAlCQU5HQUxPUkUxDTALBgNVBAoM\nBElJVEIxGjAYBgNVBAsMEU1PU0lQLVRFQ0gtQ0VOVEVSMRMwEQYDVQQDDApNT1NJ\nUC1ST09UMB4XDTIwMTIxNTE1NDcxOVoXDTI1MTIxNTE1NDcxOVowbjELMAkGA1UE\nBhMCSU4xCzAJBgNVBAgMAktBMRIwEAYDVQQHDAlCQU5HQUxPUkUxDTALBgNVBAoM\nBElJVEIxGjAYBgNVBAsMEU1PU0lQLVRFQ0gtQ0VOVEVSMRMwEQYDVQQDDApNT1NJ\nUC1ST09UMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0IG5QpRMA1dZ\n2FRitMuNlzOCr+qsEZnFGdUH6npYMgNPSw7kJAHpo2CAo4WBNAgz6i1fASSqb8EZ\nXmxnKC9qW31zf8xmnwJNDMFIYctZTp1ZVG7yox+HeI4u//XymAGEg0U/bJ9FVpYr\n6TIbFIO7HzbB12qEwEmvniWKILqzf7qY6F+62GrJyFIwdpWkmlDMUdU4L9V3R10S\nwrNOTDkbHnLb34uwtBpaMHmYgOasaOXxCNcEzdOf56w6RTJmSla9TJgeXn0hikF1\ntxlHkv3Bw2T4y7eVL7NZeMhKkJJW0J4+hWm6nWzRG3Su31HoUIph1GFhrVrq/84B\nlOqHvpDIcwIDAQABozIwMDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS+Kdh1\nX3eiq7UDZ3jBJwoKzFjLaDANBgkqhkiG9w0BAQsFAAOCAQEASzHHVt79eqzzYKLi\ncquGoS31Flq+EKrUdm5zLIYQx9lolVmRveJEqE85x02dGu8MMWjsshQvnzbG0PET\nR5kED5tVRSYx1W/Da5uE7EzQpiYeKsakmSArnslB0kFB+8UGb3KlmCUrQC0C4Ufo\ngbl2zEj9slLgjHKYbvGlki3Sz0oFAdEjuBdbWOrOaMQMUu7OZjMl/scyMBAR0U5J\nURVAGbEniMrw7a1z3LynVerc1qDAbuX1l4njUnit+JbB9B7QPbTEKjce1/pdyvUc\n9SbJpoznaFTRNFyq1iI98hsk+Iu9AImohiCV2DsvVULzACVQXhdApbVZBqjHAHbn\nkQcdtw==\n-----END CERTIFICATE-----\n~~~","certSignRequest":null,"issuedAt":"2020-12-15T15:47:19.000Z","expiryAt":"2025-12-15T15:47:19.000Z","timestamp":"2021-04-18T10:03:20.606Z"},"errors":[]} + ``` + highlighted data in the above response is the example certificate data required. diff --git a/deployment/v3/docs/external services configuration.md b/deployment/v3/docs/external services configuration.md index 0c61e671f..d392b51be 100644 --- a/deployment/v3/docs/external services configuration.md +++ b/deployment/v3/docs/external services configuration.md @@ -7,7 +7,7 @@ This document describes how to configure external services like MinIO, Keycloak, * Go to `mosip-config` and checkout to a specific branch to update the `config` properties. * The default value for the database hostname is `postgres-postgresql.postgres` and the default value for the database port number are `5432`. -* If you are using an external service, you need to update the hostname and port number via `sed` command mentioned below and also provide the external-hostname along with external-port. +* If you are using an external service, you need to update the hostname and port number via `sed` command mentioned below and also provide the external-hostname along with external-port. ``` cd mosip-config sed -i 's/postgres-postgresql.postgres//g' * @@ -64,7 +64,7 @@ This document describes how to configure external services like MinIO, Keycloak, data: admin-password: {{ base64 encoded admin password }} ``` - >Note: + >Note: - The admin-password is the password of the admin user of the master realm in the keycloak. * Proceed with **keycloak_init.sh** script from [here](../external/iam/README.md#keycloak-init). @@ -74,7 +74,7 @@ This document describes how to configure external services like MinIO, Keycloak, * Go to `mosip-config` and checkout to a specific branch to update the `config` properties. * The default value for the s3 URL is `object.store.s3.url=http://minio.minio:9000`. -* If you are using an external service, you need to update the s3 URL via `sed` command below and also provide the external URL. +* If you are using an external service, you need to update the s3 URL via `sed` command below and also provide the external URL. ``` cd mosip-config sed -i 's/http://minio.minio//g' * diff --git a/deployment/v3/docs/images/gc-util.png b/deployment/v3/docs/images/gc-util.png new file mode 100644 index 0000000000000000000000000000000000000000..f245953fbbcf614fb0362c5c4b4999b09f170fc6 GIT binary patch literal 42469 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

}A{?bV<@;`gZzJ#IpYyY(Sn!?) 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 Fe*n59sT%+Q literal 0 HcmV?d00001 diff --git a/deployment/v3/docs/images/mailserver-1.png b/deployment/v3/docs/images/mailserver-1.png new file mode 100644 index 0000000000000000000000000000000000000000..1315abf2484f5c18c9d1eadf9f05f7584bc61a6b GIT binary patch literal 30929 zcmdqIbx@p7_b*74Bm~GnfZ$QfuCi?&|eX}LP0@6mk>rPf%lz0`lsu6_xBbh-#fk0?DR%YI( zJxgdeU);6aQ+e|6>%HL%=tG;z@xR+94lw5O8+H_4{pTN2 z$Y)=vNur})6Z8M--#-^~88<%*)vVF+tld2)#6Uj%Sf}&dP$H=Ym$|k2frYP3=?1Mv z`l(%o2OldMpY%UR$7`qq(gh5kW7%`cRs&=gBDHA}OzvAC=wqk8zA({B|%)+6TXhUGe{_wZx zlg{8ycH#>#M}%~wW73j_I{F`)^hS-^9M4Z(OSwZeab2nX!y!QT%a%XfSg6*ov~OXx zq+Bld(7Uv0WA7bKCSo$dM*RWam%`w-ObMn@LV*+NS)6^%G6n@s&jl{B6YU=|S30nD z+)uaF#kff7D5gRQn86ilg(4{fnzg3|+uPgm0S%!Z{hkL&xF$4wye32PKw$98W(&b` z1&M0y&s}l1k1Bw<3e6uLXY*4EDRepMHaZVHWdcM1w?Dly;P3b8R$}R_{xhj4ge4K% z69K6WWAlxb{u2o_w?;nR^ZlBqFDrXB&|kKvtoQ)lCCgh!A z=In0f_T%ojF^`4-kI)a3X4alYOG$~WUcKM4-HFv~I?V^4fsBo_y#;hQd@R`G{ZhQ! z)~Y>U#Pe~|P|=wt(gG&?>YZ7aDxHQ|s0Z7qv$bbd%|2$Di{XrUaq%LF)_aCLf9+CT zfj?FO;l10lw6Y#xiUYwqE2<~OqDBcq>-;f!jb_=PCcI08ZUZ)7R6E0#*fj<>a z+j}t>lhP@x2B>cqtDhO@pZ>6mxJ?_-D*GBC0h9H128y+oI`H|P+bv>!U^o39RY8tG z)b5dq#Vy#Oj^d}K1asuv1;+TFV^q&Au2csk=2!N@=nTY%8e<-oV+faXuuIx>05|?5 zdV^^(c0KlWDT{ud)P6SgJRMCQ@K&c~lGw73kfNl+fR_3wQd%aS&#q~H3uGBm=SPQd zztVN1jA`4OcllLOq+Y{)P?A&w)Gt#*Tle8MuI%+VXq?Z-e}46}zp5WpYb+d;Hn}Ym ztP>^n+N%i}j%^DuT>F;4syI5Cp1RU7`8gT0NmlsTHTj6 zA%p{<@zMipE3SbFD|E9}c@7q@^}E{9)|u2?>k@Ic)1Fi*YSlJk3U}zFM~?SZMZ34# zZTvV-%qZdSF4_BbX<-A4uLxA)kuWLdXLrI4{{Z(ossL8-5L{TpC&%ox|xKlnR{FslBy+&cmfR({Rps>am^=IZ)Vu+>5TeA?ZH#R9?bPs8LIV zVMGr*20G`HX>QC=<}?kK?p}0zR?g~dV<1e&+!ZPCIhu~7>s1gPp9hX6>e7Rr_=qNH z&&HHxv{3Ztr4^Xzi7Ob~P?%`d=OksV1CNZ4_A1HDk5_BBMhs8V-d}5YyRjJr&iZ`x z5q6eP={PIY&ss`dlJ#;ka$&<#EV+x(RG5|-Fl^)btNi6E5BS@Q^ArbQ;6ciV*_)!b z{NHImJ~6L?S4a(gAJ9O%spduw^c%Y&G{kxiKK_rD$iQp*w~6SJmPUSf>w>Ib2edyd z+((NyO#e@}7C5+gF3vAeP>5f6@SwP|{C5g7@0fzgZ=O%9%?9og`_I<7J|l@RhY_j& zSR9f|$7ig0g)-!wRJuqnJ?FxX?(qp_GkIpgq1#EFUP4l;A-;ZoZTlEU?~?el(j-|w zN!jU*iF$u19lb{V7K4ph;>Kk;o;D6j{TF7}rX0!e*MZ&MEK3U7r_+;V8Wv3C9AN#?hFuMy#7mnoX-wZXed?F&LV`0 z0!In^v;?;jY8U{C*2nd28S}fu;9>`tteEjis$}eota~lpvWkSo;{#vwY*K`gqW~b{ zW>EVssvU^OHEBklzF+BMFs>RGRdY>ZbD2|&nsin*3Pf>qW7cm{^`x^s4(eLIFv<`~ zeOJ?P~>cRk>v2wAZ1?qAqlyN+tJsFF&UJTFmN zSbF7xcJ5@R?ibkJyydQ$VMuAN(Rk@Omnk3Nb$1>d*%338+Kj7tQ#gk{(;)vSRmuZ! z4O)5GjJgJ6%BdebIAW!URK{2&#@6N^pHw68QsCVRF7xb3vmccx;Bq5~yy^NhX;jzN zX=41Ws5`lqdbsoZr9;1_u9$21U0-97hs&k*;GbDc#xweZm<1}|H3uT?Vl8d26uJXl z!bC++<8R&FrG@h&bRg`g_Jf(*#nf{jXXN%P*;^FF?@s6P*VLR=WA2KpJR@W_pxRTA z6zVDF8TD$|*z22M8&hO4gDU(W8BKg0$gRZ$m8gpb5($p$q=+w0Sk#M*WWDu=I6igG z5PeY#uAvNkg=d4Q2wc`wkLS=%FZ($Y0UA(z+iK=d0{qA_6@^RO0 zPz3hgo!m#?L}I!|0uB4)j)_+lU0DMK&nSDzt#zB_?NLnCXESgojaE`T>Vps-*NLpV zCX#KRIn)Pd-tzRG9=(-zbkd9+bzIJ=EAyGgcy$5l8C3&twsI^@vngTuSpFF-&`Loh zaLz(HClt2{01%Y|0iDc9_#&Y}3v&)@@aFZ=s9$RTHT2@SnUJ;F~oh}dUnFBc!#K63kAPk4P&qjvB zz4L8<8nf<9CVQ+4ww#D)P`~0kMSwIsp>)UJwF-UD>*RM~&$oVc>*Y$LqV@alz61nJ< z$k@ps1x9V~Tc1NnG#M}k$fY|=-F}kE1PzK zv=Ng6%e>dFJuc7g(le^-NVRDqdqL8-eVzEbYm*KA&uJP;7p-gGGnXi8>)1#dnx``&EgWWA3t&VYziSJ?; zeJ+wO-!YzRF{LfcnaIerIjL7S2TU)mt-dcOz18V@re3ECbF*A&KfrkBjF>6d8CiMF z;4JsSZJhw+BiGsYa}R%}D1JkW&Ok6)SPukZa6JGPzWhLH6AY)Ni>e;Lpf?DHg0<#zaX) zt1A_~X$RQrknmRHpqe8^fpV%f(c=&y&Y@ z_-YKXt|1ANZ^H+eo~9a|H40AdB5Vypq2VT3L1(l0p0UlnMT!Crv$#wKgH%5X(U+g2 zMv1Nj+IS2xNh>S=E`R?+YLm$v;Q?}YbS6u+qE}t6c&+1}bR0KZUC_=!fPP+jm{<#P zPsM%#2katHQm?n82esycULfa$Qu+L^EB1fc-s!PcyYe!J&`n5c`UPHxWiOGq4f%E7 z&ntsZ18E3pgmY9E=A-UF_A|)#9C2>=TGCzJK?k=t41*?kkJB~$}N(voWF!*={O=RB! zt5;(*6X-VkscgkIZQM4ZlX`Zx!N=nmUDD1NF%Y>WFVU&$#tQHbYn(l(tm!vt9l%F1 zuR?5)rdY&?1$^6%-SoDY>w+bCzXIk{Pvz%{<((zgCg{m);rI}pS9V`zZ;rcWxX2SdwFkD z4JI-!^I*|a3;Rhst1=yG)^*=kb(ToPP}rWve?M}jh`}-37`ixUiLE;fl;Eq?pSBJx zjJ&`g^(%by!>g34Tn!hbp_FODWAR<)T4!je0jKlF?zQ+0j1myR0Hgp0bcJ<|?G&_A zQx(0u9Hlfh?U^~lUmjnq-L6TmitZ0~W^=%x8o=*~k#aCBipx@uRaAXWUlcYwaHr}%BjJR$qc2dfS0-WCT#d$+7IsXym3jZfGxP>a4ybUY6= z9Z~T19Qw`?0eijZ+IF*-;EBpQ4WP%h3hHH~Zd@s>+7Wc%$j)q#68;g8ep@Ba?I`zp zlI2UQ^dqCE;XceBhjBw66|WpZO@|}ceKeb!kv@=i3)7Ej#SYP?>2H8A)BsUSahI13 zrBlhRAB?o<3MW6qwlc>P_|YZ24byhYwU<{?)W;jh@^L&j?teVR9|>h#b^&5RYhBlO zU%lYc_TX=pX!>9|(PkwPIE&fipe^f`vbciteG&KGWO+s|A=|~&p>mN*&Vb5o(*TN!HG~7^(=@Z^AIdA@xrUL>$JX%PGXC~g|mMN02jC7H8#*$21>1^)Wv#X zN8Ef}dez}wW*4LCBk^bRV9P2v)AvY4DB-m6Qm0gqcPJJT@ia`w0GHraNWFIymAZe> zXT)_C3$KX33PoE*Ip%ogtT4N^w})QGlZA13LC=mpC6wI<- zE|WS+7FXG)@r`br@PLVg$%U5*60iXH$Cu;Mlz;uJm7JL!?5$b%&>C@gbc-4cqAUhw zoW?rK`A*>U?7#Re+r*0$#KPZ(enPsY#-!WdL@=mF#^90iPfmJVwfMSuf?Aer-xKU& z|4A;h(tRG~LqRcMeP=lfXZh5m{OAVqdnNYUH-pO}ORH0{Zy1q0`#N_!-X3dD+&_d#z)5_zintcvZIFQsdg=( zhzTEUw^c@GR-!FJEJWFp8xEy61@^yhW=g#*<1^Oa+O{3)2uo6m94hi_42X)PDAPM3 zhJ_gJm0v884NFA+0NG@r-cyhP^JCYKP5iXsaIg4agll_T6h633ix+!NeS%@7Jd#h>;5?2xY zYkX70Y7@&5NXJ8^kC@b{qrQ6wg2B}D<9f2$IMX)RnJqiVr~{g+9F*TUT4+tm39=q9 z5IOSY94C>2LMhXn40HTqjTd zR13HaZv>?s?_BJn^nM@3T8aj#@Q9`GdbM_FR;4|Hv)~3-ZH~I3LA{l=wY5)5YwSwm z4jM+Moj8V$@J@3n$a=$mF$M++U{xJy_vXm;dhJzgV((C$4ZJuyLncJuaNO0G?3S{o z70@>lIe$JbMALzt4>-f9!?R-mF-G8|*q}sWn2{eVt5f{>^bD*T*1d%;@TAv%gcS!Y zeO{7N?hmgeP}o1X&R~r{h08fw^ScRCb~M3TNbjD8ZXvILmI@o?tKu{O^qtwvS+;I2z5+mAZ@C$=s;?h}hA*r+ z=yrcZ+D>sxiOmgrp%?~U{{RkZ)1|bh7W0rDbz4dyqc)z!1fYj$afxjr<~8^N?{k+X zGH|K5J+XHUBzeRhQ^5igMV5)#?-j%SQEBM^i&L4|(w4$?5Y}tfxHTz&ss6=PKenL3 zSA4aBN=4FeleJs8+BwnGq%TxO`_*e^>SDz&juV&4%kI?LA7~Sx#5Fg-FNF<@KI=QX zXfv0qB1Rm742&FG-A&P?UeCfiaW*p7-m=mGMP!$C{fyVY$3rcIoc%+{BHP81sUw1| zMh|!%2LM`{Wc|ip>m}Q@h(=B0!=#&Qi1(jxmWy$ps3#7Bs^ZtpWDPIJwg@>F;MX76Y`dr9O~U6S(KhWFq|M(2A+?+@q@;k`sX7!0mxDK{Q} zU4AHNU*)_zG^o!!j&Z6*ybgmegp_zW9wNfGL3cE~w?`>g&JNycYgel>U$*O*yP*)s zcgo?a)~5ofHWzOIfJyIx>`k6C3)Zt&foHGCGy>7wQ%R@{JU;)J{!YXE2%tW2*+Xr= zA2bxG=kQ#>qGLJQD!7KixNDX7u>~TI?3)3MBjIs@o`m!26Z9-@%!tSF>$sXZ~QnSzW7)&&~OG(;iMXO2B2qG3|TZYFvPx zZ~;a}KKp;CnX`B@_#B<+PISrv&w@5Opj4gWe#VTAKdl-sA+LCV4w`O!5k{> zjrvoPeJCbw(V1f^Ot$*D`08GKg?{#EHEIAcf7EQSOqsZVxOaQra+t9@)j;(DODc-Y zIb4fvS<5KIX;w>-?fNXr%5(l6I$t^Sii^Fc1&WRUXUBPnAENa6ZTELvHDcid1xDOZE+cPTA9+~3&jWCe;d1Mb}_p~X4 zzjdvojru^|VqDaRITQ)iKK(yz%?xUzleJ(hX%I*ctIwUc!^K(8IiqqM?$KJ~Yoi9T zn)C@PX&SHdM4WETCZ5hM$Q!md5@Yu_<;-DtxMnQj&vK=z;Z`HXr5fH`n`j zT#^S2HCSBcW6jJ)K`H4WtEZ91o$R!AMRW=-#UZsL@lHryzA|NKgP_tn(wp7K!))1@ zqodBCJ!Q|8xix-eRQAFy7)`glrtyFA=>VU!R_)7uHndS=id)b2oe6@wm!oh`*wI9+Sy?;N>;JGa1gw~m`fA@*T9q$URl^cB@4WsMB&guV$$xB4o7Xkxbrk|=Fpp=H47<5ZmsXe8uwK90VxW$S zPeY1_EAzN78gVA}{6-34dMlGjUS~@KA+4NN_Qk(!vz{sW4Lk{Z=k+rdV^E^%9k7Axf1UE~>#w>Ej9VhbU(k~3gp(~WA@Q`IaKwfrB>H*ALc&qD zTmNH2IfBbR2@?4xFW;cP=d-bqt>H#^P(14h&x}cv~1G&*%_1LW<35ieFjt6~Pn4y#WDmn{IdWe`;p`vbV_N`&jLH?LA%Bro< zeVLLGQ}&)j;R2T=FSS|e@$ti~y5eYLHSqX!zQ8%jD;I`;somw)9`y{w-Lzk~XkUOP z>wjZ=Y7;7&(G9BBn~&3%aT|$MUTV6pw&-8TY}t1AGa}V)1m$UE3@a^yD&1$hA0zwL zANBe>nFLu-=Qetno?(ieB)@%Astqi`ztfh{dqypstaMR}B6HVGI&q_tI&8}R%x>q7 z5UN`=OhZ9-f6G`i9GlnZa#3g1G}*6{T$$xe&oOiLzIpZESOBmj%y96yLDjrQS7;7y z6TYBi&OZK3?7nWvws_rm)uk$!-jiQa@y4Ueztts~LDJhJ_@wPyF;!^1veMzu=P9Td z*#DM+I}bq$DB}USF$(5XQ69P5=V{4^JS#tLVkY7KDcz&c=+QZ#iSnrwx|xW0k~Fe=J)%{O#%lF|BWt$qxe_8{E$7Gs@O5DF+*YDq z=steQ;Ub3^(DCR1eQQ2pveSE;C?GzHSy`27(nq|9U4a#c4mclFKd117aD}>vU9g_v zcFGM4^=e94Yp(WIuOfJIZMtD2j~9k8B)t#htnU<_24^Z^9XUR0;E@;smSgAIAAs0d zJmxBkQ@If7l|Oa3Y{n8(YrcKEG)&>L7?D;#?ht*p$)7x;_M7XC^eN$Nj!}!RfNli2iYlAzSQ-^tO-5QK~|ZNdR%LF8tgSVp_jc@2ZfM)X)a(^Cy=eR^*9d z%KhkLr2E`y?T_hl@#O5}^0B7sKaFH#k6XoMS0oT1l)}9irKS{AEan;`Qgf%RGzAs7 zXzP?kumBOq?l)yvb>pPGpSK4KST%k@Ai3omLcitMHK>%#t_fUWc>8 zXeukZTyosi1|@C3dJ@iq#z#0D5AUL<>&|j65F4SyS`Ly~({Bhx9J|)Fjywdg8=n8z zU-a}V0+Qz-s09TC!xVvIfj_^Q1tnzAqhC*R)cEPzR0bwe z%k~9o)i4P`xxVxStmFi@v~pQer6*S_3RI`wWOkms6m`eEzx;i*=c#CrpT9G0_4_ls zd?Ge%|C(Ey!{l%k-#IbJ*j^K<5)3Pr{_oye=JkCv5e?#!xT;;*b93)*lC=(;`dHI!7!P9USXF zeuA7fi??IvZ{-~V5<+#N3iG`fW;ZNukL3L!|H=?sTYURV(QF2n>HdN(i%Pv%t8sO& znrTXjnXDFps;-m{>0rq3AuG9zkfY;Mv*tq(C}- zCd;FfH^GS_=L0(5I?)2fz4d}q>Jqx9W%vzL>SGS($C`gQsrA>?Q1|97$b- z97nQ#OcApc&ALha-4Uj`vn@vbRZARVtqI!(RJr;D2*HW|@sLDCYJ2Sk`}N4RDT(j3 zT_^p0QecXxr-Nr$a_7glOXW9!)}Lv&rgfF1xX=AMOjI3URvHgnqHKyIU2UXDu_Fpg zbEnG?XolvY@GMw-PZ&=mRX7^a4we1o`_t;>z9YqB<7@>ms!z=7q0H$~?q&@3Qz9Vn zzr_Bg>IoAMgQD<$o^8nrJ$nO$+a3)XcP0l4b}q3yM8l1XJCyJP!fESkD5)f{A}L-< zP~&PQh4UynSk(s6?a0umesK2`W@0hRm!E{X5Y^%=sV03h)ie1&fryWeM#V-aDCqBEuuY>WjfC* zXqcST23c?N*ihZB(i0$rOq0{_10Zh$1^b*Iit2Y1!&@gjB~@nV4>L%8QgunS&4GZ8 znX)6d1NXYjq=51F>u2R`M;p$23pw{eLUOmN1Tx{*xes_eNAf{8?6Zw4zvQ6fayox` zi!mY$F}d)Z*^Hxc4)NHB5$C0-e@M011V41I&*Y{4d$NB^ZHe6f1%04=l=|;Li~qO3 z!%b@$7?}2V|L&~Re&pAOsOjtei+>etvSpSO0Guwhu3n<^22{prNSusWe#dC{`K5-B zXY}x=e;xfwS}g*1S?6vL@d>vKYZ(hxMK{TLVi-*!&&V!7YS1Tke780zR~WA!+7W-y zPwytb_OKiu$*uSp23%6kRrGEGrGY@Ys5YI_U#oh(T2sp#WVk#?Kt{vkaJ-2W0ha`* z*GGN;0LNdJRAA$UF!)%|5`Zr|2xpgu(o79)SXKh~s~@#fJ~rj$gW5N_FZ_^Lp|GtqKq^_#<=n-mf) z$u%RsK9Q9<+f52?y4t66Zf1w7cIye{D|C|gbzIk(8eYd!?Lqz19;JGE3K$npR9 znR@Il!(GEoFnlU_hRwGr9DqRB_u&;n`#=e){)kCpKNWdOz}8mx{Xn-efLvxUmIVxs zWda5Xx`KP&L`X&?l$=@gzw@Z{NI>1rsPiF zyaC|54&%^ z7|hhD5x1L&PfT5vwX9%p+tD!*FI4qU!~V$fwP?X2{txTF;95NYtYK5$I)CH0xOfQ! zgf7lF536_2orgd9{3YWQgUYqBSk1$P{{zJ(gNF{~rg{M14iP&I|6_OO0sn${^;cLM zHQKMC(LSl%*eT(wdl1IOhP!#K7A$gk#jNiao)Q{=lf#C1Mp|m>K=H$wze`IVci=I8 z9VzKjZcpjdO$bH4^jq-h0PNw^{jWI-w+S97x(IP_AShvo!zYXg(sdFJMwWDWMyDTu z(jPYr{$@aQ6!~>lKmAAL_Iz_#X#Dqy1}u`DKu*i|8L}(*Zw)sUkBDj3Sq&Mdy;px= z*AZ=w1f+BG$RyF>f6uqbD6-A#3Y%UQRHty%ipb3;jwY<=@Hn;INdq2rYDNa9aCmj# z$^|S(z0LBPT*|_E#pYOn`j$il8c`AG4x4+rbYay`brcrWC>ZBV&eBFkPICb% z^gB;5s}5rT(x|mKAZ*tramdu`HedK`br%v!q-8iX>QoCt#l1b9eoF*b<&+q=7gay5WpEyeOf_8u+vE-XYjlhfKi zued!qh)QVFLW<`rGzK{Vm%02dtKf|g)^QI{MQ8Q7Ja*I+OdU3gusqiZcJG@!igmM5 zYycptdN0aoYxGmiK;`lTsWn~leMC+XE!2W{Zs2=QTo3MyO`19oh;{MfhfhtH#}9Sw z-jQC_USd#ZJeJ*_$t7fD1=~nkU%LL!d|dHk;0nMYXO=Q4q#z|QDR%cI`jt5UufNt-W-(oTI=9;Y=o`Sys9)x{;Sax@;OtPG>XKX0r?HA~_BQnWpW0ozYs4yOvoZKms72d3Yo6fE1H zC4&@CGQ~boI(rMm_J@y~*;F70Lz$Nm^OH*R`#otk3m4RuM}`P z_W6LMd_t$E5XxTh0r?L|caA8myUe9@4QuVLQIO7;Ourn#cpC09U3&dg5 znt3F$SoIdhGQZT-P`MeIZm88d z-LI>lQ5WWOM*?#Lkhci@1pbo;7wi`(XtO{J70$mvFOW0Ju|Bu21ZYgZ*sJGUFm<}- zVVU)Yh%2!3$tKr3RTs?L?#PoOjrk%r_jjqblpC3@wnU>9s~;Jv6nrIUN1R>?qGz`+Ks`=9Nyn-31lSD)9hq8Vm(t35H9!=FEYo=3U= z`g@P8nK_lgG>1wKAGx?UQB~yiS;ks~6qR2p)b=#>RpF_B6UA_zf1`0sw9&lwiHfw; z5lA)Lc7>VN%i|Hd;8{@-{2&~k;vE0pk|wH9|LvscZeV&&V#dp){eCXHzvjR(-Q-M* zQ<{!?HH5kx4cQ;15@qABd-rwX{r^u|Ti&{diG792P-b|l9p|3PyD7&6wGQi5%q}E# z0&xKVTIF#|T&boU9p(&Go#Dw*=d784zg9DqBfN+1WMA-)t)u&KtyiCW!-!%DsJlEZ zs3%`6oQ~uz{oMdFE5|w^g7r&TrGjO^$G?8)5HgQQ-k_?a(|x*QP*^fJ`ct%MI2Rda zRs})S+Vm^b7;wwf8Qe#hr|I|`NRS_Jn-Z;&-*LKr`=3X~aJV*myVG#_1JiIoR{7P$ z{I#g3SMVK`d1$sqMzPA|O^J#HI|FWTzrNj+B{6QoR2vYtjGb|d1WuD5f_@u!K$wu`$r4VxiA{gln^GHXld&cTNw}1vkGKS|Oa8Fs? z+sE2IBYEW@Fsg#*Ys66cl(Li4o9m43H8IJu%V{x=W__ zA%e#P={=O#z!Koh9{2aX?(b(~?Cs#U5KLmRFk(X^woKjieh*>BYp3SBUMAIt==CGQ z9&ylOUNwWHmys547)S0?y4nL%bNd$G4&)3Ti}&?&(HUjax{gn6YkHrYFNe{8pA?>aWWWMiHWVLXyd+Q=ygV$K{8Wy?KZOFZyJ5r(Dots>#5f z=MLGeqa%Ex-{+sOWJWG8pD6-5{d!9ZY#u6_rLst`SldC&G)}plCS_?)#J$>+q3^WR z+LYf*rOgl6TjrVZMA6L1Aj=PiJ`0zeq`J|GV(5Hb9(1udO$9o$5DmpQl>je>rj)PN zWO$Tl!R6K70C{Eyhr05b+Cz7nqUZ3%q^lJ`Pr9WJz`iMAAtsR>y#0&2%+NxH{ z8z03EgW5y5;ca>eY8c{`IC7hOUmd41d-En%`sy9wO6pk?rrTWht5@TKh*u?BTX2eBMoN8PMD&^C0dx)e0%@_y0+q5tOOa$E5q8{sSbl; zAs?W7LxA4WPoF(|5;;rcDe1<1#eSN(ag3C(^f?DG-q65=ezW3C;nS_5dWJ$)y^3qo zzMj0>wC*JWB3=@(pHUtZrqj zfa#0$LC&~~#c>^}s5N&^%ag&c%`hLJ!FBw&lqkW;2pu!x40%fDRotDylD-8#E9soKECs}$=4;?Xa5{7nj^{2nO(6s3a@m3!o70|xEy-7j} z8viKLrX(K|sYIu*q?BdIlJ7-6hg#nCVk&h zF4p|A2^)~mZoe=16+%ZJ1A+kmnDG7K0AR(fCF?eX$x9(`6v zZaWA&fi`i{0_c>V!GE*VypA!UANnZA+e`V2xBJ9R2G_{BR-=+e`-{s4Ek9qAraRHN z@}865VW?|H;M24fad|;9fU*j$$FV!RRSq`UUvpTQlC3joq}^y(HWiY8)pDy96F-)z zSEj}b9?15x@K&zRGL!)0NM>Cp_oqO#nr!hM+7PYr-;~G41@B{S`eBRKf}S727+zQX zPDB#mtZ+KVDND{e3u1`qKdU7u)4Dj5*9~RRKie@YmqJU;#X^k?9vAA3xunFaC!iuL!TXfq z75}L>^81T^L}9Y3*LrsU2-KA%K6~r9Y*M z7cf1aE~dWHGuNnT!?K?IA4h^e0Jp-(;&LkVu#9kcWGdf0hD^2O?&t97Z zhE(vl!A77=8;i)bPEwzn$L1EVK!5K!4So};aX>T22ot<4@y}lJ?GQG9UgJ4H1pp|k z76gii7Zj9~Q19Bz^k`=L+#GfCIq#bGM{E3J`iErUL`g!QDh7(v%Vecvf3z+?kY$b< zkcs`*xf#h#Vc^?Il=|lmEL14Na9aHq`j0`K*TIvB9h*SvhO%Gz`51H$0S3xUj(2?F zbwXagep&K4-#QXspc)+9S^JCu&3%IM!%JSg}HF9&XK+FIuE{6=pD&kbX%>lsLz_pP^zhUEDu)b)kMb6Tdm`nz3WVa0$g zhdG8rkzHErqy<+7MIEYNwOwMFi_`5$vy@}Lf|`B0+T-I>XWzPR!)1AQ-g%+9ovj#c ztkYLpk~EY2Ia|aN#w;uWmfrVU<);KFXYOm^+xeOC7BLvFtQ%bJX$=+SIuT+^reuuB zo)$9dM%14r7{r+?=!D;FcLoP-s7LdjY^>2YU3s6>5OVs|9T^(4G5b23mU%13^|Z9! zZ*`Y*&{Kj)j`z&)0XRk!IZ$@uMXA%|`_6&qLFLrG`E-&zt=UYMrRd$|&a~k*&ZrhU z1r5Rr$a@{Woy-~^>>&A-^{uK%*BK74Mrgg76VP5Y9vM-q+U=QkB#f|1!Pv%PY_!`i zKYEeV2*p!fp>a#|2gVm^+IRdSKD+N;XTU3NLDEX97==>hx>w&Y07z`ze?l_s|D@Ms)&B13 zPV$oHGX;@;W+YzpIbiURL`5}WTSd!tbzDIq0(O0hPwtM~{f4_YcRf47CJ@*BzSabT zYp=}=kE@MfRwEHJSlo3^MIy;y!es7OH|KUd43T7dG6jMVcN>2xk(&YXtu;9R-C^L# z!mcKtqMhhPbFHSNLisa&-4yxfNaTs!GWyPB#_~cx>XYnixyroI7R)FN|9c&Axcief zZ|r~@ujAh~F1-?2e6}~8qn5`R1jS)73{r9I^>*u2YYm%OwB+02X_5=u4D!Qfw7D{%L+j$m_yK{GE0aN{b+8m1KP%zwquVP~%T?pY8{IhtHNON);wi35yiF4-c z?gQ6MDTFAS#NeL(BrUa?Hc+ zlvlH+F_>y*+%Y>}ip_w$n$8dr>}un!c1|1w~UPv=x-+p>m92uM34zRcvW?PlzPhqdLFzD5EjQ`@Dz~1$b9!~T+UbnI_w5D@tY^pKEYq?D^ODE65aOwiz`gyd^)vWKv0j5K4 z0UK-8;&pJxIc;67oob|Gn=2Y{dAe3DIo41qh-hCMW_0DB^X=uJM+9~RFZ1zrMjoZC z%&|11$Vj)^!i7(h;131z#s*u54_sAqdgoXOoii$V?Z7baKdbi#5zle*1bsXhoPLl3 zUW&TOl<5hE%-3>ha}IYP?>5m{-?@o>SVObnBZ=VUx^YdO=fCF)HDna7&b-T zGDiGDq@hNzUT!Eu58P)@fgEQfJlCVmM8NXvu~6|CZ&TmZi7_`un@cxx4cAygeizJk zcpiH7JA@vc%W5QM((8mIRX4=gME}NAq5yf$Abuo)Tet01B);!-xd9<&awVE;!#=E7 ze4%HbtH&ZJl$XtMyq)Y$061UYbr5ch8;--rF?GC5eWvIKODVtnFuMvXo+XHj0DvY#wZMVb-oCuXD$OL~NdUEjeO>}^7!)*hqEd=shV7lv!-8IIYkHcN8@{o#nfN%OR>)QB)`7JV! z-03#Zx{L!3ADlIG$Zg(I$-*R2nv)YCh!@Rg1ql-Z)069Q-MO}9O;>EiWqLR#k;ux9 z$Bn>>++zPv>hkJG-M*~pud;^U%y*)dI*{1!?xOn%?K7f9aD~79Pe_hRPq>==x5Ar) zU{nl>sPbr=Vv8l-_I>e-8bb8lI}WFw55Ao{1+yk0j{rwk2sVC3dIdu4afaB80x3C8 zjKSt>UAKr?uFiAPtvw-3Ny!7!@LGwUSH!+tj`4-EF}v$!qj^T~dNDU;jsUyq#AJR9 zfV`dP>QN@DWio5i_rh(w*}hmC`P+@+VO&D0V>ouh%5~-fIsc*q9;f&EHYx7lPn@_J zHCu@IhpEa>3c2aogB%I&n`3ury;PJStKO5R-%T8S$3c@$ni>8I=N~Cc*~oxlrMe~Q zeC>vkaQ@c&MPy=v!*1ON<(`V-`FD!MM@s2m-!XgxMwY*yN{URk%feoAy$oJ7HbfI@@A-k+AUcdRYLQJ0JvuWau~sB{VrJTsw)1S)pOQOimlQ z9~RH~iyO>e1Q@HRP&w~sq=P~UvvmeM^7Hf0UIXx7ORwa1Qvw^33AD9yOkRUCRSSap zDJQfV;d=R5U`r}|0kWauZdH~m*WTW!DA~(VaOgQgu_>w4aGH#5zi)%#!j5+*g?iL<#ey#X=M>-vUG<%;_MQQBKa zwbjMjq7>RvN`V5Ulmev$YjJlg1a~j)?(Wb+f#AhmLvbnYq%H35k|H6vTd>@;-*?9w z@11wWv#vUT5GQPo4>gzI%Jzg2!K<58^~e{DhpzM=O3h{U#jAjycFCf zx4SPaZeJ4D#epInigB_P^@d>pLI%<|clTW*oV_})5Wb5#MdMo)H2KMozaKZyx+jDo z2p9~KTT(X&f_HpM>MLNTH;y0$^fW`r28OSj58|jHfTXRP$oe2II-5bO?qtI24ABo6 zzuL~@JL+;tx5p;LgofApyVG$8B>T9F@{SVXD21>4SBeEaCKkXDVSFc`}AEptZ1uK^}x8zcztK^LI}uD_y!-^ z5Y|rbJ*&M9B(~IUcImd!7@G@|+8A)XC~s4ChF6B0*nKBICi5Zjxcka&)Zo}9C$J8Q zSkE{LQH9DFJ6w(|IQw4pGYF5k8E}479NRlBgJ&#f>1~pN1dtrzLyEazb?C~m%COwNh;moULs?yUw z7(tRjy0^;uxC(N>wa&3u?qy0(o@w)xct(I-M*De4e^=KdY+(U zAg1R-GnZqh{LCo3`Rq=TL8oOHuK=R2u1q~xQYL-$vX@gg?lGRE zz)+e}G*3(9G1~UJ;p-h2DhhuePTyv(SvOs)7<;(^`pI3A4iht_we2^;GE2I* zd&jBM)|J-wpV^m6Q6VtU)}t%?iMoAJg*`1bp2uM27Wu%%=u%DHFu6UMz2I+ zW0BopS9hdkm=7c9f-`TzbkXD9r9B9GE1aTv;yj7roHID{g1Txc>;^T{ZF`%2+}Q0b zN3gZwh0(+EMidB4A=GxbcG>C4qQk-H!OVD$ul+3j`Q(P&3IH0Ob5*mn9a-Xdbc^^& zu8*R&-Ja^-_tE^B!hGK%iPc+Er}+E*--ODK|B8Xi|5ZEx%Qd6@YYFk`Uvr`#um9n= zjsCT#`2Jr$e6TP=R+hizA=;;y&*X2>1O@&*p@P&GxnO>pfZ6^N+^sYaC}M(VUv}0_ z{qRpIS!#-&raW>63l%W4m&j4*mdNh_5?UU2-`6qdFekM16~y@4k(;X$r%jy-eaka4 zPn8<_oUA*3pxeQjQ~=-}aLlrpeK_lxD4$Tmy%s+#*D+$nPlA>!LDNdhJ8<1kbdde# zAYfI_vnycF9H=Z^?K|(iBT# z-|DC}phnKG0rzDRJ~{aIl46qPfY$-S+a0hT&91qF@o7Zz_ocU_=Eb}#-TLi_|IzqG zMxfURam8N|7zmuzn!{oUO9tE2iTCu?nCsToz$#-xw0AFtyEy*l>mO+#T2TL z5AHVJL{vk~NDuC|nYG@DZFc9-(*cGH-*q=#CXe`A{%TV0{_WX7{2bp}$&XM7xOzbN z0^j$D9v|O2)}O;z`qMAEw^nPH^N#_(B90kRi3yD4t>y0w0wv*Gzb@qqviJm;&_(HJ zoK8z>#)G$!L-au zj=a<*{U5n$`t%Q04~RRAv_62B=kH=bski!vA=ln#2@F9d94-(X&zxo{IUumKUgf|Q z&u0Er!cGwBZdHaK>tbL=?0eGv2cjvn3v4~`{M_I1)=(=_fVkvsdVcY;_Bd{rIy*Wo zm4{4vua3E%;fMR3qhfcGRf-8XHuvPx{=6yK!=z_w8ThS69CtKqzID+Smu+K@%7g;$ z%Mzt^7kRD+8}%PXxg;YSF`wpJBvyTFlKXBI=#d(IF;|3NVv~O&ew^{p70*2Sr3y{w z5vaIoC|m|oTuAAk({c|TNx#h{MJ4#=R!(UP*ku@dTA1G7xA4pIAACGg-L^WwTx71$ znti3K%R9SCn;Gcj^;>LzH}qM!>f-7) zD3qNDymB@ZZvt&y9#S++n)Px?#W(GBG9DgIc>0nM+r_-ef)>#9c>SK>N}v&>y$c?r zF}xvk(LJvdXK$TxXq7UyV%skeyHxmzZ>cU#he86NHED* zbP47MO=`me@QrcN0qjIiUf+`$iv#2F!FPik6IIXgeWlB z=P>nU)=iD(CW&}<%Z~8n&8@iV#m`Cx%bjfRCX|ZLh-X(0cLTB!1yoE$KP<-o4>00Ele3NKCv~e^jZ!R$8EM*SuotZYFWGG^wpn1gjnhbhU22K zba>#Upg$ma6$@Y(7$0F3-0iz+_%-5i*8fd}$v@{3w#Y(@=*}6LO}! zCsmzMOkSB2w4W0+@4W27iK@;W7SOD0#+se`;;0C82l_GN|T>5DOs@JwM zRHH9x3v$9bGI@SgA?SQCF&cOdXUos#zNGc&OT)s5!>@OT(>#rM*4A<Y_V4gNv4HYkTQ5FAiWDU#g^G zPqdYl=6~n1jTtwQxg_U*`y#QyzA>E=Al|$~EAD^yA}H!hyG)s7d1g-tK@d zMQV`N!dc%WrmZZKT*yoF@JMW%192KY%^*DY4e+@&R8DnE4-Er@W6`ukoBEKe2qhS zAmIjYst}o)M`QBTgKpzY<5?XgfSolq;9ZKBk4&II(;WaMa6tw8kHVi#2SCmsJ^0|9 z`}|zG8g6%L{hsa!h7>s^Ef;cog}Fm?w3Z+^abRkfHhT$Je&=0+Pe;nh?=xu%7Ce=M zW-<-*n*jb<=2 z3x%duJ^X8OiK^7~<+U)+&(I(isiZ)@sbxA&iz-PYc_3`tQ0e>NLSTj=PKW727zac`^iGXCU^itHJm|92E3?7+%Hj!u7Jw$5UVB3X|g9NC*6o z@Ws7`BuU(lrsMU{pmUDk7b~mK*B0fO`x4Yoqwh?Luc-o?!!9?L)p{vwqtJGWc7k;Z^(hCX}m!s)^}5E)Vtt zG%p}cXX?|3r~!Hq{4$y44q=MC$;si$$iL+P)Ivz7H|4zFuoth>O6vPCn0N0o@r0sa z)bsKArPCNyOy;o3hVDh=T>6ijiv9-78G3=e$B-TS>lfK?wVU1^dDr2hIVs&xH1F*l{Uk@bw=~9lf;ROiR?ov@ zt{VLZl5r31!SDHhVlV$GJRF`}-r#2279CgxUj^~GS(D+?ZPkA|ildCpFdmGdxHwQc zup4#74I|_h^qRP0Qz-PzwrO<;spt&ALu;v|>wpR2DG@WP;Zo=ydza_xHp10$Lk+ryF?JOfXX-OC=?BhL}=Amdb-NjN8-WLD8arLOVrcPPfE%H42B@6pc5td~_) zRlRRsw(x&wbf};RDXpqHd?r(j^;vYxWd1+wk5T!LdhY)e`-Ubt^}mDDU-t|B`84<0 zg)xqDKgTb@^?S`W2hJ%2SZ(sq$)S=ZZryInl|8j$0|Hb~7;}E>b?#&_v#`I>BosdK zTEKjJlYv}+C;=r-SgJk&m#D48T+^#50fDpe!XyGPFu9gM)Aumhr)rJ9BQd$wDy3}{Jf;N0~6x%B=(5OBWvh+^Y$ zR}ozk+k1+bSVR|-d5GZ!apby}Ya$=m?zAH|U64gF`_*Jh^!)?=2g7+y<{~fThWJ}z zMDn?PmuuY93TLveHlsC4c12~3r_Ph_&TnI1{Us}{Hm>#j5p9B0gPF3$E{61 zIs3UD9gRORua*W0-+j@nS&qY72rwB_nKo? zDLVDEklzi1-<9PQ?xXYN5Yr!W9HYn?l}A*|i*e#!bLu3eKW2)GB&YSRGgerrkr+%u zz@Cj#a(Za&JAnJ}KO&4ai{Tc0P(lI=2S=e&8e>1ZHM9g$E6bK}`k|ox@fSv$u*leQdFXN{- zuFf4>u~QRl;ls#_7pB_;)Kx1|95s+PGY8^N(UdgRz#@UGs;ApY8Z8$ro6d9mjLO+p z{b921Kk))}+ZgLXAa$GQxs}b83`;yr>v|n`jfx3bAE<95f%Ja&Yp#)~&d6X#YZf*K zW1qAU{=H>n2AqYt)unpKdT)Zpba~gIurRCA?(!)GW#X9?+ro}*l)lvcykQU1hRNX8XRAZ+94@}t-Yq)U6!tKux>OTnFU-mw!>l>H7ld;I0LUBlN>RH zES_=*7p)60(`>26+WSS0(QcgnE5Dx>>1nB13EwhhoUt`?%yiz3`_F_XnUd)h+6|4! zXChs|VXtJQ_dJm+4L3QcEF!vF$;4KleoszYM@`L>(!BhWEd~xpl5}kI4CiVWs59P~ywtn--iZ{m$9tU|Noz zjjEK&Uy67JovK=pbqorHE+;Z-6Lv#qJW@7%Eb0amlTsPilez&8>Z#8l z%gIrhldkRuxnL*WOhm2aD-sf+tI34{my;_ta$OBVM#C{`60$9acYTl#s5Ww85!Yb6 zgHt~+_hDi21HGnU`#fv7%JP&fnUf+J+WmLMmmc9DdGcE-;-0%BiLXAh7YX(@c?e1+ zmnU~_zQ0EHv5*S#P(-DG?=16!ACW(2W-P?aygDJfySwn=0NuA+dYFfEhz685k)8q# zJ{tn7RVjS{hD%MtK6JNNiBmMtubfz8-N@~fD#put<}RxTk?MY)(8_n8+6gj3krr2A zYX2;n`fjN}b&Kqg+jE;RL)ZRd7gr6~Gkh>#l5@E8*9*Uh5Jx!N<`qCe=NG=}RWlc- z^kYD_-fD@8gTmx15NNzOQb$;Pc~*{cNP12S2u$~Hos?3$GGv1vT<1c;A+8%!_yNQk!egi6dHrJ0xKwzJ-_=qCS-!0O4wJ!~}? z#gs%8lfSszHw=~!C!?*p3R@iKyPvr4H01(o`Mr8a`x&{$V)D#Z9L9dRg>jc0fWN#g ziGjvnog&#A<+kr(&}<`@9tw3f3~LEf**AQ1*CMvFwTk>u*()L(b8yNj2jzXv0r=tH zCsq12keM9tHail6XP?T(qC)jF_6{I@x2^0La`R)%de^m7S5NQv{}&Q6z1`l8%k$L4 z#CaNV&8{^jKE(?5J+iVs5jeo;Ov$pT&rY%Q6Ba+(w+aE+IR~Xbl+4IBlprm?m!(|gl1y__j2-Ond#h}pk0IPZ9M zd2~*%x#;IHJ?%+)U$wy9DPjXI3`UtyU(^}XdC<}|mbbOF<>%WYS6$wqeL{MN2HCq3 z_rk17Nt_}0*jn=6y-!f#|JXmNb7R>L^Pt(-`&)qYwPuMbElE!|BD5outu~Rszd1$v zxc}(-{{uJX-Qv{0>Xe$E4p)CFdV@kUykv?D98SDsq1$ed${|+yNb~<67<6fWoI8t- z0zMU0Re_4rXmuDU*mR~N%E0jj2QQn`U(wPx+m$!-`|8i(qW^Gsieh!|-#i@5k9!U>p9N)Or@@D!CvcCqcwF zppON2^LsGraMWex$kBei6{=6?ID-!re(TfLxEx#!N%NJ53-^pz~UE#%YY9vFm4~to-nf z^bPr%T|R^SLcCjHR9~0(#+Nt@#_j5JJ*DL|Yxead5%oF34H~~Ixx-6KuZ-L3c|>v| zVT#3NN?c8mp9xCvFG_cOcDO2pv68jVkRM^F8CZ`DvaBOj6&-Z5ygXDLw15yhi3HlJ z5-93~jHa!c_08iqo;KM9eA4d3fIaHvaO1A9XxjND7(JbfhB(g*g;ZclFuw)@3m{*Q zj;mML-)OjdW?ZGj%`B113^u;GU-r$cb3z(F)p^D7DUiwo>rYIGEl1Y2ZB&{0Y zvYX=Ts$Vom79cN_!ZG?($g~`(Y;4Do05Qq(VRUSIHj2_$f2u60a9n+yrRg{k-3yLi z$`VkWb}u0A>s7#VD;-*HX5x!o#rh_0aj&hJ+2RWCS6z#rv-ffXoep;q>B?rBZ?@qE|ipyzEl|j$UM9h|eED3}C0*#ra&vjC_ zBhPDYV7u7y!oo&uj*6eStm8Xme@lg^s=6p9RhGunQE)J={q!^M)#^!#@pEhfQ;A-x~O1^rJ9!>dwv&k5lB68U&xhAYL}=mU%G39> zwCQopNj4|*j}K0e%J^DcozUZBIpe!DMi z#Ik|buyXylf{3u!S3q|70uFu4V@;ZqhH9TL8>qE# zBD6R9TQi&ZX=b(JTH(o-Lr`=^5Qx(nY97(Ul)lw9O6e)t`{K?|w=KGNQ+yr55p0dx~DWdUw52 z5_WYNF5)Y7s%!=fQ+ijA+U-V>6p@Yx)>C+ zn^k-RX|5DkQ0iezIrN~^T0XH+&;5dYl1XvU8C_$5-?hz`J!kj~j%8x(43#Ip#?A|T z!f}+1YS$O$EmPVSo}$XO%({6j+n5xqa|;Z~7%Y5^-AA;)LRS>zTejW!0mAsu_fDBw zift+zw?*%eCH7#le>_Nk_cT+O*4n!|Wz4#!yUbsxl zrwVy{`+SrH;wyM%o^KLZUQe((gl1y&cMG!xlA0BcE}#Eo17ve{O&KY!{k&i3b_PS@?%U48mxZ-_K8u@EEjJlJx`S|ZF* z2$eOBD_muozO+t^oCr0*E zwKekQZ1eka`5FWeb~Mn9gXq_%nwlLlLN9|?&J^c}FVlYTnYkUI*?A-a*{n zuLuDlOg#Gj0gZ9kLCtIwmn9BCGZ+4Gfe=$fAPc3<+!;}$>=kbCFbFid?oO3Y+i6>( zoEjJ?rf-uaS9Pl`w)t}v!T{0DHir@M2Y?dK9t+2YpWb;VhYnIqrs^^CUR4uz1f$?CK@Y&0$t zxo?(1Z{Bcm07}QVcR^?T;`-Rm`!%DJk)`t8iDAf!!+FKu=K$cK4=oO6ug4WYV;w zCg5g!mfaZ)#$6*E+NOttp9D8(qj67;pislpGO<*1u3b&|5&WxZ;(_8flK1r0kwX=D zCx0cXPH?U=)5?C$Esvy$M=@; zWcurBvo6oQPy$^YUMlxb&rB2eNR=jG+?f4_JZ4MU`4kMtYN^98q4!UC);HktE`p2! zyV^kME_~0Q%3y&6sX+$)!jgEc`1CaTXs!h|$XgvvGp!6x7)s85`jc3ukdQ9zIrIbV z4WB)1fsEn9dv_`TN0>pVzDNO1>OS|6`>mOzU9vr<(x#2Ex@^&v)q-;N_Uu&#$%`r2 z{r9z1t`sw3R+}FUUq+J&r_-Lj;u?>M3hwc7oU6Y+bnj|Js?{BKavW;cuvB@+ zW-PdM>8SXfG%dV0T4-lkUE=-Dpztk$>|^6KTHF|iNr19w)7=P{VJ6WD$PS&>`)JRM z%3QbM?v7K1XS=UIn-&;b(mU547@LT#b?z_{`{L#Ajq%niV85-Rpsfm?ea%k2vqcvd z>6;aSfYTigJ&ZJ8rKi4Q=#HX&UpYwEg$3SMb5FZdSsF~P(gXxL7A@-ziuZy*XWsp` zYU&z3CAz)Fu9de|P^yntYiJOfgPa`wD@S-qGwzTcmuZ&lLkvS~oZT ze-ybt(k-8*WNl)4pbkRI-4*{Uw?_LvCExzbfoHitm-+9(L4JbLaRLx%9L-Y?f z6zcy7+W(7pnE#hOZ0)^cY!=E^-~P1Mf%g7{#NMva-#VS}IJ|n_TGtSK z9r$6D*aubH+`DDLxRNyp8GpI7_fgk&O|GabU;-+yPuhquW1E*9t_LOqV>7Nq`?t?+ zJ&>i$%#)|S9c28D9^a`h&q~vrQ?9RhHD7M(O{!M?2$Aa@2mvnak=r&R-8!0j=2rZ- z=2F=XW*hwLb_%j>5{Q*#l9lxDU*b<|>hnKuyt?hS)ex(~awUGeK)791U>70B?=LZ! za)uX`CZxkG*luI7M0990Uoj*H5qOzek#724t>CbMuJqvDj^PcwEaYlYg8m?` zy;2`lOTJ!*u)ZlNum8nae{jKaSuIasyMWrE@O{>M@gWUNWcz^;K9_x)Xfr)!YY&&( z%!X*%*L{VfrGIPRXbZ{i5S#dPzh;nJxjAqKPV4Rz`;szJc4i@Lj4x~;$y0TxmQ4#N zwXt5KiaMK(Jyhg3l=mwwncgMw?=-NRFb^y zd=)+NN~+WW)TKlM1DU=g<6HoCfeg`kvEuTg-S--CT4J&kzZI8L#Sj%4p)3(2)kzuf8#2m0&3(! z-U&9=r$LQ8g!n4+{gdg>k=&eaOx`y!C_70JeIkRhOk`aAGJQD6COj&$mob_IfO6W! z?glEH?wihEv*^887zBYpESp*eQ~;YqDGGz#dBH;Nv^<8t0-sM8?&ofs3h@sWb9lP4 zm98@>?(6yBZkzkRA245>>0YdSk>AnJ)RHt)1pW$OlJ}D~RFj}?)Acw#>y9+9pW1a6 zdM&f8AF>Uf^e8;?HBcBVBl2nAkS~CHQkA~DJ@49#-g4}ZbBDeH{0!uQUQ&MDtnwsZf zy&IE4|IFz(my|-w4w^rVn>C7Y8!)IHX^pV`yIhTq3(e`-xsEMMU`{}cs+1I*vZL~L z;TM=L(ibO#eO}HB_M@=LpPs#y$2F3W!s!{AP=VI*&#HBTh;9O~=JgA_G=8CS$LVqV zU2e;rWhup+0~Trm6X?m63y~ffkQfBm~(-VD%h~0n2 z$X4N`#hhWbLaw=ZoUmVVG~>5VmyKULc7p|C^i`AtkE`kOKw(k;6KZ>bWD zlum2iSYDUE?h5}kkyagfSf}x;LU7rqWVUCW*1O~(3(p{9e_SN&iT{M(&iI<_J>Xrd zPQOAi8$FA>xKaP0{lI7n|FcdPn%m2NN9+Ht@~dt7IOCW~=vcr5EP1aJ?7{?Aq;t*M9u#r*zBG$@MpF=>J-FW*|lUw*cu5gURl0 zSo*5N6W{E(LjI=Pv4Bt;k7LM6aGq>!iM6}}pSdae3!UEIl-Gs+vqQ|nC$t8!31kdv zN9Ud0c^jPnNulw=h=|Db|J+MaQj#2>*c@UhbtPb3Y;pFxa&U z*3YE=yso*}zNw6#AD!Q}HCfuB{~a7#IH~14gm%6Dj_7FrD_-tT9lk&Q=iw>5a%SyN$7U!1;RvRH8`{6-xnkK3Vp}#N85vXNXDxO8% z{W7)PY2n8KUg3&xOTget+u}ki_1-o%DbuIYq3K!6s^x{FQex z^<3dAjKbExm4l|ZEA$W!C7wzBHSI4KtB&e=xbVdf%e}Obxl+??0!Xm?xbXRQ(bfIB zLsvRaMlC8ixR3pU$22KV6JI%zwOGv~ z40B2LXw^i1GvGDISi((1#fTK`@iuY|CWg?@{X)Wgt1pX-ws&rFor%lc_n1s zbM^cFB~U8~dh0Z8F&8xld3dReY}-v)+=qxUt(rr*0j50=&&kf{A*OX#v1Q#3jk{+( zIdti8fkbM>**0?=SRXic6XD!-E)HrkgJl9TrFg#%u#$U>Ie~XFz z?E~?Rg-qhd=a*m&KN5WW>Enqi7Z^*56z^0?4P(l!#m1^`jfryonL*(?%`Jf6#*ZhU z#zNwg;sU-DzVpVP3CSB3sq2N8v|6Q;jfIBe1UYBaW~B!TM04kXB}M-3j-=P;k`>uI zm6@#t>z5Q9&c#}t4+hpYZcXmU_p@<`rK_rFos%k;XTZ^4rpK#n@0x);L$S%O>hsBy zF5xAs@#Kx^pwfrOVe+-5JKbHzLwq_86|Dt|KWM6H)|bKAJMu9Gt2Q_m*bSa^7%6O1 z?4h(OgRFpDw~jBxBW52a`I_liuu~5_Q#t}>A(XT$TLE=#2FESj3&TH-q8f>xPEKc9 zVFOAJ;RX%rDso*4g3Lx=k|qr*o~@m@#zd-tKsL+1uip*2Nod~b3KQM;>qh`}&E3woZppd$+hL-Y~aw!T) zJzV$9To2lJ8{lc(a=XDTuAJuQD;Vw*FK^%ttVO<6uRmlvb?2qqSnGQ?rXOX?e*)F+ zNAVh{``^?lFGe4G78kX~HmJf^z>;4r2`(eQFT?~MFo(4e#;IJB5LOh^_KBw$%;{_N zSRkU7|8!9s@t^PXZKVs;ez_j)p<})Zs2zP(PvF9yz)C{@W4`AlEg4Nt>Wu7 zGv0G3j;$wk4#P}>=~k<0`pd2mmYpoP!H;Ed?Z+S;C$D}S`;~&m4tC#s+K%1qEoI#qQbKr ze>9<-EwdM^Nm|Fn20j4tka`p6#LwN=!(()rghuF$#X%cZj&6n*VEZWp%H||yXJ5NV zqj*KAINF`>pZr>*ka>^Vu)sa4Qo5(RO*SpXJ?onI=klx1|Bi%c|Gn9`U zUd~U1Z_2@PTk&(U|E3S4G5*v0qWxc^jsJ~C9uYWjRCl<;(D-+~Q5gwEV5OK*(Ek7v CVh29} literal 0 HcmV?d00001 diff --git a/deployment/v3/docs/images/mailserver-2.png b/deployment/v3/docs/images/mailserver-2.png new file mode 100644 index 0000000000000000000000000000000000000000..8ed002fe4ae9bd88c58dbd553ebcfd5db8c5437e GIT binary patch literal 30662 zcmce-byS?owl7MQm0)QI5Ii&%Jh(#=8n@sM!QI^xAkcVlcXxM7aCe8MgFB5ijdPo< zz24bp-#6ZU=a2WsfKg3RJ-=CBO`pFC`YbDk@sjW*3JMB_gg8h61?5R93d$qsUyqS9 zS|8~Zk;4mHadih26wI!N-$$|Zm_#TjZ&4&bAC+8F_91R+I3~?PM||XOenh?f^vWvh zT?peBd2t@m3Q5HX@FLoIhAE_2zf>|p!_9)RPNT#)V|t>F$3#| z#UteSfy{QH>0#n4=Vvu7&-$90(qdB*?ct#k28M;E;JUy+DG8QiD^}PU6G{M zj=gNFkdKjZe5@*a+vDB|S>W*-_zuX0DLOGWn_Pi1KsJ(hkq4~h<%hWm0L1pqjGo)o zIlOAT^3Qpn6WROysVg@R_{#li2%207oS=Np!z1oD^UP;^ho3^Se_iDHCHErS;atZ% zC&QbpV!8kp#Wn$?nFr22$jyi7#`7oTzv@~&rjxm)d2?2}dW(WySJe!n&yJMQh~b`Y z_-b!-c4GGU--iTY&cEp`SdC-+OF&}cH^vIRQ0)2dP1r5}d;VGT)g-vo^LJRx>20Dt zuK+BGRi|fV_e=7!A|7$fVJc_IaG5!+pn{L1tg{;LSl!xMpFg|;ugP`pr+6W?N73qN zah~eh+S;d8#cuKaI6WNm3iFveoPl7lf2Xjjk7a(Om4rNPV(Ul6tOAAZ_mA^#w4zGD zd$pGEvlT5MP+59_r^nOs_bQ7*xWP(!?zjX|;WNU&9jhvO~<#jA&Tzb{0lmzSe#;IHeD< z-i%G0JFjAQ4}v>$%Qf2!4Gh?4wc8B0JMlt%zc!>ybX*M4p1b#higH1@>5t5+xeR|bXK5%Fb?CyrYpcWqot zsr0z-U-HaaWkt`$;=7r9^pPH3KMt@AXl`t__YrF3*nc$%Hw58PB)zNLnj!%WIyl>{ z-+9|x%vDO}w}iY5cv@P~`EVS}U#%>Ssj7@aO2Ve|N1#8p;?Eu58<MfFlXc_ORgMfnR%2msUXAA_l@)LQgWS7GItv#?Jp(igBEMAH4np8-k4r`Cb^B^ zhjb?ixorOU74?Gbu2|#%eu9;_l0a6ud+opvjU~cs%MQg%!+GyA9T#mcYCuq7FOxxp zLsIp{{pcL$S*Yoi%U=E>?x8yN8#=a=JN-RuiPq&W%{x$kS2QMTUF;Ud_#r!wH%Q)F zIOnv7mfse=Q``YdIvA-+O1n3EzpYynXmC4Lna7dhOt2uY!f~Qzt=eVA!`kjqhO{K; z^wl}pA$BcvE)g4pR8}=&2V_$D!dTo$a*o{bCnw8wUb`ma7)tjJg4CyFa6XuaT6GY+ zn;8w$Qnh0|=KE&5O`%4*C&HM?H5y?v;_HGP-wH`|HJwX;E!8)~kEV<$AWlvkw+AMc z#Q7q1Iyl!Wf@;h;;M@0YUAyybdcS$jzk^w;nCHR%mUw&Ws-9LHY?u#Xi9#svRets; zvXZu(+P7+GU;BFAHVAAr79^!~(bWOp;(Qakcq!vjufq@2ujI2kcB&YCfr^RzUdBcZ zF5>0MeWTlo);UH1&7&~kHT!1Ao z?+oVqNra%em?vTY&0*a|8KLZg`@K8Xsx{;Q?~g_P$@Xq|RCc(CNjo!y$;Ob$4!VCy9ig2R?ZuN18m`{int?Rz zt2o>Dbhn>K(X)Wg-1Iyjti2;>l#3b;_dl-X7}Nb9x`Vf~4@T^(;2(eT6;rZ!y3XlE z=?9_nEam^pQ;bay?GM2Bth7b;w#|)aW~f^5{&myK{|}Dm zzdh-H;<o_ySD%GcG&;&c7D|MRuWSnB2*8W%4#VglOP-0 zl9pJmVsO%&i!AZvK2Px=37}1X2?9;}H(^&JDQv$>I znJ9mD=BBrXuy5PSL*l*3drvq(gz6PtT&@R?3#HnBx+>nv@6jhFPsJeuG)$WK3e`8L z>AetYAd(h z2FD6D{`;{@#XYP=_PnM`_h?<^ZsGk}IA&BmQj#09dD^`?>zsFI)& zw=ubE<(yrdio>F^QQN~e7_P!ZFAf3Vx^EQ z5QDmix;Rod5Ob9dYXo3p;H&TB$VMBSa^}6>FCw^RugWa5UoT)?%*f@EZSzx(6&f35 zB1r0E^oFeD2)l}TaFC9{AFvk2+51kiw#IU8Cz=9P#O2yUKlH|scK!^{I>~g)=xS*A z$%p16x)G1fPGO3e%P0fye3#1;@ax!H=bql!&=>FHdr4v=ZYodIU712Ye2pZzqi=wW;u# z%36eDU6|k_^gJxkRa3(eS-058@7-BgsduxR>YAu1rcyGx$!t~MVdvHL4i)L?T=u72 zZJW}@yNw+Ve0dRAN6EDUvtW}PJyylhpqAdIV=%WCQ+&U)01Y8$&%A$M*SJfP?wm*#&_I@!zn-qDRuP=?A6Pmyb43q1qJD zSqK)f{XQ9L0CjO~IfPw!;s95V-IV&36qYY*9$!WpP2TjNG6;+urC(bPRkVtRFndi6 zUyyZ=OX_urqfv0)=QFp;qL-;%4weoIKn2_T`iswIhO)b3N1LCaxXQF%o$4@tbNQLE z-*5pO;B(BeY)JQ)0(EVi^5FoEsiM5OMsgv8l7jhtmzNIh$B!Oai~{c6Toj9UPR{wZ z;@bqWBneVAS#13$?_c)yKyp_H+j7OqEz2r`bynLHJ~uJ!_B=zEdWcJR&U#}@gqjEI z4a?K-S#+?ZfB{AQ-U9*Kv~dw}Usj9KGX=~WjwZF|n;nUs-IA^ulm(}(M^4?mjO`*L zY`M3Hz(3Ial1xw?HWgqD$|;?vc%oljn6-c6wQFN@9QXBLI;>SuUPTfQqGPLwa-?B4 zcuFd_E5z<-;OVWpX2`t$%reNagXIWUaw-q`{gqGx#$N2}dO+a|B&c@jP&{Y8IffC%O5 zY$rV*%r3N{D~67&ZMEt8`kl+ud;N8;ne&yLs+OT*Iv_P-)_}*0ic~wLiz&F_Hs~b= zfaRr|yhZwE17}={!ewi8H)8E%pl_+`c_tppLhPoThI4h>i-u+<$|7<0pio`%P36`-b^nbQXyWC zvFIB_hpk+{-fPu6eDuo|95kGYU0j*~Y4uOQZWFEAteNz;e&KW|ydEw;k)GQO5!}C= zDV4G*@8>n6TjE*DnioKd$S!Uw!Zj*#Ie3~3+^BL91UE;^d z=3DF$>J(;0VM{rj)|EX*$#@jzxtH@bh2VuA88U_`vy76J_s`)!ouhkjh2Q^)eu_)c z%s3imaZ!GA{HT(=QfFvnMk8DBjmSsFG%QY67OEwtlae}-RlzTD4Aziz&mgM0wNB5* z>@wT&P&CASu8}J;xQ_+CzP=wFGCUWv++k4! z#h(kwA>SfxZ%v3!53$P0^l8m$HS5^f&@Xq|A(9BDU?d zXv%KFwHiiiSw{`dXFYK=vm8pbaBFaa1s=i3Dv8a8*SEGd-iNpOg`J$fzHD?8CA)ib zSxBKu5uthMW@;Jd`*g$r|2rcQ6VOfi$aic~q^maOISkWlZ%*~JdehkQsDF_%m8sfc zt?+fQrsS`#X`;tax3jdVK3~*wI^s=`y@;MQDaJLEeWJgdv~kx-E}v1b{z6R;fa3-)G@*~N{qL0uPTE3k*F3Gk zu3_B3akXaiMj%)Dm~}%$Bd|W>9ZkJLle9x1GK+L!@J2Z^H@j7P0iSOE+s zDm3i&*6pcpSbdZo1v|OO-n;AteASV*o;vwXB)b`p19ckMtv%%*qP0Rqy&oU7`&L?4 zJa+hAYc>N$gZ7Tkan65fnWn>!ac7_IxMObUgV;yp+arkTixD>&&=ImTw~es?K?`8j zlq<9$DLm+kJ-JN~-iy%Qu8ou~We(2HrhwrhMna{i_&30@{Tx5_RW z8?muRgVTZ0OVYu>{Ls0mxE792iOf8kF7ENnRC)Y{#)^4+;iH?TVCQC*$YcYuY<6w6A zkJxC6cK`h#aKey)l&|*>+@!w*_7f!Sses*SW`eAmWE+)ztoIGNz3cv-r0yCcrVZyf zGnSW*C<2ve(Ppry3@g^$N4jU_N;kWF;B~GjGO3T zJNVNvRc2QMb1B$HR4>Gs7V&ro6x`gem*z6fu6wCRacx#E7TN4Yyq#rd`&amcoXZ&Z z2B>#R99BQJbogea&`TayLG-d260c;A)9$3=UI%4{%yw@Sy$K(qF%$;RTHqgN;wmc_ zGHZ{RakrMVtWM)khVx%@KjpiJFFK3B5-pur7cF}Njszl`sozJU8lgwtc464j;7p8A z!3bkoH{$cX+M<12#ZnGtcM2u?17|N)LqLc3WKES+WR0spWuXn0ae7nX79(k|fgI*tn{k4Ym8$iuWF2b~Hu{ad?S$a7#x)Df| zALo4FK)f~L6uL+lTi(A|%OiEQGnd9OKjmpUcGqC2uCRIRChBpXR^SGW(+tAjy8X(Iv z!J3V4WiOoUXS&Z?4R9^uEL#=w4@D!0007#oI3K5ZdVVTK#&a~Y*`y}JV!!i={e+>C znuhrr4pReO;j^Qxt6s1lk!NDp(sD@M;Sz4Wwd>tzWg_8flMJR%%8$6DIAWmm9FeBY z#UqL%%=vQz(7wyWo=5f`2DQ9h>Xyx4P#glbcrtt^g^x1q)9cLY%32TUh7k2&RMadF zbxGL36#FTTzw^O=t73u*_7Z!^k1qL{0LRZnpKG=8008N|Gy$1O#mlfYv>+*}mpxJv zhEqxuDu>v=4wcb_Y2;Gg&t&7%Di~eDF0SY8gBnQh2?y@aw91SxPGLBXui(oq{1SbU z31=4tsk)bk#K#6p1wAT-#&kqwb6+DDOZuz~NKN8r8ZXfon5liXl&+tEy6R7_*e%P} zCh?0ID6T7YEmNUW`eCnJeR%D*QpT8#618c18yqMs@>B-bKE;U{Doqec3sM{vQfARG zPsEW*DGuXcIlsKs`zYSO9<&y)Fl|=->qX&?5h?gI6&-Re^C&~ZEI2~Dwl#WNc_EhiCACLI??M75llse%ObT|QQ+5A zV@8Y7Qs81*g(&UT;wRoNQi1@xXDXg_C7$-As&A_(f!KdBNOXS2k>R+MQi+cBl#Nt8 zYJ`@9renJh<|j0Nxqs`{XS^|-@ukvLQB|F7**9M{I`Ox&(w^NbgC7!2_I1SdXfTEc zg@mc!XC6$(Z?v&7AND0hYFBqY_WY#qChJN*yJ~zogW??z83DP)p(svSb+h8#xNxEo z$Y`FWcSGMr)mlB$mjTiS>c zJ|5XV6P6b=KIpGz7N1F_ zldS@UoEQYEKJdcbtb5Ei8(QBX4Mw~f6SRvYJV=v8>*!N`0l%2yr*!4Waa3ToPmqM* z`_W6I<+o4DpU~3}2HmxB+|TSdq6uCm40^SB#PR-^8LXX_E({)ITf?RpZCN^sQx0GU zDa8;2Vs$=AO8`0@&Jy7wzu!_HFn|9k1LVagO6`4B808a73(-oyfoW7TIikBAYkGs- z^$R{2fNbzb?C8YEe9ua#%;?PPUWxrI@M3zw z*egKx4}85)C9(Gt*H2KJ1v&1wE$%~S3rH09v=8m59JbIN=X<18kp9*?UH{@7o*Kya zY*^#>D-O<`K$07syPI}ZrX^3EU$173rTg^BUkGAqGU)Qo8`K6rExXg4#oXf3LL5DZ za<+=R(TQ|v7nh|1X3<9SD4J8hcw)dTn6l`i^J%v;NRXbwOJzp=I5mR8`@UghFJjGH z$dtn_>8^8@Gy=LG_sC=7F&O+#2@heL^iyaxSO@^HOU<_dC+pNxOF=81LM!kWnYX!z z0?RKLW@ro{eH6M4tskJlkOp;%i1H}RWox0n>HXs`Umql*Q}LAUnXq3cb%;1FqH}*N zT11-TMGKx)X;`-$54lji=)(FX(>3+MG-ek8^7+=nxt{$Bo{~YXt=Z;=gI(ogIZZ1$)Ff%<^yhZU^|QforL@E6EZH*XP*&oP-is~{Mey&kBi zYH4m!G)5NECT$GzJb!Mb_z&v_~ke#?s2T zQW2!H@FmiX1sb8KJ&592IuvKI(n(S1nu|Er(;pJn|qP+2UQcBNop0(hY8P`Cd0=f=R6 zg?1_d{4&kbDV28CV5UT_33`)+yOZ30c~DgM%aK}$s`Ue;?MK@+Dw@Ms|-mKzG6yhn)1SS%5x*3;^5E&`YfgzL$ZgiPty6+ zokreU!5h=d-x6z3R(EAMd;a=B;pwxa_^}E)SSW)W9GlSFyJ(Pr%RN+`-y-2j{WGcd z8VX?$h|tYlL8X7tY;kTQTg2e1{$CVl&JbZ{uzp}x8L$7xnSg(=02j=j^=JTjiSuvi zas#zFo4jG^tTit4ILzO9)Tzrs~vV5)C)e`1`(%fSDE)YkuJRK>@Mp)SWsm>iVkAJv&^b0 z9!F(6T*{M4w!ujJy`|*nxwuliVTs}7bZy#_ew)fk12tq=5MrVx% zV_RX;($4+tj_svW_pLpBxm;d@`jm93IP}IVpfdIu%i{qz(LgW)MjX7NMV!O!Do+~4TO zS-y)J`8(;Mw(mdZ+z@*e#fV$+ns($MN-Q`tT$lRzxr~$`=Q8wVf_9d)w?AzfsWwD3 zVcb^?XLtfPkJXyFVl+S`=e_CB^zx*i zs3s1ekgag2V)TONiQB@>lf9QI#?RVJ^1!!*FTd(>aA-DMGCERB;DO5dV&r$Jy=we&SPq27+uJKQJKDmWBKlo7 zw^>TJ+T$DE;6x$`(AnIqO0>=gLubT@onG$BnY%k|ckDc-lhyJ-o_@EYhr=ON3AD6C z;O^6C#8Pg=Uy1UkdF_Xq<@MT z7lF^tzDY1E&D`p8p!z1E&0A`aY?7ki(jvw+3k!x zaj!qzR<5%%VFFAGQFmV=LOmS0%B&_QKK79VKiUkwRF4b*^AZsW@q`%6fx_vTT6%Gu zxTt|TSmZQoBTs;w`PFulLd}6x1TLEjjd8(fxEns{^YzTBQ;5qMr@G^U$g6{RPX0RI zt7Oy9&J-eoT{~ynG^VCMGtGfvK&o?B(ZtMSKVQ1)D-4`S^1w+6DMH{Mu##zGUNwMV z@diP8?lQf-S`}; zs|lDdd>)JS5Y++QmhN%TY@3^#3k=-riP@`PUAaGd!>=)+^^*%XG=aNj5ywp<5^uJFR_vGp8Hi->FsR8nK6ACK7mW^`q;48o|6}QNVYte zop8!`Wqf6wkI$S~RBkC|{~}&~>(=?*JVLs2nsJ!V0@Y`o-kgql#s(_=d1!4$Fga^Gq|6fmtg>bl+-;nhwC{-nvm$PuW_!DWmNjfykW^j=+H_= z?}<;a%y}W$#W|L&3B~DM_6^kIB-bAtJaK-TpyF8{B{X-hJ=trOz~5KI*ZOJd_Rt42 zcMfCECiQHw4#Mg{XETR?@q>J{8-`<3_(Gn0vkydyfea6S8#ck>)7Rtj%mY#g`J!(3NPq|c z#Yxs|i3BVAA&>iJ#qsJB)HbL%D3wHP6mR07Mr`lJ^DFpbyUl@0TP~0C^tp-9HyTp% z;Sinb!<@{xNslQ?8d(vF$jbA+n_{`!X^0ql5O>YF2kSbaW^+X1x{A+|`RzGhVlW}G zCaTA&e?izDYUo8*bA+COQGG#QQhM>&uN6cWe6hO89wwhpjR(w%s?lCV%aOXZlOjN> zea%y;{K-~V`rV-dqpegGSv$}y;e$13{t@ZbFG^`xt!AYyUi=Heikw6OEKF1H{vh&9 zb^nFYIO0WiM;`w7KgaO>XUz3K2LYxDUXNC9-HAtO4>z7?l$5M2aY;)P?_Z-I$K1>| zmoew_|KS=>Z^yAIZ_{e2>C|x`ozcwbDC7Q$-Bxr@`48vJs-ovqM3Fy+^=qBTOY{2e z{;JL7{0Vg#yqa#`hgR}1u>bbCo8IooSG-$laN1Jj$_Y*!A2mNJavbiQMYb5utFc%> zF@JYi`W+4*9*Kg&5o>YJ?@>lQRi;*Vp_|>p$k>D(`Ez1bH(QJW>#k&+X?c>?=g#e1 zD|%7BOKhu2QU*IB#peB>^HA`ZIxJae>mgW0LHVrMcpgDX0C;wB-3FO$TV^ont?vmV zIF6|$%moWMT8#Bdi5;(c$FjgTA%f@AHwXQM`U;#fXK}%h?vcZ`Ux6WD@x&^#toZyn zh$635 z4u%def#5#tfinMtXpv_g`53yd@=eF@9*BPE zopLR6s(=ZDXiY{qc@dyhTFm@Ny+<4t)A{{^7s&%QQuav5v=@zJGRSYEZgpBYe0mj6yB{zmEatB{Av-)911#aG@viU?@#$7)U{7vdF4qwyB zQl>3bIz;pn<)z9j7u55&B|RK=2FZ9k%*b>c5vCjyugnsvlD}cgEh^d*kh%-)`u_PL z!5eFHEYXqz`J@RT#G>}iM`}gWosI&6g8aPF$bpap!dVVpVk)i z2`P8@3rM-#c%SPMb&EIrnUC@x@ZP;92oQj3j*FNul@6<6nL};FwVy zDPi9#LcOT)K@dd%(tP|kJ>!V`XW7?V|%%V>$D_pGJjpSpSzCBH(Ih8)I~0g zg@S89NVp=9GkFe|E12E5gGmQ3&&5(^Q=6_iGxyH5=|M-39ehXZb;+9m7S#6n1WPXC z91cLFLid|vH!Xcuwv(7zvTKWiC~#&2LK;d+N-!M(}Mw?HbF0wH~3ej655WvmK)qe zjx!I|#L*Cmpq~v$W~QU9WaqN!{L}U4%?sU^;slZ>cbo5h(!k*5d3c*2$o}!BrfXUu zAOEQ87~OyB#Qzai{|}LWaQQ#Y9LS9674yaOvw!@kD|2J3`+xy>(H?A{U z#RFl`*W8i}_S$JB@J~&PgaUPk{w6=zwyJAND+;Y#ad5@3lxB*~r za8&1}Yr|Q!OQbBij1v2_CCNZL=J%2F%KGCM!`|#0`*}NL;DhUP9G?dMO==FvJ_WMn za4>kgL;`y7{2=L1KN|9kJ@UQJIa|914MAO6K`#mS%%Jt@u2a58mYW0-e{5t;uE}8S z5Nt1wwCr`n3HG$CeF}cO9SaRTqkCI%D+2#lwyP5!b5lY$N#mjEX6*X=`28PaYR@81 zjs`NaJEnV?H&e9MC^fNPD^Iyr*S?k~&tx@Vw!!kY0#r?-8C*(*Z)!=Pk)%=IWX8sN*|SF>M-lKWjDE**pX#?U#PsdwstU>qf=sj$I9( zblSnd=6rbVEp=&(v-Uz4yzYZpJAMpdX|CaqqZ^GzCQ2$-l4%z0_GIg0MsDYN$D;;o z_qQl>?DL`$)-OQ60;2_YR)av4M_7DEkWcN8RB9OqM|Bxo-~{Fp zT~2AM%p;Q0D(uUajP>2k9m0Zf=bK!nsR`8{6p}r%#68)?L1M3UCVLj`gXm9^_Z1Ue z*UL?K|1dWer(xh}bsnCpS#>hW_57KbQ5;7dN;HYvTPc3$0`Tk0XO!44&8g8!o-I9g zyQ_8%d1)!)c-Uoz3!uf7Tz&VNY7|mJr{}_OFYJTGB>%1D^V@y(=ro>B^xuHG;hBFV z>p;|EU8C2{PTefA{r+8RE0d{*j^BLIx=kF&QTO#Ov*mXy0Kmr8c6%%(7RD##ndg(9 zP`+XxmZV!~cQR+2I0^Du?AapZx2b-3n@0n+%crlTEpxH;ysej`Q&Xfj<9MV_TRPhj z_;z6Nx4W{JCxP`&wASxF&bO5a(>e^|FHgO~9vKcCm3p0u|jpmaRAZ1_w*$a3o&!|`9`qR(5g<@+!D{!+i~CFIW;7^T+- z7celhvKQILwA0id8LZaXt!&S2IcL-%M z&|fYS;z@#P^q=iGzQ#TY9(31sJc6JiS2(ZQxmr~IV_DrLs9N1G+E^aW@4qe|X}oVc zpQ6>MT-{JT(YRW}a)-6nG5xX0NwZpIw|{Eil`IV;9Ud?}+XqPdhvqTgJB_D&4`f^q z{)V~#e}OIkgJb_UAMlU){vT&l|7rjKj|5Wcm>xEl(OP6Ug^(m$^7*WzoV#L+KDTcI zV=)9EZ`4dBnRA91P0SaB%oEupys350C3*a>y96GeRn%>_m;w#P<`Wi&iw22O!_sJ` z1PimOc7OQ=H&Ye0+u&;^oenoARH>CJSc-l7bFJ$L-H|u-CVllpGEa=l0SCu`WT%EV zRWyH6*#Zm}Vc-nu)(0eaXZ5yLGU{7S_0JXH09cgGMIx&jK-0}8T*AVB@ii1zsDH5c z8M#xtyLISfx+XYqt#Hb;1-uW; zi*Af}h3e7O7%&$znrZJ_b-V;C4)~VN8TGJ2P_gLB*88ojnr8jAP5-_$@gZc}u_^ha zgUQ%NP2&j3t4hA2szq@T2hTwBV)>nN=5z&k13IYpBeo*?+c$Co+c`_TN=GH31!KJB zWv7+Vbmlb07=ePsENbAy`jRs8XP?`}xaIU~V%d|xg*l!xw^LDXJy@DbKtP}6a3{-y zM4Cow`rs>D)W+fQr-qwTq~=0xdJdi;pMi<4?ESO1H_S=sk1d z0hHB_1HZ#hiLpHYgZ8zjDRqyZumlyUQWT1B@Mepl#^f@t!}{#w;^ zG%U#)5yV{)6Or4dcuJQ^g_B&}$Okc{WJ@%%CEe6B519fIeFJ>BkRl^*^3)LF#9$n_ zjfm6z*a!2V?T34A!F%a*F|4%2#pDk9Mjt41@%y#Jn&Gs1vcLW$c*D(__Rxi*kV=;N zylR!~>2Nt-&vfA~7D~*;jyjX7Y)4l_n&D4sVcA-MiT&>J^)6khtZIGa+#o)}I0rDk z7zbIU9%kh_Y~j50cSIOh+X%sGR;$(9Ng9+jSP|M-cp)MniTW}mE0Q3Al4d-pa&5m( zJ@afKu)$&O!pSgW-pzWdRk$wn>+M`TpibzJ_{KwA^#z z?|HjFYxmW?P`Aa!x`4ni6^{#ZPJk2Zd+sA4#URtJHmi2sW`*XU)UCVFi#;tEleSaD z#1XSPK6UHbxvtIm)%Ce{sY=awY*GP9V3%?kRn0 zUDFQ?z^m3QSC9U%BqM1)yFI}dEB1DJ!$Qy1+9g2p>iD}>xu_9BlTKd_25sc-%gV|| z7-@k(3JT#oNyrsnp6<#GOA$a>Zfy0fx8CQA3?FP%Fmx)e1aJNZK>JI51%xvb+LY_Yi>`1fil@U|Z z8YCg&`E2a(w-@^RH0OH1!Yiul#!ZPF_h;*$&GhCE2{=+Y%wA4iD~E!i-NI8I=Jzgx zQ_6zZbr42oiY%nv>K1sY0_PrDE*0wWea8Re5I&qbI`LXsWHW|z8?#T-x}0!mOhkou z>l3_c)O6mem}f9&ox+y?u5nOnu|{0kYZ66X`H0PeT18nEc29qsta#sO2V(*>I_|M_ zI=uxzd_L>_G_Ib%NN6Sa`}Xkgq`>8{9>;i`NC|1GjEjlx81nvGH;^P!Wii6!mvJR2 z(oLPT=WWs{3t4_23$_e6tGdpJ=uGxx z0~Qrcyo1FfY7dTm!(3kdy*b7)!xAf6pZrI6vQLtdG?hzN?80_sY0JNqL0Swf46ML3 z#@QM zneO<^=W)KT`dPF2D?M@n%2&KE<6$=)N#lP-+!tkfoQT}gazrPSrb~f9)6*J2)>Xo! zgf~IUHI{l@2mABY^;U~BQB-`7|5gU$H}>e3AQfak-s`Vg_?JJI?LJ)leO`R^w*>Gh za!u)bS~32;`aDOcK&1Siznq_Bp3@@Bfed&dg+=b&xev_zoSep}s=YTZDpF%mAyPgg zG`n&83)%4hC?%ZaLHeh|aE_4)W8kg>^Amp8e-ztXGRaRje7yk&^muTV$#-ZlmuT4&kK#Jc zVR$rZ7V|OsI(r5Zfgo~z?u38EoJ7evqb1P5lG!Wm)46s%`fdsrF<9Cnn7Ddw z3h{M+He^pHamjO~L>sx_IOZ=A72I`DslE}=bK^~6+&X)^B1tum3Y67RjZR|x@%#dd zRR-F^G<;D?no4)q=v=>b@e_cFrFhX=1AfwuADJmHx6=jix)W^rH(UW`y+PU%37?4P z#c|0=@Cj@9WP_PEX3+&4Fv}kQgu;V?A@XYV76Hn`@%MFnygrZ|3v!x+2u?b^C527GsHJd;I z*4e>6W{V--UanL;Q8hbOD@Vhx?)r9j%Y%Hk;qh26we~w2Nvm1N7ZoM{Zaw?*S`}Vm z3io;>;n7$^v{ugh3l4YBAcIwCecd(3GRfQ*Zir#=Z9$vxn<)`7=J=x_M4*6&M-MJUyeVBU0ukBxmnOyWm3$0<}0;# zlHASyp#%n78n^zE2f@;}5R<0kB+ox)s^$qJap32VXQm8H$-;8z^{qY#>+aMu;g!T3 zTDDc5SI7w0dUX=EFy2CpX(n;&NtKLtQB>Sr%ki2vcu+E2^c|RP%Ge8?%<5-<>!^*7 zmVDx-E`IQBsKmc_pd(j0uyFC|2JQu`ZFG4HVW*`S-$}Dm^|3sgm#22xdqcek&&KZv zor&}%K|MC-ze!YITMP%8a}Khw=iEb=Q+qg^Hf&JtsVJZOQkFbY%KG|-!5&Q*TTT|z{PidH zLWgu%+_xRgIlB94X^JnX>&vE+xWaMeOgkumbc1qB(O!NQS?xs>@z)_%#_MD|cZjln zFkIRHHuJ{Vtu9t|yWuVE%tNaC(_wd%A;M}X*H}e`+WCYli$9D=a}=L{dfeg+9YBCS z%m-bL2RLHc=nfd~cCNle%x$WJPFtH-e@;9@@-b2*qwv`yS{TK&Q)ufvfBuo~8JgyKs0q$@+^h#_KS!t!r?$W|PMo zn=5Cy+qE??^+g2OW^q_2Hp*6k_gA;NN~Tt&1}^{RGQXk7@?oqAoy`)fd?VdiVsx$IN6YzS0w??ei|5o&Vy&=wu`0W{F;C#9oIx4GAD|;99(bJg*H)Oe1#z zTA0-n2^|Uoi57EEB1bD`>tJ`QQmbgv`(DdO#hhFthO~_))GUSZB zDxAUQ{pp=v$jPgtIJb{rs@4AQTG~!(>lrjOipHWF_6kF`6}O7-fTGqz#fP!9?uRv^ z+|10(Y#UGDTCA9IRaiRtK8&fhpE@D!4=fS&P+HA!j}vwjN{!j0bzV9#Gaj^ir*4;=b&@Bfzt*%x!NvTvhe0|TXxjn%Ml=yxWeXm z_oynfTeKW_PL1l5X4F1xcFt#PvY{LCHClZ*VMSn&F~Y-Fuk)o-WkbERQEWRCN} zJf11SBksgWs{;&P_A{1u&(APli;3v1bD;(aoEwE+^e9@_^`H0q(QF^7hGg!L+`-we zx8ff=jhc0PqoJ*G)~Zt49~jYmdt_obag1T{5MMp`?t!VD{x_CdsZKD4FnVI%GTeIshP+T0mf2CUc*F_y!pJY!Fi=<_#%n z2L13KmXY&+2(W@9;lvNtmv%ELj@*hDP7%%?!NB+S(+Bv#LE9+x2w#WJ)arIPkp`iU zNFxj;dpR|x`U<~R+0nBnARGeu3O+nJ`+^g!EU_PSQhN^w6?aJK88$6?X{x7#Itc2s zso4v=FLE@x0l*Pv4M@od&A&)Z?)akF2DyNGA0H4B!-c-^Jfs|4gNC#|0RRS~;g3He z)~ty+C=XOkbS@SH@LN-7CJXT}+!h8Qndb!L`6L{aWb|ml`)LP;>MG-1)vH{3V&-d&=7B1A>6UPJLk^?cLpHXo8dsmE#{P+kFAB#O5IM>ub@A8uma_o};ml zPK)i)M}TN+gRee)x9n^p;89jnC;`4!sFZyN;pOLq-nrKT%tc78>&3!DMx8kg-2uy#Hjko5naBd}!sFoSe6~ zR?{0OByItJq)PT{AC_0$6V@qM`0dNAvcb(Bi(=#0T_MN*yh7Je;;G!Jw6iKlBVRBR zog0Vu#_IE3ys3UW^)V_vJrKnb#y`rAKLY1Bph9P3LSZkdL9X&TyOrg75#G|x>c4Wv zD*x!h0q$vO)14__ZKL6b*GyuEPYSp$#Tbe!a_N^d$;pfNoMMU*nNYm__==W-Ta&6LRanh(uw{WOL_H{tZ_u_Dp-Ga;$%RcZ$YFy+u*JO z8AINu{qY(jom1(rIl8sV;Hw#lgCV%Yq(|uMaK(_MVRLH=C>(K0G}8ZOFm7xJuaG2% z2(6>k>hKMb#=U-Rx49OBUGS(nBQr1^x{sqc-3&KDFOS{7qaGLQ zE7gGhn7?4kK%V=;gjQ8m$vxQU>^|NtKob6)NF(CvXTZ*VRSa1YB{>Y%@fJw-Fj|6x z8@q4R=Oonya#|BfhzVl03IYM1OQ5Hbt8Fbg5py?C0@@7w$pP7IA7VISYv#<%57Y$!oqzpOsqHb3(a8{;$VH8-;^(sjtmdhmw;Qm zxt3?i%FP@})8Cf{pE-0WhAGT6hX}s6pz%kMd`Q->A@rJPZ^b+_Gy%Rs&JKpIfm=xO(~7~E+0{-Cf6Hp!0z6Q-%lIJd>1X7$ z(QBzXv?dV|npAX1`(d=@&neu&dx@!??7iG><6_g3iR`oc#=rZElLgT6BE*`h>DI_@ zv4(j_c_Fs7n6O03if+IMLPAN%d(w+|9=|HR^V!;;YE^l8AuR#&Rjn+$5z5oq3Xum4 z1zri5tz;{gq=nShJVVcq)A zxf4aS@93lipYrFF6%b%O&^G@479qV68BIwZW$iDE-YIAx4IGNFT|-qi)$HD@3>TstA!)Z_d%P%vIl(ZVzMgH61z*qlhq>CpYqtmS*42h zH$e0OrK+7mWRfADrhQI!=DNMwZku$`)kVdx74Hw5Z+8wq;`V=>PkV7$n9LqrYX-UJ zwm7R0rtHt!KhxC2zZ9y#2~ewG=SEg%H4y=#18V)nBo;TAuCFDobg&6qW0>qbDWJfh zX<1}xUsbsYf2;JnB8?ovtLm`%JVi)DUq&x>RQwLk58m^mun4(i)>z@LuTebtYtVcT zaroxS%Cj!-oH_~$>I*rP0E9qXia^Hm}Y zeS10_4!Y!el3&!;0gtIa>2goiO|TLK%w2(I^Uh2@PqV!AhD*OwfRIrdDITB+RIm=^ z7u0>Y8(Z6BpZRfdMYCy$0>m+Vq8PiikYT}DV~#-%L|tPEpYc|+3zlesgm%U_+4dV~ z64d+{2QG%YN_%?s-YSUb;38DnQ8sM@Nx>~p`o?6c=3|G0C(L}}U9d^t?vuS_PW;Px z+}2L?m2cp$#vTrqM-<{`s7%YHhA??5v?Bh1(|FFEEHj&V8FzQKJV~VGh7E` zSM%oD0D=BRM}Z?@@zcuE(lRAI$&@=Y{BGe}L`|jQjk3zCNhpT>=_0y*X>hub$;^yD zVaJh$7U#pII(J0Agv8ftJFn%yPfX&z+x}}>9=)rwH$AXvhgr|nN;Ndaa49LUzaa@_ z;&_y{aQi+E#Fgi!B6~QXd%@KeE6dw4r@A}qpj0-~q%>iSCe(6(i|m43-j-wAIed|{ zB<6$@;(vy+1U{$I+24W{QLgNF2Z!g9Fsr{JSRT<$Nl?AVpq4R)?aq&!jS;4{|;0Q+f7oPXA zlg6F?vkPrX06=58rI#?i4vTfd^~>aE?wR4brX~-jUZ>m$S*#{@%2(;Huba^3ZoVFk zil|bwSBQ{R!0gsYGGXcD%v92c zS5nkZadEy3*>f*+k-C#os_-hM+`Voj!)Q4oNq!{3P_Hv#4V)7HZa&r{8Lw zt@t%QPY}>cLWkJ>yy%c~F`bFcf>x_ufOx*{!@!c)s^0{1o7!T_oMNWRlQd z$!W;Pz`un#MQyrVnv$o9LGyLj`TY6B6e*BV$>jxZ(&%ie+9rY6?{0(Uaqcs=f#J5a}StCa>y*AD0N1xt+?goNl? z<0Ioz*}p$9JhkhQ2yp&pB4q#@{xVQ7{PNu^+a8t9YZ{wD1ebm>$M<)h#F^ZMCV{s0 z)zmx)LVYEFw~pEL-Lm6hp3aL_I@?Z_F$$40shh3XJPdGTvgCL3L@oR6us4fs#9b6A z;G3?g0h=R&B-TT4!<;^1xzTO_e}j0%7H>tNRo4(gCtakvl2M-gxcY#z_JdHB{ce3_ zJEc709Xh$;B^X_pxg+)!XWz53@?yxM4?JzCQDk#tlFpzkBKJ1>xHI&P+W`7TyW(Y0 z5KP@Va(s66w13B*c#x`cGfOuo{ZE6*1~&XY{^@MIKsg{U*SSUPOJw78P6(1sTcf|Q*5M+ zZOZ#;#8WF&vV71+U7uv^Mp@Hy9{f%}(|qei0!{juDEr*Wd3QjPjhmr>#aD)Wl#rnm z`tD0pQ`2;Utnx*uW~Doa;!hnS9lR^P;kl_BkP;1@Z7VMMa}p*_YG&a|_fI$LNEbT7 zk0zzE5)hNH(r5`=ISAvEurOm=FkQ_95>%OIQ(-Ynv!zndT_GKd9Y@HMo(i69T7gsh>N=tlGV)4==RwXnP5q+hs@Jx zBOXjAep`C6IMT)}?WV!*^aFSY$I~Q@!-5o$Bzz{r0lUT=y>okgRcf)hun=bGeE<5T zn3ILiqK6!%$XvAeb=C`$6E;RKWSdKuAK#;o@X}6>39w1zukQ8x(`99lXXRNbjiCF(*#y$lQs`F3kGEt-~*H^=CJR zj~MCG!<$I#lEnn%81Tc-MYXRt=pBOV{nv*hz4&@}x%TzyogbAmE9@5EzYfXL>^Xh% z+0_xU9y#(8H;|#JgWQ#r&;B_b&zt1Ks(SzN!6nYoqr+pfp}RIRtdAL6P< zra8fu`iNLAS=IMSBs9YL8?a9=iDD#Qti&XdE#OBSOtrl~O#On%F2nZdEDdMgYoCz3 zH1<4~CWly`I5+Z*wZHb@T`UNC@z^e-{5ij}+Ar88p;3v6=xa`#5_~NBkR17AY z9FTh1>JmPg7qPj{hJ!OHyXMx-{^1dJEJIrFDxq}_S ze*L_o;7{b;ijto&V@YPEl$nXfexav**aceq{~n}T`zwIMsVm*9CDi_>b*SyX%BBB~ zy#(^6-t1VuGQ)eS?SC*1lA>{Xhdrlv$kn|gsZHOTh~6dnp1i7%ZQQIj=#*PB&Uek? zS=Pjo7vqZnq!y;kTykUod;y&CmA4lY|KI{P!LW0qAQkV`71W|8-1xyl!0~llb&{d4 zr&@Dq;Ymw135;sZ&ch=Dxk@)6MB>O}p9z{-i50(2^xKcnIcp!fm#DH49i*s31qO_4 zy+L|VSGxw98Xi`~EmB8BjoEZW9L&1w|EgpN(<|?S**xqDkqQ<}S^pGU&7AR^g~y3j z$nU+ly!U%BV#wV*Nx^?53?CX1*h1pJagN@YWmc{dnu|F!8QPhpVTHB`(Equ5L*B06 z*J=0rIE(-qn6is*UklOf>4y@@xgxcoSDYy)hCkBQk#dTn=4AX(RO~YcneD#pGOt_a zks$TQG`+(U6%=$fp9o%R;@+MHt?~KUf$2>aaDc$;q!u{*IPM@1RX7#oA*1VpWCYE* z@00A64lerQv3kC8701LcuhhZMAR;txxE!f&;P2#GOYMxdJ3Z2DUG@Pdsr|yN#}QS2 zSG+PTlC?xY8~aVNUGh{T_E!VS+F-^LN-4MT6W#h`I+2b zt~ibIU~STNlwTbE)$*lIUw?s$jAmU0BXL8#_DBpPx5rGTfp}t6{`9bKZu+_ZoIvMY z#w$4}>;o6Wpb9w?!PdU?7yANwwVXYifGy`)gC|5ZNv66;r}Y9ySu7gk<2{`j zzIhQ8uLb_aacKdL+@`=1CeQ{mU;2j;e)|?4Opt z80Qh$9eUrLpAiw0uB=-+=cgODGT?CfSlxx_{R-I0_QS_{B?B{-YTp#Y9=`HbEzJXH z%&SWA-PwI&!6va{v8%nznY^p@E;j+0K1Z=q&J`ap+@UD(Mc;zru=GM{u*qy$}0Xij;cM8q0f)tCZJp90DLv@j^f+ ztCWC6(21{;y?W0jV-9|7qBB2^Q$9F6&L_O5!+_d=`(D1nki`I;>PYTWvlfD2muGn{ zu0etROit&!fn^^CuhD3_7xBuKtGf%?;PakRzKqrU<{tc*@R{5mlG5CxI!(q$(W{P& zox7xKcPBMy3~I&nI9FI`t5a(nKauX4Z+1CUdME|%E$`${`Id3eCkiF89Q(8@u_cRf z2Fd!{PPGe>|1yK?_Pi6!tZ$K&q>UHPk=z3pn)-@D$B{ zpX(TSmPOU@12XREN*c@cr}cw!iwFMGt$1>a$J`FEpqCp)qJkz1#GH-t$)-tWy9>U1 z4LW1Q-%_`ql>APIq0Y~fi{vn;yaqXr^Ktk66w{-y6ojv*Sa#tkpApH3mUUr7k>aMT zuOJU$mKEFEI|LB4O;=G5aiL1jKC4tnRfGvO8Hi<5c@TkLO7zHWfBMK~zJE zFaI)!p9hZ?AeUFv4Vpy0=Q2 z2a5Iv`Fsw>+R4MF-1ErUFsP|GsbFXX)nNZ*^X_gC(}CCRGVk-q=gOwn=ga*u#3w1n zZ5CYx*nAgqXe2rDW%=^)0>H)6cyZcMY>ClJ(Fw(yh~n*Z%0($AF0cZ#27jfL)%AKh zzzn3EO!QxyAWKb1CHY(~_q_wcez%+fPO#moJ~m>0O1gOP5oUH$rM(OwZEYUL3=DBcC5n!D(-G4lxxFvp(h0qUV@>_Vmb^PaJrZ;e)I%E&9l z*Q=7v7!|*A(Wx$WSN+d%$M?kGp?`~5igH%OvE3NZC?w{cF0HA#nVHGjwe)ZcY{NkY z?p9t>#-m^7b9Ac7|H!G6tTG_a(511ZrE8T^Q-OcuCX@CoK{JrYjTI1W=s*uFi-Yy* zhepC-$%1Ca>L1cZ(x^JVjER>Nrd5liy}8Wq7*w|ZCLWuvzboeJ+|qJu2K8_zh5aS4 zU}R$}>{wXRm-i&`_&Du_&8ZKG;@e3n6MIAUhLoAev>fv>F2u&(J$qh@qOh&|Jtbo;3AxLZhI_Lfs)y#CznisJwm}#A9$3m#DDP# zpIQeb`KmDl#&+0m7%ME_3eO8=FD=inpFETAm}#yV^ivYxRnssbPtpSkN5Adya3Mcn z(iDwE#lZ**x&?~tIQJTCRxfN2Y+OLGR)y^p0x8`;rtBsaFBD(apC7!&>J=qCFSX10JnDK>w`$a$TVNhGbwKSxjiig90 zs`{p9@xc!6wF8|5|a_8hWvOMjyzdZtOI3E1ED`umug z5fD1Jk8p4ErR)}1AjoMXl{pK6+D=_aeIIX&vEB$!KH&tD1@^}(vM9WK*7#B3RPCb6 z%}X;dWjGkt^VFN-QKRynKzC8b^@1I{fZ({Ex=UxK6*!>&W9P(*H~5!U#CCD_jbCfS zN#%R;ed(s1unbO?0)Y*5+Z_=eV%nt!R^t=#tuTih#Pd0*Jk57+k)hKaBmF~Kk(>=! z<(K1e)k?J=!&ClSZf5?kQEyl#nv75UfSDF&_46NIT&CHGiL)*PChjO4&rftpcU9Tn zSP-j{Z*<6|Geh8c?b@@|dYeh%-U4fv_ymrJ>pB;D6E;esHmU-4pEfH?&0F}WpN#U_ zcW;vF<0e6spE_0J88&_XLOR#x=dNI4SFrWEum0OF`K!iRrMfDOpr|K+4T86$IRynL z!ewY*4Ogb}jvn8x?9qTfe?X#qN|KV2GGjP2L9Da2t9eIyq>s(*JYa!#Hix1X!F2?* zmZK{y#T`y*;sZMm_6YurtSH)jkFk=;$3^_wSjQG&IdfK!T_?ryb=}T%XgR*6?SS3n z_r^csKpg54(3pF2JM7QBfP>AL{vBoV|1UxPf4jf>n6k2{;=cz!-@iDat?Takw+`(0 zESFKk=m1j%&-cGlTAcq30{$Zy_+Pd2Zmxg6e*ft>YUvVu`4$`g2%{ca-V6Oj$!*)w z;*>3d`b-@1SNspJwlL}%B`Umo`;`p&?cR5PY0{2L?a)8JEqn~ii>gdnJ-BmQA&2x| z78mz_z~=tf?Cw9y6**g7Qn7PXyeHyTlc7d+$;TKy(^)M;Z=a=%x9NzOIOnQV7>tX_ zpU3=AMue-%aIa`{I^nJ<^9@T;S@xEv*t0)61PN+XT)ay__u5uCiG={E?No3hz3*5Q zor}Y$+wX(ShIubj?BV`)FUBO~EH*tAu7G&WSEnA%OSk|BjTH6B>sGW`C*Jf{LJ}Zw z>-s_ti=||PrULoyldD}&XkQv%OLR)Pwe)uFtXPyrs~4hTn8ER94EOG9pxthi+ktpG zR}o(of`p0`tm|iWDN`7=k2U!+C9gZ_1`djP~dg&aBpd+5P5}<+}w|Ko$Tpg zp+fT(!+ly{T|&H>uyyZi|Dm=w_=^_42}^=4g`3)%cJqtMlIN6q0^1$WM?cr}|L6#g zt?!ZZ-%#<{Ceb19>U=F`-dPv$ zyU3D{jSb3HjUG$RJ6y17K6 zxd)BJQ0(WftOxm3N=S?2$X*{23y=&HqX<=ds|r?4+dP}FZsc%$TLQN-a~q95tDiPe zGs=g^sd2 zU!uz3Q*?4Qjmz$${8*jj#P^F!q;q-5cbPwgT{L5^$4>2Ueup-Ke+E8H!Z!Cy3)N-x zR+}n=VX!XviskF8jLd9#)&mj0HTb2ghIX3stW4KvQ4B0Es-wf}IA)!m8vrnR&TLIp zMAtd$|FiiwEw=rn4|mh%BftQz>e(!6Hk8ykmS|r2Z)N(2Dr}|Y7MtAd++LzGtiovT z^2WBayAvh$H6t8+onFVn9qyg*B#tzRG`d8YHxj*WQy3Oh-Gy9D1?w5gfN9+z4EfU< ziB7`47HmzIt;d1FnPc*O5N|*7tgb~P|L%O}m=uBPjAbS*Ig_q_C@+d6?yyk4kkj`H zD&9$nf7$W%sy?;FC{?EB{)w6H5aN2qtS<(2ToGhY^>dKRyA&#}<>B;3cd{6qP%NP4 za^jO;CqI;PFJ|`7R=>obn;~_`^;<3`EkaNJxR2k=T<=%(i_1?B(Hl$8-CSLX58YPA z$mqm0Cr#IvVpO~aMpQ=55X*LO)9SN;= z7>~(8z*G5qjbs@y-4Fd`vKPO)9pK^9MN>iHx-VwiD^zN)y2p_igzA1v^~5HC$8J@^ zMzJd-hh4x{7F;+$+9};jvuBp66lTz1d<1H(j#!CZjW}Fb+dbP`t>C%L9LkL>@y$aZ zq^01lJI=bb);6dRkl&!`FG)cnA|e_CtoRGZ)!mf2{$!@=gvQ{m=pb+XE0!Z=kvB9o zPnD?ShcPeyrL5Jpu{h=cJ4j{3$p1K(20OKAo%Ax4v_6kI<=NVY9o=-43gOlR|l!wK-aYZ*;|Mxe-2zOYH4nEAX))-Zp=>+?Rv zJ?q#UD90jbzoM;j;iLU`PaS_WtboBC6S|e{L&Xzyblq+k#_ey}?QOW(pTONjT}bHm z=|fD*t;$LHtkz4&8=|rCdS+)89R(v?gR=b_&FAQ%VnI{gp*`I!5*9%;R0$1vG1kW=g^=T(GZ11Vc*$f z>|c%2;7@UTfw|!@JSF{?BYNLCuY`_nNAHfEDMI@{x95cowG(aFymD1NKS7h*g($(j zJY)qK9@%C!F&NkU z_L^vCSJ6TiiG1c%Sv=FXMESrb>z>VZEkvt_M9WdVHbLzuEPo}2raA;xaMwvZ#av4O z7WOOArD9sR_N(C!rc$P*nWBJAMPj3QYa;WbrMj4aZi-C`$yix43R*{(^q{=i_kKg1 zwe5WbiN)0kgpDh6i7H4}u>Qaoitmxmye~wT&P$0fd(Cm0XQQ<|NTnE1wCMm>9+e=J~+zO^0q@3Zt;1WF+6QoFBkVstTQz^f8h z#(5H`*s|DvUF_iPf1Tfc;^gqk9t@}+gVn0u0s?`Jza!R5q17LS$qT(vj2$)24|We= zZlxy>bvn`YNgf1N!eH3Y@{Y&I>RU|wa@23LtNDi-gI9iU&m&v3C{2Nj{4l+Uc*QF9 zstP;#a1T0B*^f6{TK?{vsB3|NdI!bwb|allSa8$dcnZX9k9>tZ6;6#Sx2nxtCzEk0 z;95JS8t7FqQ2tuTA?CGeLZDWxAKD1^YD$-zNa#CyNO^WjOUpxUBkcKnMGHE&>tmo( zDRt8%c+dem7T`)njaE0M$z7(6;Zohcn2TBaw1i<9I34N?c5TQqc6>L2n<7ggrB!+u z^t{rhGA^Qz@_5OhMi+O4qNYH;d3eiX)b?;IGR$SSK7X)gbS{Vgi-oUGfKF<~vl@08 zwb}U@BNn^UvuX3HICLJ_qiGKwI#p#nY!9<8Ub|muK;a*H59Q_$ zIytnj47?pXZWP4lex+6|I2;d);89Anl&btmi;7q*E^t=rPCC0A@E4DOo?kv2B9A=S z%m*pR&!$z}jPX)^#N>=MU+5W3H|?hMSi2lOapxmQe8Jt(>3CJAxaIyem2D)}bX~-> zK4?vC^!rSO{TNcJ8dekKuR4B+q?vQ6|31^VZX8IvaTz|+Oiw< zyVH;y#rIjQlR#Rvo4h4~@|^Jg$oT7%f~5piacx_5N>%ci#gddv(bz<~@BCIa*>g33 zliwY6XK}5^MIvs))}5+i52%mWWuQ4*gLJkG==+^Jt0vVln)|O8)YUcrjf&yMPaNF$ z!W$q&5C-AmzK#lIHPC3uuX#jurho&K~=h}dspc78+~2B=eRPUaC>-lk?+FaXcN2Z#J>f~|L1Y~ z|7tw{zq_3!*VwA>iT5042%~i&vDE6&-f^ic&%r5|x+d~&)dMk=TYsrRdo}NdY$_5l zK)+APxODINFg7=1G*Km08Eho(t0-o^Qyazg2TRV^4(b>0h@81utgeG}$k3Gr!mei( z(fwPvMR%Woy+u68-K>ze_cnl49`0LaoIKtwTO(aMvkXl=bw@e*iVhZQv`=VMo@2iW zr$XG2*G}3ul-PZ;<|OwcStf&2q+$-$0k-GUY^?!l$F2TzcM zeery<-?P7W|2yLx28<*mx$jHYnscssL6sGyaIv3ZV_{+8%1A?0v9NACU}4?*_24%6 z4|KpY06aYWD6Qj!h4r}O=I>TC%VTmZtQS}^5D9hnq}_QJZK7%N`v*v3ilA>%FQhXW zU%0wuOi@_xl+?R^Dl93qM$Q;mvk>2_c`)_mi?dsI@j03cqfPuL= z*k}Rl5tcZ+&8LGs$^ZG8!;p1#DTc|A#99p(4y+}rDdt;ZTZDquW{IKq-mZgRz7Xq4 zH@n8EV}Ww*D;LjuSlJgjHN8LjUF@wX$&B2&x+_QfzNcH1>~D9Jk_m%ivRI+*B|E>X;+=cA zeSLj28Qs20b6&_=mk;mEjc4-a|2DyPAfSBv(H7GO?Oc} z#j`FopQ?jh@85de9tR z?05{{o1edY5^kM&GyZr~7t=z#+8V6CYHh|G_OISROs(uhEf(5JL_LKY_$?O-&}%G{ zQ`knfcjSj+i<&8P^rY5MWiW;QDwcerPeXsFJi8Fy=p6mwb5yQTU`$}1BbQkYSD%oqh@z_PrjkAghalNI|+f1?_6A>SZt|L zlRI+ZYvl$9K{yO{kz`~scXHUgv6ER+vR>_cS1;a}l!78zZbRwva-NWhX>X>|Z(&ZS z)?R-kA>f_#PeURk{qX^h#$gard1~; zT~~U+C5;RjgTkrJ^1pkC`b5r}rZAlJg|CFpOn-jfph$kxjK%|Rbp;BkLniE^SGqA( zE@Ph5Ft1Bb?cY0ZL-g;TAe=5v1kWaF?H8MTF6}mdO6-nZU0ta$g#L9Qer49%!L>sF z{d>UJrzZILI4x})NJo>5R_+JA7}OTcUA z1WS%w)cm#{du$(DF$KJ6UYR#jQZyDfu_k6y{!oY1zr1v((ZQ)l2&{GM@hqZtP7LPr zg}=Fk#4nrkO)f%z9P&=ZfbRi2a$pV_#zCKTZ2vxN{ z&n-J`p@BxR(_KA(<9pA&C3s2^r@=nNiDnfip&x3()amhl^l%$`O4&mZ^JOPLSLezZ z7KZzG`bq+9>#5ih_QpIc-syzjl11gz$Sw-IfgWaLWK8F#Bic`J2X5a^;l??>r1Ep! zo%_lrz*RX@ZDBN`AF5cgBVc3R48N!SB0SkQUYe)WZ4TdEfK`;K;R*Q*b%H+(k#rHVOTfI zf#D}Jvi212z5wUumC@Q+r09s3=Wu*xF<@wHVB;dGcBDD?VDaq5x}vtH7YoHz z7!Hy0nqGEI4L|-}F&|<=!o=icNyt3RnLb1CnD}ga+CWmWDQ~?~F80oy)XuI>4uhHu zW!C+P!u!T|zFj9NA##bicnbM^wxgm8;m!znwsowcUy*)|W#3tR%b=Q?n)T-P^7gWg zjj8+YZ;V;r_2zhXfHLES<;jElUJXqRuB?Z;aK9zxe06wPdf#E@{UAI^qI26V0;sx> zQk?LgR-9vpwD~DT+ee>n3!NQq^0{1;@>y-} z&NX*V*EdVkKIcul&S9I?EI}2!4Iu&1+~F4afZyq+5|y;Dv>CAW`pB5KA%-dsD2Z_1*{zBoq!V91l-T7jZ1C zz^5DI0lv3#IrIm6dgwCj!uAgX+0BW4i$i~j^YV_1dOBM!ud7Z_oS(USjNrL)X&)97 zU^PFlH7W~o+}?T=oBM;pQnT;dW_zrb!0r?E@4xfn2859>b8klj6tooVaCx_I^Lchs zlD-XW@ph#y{S?P7;u={jJMc#EvG0E%tbb|!Qtbj(vt*t2b4+3LG0R}M+O1}R|9Ex% zAFm{f_53Cmg|V_PF{OWZAO6$j7r6jNe!L?{gw-s#LN5=1hr0%HnTm_69DNU`c(S$F zZSk|lJP9{n?Lw2ApIPluvCm(N!OVmC6(i|7|F@W&2ji)I>*G>`A4+ve0HBNM?w9E9#vtfjljU)VLRlc z@k4rLsLC0%*-U?Eve#3NX}_hi&*Amz%xmVqf-J{Mj>}j4oG5G5JGFKd^lCagIw-{* z-%TL;niY5Go(p+bH9MKiDHXF8!fm$%oNe;)hSvOi2U6633CeQE7wH7MO8VoVJdQf- z8J?_^!G1aV)jv-e*fqP)2 zXQHbaa}aJqLz5X8XdJi3g8As|$X8irJDI-I;Pw*YynodRuqvU-tJblEu4=6k-LV`4 z3n>OI)Sib&(NZlEE;i4T4HEl} z%Cb7HT{(=J_&K>-oRIC;xIH~gZ*yWu*gXkHppm({HCrF-EGJYpAus++Jb^;{h5=ljj=Y?s@URDV1T)r7#+wr-! z-t@&!>AUM{g9`STFLb!%wRsw|UFj)uBb#4Z{FXqTa~Cnxv3GfEz7C+!_SE0-a)({O z4)ob`M{Agu(CFSRCw0nn))KUs1!qK~v)fPD=lAdI}geLh-Zkof94Ad$bw z0CQPzACJm@w!(NokC6a*d9~c88=N8l|%i;r5)ajL+p0W z{y>$LEY+<&axD%cp<`6}Vob4c;O266UvSLT*-nvVvp{JGC7%czTN8w_)}I}Tn4`^@ z@GE-o$V1fOY6>tmG4wrvfROc`mX|dOwRVf=E`u#Gg(aC^)tX=ygGm;tDWZPqo~KsH z!Y+;bPEPRM^ORtcM(?vMqtpeHE(MS<&3BRny?kfJnFLC`b~e>Hf>ykatrGc*XKE~o zh>tE(N|n$TiXcs5(AQ7hG0WLj6IBh)``V3LL@ZifM$MiduJ^H8ya2WYnb*8eynYKm zJTY-6{HxcUR1wq)(oC;r-+dREC1QWtrJzScO^ukZ|8tF6C?XpJYc7BGsouGP^d`!| z#O^}B+4ppL-V1Lqr6q5PM)^tZ<{kkPl>S--y}?BI#ZXk#WB2FRuRc9trLP}p_^zAh z_;|Wp)-~Ff?gJ_|SCc(OvX{HQwzfClwDJe7XCUNu<+SHtVj#SDQtypCJCzDUPhHoK zPfToF39aOWAw`X-TwM4{vsroxYsUA=#!FEgTUTN7Z{BovX5YdG@pO1})UiOTHUS`_ z=^5?ZtSkbRj|a01m|MZb{Z7thwFM^UmyV?efq}wq`<7N#ft~ODu3yp7g@0{IF0l&< z`zqk*w07w3E#^1c;qV6^e<($qLq$SCp;+>=##_utMy6+Bke`n)I*?ue2o8s1%z7cV zY{ljS34c!%?rb0-Z{ECNBsg*xaRII5`{C(>ub_Y%W+)mN5h3b%s;;Stu?mUNHvaN; zQOxViyC>uP;=;3fV4%SbaWOTN8W@`T_e7CS%lDES32}1a%;G`I3%Q688zg<1sZ%SmE*|+Fw_7z zLqDL(evxo^RMPBi3>rKiZYh3ICpg(PFk57^ z6XRaCQu5}n+b@MjwIS@W$LHQ+sn;NEl;~2T@0C-XglBdaYL&i)93CE~Hi+Yskdzkc zWo};Iadlzi`mj4PYrq^iU*{n#Bt*}7Fg=`p2g(Q-$9DCO&HZNr*2US`J?6bf$D4bA zGJ`DgBRI@&nTpf&phfZC;Ly;}@88;om&`TL{4w9+^vuk6Q#IfAgkAZpM{0m(qi8Ts zNAOUs+3SUTyokeips`vmdV6=~q%_$pZ*KN!ShtBD;|>j@(sK=siIy;`P$<;FZpwM{ zV8r;(pCs0C3;YKtHHHwTXSddm&%qP?2hC@P1HD30P@nd;wssOW!;7N{Yc>Uia)|0+ zbH=PURj}ROvqYyoO^?Fgwu|8>jLBzAc>%n98k?ye;4nO5XJk}XQ8AWV`0H-`L_w!-L$tQ>h5HG0hEuLm z+?Ah``PSB!?>@1uscBq9gs!&s@0^LvIBjZf?u*HboRX3SfG+@4SZID^IaB3e>*Peu zU1a&r+N9dppi}9-8ObWxaVjb!cDM#|yD|9%1yM<=tZhst~ z+w!WVR@0Er`D-6`C!Vq9CRpmfGXF zbI*5d<0$($*KWSK(tN%vqtyLuV%g|WnUVnNJok-BOu#O>vbnf8Bv|h2V$3z>LP2@+ zvdrUAOkDhg)pUi2vhqQt#SjlScU4vO#Kibt*~w4Ku9yA{BaOk*Zi+$gzq8jWEiv)X zMZk;YtgL1#*8CuE-_p_1UEcqz;(A+i46dj&^x&Zn)rD9QH>MUX;m&3do*dmYZp{_e zJzHky;tuJcDuhQ_bY&3628mZyW1`hSK#b~J6Awvtzs9t0a2VRnRP6m8Ap{~TeMXoT zsjyxmEc7u@FWmu`rlaFyWSkOz@iP#tm&KOr0{}-4A3k*3U+_9VI_*vd^BQH_cqk8^#V813%Q-2o^JTQvbhRfsV4=M!=gzvCGDyCo`QT;7{5sfkjd$)rMAQ7oF5$el`8bQb_>^bEP*q#$#3 z9t}yxJls6cz@Zfjb2Ec_&k%}gb_pFFCNcK(4#ttM_rqSlUfft;-`d)F2qO3^WjMb^ zOoiB&qYfDvnIBO|*Kj~PqK$~a#fSVBxq1$U0!8v%hMH&Fl8NHt7LDzBLt!kxuB=MnLYwVb0cH`{R3WXke!_^ z1L^8|3p4@S>6*+<`A81a_wT*e#~rAj2{_1dgxvxJUxHc_2YhO_B+j4iC*SQG+ zgt^MB3w4&{!Z30oq9)&gf+N-_dHP2Wymg&jUdhT@>FawNE(9F60zP%;c1o{lDstq( zUsr2#>x0)W+mlqM=ub?u-z=T3J(jn6SanpdGzfVL4ZP0E#~RLdd1|XzJbUsbGBx~4 zOh~(sg9f$qY-~llmw3;&>z(WMB4cds0?ubWX=_SKf8rD8)Sd&cIjyL4saegIqIzd|qQ4E^o3r21qgGkzMCvaiE&W{l(Bcv{2zOPK^bdRd2#*6_mX){xxo=@- z={AcD{qp@n5xrB1(mcPszfGQS_wHT4CVFvQw(Dbh`NYdR?5DMs2gBh`8yp4OhF7)f zBd~!#BsQI4xo@Q!SrRao;}6cP9N?9$QoE2o;sGl012$%(iVtGKhuihy!p4>=!mWsQ zzmJiC-SIj+$FKgd(7!R$!hS|gedi8(Pfx&iE+j*lI(&0?i;&3hIo2mfSs59hWvY*} z$bGidKA?CRw_Bt*ZR zEW=jv%>PJDRkflr-z4ag-0w$I!k(1S!y1(4Lo6djNy+(4saSeD_9Tc}l$zW{cys+y z!{-U029c#k-qgy{Z2p#d_3(_B0XahKh3 z4?E9%WmU)C$X1J>9r+|N4toBS_P1Ik^GCxRpV~iR9i*z4lp8_SVJ?%tqVvzbUY@QW zx<}75lw?_$8r1ty~Ss-XKnzOu! z4#Y%8IhM|~?5gZb?LyD^jp|jfQ2XAVyIS;-=xXH89RIEZ37=`iTu0WbN$y~_g(-gf z$>z+jY~Q9YU)ol3hom5H<;+xLFBF?#Zb!#{o@@T4>7NZ1?F_*UsgNbE{F-#sMvc42 z%$vm!YTHSeM|TZdaLZFN3a8c8>HZ>{czO8nbiN;ga*HfpPP52zqDV#6(dxBoMSOlw zUOGB>o8;+JySe7ssox(zwiwzlNG=3Wi8;Jw4evj`ns1ERLXAio-ER_g`Xl>RQ}fhn z2JPumTVkTp*qOB&1sW{%raK7Ic94%Ij^Xow9AD*<%;_wc*%;akkTy`^6llbb%$@v#}m$vOQhZOO{D zc#gi*m$zvQ3R0cb9GI>8piBL`?6c3HAhGMCu!sKc8EFQSO&y+>R#pc2Gk@QA((VF~&!OY1 zCfh!9ilAbCj8bZXHwyN5O!dIgBkYI>wL(j4GIF@QtRhrNzM``H z+4yABxY7nH|JYWK&w6?NW?*XIF5HzBV8xTY&-p=~pP#O>-gO5{{Mp-d8J=~o675RM zOUih8P4&8yFc%4XNiu(Euu>Ag1yrA1+;w|S5Mhne9@x2jZpcEDkwGQ?P#-l*^}amL zI8Mv{iv_#3uCliF)0b?bCT&&q_Fopca0m&>#m(St$UosY?X0>rLQB(f{>IqY*vH3@ zNd0?y29mj*Bvc)-h2xr2uN zin$i1ipfoJwujTflVj`bK-Xb1Jg?Q*QA%#0jh3Y&fNHb)UeSJpw=K5OWSVm8=z4Z} zmtqZe4E>iEAet;*2d90m8Ts+p=yEC)N=M*tY}oubp~3Xc$Se^)kpa9xeH`8`r`5<1 z98)ajx~*?$*sRZv=Y8ggh9?t10b@eUxvkC&2!nZS={G#t?X<4fPl-+Ci0$*!tHvZD z`M}GlByOi)qhLzq{_-F|dGALMS#FUz)?b~?-yhrXj6p@Y?TI^Hw5??zB^;`jc}f;x z$KZ;)C%;VmN~f!6*hIe?$F-bM&iE{mwsTUIlG4FHcVm<~32vsr_u|Umw&BsE&U28h z?B;ye+lc&)W!X-eJ-?zK1j#ALrE*&vA2cZY8^2#(W{^)Lry$II=irSHe@{x^lJ;)- z#AC>)$(WR$UCbEFQhmKgwy#j1rmg$IRBAGE2G^)YWr)anU+lmH3k!n)rh>Qr_drBa z9UDD$wtk{wuIZ}poq?<-UzoIe67KJx0LBLUF+LOY^WbQG zKyrQrD;3$A>xxw5L-Fy+$S0~eONlPT=Gv}O$xldvIvIxar4<#_G*n`ERjrutiGv%oE`l`1^m?D$N<#XAz#L*3wY%prYJTpG@)LV-XhS zXEz2l^4p)&J`gM5;vVbfK%PD$4mVORyKGgVj*!isD6}M0ag^PTf25VA%GAzzetwrO zf#uYI85?sr8XY&^JNjBf<9pyjBd(01%xs+x9{$<}NnB$5H~;U}mR1#_;C9Adn7(hR z?jk8EcDVP26DK7QySByGM6@UaQ7NyQS${suOt#AzrsTTW?Nj>kx#O8xJV4hx)^W@bej2 z9{qJ&0oR3ERZGi6{MqMMX{fP$70H0);qmb&!JR>igjlF_Z=u{8%jtd)ebI0O9zV)b zwWeoWIQSt{qUr_;#d(h<$E!^m?wvjll2uh3!+1m+lltQy5K%O&J;I!BdmyY|r+*x* zl7a9#VN^Rsi}FjU2osf+wet#8*JH)npG5zz>rCNt?7UAwmTWa)E>EV__+jYRih)oS zsOJ!X%eWpJWmjt*889CS%5{%BmF*x7hn7A<$DF2C60dbD!Z4-pdVTb3L`KB=x>@|c z)W})Zj<=0&u$z&w)cl=Vy?+bqsaAvwu*l!NT7a2eLi`rgu;jgW))6wTX2}hu%bQ7NW`_mzRW@MN^8R_}OM7U?* zu*dj^?jrH>y@Q2WSsg2fAPmr{<}dH#?v9O>N z)yc=U6uYu1DKi}dboBffkYs>SVP|HR*_T6{thjDHgq%{ySLoop5GV$+DECf4N|~$8 zhe{}vlIqJoOj}VGYaQFYkK%k)pL>d z{*Bk{>_1&*|55|}-{s7I5AOfVnD+n1S0uFuJrS=L7MqcPJuYRfJ_XppiUI_z(%hZR zce5}LLTeVeeIWqr4=9$naE^Oq{q{ti(f$aF&b{H1i8>WYmKhd+`4L08PTNNsJE=|X z3J}o-7b|$3F`JqRbx=@f)AeT0xttbJzjjMX`HPgdfnPUSZZPp@TvB-a+Gv_#r>D7o z+FY7%r#To$RPWQ|%oFxiQQ=kLm5oE<>H)D55J+@fY|mIIYe(EP}a!#1|)Q|e31~;E^R5E#pz7BZf|3Nu1O8tVdp{O&y)2B zSZ!uqHZS%K0+)%wQepm@k(3aX^cu1&BZIB28%ILC%JMj)6^If3xMW!c1wtR*wcH5^ zWh^NwDG}S4BopvyM4Vsb6&3rxXJs>bj6=fNJuE?>rJcg+3lad zh?ZsMH*s|A9nfq3dLQ>i27bH0e!VB~hbc(-NZr58Q6LBEOF}|ImF*ZaJ$=kgg}CE= zd5d3KM8xl33yNB`Z##v6gYtk5Fisy)gPZx*c)skT-NEoRYHjl{5}4hJfxhGNVK~3A zL7P>~cRA|I1(17h>g%8|@6qRa|1qU;;LD7+cDS{+(`EM85|=P`r**de0XC->&%mr4 zG4|$%KCXc{Uyl%WzO*}Ez{h?Q^ffBTIIdkPl>ZB`g zA`e0l#n$Lc&!^Eq{B7BCIv+h(1BEc1O1sSE$DqOL_udFryByO)oH3&l!^l5o6CRiB zCsWX|UgiRD_3izp%aIW-P(|eA<~60Fq})few^50B%R_p5We*)5(zy!pa92h}MPXw< z0*VRx&h6>8w6rCQp%e>K(+`%`g@ySKQFTx*aHCsqwz`3^CfT3~sq*a`ROR6Dxnv)= zo|a9Q&dSL#wEFgVPnW6g5Ru;A{R{?EFEwn+>nJl<$n|u=qZE1#kqp3@srN$E>Z8Nr5>RbB8R>@}?z z+yg$tk^a%Pq`-xMH*-f#PP-kJ;MUm&1}~m?i_q*VJix*dj~Z$S@HI5FGnNqZiYZlQ zRMk|`C<_Sk+Ps6+ikGb~7=55;57tbo>OvBTI#@w}p6Y-HyZvA``H%9nEBa9M4uwV|1=Re!64Ullo6hSe^-}AVis|T zh$wjvx9($4Lt5IWz>fEa=f@iUaRm3>;1C13QPZbR`O{i|69U?^gg5BorolVYY;)Zr*f z${rc%m%25b2^^lp_`qh$q1$+}Rye7fknkS*t$QW9vT3T$o%(1K`6ti@SRlvfLt4_V zuRrGH8xAScD6#5!in1!PmZsBJz%^(xgkS{&)>^Ztf7d88r%o4WiZk4iWHU?s$qPn< z-h3vB7wB)VQv35Eyw1PVfWPIhyLT5GU3SKMGHw3+h0u0~TX;6ouhaC;$-ZFy+@ z6e~+?k6aY_GdS%(b)q;@r(yJvx(G7%auM|9ljHfxX+9{W7U+zCEVELM<@-c*0=+_+zG~>VOs<(w;<2eW?|lsFHLuz11!1(Zd}*F;vg4bFYBnAkP@n> zfdnS5H2se)M*lmqtRzxi0!Kb7^qu&>Z2o`a(m&j~M8~YIX*`_AVho^@D}aG~9^`GV zczTqfSDWXuBfItJ)9vQw4$jproe4A+7US3kBDcma1i_bg+tBcvb^fiTS^t%PIRoII zQNH-!wm3HCt+P$au+8`8#%pdkOGah;w_ceI4=W=#N3x-bj~GUtu8oh8uq%-Xj~2!B zh`%v3?BJaLC_>aMR^)}H{E#~HJwIZuTSHNU_bf3o^0M^XO|)8kui2M{`nXHd_J5k# z{yWP3n~r|IiFB27> zu5HKzPIX(H|_%Z^u3z z1EHR-^U#|;Gw5gA(DxeX3|s}a~&XnZt~{mJ=l%`n%OW(3falX$0O7z}vk zj9Pp%$4g>nsHkD9KG_BVCBW4LoXx?aev#6&HXfdy7ptkcdb4nz$}&(x(w3I~AZUWY zbf?nAjI{n1;bAFE;%eytR;@wcy#tkl0lk_Per~K+W`*w*HB>YQ2M1NuH0Y?CU$t7s z0=uuQs)~vwya<~8#uike#WhRO9@{u9g+jpS8KrCV-@tC|p)c?+tuSENPqXLd^lRU; zQHr10PgJ})blkXyYbfS*bTmzP-Hn7f?@v{{IlhIyh>AnjAPmG?7{+qZ-k9B<6j9iK zQQ7LRuTqewPY#@~I#RvPHeL66zw7Yi78}$$%$_ChvVuDELb;PtLrrntwv`V05bwcr z9y`^clzD*QY!>SFf#;`ivdF?H;p+GVR516atI@mpE4Od8*k8Y#o)%n#p7%vTceyLV zKHs^})tML>9cNYQ=jhltMu{}1MQ8zQsqC*PTObqB1&fHr)5!tNuD^d&fHzV$8yFf7 z>K&{>Gpem-O)WOcst1!>KA2j?|NJ=x+;u*ZmCIqk%)^6oyu4OeGVe86U~6JDd0uPA zLgqhRW@%kXY@0g}HxI1(pgseV-avmpK(NcJ`QUO-2Plb%lB1$nWBbVb9jr$kp_3J= zUi->JW_z#@?6wL}xYU~-M_W%)@^iOy0+;e2ZsPu2Q>-y56cUk;(97B1)1m}C_iL-G zPwkftq(5}Ci`Lp*0s{UJ7$HBv($Zcn4%-0j2&erAB~Q9VsqY&OHtkKF(q?kud|H3eSpQMkH9^^VT1d46iiC} z%Mp=k{j4@&si;KbxTB7%DS)zdft|1+v?;r~efW>KnW;H9&I*Dm&;A4P)2I6HJ^#Ef z1)Y;{(Se|2?87$;4rH1 zZT1Aq>+#;~Gt$jeK_8J#jdzFLRYvrLBLK|-Vq++B+~6?Z;8i=gtIt*LK;w^B@3b@X z)e9I{AL*3+jtqoj>W?OM#>U6TfuAhkdm}#=7kq3CV1hM-RlYGaFD>m|f1OMuLkLH+ zRAENO=+Nanq&a#U{G16IJ{vTjti@99v0$WLzswEWL8zXMN3y1(Hx_XS! zLr&He$_j&>M&xkGVZh-Ce(=Man^TtWG8Kx)xUj0JjR7x!B*aF^(b18RfN=4zyM*C| zI|1v!C=-{MDDH)+5a9}*g`qhN=AThE%|r7UlPR@UVk1IfAJB-%OCn; zw%bvv)^DY{uY@cx;NunL<@6a*<4@W4{1zgC?+xfkh+toWUrka1E!|4~A*2H@o5=L*{HElU~q(TIxrEMg>sNd^hAzeCi^_SEg?qVG@E$ucg0z<*&LVavZj4SY70r@f!&IZi`YhJU)C0HD8KP3;* z6DTb;u^h?vLYz@FlnZOqjpwCGS^_M`so!OXe$!Il@j+vsq`O;avLb`r zsh*=&e>J3$0BZDtTGU5WRMY?pQB_t}R_CFiX>VORo|&mJiG{&t(mtcbPFkLGSqvGx zv$7iyYxLEVfB*`%1J}3Eda-8N9l#V#WG&9f!T2>sw?w)@5ET&!OMA>vP`w zQ{v9lub~!Ko0vel&cbppO91kACW{TvFYUo$9dHz_zi&fH783m9hpL)dp=R+jt$7xF z*PXNEd`rua#A<5lczHz#I6Iag=(C*#T@e#7SF|eu(oy#sAa*_%cy_Znzlav|9$HwR~fKLKmxTCG0H~VWL)HcK8I0q7ykU)%2)%)OV9Pl>9(cELp7Ef)7^%G&%ey(+x2%?)(l9Uq?^RWpmhW z|4S!JEXTyKvQd+H)923;Kqy&*_RQ2QCC;j*f?F9 zvA?g+4|8)8FAECg0^UOwd=+))D&Sf2Q($3Y0;H@}Ah<6{=;N!F#cNch!j9&yMi#by zqx1Qs;4$zK0c)b`{!~VKx+0{YfEg$X$qn^#*%kZqLLB;>0XM@`<6dFG(ZI{iJ3czv z-_wKpzh&Z@o2XVvdsuDuK&J_RQLL0M3wPZ|R9c7y94dMh`4H&-odJPvz# zb92+3-LTAeB?h1?w-1x>L3j*XZFRZb=#=eMhtb*I^hlM=O2!s})+s2JOSxk|wo^zF zv!8`6UTdtby}^-8Nl8MQtgPGW)uM^6F1Fn8i3?t37kgnHd}X1V)=<}&OC0VFAm+em z^~7<7a2T+v962N_#XbqwH_Z5`qwoCYb^5B49AE$-Ot}nTkuCxP!HH z35aCO(yAf<))r1Xr_I>Qm-0Jsd1=6(O)dN$3@%Ir&Mq;Yo63Crm`}wQ`;m$cEARR9 z1*v@IGqq_J)AjzB0s^BW>GTSDipd;oIt?)i0u0peOLhP7|1B$~Q{g2LYyALFc9|ue zGa0Jbl7-EMdUQ*Ww+}Q>w{|^k?QD-pD8XH1rtI@q0x2nO?t-G5oAnI)mDJ|5J}&_$ zVmhNDcA2;J1Q8@lgg0P*4K+CQ57FRw{f~suwUL^+x+4dU(F_w}eYac8(JU^20SV!T zQW#WxBlSOMpguUQw)*}xAL}6G@(Qi)T?&+lsC(W2|EjtF4~^vi${uiyHQWHl!dPc< zd$_t9YAPB^e1=d*%Vu-eC;egmJ9UT<`!035@|!m@a*`TqY6^@f%`-gUJHh(I!(A^T z_L5DIPtHI=M@>>gOG=LMY2dfpVyTr?46%K5s`2W~eZ7NniUU6a6-UP=_{U4xQTMo6 zZVps`q~Q}4W*5`Ylbg>8El((Lq^oY*IF61+^~zGa@DWMg>Fwi?ml^Op=I@;<^H+2k zkhQ8xx{P;YOfPxa zz6Wk^ZqDpX+Sr*-*M}y5^;Mu&Rnw^9EF~k1B_ND_ZCUSQ?y_SQBEFZe#gt?3Gryq$uWe$8Ek*(W)s`g%-t@P5n8 z)#l(&&ysfXI-SX38frqCc_jYBp8R-?>e`?iQb!aU9hsUEZlcy57euEn*j|Q5Mia{e zwhw6ZAxb3WQ}@QPyEo+_w0i|#QeMY$Vgo%ZzCT|_cBUw?18&u_*o0xEf3FzqO2KLi z{XN>aK0B;UWELKi^9(6>$#i29QkHP^hyIYQDzep9Z=+WS*YAnfvXm)Y5b;QkCT1I? z%h2uJ4o%=&hr3ixz=;k#Am04NF})jTz0z4NO33$0rE?L(`*O2`nl+&p{`CY7@AUh} zP^5^T0$}9?+I=yrKs^0Z;vXk+CKgN70yIE@|6kA;<$}3UpNL~C=6w_W(6 zOONf!3NR%gjva{h{_dX`S7tM8dqQKfYAu<<{rcs@@3c#VsoQ#bxP_Y5ANbTP$gP(N zAEIapxL^M|(h4*C(TIxXFJgHq5l&_apN?P^*$Dlz}%{r41c#44EGk z*j5ywJUquqMRJSQckB|>?`Z(?}qT8$wre7;BS{NS6^s2|=20Y2B$h>Mpa+lAHy zBZXNgRXy<~F6Y2V>yfccj@$kzLeh}kkeEPe+NaW471*qkvHzUpRR1PVe~p?nFDjgP zQJ=Kx`2NF0U-$YSF|A{9+WNwCru9Dp81M5qQflz#4;Q{&YgWQudl}iJp~9@P!q=gdXcwyNr6>rsQd*RP z{Gq$|UF2mG0RaSZ=Q(*4tgyGBq=3IJg$4h-(XTINYR9iGtVNxf5WD5fm*$^T@u{1J zG7KfMFf0_hSA`?PN&}5Db$q|ta_?gBL7l>nBvbB)UTNx`T#JQ?j-a8Ha;Io!R?$;g zX=N9U>iB_~7~Ri9E6LCP)|GkT{*3DQ#YMY9tZtl61)*U5U1sJCS#9Mv|0EXj-GkCk zL&9TS^KbLsepe-slV*Jh{gK5@ASc6`ejEB#+SaXd@V1!JuT~E0i?uNig2QEaa%}aE zrd)&PVXS;rK{AC%PP7L_yuR30+ryf&7}wK5P1jv#S4Cewwo_T%(TXMao6PqKeaMe~rBP^r83p=FaJIs!S0c~@e10d=@GJ-HvI&dBDeo?l>OVUwW(HOQU)11!VidFRo@ znCpK!$0I^nZaJYMC2r9=Ug5VB(oH|E1Vf#j#e?Q$_-<#2!DO1WcQR}xRdmsjLJ!AO?@r0J2J65Q*ldGhcdt6`H z{eUK{o94bvO;jM_EX?7_O6d!{XXoO4G8F;RFR&|oKwqw7jBx*nPeJ~C3K`uPU9#|E ztIg@12^(Yc>FM4<#i6u35qkDFv;^MhR0Xzw+PnB9e)0mlKRVVZ?q^&{{{Ld`t%ItJ z-f+24(U1_eY~N~F6>xCoe?3v9l?9KOmYppk*=XrDUG}62AnEn$YxU#S{y`tk}W@Z>@eP0!KHql63f$|>* zkkq;65THsQ-CbIGT)sqeM=zoj8h^k8RUw@KRk^Zkg z`6~;ghEfS9%`E;~&x7Af*v7C^Xno3DR*y0umVnPFhLt5=O6eNV{ zseh;DVhHq-w};Yu))TKmE?Q&p7&Ou1LCUo^l#Zz}^cgWwjQr<*vTnbczMmUfR3t*@ zKwy<}f2B_O{vr_cxAUEKc9O=lUG*x)m8=1SZ}w{rbzq9OcZxSc5Z|P;dV$LPvW?a^ z2WeDjACC0MYGj~IcH6pUA8I!A=#_e0DQSP)_sWWQeS0V1iAONK!}haaUkNWx*fK68TD&ZO z&h22Zcl3ML=zEd(4*5Ao3$TM6+YbEUdZxTvu8Gmbrq3j%Rz_yVQ$?q5BWO9Fex)X; ztGo4tT?oKcis8*xsxKezF-{5Is^1d3&v_~k9zUZ$6VK%^qvm7@4dcTnH$-R?#3|)qfAb@;VcX>JyFr^_#^GTo=V zOVi6K-uUh}aWOpqwj&tp)E{db2O7|?_rxV?bh-SBso}GNKY#F90F?R}S0rQONx6&I zIK|jwJ-KNSZ9P1!G2j8ca&9)OjTp|{snTzw`_W~@O`NUN^5{i7jF9Uj^U{@A>m67l@b=)&T{)Hy!7`Og z{1LA~&DYG4EidI6iRZZ?Dwr)A`}Y@*OLaha>gwZMaJPHkZS*_?WxFwgWT#_e6%tu_GafWyl8@1A?XUm-fq&_KEMYIbH6=UY zc#QG%aVF*5&4b#j2Y-$#;sJAi3-JLJl7&wn+-8(uyKsf<62wF$)p?@!O0zN}Kd=*aZF3sQhF^@qLDBPegj-UyJL>%U`&BrEWb-U)9aaF_Knj za>tgmvWg}N2K&M3#4ZRj;nOXlv`2BOIj@tOkRlK0n43j`YpT|B$|yxcPen&Xh2PW83p~Pt1l?Q}u{%Ly3#-x5 zE%B(}q<_~cp`)WSF`9xTGP{#8b1ufLWu;;24;EPf!;1+2+c=EdeHOxk<3J(Iv0y2YThnj{5H&`d9 zlc0TOJOA;M@kis2^A~wWpPPRprC6Ho1MBdZVlwRAGx4Ut{pl$(=<3m<;HTv8=p)$- znkcSbcy9X+l_Cd)D0;@nHCi0v5MZnw1UN2*v+0uWCJTklH`-%`$Pk9$Lx7uLpwy+^ z0mq zBItvq_0ZUaBsDH#+GBGmG8^XZ5;GmX95K94A2K#ROp9jNeW66UZSmmChmIs+gEl&+ ztyMa{X5b>qVv5*wUis&y-d$`RTXOIBB?@Vsy|=5G4W*c!j*TzP&-+~HMrMKCwzO<)ISf|ZBA~Tu__#!$}_VtgU1R-7Sv-v z<)1nv=X06vns?bd=|U03MWMmP#oUlHeYMG1QNcWJgT1+(pPi2kx${l0NMIv*8&o0! z6{XI05Okg%AC&?o;ZX^)q}$sOBLmH|st#62DMdv#W6PJ1A2pn$)Nsr8KUdrPo{uux@cxgmVB`O zX9=H7oz41&-pTEZ0J5vW0!Y!cAv0h*agqh9%y%8$!eIY7LC$yGAz2D+4rin7-D2$1 zy$D?rpRDYBLF1dw+N-NXFLDgnO}S2tLe-w%`a1D1QZm6X_}JgRir1+RL_CN)LMd(D zFmWErcW+^8@VmK5QDFRVc{Vm|BqN9}wbfkcAwYRQft8Q6I9k&a@!AWKU}Z7kX&yI_ zdu$>{Sa%N0v#OdJB=T0TL3ElXJRw3xB`q`46oNt|K!pWLDatbWXhUC98kffez1nob z@JlPo!ho9Fd9mavt&T3Z#W*n?%gRq44<#^h3ebSVUKUdf_zWbQJB$_4Udz`XdM4eqZ?vJhq_eJ&{ES=^`ktX|Zcf{B(^S+uwC>%Jy3 zx2R~GnjMGk{F92KwAGbXB}XJ*W#zbfclTpx@y#2lkPIai4=qp5n(UF8Q6~*k$*gaD z&{MMQCIuNHYp^$^ZKRy0zemi@@$pSJ<4djRVd*gU%$!puHQH5_#rOwbXR>1>K~f&c zshM3)@JTx9r`+Rjlgbb9Cfnl#7n_+F%|tnI>i!5Y@_ z94+lo!?P=O(8$8ORc?HEILaOG2ckK?YX95gP1$s1BoRdo2JYgNDgB-2P1FA+2idzhIN z6B^2G)}9IKCH|0H0>NcZiF{f^S^6fHKBQT3;or(_+mhT+O?+i``IYy+iS+q*9M;|p zgA71dh4D##^==c@Q*Mi#(Y^q@P?0i<061atk6-l`T{v$@t?w5)GS6gnR2+xu zN&5U>1Vu@-hmrn_O~fa}ue0gtU&Gu0L~|Kfc6|QG$i`4}E91-C1Esf;Xstcsv(>O< znM_uLSEvwCvG#)1<{MIZD`A=b%s`o+n>xNe3y8_?C(;}qmkSlEiJ-&+u=TmQ8g1*p z;)7H;W~|+rBQQfk9*-AlpD?j5owVimW4kmqn1x_@_;c z)}?F|sSd#~ei;4mQV7o@P3>DAQfW)1&5qq>uVUAJsok#5xijS7EL1_`g69HWi zH7=TrOwYT8c^>*wX)ZBbl%TfCSKMU0Mv%|n7cZIMF=s-%uq=ejFVby#iEqHrKS5E_ zR!@q$8Sk1Wf;OGpm6XsSqm9+WYO2;2Ba5foJAQtW7$^@YlLyuuEG;aeqoP1VTS6UM zV|vOUcolAC!5SbhocoDc#)4LrsW2}O148?1X2FKZiQRZJ(ltKKPQw`6R`d+*S@CZv zgjxwNJ&{})@>u6|sh+*Gxdl)|U0u6(%xo^oQ%@VJbvoK6TueUGFT&x%4Ct2t-smVW zaJ4EI!cD#avI+Wc96M|NDf|V=$RI5qj%)xIE+O%#PXV3xOf@o_c*rrvDk7wlvV8XD zA0=Kz<(hr3BC>%3db+t&!ND!)d?#~W)VQpdQ>dn#_5_8-JxUte&#q=t?k5Zn*VxjU zF(FWwwJN8&e2Vq0qvO%1u<^>HCj%--9}aI~Yl%r!qHlFlg)l8=Pt&aPJ;aUx?qm!Ne?G}CCc3mpf z@g;GHVYY~!Ru1Cg2&s&rmPc`idh;*Da{%wteVW+Y8stV~d<*RmlI`YRbG|JjG97Zorm?0P>%oCnxM% zZQSI#Z*n6mBa6=c&R*Q~bm-o0-Icq_3xclD??+pcOKP6Yie!}}WF!`rcaE7aK+=*G zoXln4TcLBV0In$G9p=G4-sD{I;cm#M;X+vklE0Rg=7F65!ps(i0d$U#vh)U@#J=2P z4Kr1XvShA%cz3nqzu2oRKtW@BA>Y3&T@X6K*mUQ-*aK|XIbHG!+9Fp|ISQ|{;nPe@ zuHopYEQP1wwy&2WH^!~!&224N>Q`uWwA}nA!KTa$k{7m?m+vYeq~pYEQqa%tH*h0N z<}pX0bxG4*kzBXeu-rT0>1P$pl&Z+8s2FJYi{39@iTsO-Mi3&L!xJME+zy=!9Rtd_ z1Ry8^%s~z1z!1fHH@2vb6~OQcBYCZPH{NQpa?-WJs@K$Js0KW&sY3kVg%bM@55@4V z4CV>jrh#sgynMxE_9Tf+E`GYWxqsd#ZG&}6FxqN$x9$yzkGh6N6-W`r?kN$?e!v@; zvg++@F40#W{r+;xriG+~66_+(eAiSFg{W~d$-%Cb_V~Xc8ii<7HQgC#q z1Rt5%D8Laz(k-t{irNASviZbN4KVE^BS69zpWO~cXq}S#nlC( zQ7fiw3)ORCWQHaAC=ZZCadD`G=SnSYF|F6|--$O}8SmIyQ;5qxK|=xQ6h3^pR!iAG z?bOsEzpsmE?AZXQyBJh&Z^t!-CNr`!X8z~`k-^a{_2nDl;(5=Qp9;7iEDT2xrt9Hi z8Cj+`u$zLUqO)I1RQ6;keHGIQR!X$XpOQkUL4hZS@dDQLKP&AF+*YPsv~tH3&1JmL z;mB5a#Xf4gV+YDT6$NZ3d}OUJ*WFFb6;_((`V4BWa0xB-4aB=v zYQI9eb@fc;J?;1LkG4AG`1;%3P{;Q;09c-i@?X%PYGJg5!G*z_fYAEpo^&S9Dw#w9 z-!x`eH;6!X+IlY3XA)k3FYFwjcDTt&EhNDayMI!;cPpcgh%93=74&!9nlALsFlrQe z_1mD>Mvt#6r;bs*cVKQztAI5BH&=pYh3ZmFfG|iUV}1Ztr=@Mgi;j!5Klhw_-cfIo~6)5oiy+vBwI^O(!(3$-6?u8bh zd>R&o?9yh|*AaPE71WEpeG5Asz9b}!R(^|@PpPe``Yc_caB`C{I!Y!aH5dKhvQDjh zc*FN~3#)z&BcEHpZv7Q+w2+^8bsT>#eHE$bxuFEe z$PZN8aef9hDS2nnB(WMa8b%|}j^Xt0rgi7{^0>Yt)VOfu>$s4aWC550E=uyi!rk?k zI+~9tqG&;_cqsN@37#_yJVCJsNr|2Z&e-TE2Fh2Eh8zWUt2J2_8kP82?+H4|IWdoM za$@PSisGV6cQM1~U+VIh4(0VC$V)zhY870!QvIUrz@se9pzZJyun(KHFx3eNV{lPQ z?j{x@7P6k803K`khs%LxHgSA+!kFJ4_XfJG8q~Nq&WPSye?{LAP)ox_`D<9_7Xl*p zUY#SA?z%T$sU40nO;|L;Bjedf+rd59&NludMOj+Fr>EqB0mgNTCF`6Q#A+T(%ex{aU{ z;$-(42mR~f(Pu0yEW^l+)f!p;vl}h&SGZ_KlKT2emn{*=;BlgTmHHg{?5xmA8CBPU zKTWR=##UZZrZiOivvBHHbfPS7Yx+Uwny@X=nMQkOf`IE5NIjcx;aAOLEe!qAiRLd| z#)gx*8UtlDPkYoq-n_$?9PDz80V)8jh~_+lN-pf`)%Ts>F=%Lg3U*X;39nakyD#bK zDh!GtApZz`7~DdaW@O*CkzrY90BJfIdn_oR0?m3XU7|Xsrj*UI+rgRhw@4!L^5WFE zZ-{!V@*ZSrwsoAxPJ!g?ta6-M`A{iXvqB6F!CGgQ7HpUt;!I*(4zlF@tgN^L`nJ(Y zpbRiMGji)ZOxCp={)jz!I;&w|@Vy2&9I7U-jC@B`Pv7UZN`%QovZo7G9&AhQjuRE0 zFb+Rt9OLWjlcSvpA7TUYX-hi6kFk9H{NpJ|+?Xsaa`Ho{I8PRbfNI(Wx6Wq~CO3=O zXTGa6%-P+njxW-g7-;UC-m7;BPPN?#VT(e4dd=}w)l@SYU#fpmE*M>Fvi6)!m;YEH zHYJX~#(2h9=SO+h7_RhsJ&QiEK`<)HtTafH>k0DVl2<&Aw7pRAL0<3NbXv5KFxt{{ zR9zt|L3ZU0X>qzB1&wYtT(+<=3ndy~Un7`=v_+ecTb{%8jJBji8(I(f_=KZT%xt7~ zuVOjr&OI@g9*Y{Nc)uE)s3X48q{f9rhWwKcqV&F$hW}np|IPYILBDa-nKqxWyQphg zwPXONC35VmVh6U?R1LVeJ3YR&!awBy4GVzeJ-QsO98?o{((|>=5c6D2&_BH>YuZXG zB#z=zLiy7VK_nr^DjD^wC_cA1x{6`b=Tl>R@nV@nz)_}d8H}zLOH4^QBoPqB%r@TJ zwKdn!Wg0&jNb}2=rtnoPvd4r#)iGK_mFrsH_in{VFFUJVKDuC%K~b%rMika>P*dVE zf(>nsl<9mpFJhP3lLi||JEWrID#h%yHT>-(sSvlTD0|`}6gGppSeZ;f7>9G4%dN;p z5Wc`Vai-H51mT9T#pWRgu{3Q&P^6EUQoBUN7>4nLkso~^EHGm3L5Rf8;CyC5n(}8? zJ=sXciq9EFuO}p?fx;qvNR7+R-eDOr5Z3z1_G<*(v(acS;q!{sLZd#_A@qaTI3A2F_Z`1GxH<=ZJ~M0^i1%ZSO@6b|< zAH&0jHK~&QTHb}jG^}pXA zdi4L{M^EviqhhL@(a=)qm!1Spqx=uQI+&|7x2=ti>x}h$PuT2Mo?AvU_UF#@W1G6wO(6K>if8 z7+>XMJJ0p15)kTt3?V8hnx>|v&bH=chhR#~H}m;i;{HBzT>~?IlDx(<6xnoqZ(Q$kbn$Vir1ryM z=_7@fyM{U>@2qztM(m%`oSbjHi8`}acS3v-2n(B}5GukW|6d3`mtQ!qM#%lbm= zqo5fQetQ@Rr->nuq>GK+VyK6Gl4_5u+tSFc#v`94OR=E%Dwq3-;4z(lS|9C<2 zH|;)68o#4ZxA7e{^*k+uV)E;lqKtC)u_HyZ?B6-nho%^Q>~MgbO7tWkUYE42c=`aR z5ksD(cydrrMeB<9cU%jV^U>+biHsWG+E#sNWi1m61>O}`XRQL~t3hrK4o(gZH4{+G zt35D%i;Vophvr7hz<>(+r`e??uT?X(D;VObuA?*4*Tf8|mTHbPCL4d+H~h5E?m5cy zMFfKU#Kk#G`Wzij?d53~OKY*OIcM`17D$)NjS%v4C zBG^l9hBIa7-pO7AenBzUs3$Hq`@E*}54h@NE{1n}TR%SUn4YZr?1ZSdI33{R z3`T;A=BlTj|2E)fMhy#1O!k#T%yaR4}g0l8J0MC&=Y5>NVPlNs3tGZi5QC1a$Hx86?naD-&vX&1fTkS z**kUIERTz#q@m%u)x5R2u_TCGTWruIU2WIAy1%`%vp-+!ajEEg+Q}68VKHJ`OySF*$Ay&NfyqgF237UsyHyP%7wHHDd4Rsc4rPb9F z%47q5J;?&*H<7=u!=HTIpU*7PFT;iaKZnx51Qqu_`b*jT9XFsN>>*!lZK5c%=rlQk+mIk&hEP#%#?LyL*#F~MMhvY0_g$XA$NNWyMcv*nDD z?&lb9UUMCtAW{knJdZ|63>FjsqXjS*NCeFO{P>Ifj!p3TY^&|VE9g&OA|Cy}#ebdU4ON`EPj_8 z-^`H6noQU^WrN2#hHi}~I@BrjqV@d?f`6gpdu3&1HMPv4R@*OmIXNd72vPb-P&rE= zrvP;36dLhl=r z$bLG(9z#Z>y3Lu9X!+%@GhX=P^^u8`RV8> ze_L2iSkr}+S)GX^T;gneUwOZ z8I9+kc**iAxs`V|QjnnvtOpc?fZ2foO>Qz>Ygv42DqcN6395??bK)w zY923lVPQ~`vZ%05we_y8{g&zHm+9Bm7he_gQqS#rT@Ax;cvKXCMJ_xW#VYd)3-y$h zrw0eAy|nwfyMfsF(CFwJE-oe(mK8gm=5nUTV}L%K%S}o`Ds`tYSQA+l9lcgT_BV{u zKa7GuP%PEcLPIESQ#7!H*+M2rH=Agccztyh<39T5&w$3!zYT&xeMEN-q$HODoGcAl zS?Y=gVPdJ^97v*iXb^80GpjQ+NVBrA0HxXhw@VC2B7_{iIvIe9BZi5Ai61%tdlGTD z(*90DNZ9^JPGA2nWKn0LXd!_|bX<>`n_Gifwg*VlXJyobOBcG|U%-j_`O{BQfQ6AU zlX0lLf|HSe9kd*0N6VeUu=iMA^F&l4h-lK7FwDzWB$ZVM07L-#j(TrzK1_H z2>@_mKu)#FqVUv7*rL*Ne_;=z)AR68K+a@qp92VB`t~p=lDi&_PBADxYY(HiHTO9y zai26B$z4qhD`Rb7y<5BUz(c>9-l^=*8q&xX@1MIx#opaqVYsRKyoE6oF!xJGuNxPzF06NgRd=;3*=jvT!dhS%8A9*n)0M7Is0854s-HeR zU$U)E`1VcEi+ppq!XE^e2t>jhe-+Z7vJE8xO19soBC?M|GboU)v)xJdu?MtZ46q+% z^Fu=lg=N5Onoab3E`=Re+RViMJAk6E9WH(=B-VE*{9-rncCtaP`Xm|FURA7HvfAv| zBj|D3h4cS9P6BqXG(UHn;s;;f+Gz4!zeF~*@h&pfZnd-_0JUsg=?4H z*FZ0IHHu*ADEzs_bL9i76qaOwExm|0~#@8AP0wl{MEe@pD1`#al7M z;a&do@dEv!n>@7JbKOP<7ETtyrj$hxF@i8EjFK~LjB5^%(Up~JKTYiCF?GYPzu)V< z6f^ibeiw`f0aKKjMO%L7vbMUtoDd&9J+4H3;^%(C<9Yjyg)lmrh-kO+wl>!`dHgzJ zsQl#o?YB^66^(1yId+%uo#>|Q;G=UmfY_zl;=vmU{$B&}z7;ebx&yRJ^dkS*m^{&^ ztGwLYTx_z*VgTDJv-~Cqci)~hc2QGfewQf%fDHKUk8w8X8%QT6#&T`5*h=}Ig#qo- zeC~aCz9gMkp`yIJ^QL!WqYwq*2>DPsov?LhZ+Cb}vjz(XvuT$i*{YV~bb%jG=wl%d zT?QR}x%i6Txf)GH3NQ{>_}mjW&zb*x%bhMYj@CImKi?9-IGE_2z1+Zi_hpYzU0(Ne zcbZ>|l7J;MCP|Eqfkt*?Y-8u%cY(&;biCAY1~1khs6vYW6X4ZdCJ_%Pj ze>Ym`OdA;OV!yY#^*lzeXR*qe*7_UFq_p8Op)R2^6gl-DH1Jv+qs6!(2&2xC?HQ9# z8|P+&^^BCPjE;W>8s{ZC&i+CZS*)@yCS}=K@kx4x^Sk6cCVr-u2pdgRLv)QXue%bG zB5R642E(@Gh1#8WQmWcd3|juQx7jvtFSO5y$gg(mm!y8y{Ob)G6 znpl&~b*vB&mht4>-|buOKD5BfG+vW$P}MM4hzs|0R|xSU6vst@$U*!FD0#BPYy_+e z_Zz7`{&#oIJra_V{yiE+^08dU>!&?H(ud8Uy+7f$CC%>`giRqqUJVXo+N9BZre}}a zPF8wMhF_bxc>AM1H#}XxZUZ%2()y2U0q5&NNVSBAj3jFnDK>Ls1GO|PG_T9bl~b07 z&#&p8ldHztREFg8o+O%CubCuySgn2e9H8;A!1u>WYB)NHc*O_AA(%&U`*@mK;&Rjd zglc1DH80xk!;~KaM?Y7-$>XGVZ4yBm7v4ZvxQ^Mh6Q3OQzG#X2qx%mA3h2+@%VaUK z`iSpk3~3)v5UiwA*Z!A!?D4w;0Ri1z{ar}$G$Rt*O?AhwXoMN+belH17jS|rk@P3U z&Z){!L&p_^?s!t;(6P2^As+Y>pSCi9)Y{7WQO-@+XS&}A$84~-wtTH#>S;@j=q;Q^t6{jr~v zpWdSCqsK;;l`h1M#9Cq7=KVEKIltmu`n`+VP;F6{;|jZoEKj>hFwEKy6ox0S%b|KN zqw*8k@KPn=tnb}QOw#VTPdz{B7nm7;3LE{oE|*;D*(dQugt{^T&?8=1YFkPiZ4IcL zo;Z;_Zr|qI0S=UMwr*={3JG+aC%qO2gSQq!o(hdlb=mJKGVktM-Sc^Z9QWR>b0&Xf zxD6A8$?YK|oM1+Zk3TkZ0hPgSuTj+@Cy=d6(3>Z;n)1Mq5K&)8&{B1Mzd8&HrtW%^b+Oa zXU*-r!2OizoOD!d;hy!ltH+3ykKM)AW|0T0rueV^V6oa>+MicwOtClO)mOi(x&PMV zY9lVJX_(}+>=ZShaH}CkDUm?(x29tE9g1Q#UfuVNnxoOe@12{2(e5;|rW8_mmVWpp zAIAetE?0kjN<70K6zK!nnf-2(s$Z+Zc8U-!=rTXW&D{+#$B(^6Qw6r+k@bKn z;e;GS1Z5PK+bp-JbccvK3nh1z{O=V zcO}2Jwg$ad)zwv3p9j1bdkWkA(8I%Gq{Y5?f}u5i{UlIU0TWds`tCY%G_O!k4-U6> ztQC-NlZo)WjXB)n*BdVk6cURu!aZw1KK+uU5qI^q^*gyvh zN|~9CLyAA$x3zadCRTLhgS_EQU7`}^-1}a?RC&W=Y}YSfRkWQFK1ClntehYY*4LsA zmRF4%dc6TRo4aR97Vu9pW^w zAAbM4_-sY6@BLNt@sG!9nS>9Z+M>n_x?y6uv6pu3S0gxS_A_LM9Pp zYAxRA1*JIqv7-dUWjs%GzSeuzxnH`RYCHL-_hs}zlUEPzZ zA*4Yvs*i*lG2Tf@e<%3Y22E4mcMA7kCdu6~xQf+uDrk0;ARC@uM#e8!{Lx|* zkyn@NV*H1LJHZ1sK`IG}IC4HXIBIGzm>O0SXI0wsmUQq+Pg@W##ECjR zd<;W|eOTML;s2SCc7r!Kp@Deok`+oB6-5AB3TsdbDls$VGVFww2A=y@p6MCTw5=X& zZ<8`b%VaZe?d*VI9qsj=V;9PDz09Tzl8~LfJ(13QQDRNrcFgq?@)LvXz3DOehZkEL z@atBh&!L?TU$pj%8`<)VXe-faKD}`J%j%XMc~p>6AUYnuo<` zV!nqnspWbKf_yOE>+80zLv!3_)Eq_&SsZK*fm4X(-i+@I((GR6gPXh=Y#c|$&Kr@X zL9)tJHzjnx);PktVP*FtvCtWnJ0{gf`?{!jkO96|RbPKId8m@e?>am- zCas__RpBx4JJko&C!h~|h**A?-O7?m2Pda$hc)-^8CS2p1!Tz4M1G(9!{%9H9hmS+ zcF%VR29%J&wbDC_s53suHSL=ax5V-vD*errC=y!F>dH*^8ki(}HVak^2Px*8*vof~(H&!kf@gKMNPs6OstRayW+eO@C!uSWKBAqqTUxX>< z8ek)LQ=-f=JdXv*ioXcoth4Q~NyZ{qC4RKkuCfhWz~FkjP_xl1>=pYF8Crk4-q+Z4 z^Cv2WnJDSYb4eV#CYR%6S2L8pUvRe}D$z#&$B%5PD`Z2P(n@0C9~2L}cZJUc#H)_C zHnIm$dh_mI|6@1|Fi*2TNHZ@ZDlproBMK6Pt~eu!Y7I z?ka2{`t|WS_mdhg;fzB)?yt6&&X{jrSM4oMZJi6B^-MbL{1_5ddfx7}FdSZvOA_wo zoOoq&brd_)&1)`#gkvX zU4U+E#C!*@eF~z%|?re{8j}T8$gm+ZIRG*Drtqwdq`f*zIrsdJu%=JXc_O@-AQ*d0|HUPYU zK)(6c5`a{G)KIH%k_yaBEfV_Jdyu7nTg!LacOvd0x%%2kWWn|#=UvX}zl?%nP(!IO z9PR6SRUL52gI*;6n^Ag2X7)h(@e$?>ABKI6+e6S+1W!P0b7w^EcC;o)W5i6AJwPt? z{p<`sP=Nm~a~mg9)F|t5zp)fqS9vpwh^srJ1WmNPp~4=?ihDqxvDsXy=ppvB@E%?x zBuHxVe9p`eBWikr7|(Pauz?PEmZus9JI2O1$JL4OC2&TD#_?dXM>DFm5fRbG{BF~1 zFImxH1WyQW^T3}YUp;#8CpKsTa1t;K2yszjdgiJe@d0s(`04_1SGelB+ov6ls-J+O zDs*trHPZ290R1aKrv_7Tj*1u*=N=e!B*Z2WW}QaF>#YTpP;`f*dI zA5m0vmLwboh&h!U+yDZLmU{nny;y~~Ke5rWXJAL2#XUKe;)*AY(C{j3Mjxl3K&55T=>)W1x5Tg>E;%tu%i+}4?rR_O-*`68bzpiJZ}n8za*J8 zKLtRlJp->NcVvUygZ=G+a`Z7#KUH!^A38QJl)JbAjB;UJD)b{U()IeTCG*&{(4e7p ze*6lNxg+m4Vbu$ONxQ4Nq8iE%y!mk`)k~+6g)A`IQbu5Wwf;iz>G3brzK!fh`c8Ry zIg{F2>#IbNh?0F*P0s`~)07A<^7Z+VldZwPl5VXFGe9D;;XX!80Qcq(p znFODJXe;3N&;vZMYnTnvT_cL9Zk;om z0K1Hu_*Cy`MhT|t+h+ax;1vhAc8NzS48bOYTQ!#t8TxgZigQ5CyTAx$CpOUAKUK1^ zSb3TckiqC*HOuU;e~aGolK1~N4#~@4trM1>37fb#HW_6;6wu2{^Op0-cD~6esrH-y zjt>Od*M35Q7v@u8A-jMHFmA+-d;{~lCxi=Htp+{CaV5rdSoH#lA z?vM+@XoP4O0VJxW?NsilRX)8Tes#%dL`xW4?xPzpCh!qO^Pj=or*j|x(r&y?LW zqYOJgu=hQDTmBmbyZm4)RBjmXkt?ON9(Ep`$5Oq zkYCIV0oI25>W?qjF5?gV+Gbq#&+Qx=?62X{=2HXAM2yTFJXl!KFV74*`g;?&{tnIm zLz8`JVc;sz$AEMxi{lMU-@+PNxfxNz5~i6tSy)&~KE?(G%7B27CZ}5$@235pYG2~lC6+%~z_Ax_ zyAoKlCWTtt85-r~4Js~BG5j1ZT5AqEi5ni&QVPK<)BSbs=LPffEa5ZfF=k#sVmJ8l z=_dmQm#x+4@YuP*KhBQ!1sisJ?$tv%qu?sROkl#ETxIEY&&&2*tr2?d|M2-3!lk&> ziK1`@rXTtNN-RRq=_PlQh`gHd>~|XVpSvklSWR1z9Z22{h0z`! z8(1^&{o&kCh@A`oVFg$ZVBB;8G=E^}*Hbd~rzZfn-m6#dz8BoJ+bf6u^}ULkTTIdt z;sd}sM|P}~Xj<|4+zD}b994(gqe}x$ir(3Z6^s0OG+7l+GEbG&Uqm}k=AQdo*sY&q z7RS>QfOaLc2KweLUQNQD8`k?FygMR^&ECVeC( zrf%p@$_V~KhM74##jZ7=8jeZF{*@Z&Was8Uf;iO(q4#QPNO;nx3&~`p)y>wqIXOS1 zXqUt|ISC=^a4GP4tb|9oGY=uq+P0De%$6@B5CqU&6|VNf!$uFh! zdd2{`k$-*C1;n6q$kg1}7MPczS9kH*qZ-*esYu~d+>^ZGjX|^W!}M@ED2g5de<@$oc(m0uGKYqvOLU&^>FS7^OJ4V`gTKyWQ$2y#aHx>d&0j83nqr zqQtoGto0Jp8w$ZZ$mVzgl~3tkn+H zqe^7|Jf)1xn@`Vuob!nq0%dt%hk0c_bHHuY2v9gh|kMMNbt#q%!_^ z7yCtKu1FQk05}Y=?Pg{||JvEdhRa%BRsttEudU7?fVO$biGm8#3v&xIF99V>6!#@4 zH>*`>@&l6GTaTDB;$jlAElf5#OAE{BC^Hn%j9Z<;$anOIm!3-lPJ9hHIVk@~AD?xT zMt`Ay{ZKLqn7klJ`0(nfpLiQ6I)X4Kz-FSQZ%xml_TZ!GN&aUr7a}RNvRJW0<1j#r zw+0}r*BfwkEM-gbb(o^n)zltBD5C!z;lt_bK%(d|xbM@=b;;ECzW0U28#nd`-$5+6 zgf;Kw?-w4I#8@w<*wdNuqYDtH{v8A@4M{SHiAk&ZemG|ojD`HDTwZCVF|Y(28d$NN z50=NQySMRCs!N4%2GqLt#Ou{9#~v4x?#JH{dImr!FC*jKv+#dhmRLNo0uDJCxCJB})BUjw**UWmNnDo^YaNQoI=^D`^7Ey+ z#>OU0XZCIv6e*c+_Wy4%`Ji;W0KXa%|CT9_&B=Na759fu4WypufFuH_cG~y)u)sC} zx0}v?PX;Kg0a5@)Q>W;6Ds@ z)J=^ec{U;i+T#8DeQKB!{vwOFo{s+^?>rJNgiJWg^dIyf)quhwdal|WirE*%&E@0& z)e}m!9p7nP4ad(azH)QaK|M0~l6)UBnDyqEZ}P0nOet(pru`?dF-m%Oacp-n@&Yn5waH5_1oCe> z`btydq80SYayfV9*>46{QEDAxMGV!3^)(`<`IsKI{Hq7Bu+lK{-k1~kiQSoBiV-uQ z4#mvVHr0LRWU9go&Qq`4bDvy>K1w%ipYpWOKrwh8StAdF+0E-`K%1Ynp*0bi2n25+$q$ut(s+70QOn5&{BjPioSnp`{S1%0HwT|JPU zy=`vR`p1aIZ3QVMbkLKR>F&II!|ui(N3gF@d| zz&&yu=%eiEqXxN)^{1K)6KIfDul|n!$OAY01*7Z#S<8$PlB$u-rgF$NBiuL#9w!zUpR zpNMYp%R=P^^(+YrAg89QT#8{Hc&onf0%13=q9d6S5w5i*mXTUZVls%LfA8bky4H9- zrbnkKXB$#Os=?f+x~mdEIi-jPP{<5i|L>h`a>JK%%N27fLI|}u7iWh%_aDBDef>5y z-QLz(^rheS9?Z)xT>Rr~BLn@vj-Gm(nl8I34Gj$ng~DlQC@C$|)BPu{>gZ?#fM06_WzKLbP-*xFXF)FZ{DYe%rD*$rTut~D)Gm2O{gB%qF2q%rNfT9I%~ zjhgYcnh~kW2NJ2-(6GRbLk9pAz5y9PyZXS0DqHeD4Vvq=U3Wf&ITay)M&0_*7jwak5JKNB5{a~O$^7x7hqW^^ z&B@J=Pe>}Os4y}#0D$RJCm0&&U%hcBDfz9dv!gt%O`9}kVE^8H0sq$B2d@*}P$?7& zg|ceN{4Sln6OxjzT)*}7*$XO_3IG=E%=~{n74 zP^q_sXp`BWx9M^8QP@u&Qn@^tL=Aw6nSP29LJELg+8d+N2Eg8M_~VL&aFcYPQ%jJ3 zFbaUtU`cU^p-11RC7}+Gd5`-6CYIZQE`?4#ZuIXDPobjm$HKy5*KZsB#RERFGZ*<| z?6njc>ZL=&qX$FJolk}DG!^CLt>zmlDGb528k>auySuu+eigsH-ht13jUeMSHO)WU zovFq|Q&UqDbRA)3W4n!7B0iX|EGgWyA$Ey`i7kkh4tiR@dBf+?b@5dahl{IvdRhnC z9Lwq5=3z#7>ann~?SFlD5`-NeA8*g^QJR&Nh1o2Lo@GlL6BzR4i#aDJXS0i4fyxue zsMT0sQE{(3JQ4C!N_2J+j!Ef}lUKHPc2-qUd7R?r*5K*ZP=EGu$b?O|iUhikL+N## zpsnZS9d0%8{>>7 zx0SLaz3P%R*VTQrk|P;@Dcm}8*&-)&3FTm9&ZrY)VaV_{||CiX;F zGu**Dhz~DVui2B!;%ZJpaM#NVM!I@?&!9Rb(<^0G1to=aj+ zG=XOVf!!uWCFh(R+&YzBn&RS})+M^qk(5Wjel4_mW`6ik)7qLIF-#;NfCf!hIZwJuT#_;^WN@F5P)i{vChC?GhvzUFYox-M_+WOT#$9TGUb#V0%AujJ6rpPN>b zrFAoPt6S<+&~$x0&0%t8UEQP&5?oiE@c`1nOhoe{b4t9wYy8VO%A|)jS4+UnO zo{EZ094u>6%SzT!zB(;!o;Y%Pe4d7m?ldqR5>>~KlFJ*n_;z=?@3=P5O=iHmi#;74 z8rs;H>2Bw3ppG9ebyIH>n?!;IrKF}pMst&Uj~*qL@hr7=4nBj4-AM=F&Z}YwNNQ>I zeEH%x3`hC$evzxB_<@@_>2l&RRC&Vt-@`r{eC-=cMChh0c-A}hQ9UYIsheHF=17O>QuV|ms&^&$iY;t(``^<#|W_x!J+{(klLsaxJ z^!ws|sb1sC=bX-J^9}+GNine_uFLad%;^?)+QiuOjEwTUyzeg!)YQcC)XGXrDTO?y z&rYR@qxp38-idx5hKD26Mc(s(_vs{ex<64OH6j|db$L`2nla~_N&j`c!C@H25v}TXmD_@@pb)a zkn>;ytBtKK8#61boBFql3vx$cRaJvVxBhG_vZ=)Qcp>lYKef{`e7vBZe#TK0J&WpF zy>}ECsLTBSvhGU#HFZz@2?1A7a%7#-hHr2XOl;{%mP+5UgUM?XkyYUknnt!Hw)kL{tI;PySVuH(y}RxfUjV*KYjYxBb5;sm%Fdrw94=y z^|^gZ^VP-C5e6>SO+1^#P#T|i!`A1KsruT5Rp-^>&Gq-7(lIhK&&=$-u2gRow5yDn ziHHz{EUbTmzYH?!b#}j@xYP{{$kCAAFh~4QK3!LQp`^q%Q!R?_?FlY>FE{`kcyJRJ zKZO0@L2aD@L-tsEEc)3=%d*jd%oz(9Op^PZ3XchD2A9kR6YIPO<=~hB$Y2)%{$pd- z>HZn}-RZFyycoX5#@;mLo?Zsn8W&t)>9c)nSeTrWQe<|viJ93`XmsnO+P0jO^d>%z zproXPO4yABhMxaQNnKricw}Uz*3r(z1sj^4qaw*It9{#H0zG$o+uqoiToqQ;(C|Dp zz6vq9?|i$nzoZZ_I)#{?enLlAroUWUGBp>Uo16QHj106%mkU&x=NMLX&CbBCls>K(RCXoEw=8oI&`Oy8Psc4=<<1- z6mk_TJhPpb%TiHlBHx*AFPeFa9o*dEaeTJdyyn^0+}P-{vkoQ@1%K15ZnEwkM!n74 zxAMQ3x#Xp_Ux6`MegYPCjN7ku#g60AFGwidT;p8Yr8=Z1EYn+?_K@2z8i$|kw6o8Q ztEV442n8EH{RhPGu;=w}MkpjaJX6S1PFA)uJG*KD*4XIYmG@UI507?*{`OQm6(u@t z0Dnw$0{uvPZQiHC(em8NXa-tV*02X3VIA@bEGb;(S`~Mv#igalP!kIUR8w>R^5VW% zjm-<=tg5i5znTg^qeBD)1pHEOORle{piy;2LI7I6sd|gQkBc+yC9sv2ldEdWdO?7{ zxgQv^HNjeUFum=(I{EcpI1Uy6_)9iwYHIr1U+rkaii+H`B969}mdFrk#M!$`K?D3h zckerviz~Los6?cF&ae=rHE|=G7~4(QjoKvOkM;1Ry6U;>ftzFFOn-mrCkoRO(T=;&CP zV~-DnXq-+?PYVfBnwzD~_i-zYI$Erz%DuNo4YzDOU}A-Haf#Z`pFe*}0`KXO0`EUD zI-%Uo;)kidxPPZa&Fv`0A1DbyCMG756b%&K4Cf)B9NOXjmoQTTuR|>B^C_Gko%&=U zXRJ^x>(G&OV35(}!aCP1_v&o#e1BmMk%|v0zPJT>K-zRDWd~<`}9c|16-` zfnr-nBe-IlB{T#We0oaO3cKdyPGNrm$cyfLzkHhJe}sSkn{fH>4!@wMZIF(lG+$8K z+1~b%dIhjmx81d1sU)qno9Ik+AO z6EnnBmE?f*8Xb5xb!B$uR#sNnci--4rLylLfpWk^qZiUQ=uJ2$_4+j}^qkTj-S?Lu zs}LPe#M-(KeEDnOEt2s3?oi<-I%as0gt)A1{}*$gH(QL1Mg3rPYiS>d$BE!z&9=Rs zLzB|0*^CMZ(6M!a>$vsB(1pJm4Bp1^K03iw6~3sKwMiYy5Mriz$`T%X`*VwS7zrgr z4B%$ob1vLyV}PVh)Wi@OLP$m{T@QS2mARg(dwWquk@NW%78MseEN4qwk}}hBosOi7 zgo-hj%q+8Km~WVN_ekD6ySO96rVg0JTUO-}|6#Au=*Jfkk&Q8CREO zawNUk%F0SQ;esA)35F$u;p+)5MP3e ztBQj5aJr#CU^zp@YpyNnFs@W-L36LFf( zaP!_6SHIp3~D)6hCPkD*SjtLPDI` zIcJBiZ{N6AB*l;&dp~D41K^)eEz;kCX!k2AY~Y z?%k7wKE}t-G+Ook{oB|S?(Xm3JyE{IGf$1A3+$|3O&?!I^hRZJ^YB#8 z>=G}t@6X@tbi5DFn6fi9UsdH0+Y|}q@W;el%FoaB`6Q;Ujvpaqb(|p0qDTIDPQ>A7 z-%TAF24*8y`Pfq>qWgTQNzW zMG-WZ*qf`ryF6C1l67__g!PW(^xRf%x&oZ3U17jym7ob&Y7E_=bOdEBe7M+8bjkY) zd;WIE#XLw9{l>4YXU9L{A(pq7SB41A+S}*k*c;xO0gz~x$}G{=78VgczJSZFsfP!D z>M-DM)C213Y7rkEuC1*JoW-Q1@WXctM-&(ZQUy%=e#}1`7#IkRl9L})YD~*`I%D!_ z@(btd9>`DS$wM4W!-gL?b_Z7_TF#b)WYj0G!BRT(dq)a~!^`Y2G5-AUPjGN?Sq=PL zT3N+gZ1d(d`r#KzI55ck+v`>%oRJ*6zNsnY$xl=Jd&nKnQdxzSZ%~ojN_RyDiHX?_ zGI)I#hf_0%+4Mk%x4uf{H{Zaow_9>>c6Pu1{U8%@FjHbKDY@oZ;Iv*dSG%LFlqR@- zKny`CDJhBUhDZ=Ib4g6h%0MyGP1dCbQ*CK!i|^en{9$$J5DVj*A|#aiad)ZT(5b&g zqtm)|hpjPdT`zHdD%p86rEbnYad>FlD;`X))R+O_YFYWMKwhV%l(_i&>WN=GR@zrr z_j-DI@B-c4-345C>lQ!T0i`czyzFz%3$p1xPPI-{CtGE*XXG%kO|(;< z@_V!aqd3TaBhg4WsFDVXalTI4ve>D)IzFE`RTaq@D{e*`f{vI2!oI>LfE20dTp zNm4uDGiaIYzgwKO1u266ULqpJU1SH%zm57~P;zBuR%ChIhZ+TMaUq8A)VMhCybR+n zI6*TO;r|Ebs721=0GQ*+lRrq1j;`n`cK`Q-ReB}zgMFX2mTMuL$NPAOTVh>cZaJe6ug|2S@h%Hrk`u3W8c>Iv9^-mNH80(W3;|%(?1j7}i|XmI zxT(NHNEk1lDD?B^&vL_aevfaBZRKrI9+`~lKF4joSDVqV!DQR3OLkK8@)83ZvCH%$ z{pJVg-oqavBGlBzX9??u4aMZ-QYtH>pU@-)1fnyT_cr{NA!6>hy4_puytAt{?)k9Q zL5;-nY~t$HMse78e@UufqC&qN3{sbpaa#!bOq27(`Y@ST23meTosgTG>*!FE^i zf{W|J&+4wuIY{#NJYN5oW(!*ER1C(O*An};2!a0L^!T>!d;JWd`D6ey*qb<5_B zS=@b3&5G_=@bs0E49v@=zb|~8%f$)$x(!roqeilZ%~^B%NI8$CdF+> z88LYym8a&qw}?wfn2?e{0Nb1>P(G+j6$K-r*C<*O7V2&Pvyb}Ty}(Gv-xUN=fRL9bU=Nn1Ki!6)poP$;S`?9gGItjz8xAm)_V{*!RF6h5_0mYH>*UM1#M1EEULP4a$y}D zt)5e!YhgUREw*I_)efL_nkzNi%s0e~Wu-asO;-A+x#?=R(Q?f~aK}l)u?R~Q`awGKgsYl<(4&$t4*8`6V!}hw`;GxpeS}R_1LAQ_& zj)f|-)mG2*vMDGWj$N7eCb@Fm|6$$iX(X4f1pwl--N@WATvY3YCF50 z!|iq6_;^)ay1cAx1j(EIy&I$9?bGsdbLm@?eV=`&UeD<3DQsRYE+NOs?x|kiwXoWv zqBk3Y^B!j!w8CMLVaae#$CU1&ohgx%4Ge14*ng7N>06bYe;qo0N;@YHs*4+&V=mOgV{GN^Vbs?W?0;sFI8=&00 z+*}=1)fwB6`FX(=%eL8+l#(enusjZcRPbxHSJ;@>lO^Flp*aCJ!sgDkxa8a&rN6NFi*ue_-u`0ljUU5pIj>Q6?ciVQHvtK9T$@ z6QL|C3ji!0bas0+Ohfmdp2I!hPF~a{W_OzrK*dPeym&OSH*_y)+~> z^V-^kpZ|6j7Z;b4+x8StHl^?B>H-2sUV)k0Qo9g*cN0jod)qCp!FCHx{a1_c2NNrh zMID}6tyJLC-|{c7M~EPOs;jFjAzH${#5={pQd5heP;a1MWbD5Ty05C>7m)JfM!$^J?MxgBV)YF%7ZAbl!GVS-NfN|dgb+6?b} z^lV+4Q^33dgVEGU)%5kN7~z_)RB3T>aYY4#R9tlQOuO&F@u(==WC#>CQ!_IWes>6l zj!HaYI9vI8jxUOfRw@NQ@bbR+&dyHg^*z7&`IeX%HI(;R>06)6E-x>^nI>=4bu@Ad zKS9v@n%dmlyq6Umc5mJoKgB=A3PS!8+pFx}lJ6&)>AW-bgptvw;jX6U1ZYm;C^tCY z-ZXcj;at2KnV(@S3I!XBi$747GZz=^CDFvvd;3?mZ*#B4ESp5O9I6_!lSEym4^Os; z=3K2$o9wNY{kwy4DBiFpe*6f-zxz$??x>Exw-kG-sHg}XzH?TCe*8*-MD_H@Aq$NZ zKLncJ`1rVikY`;vY|Ra#0PJO9!VOI~+f6mtzb4V4kzu{wjJn9Nc3)Q~i;~%_7!cHxtF2TG!JnrrbDaLOkuX&xr=PU7I3YNK4r#tH+uG_4h}0R!D|x=3d}x`@~GvC6DJbj zn}><{i}yxQ3BY$P7#U^V`S>IyC3$#iyX9})Cb!scAtR$t2OGpNqBDQMsN58=Ac>V$ zUWLZ_T~N~wW?B*B4k=Y(4wjZFA3l6&yA=s;MY(SQ-e|tdb9rWhuN!oZK<$g_ea&&p zM+P9&*)c+@sOauwX}S-vxLfY<^TAz`)IApN698^JhKIF#2DjgIDp z8kVxMp&vdBg@=5Mi__4as?PjOtve6oLhf-1V%jTfD() zahiF3Uhdt|fk>>-8IXh5*VJ5JS93=7mXwr5M23Y%DL>zG7+TApWfNDEXa!c7>_~k{ft05G);F|C)@zj0@SQ07F=zysT zrYSZiX1mjtTyGr^dFtvsJx(@p$?%(f+iygoa<{uszjo4URlKYRz9GQX&d$zywsnb9 zio%A6hs(6$w7>zY18*v}SD2(DL~m`45c@2+tZZs)2S-*`c5vY5wPzGM1z3knf$K)T zI!@;yuzviwf7KJ`*v}_^WR@GWeoQ<+0`FJ>u4ZFX1~f^3v8a_5ysCmT9^jaTe!$Rg zv(|K~k!kY>M8ue52w+hsr&_bzyd5&q+gA0L=6AjA|CAj+E%jHd@-uSLf|gv$W2HsO z@1>%t8IRbQu=ry*M3B{e6ygbh_5aZuYkpiIiD;psi0bMl=j6nKEjv3qjl8wIT*=9h z6OgG+p9XYWOp zquPN|Id!dAgACkpiC29$mBR09J~%D4-7L0xUb#Dp0jU!`LW+lzlaY~?%}xCfxHCsP z&oKf`dN?M=CNI7%jnM>*@=8A;aA-)Ijx5&dfFOd#KUsjJX~gqQ0@**V`}RYj~XC=U(cXb~J_^_DJ zZ1d7QZBfo#B*4gPX<0elxfXD3X+3a1zVO1u0)%miMpg3dQrkA5^1qI;KE@`#=1`!Z zzybQjqMa2(_A+=ium1WP7?S9I0p{7V@v@S1)WYFW3a=eogcKJy_lJ;&t8ckXRJnpOkRhgc%Vu9YWG*%V24-#+9esTY=physl~7w|x2$<3zU$sB62wj;wnuUM;Ma0~ zr{UTLSQ#)oyBqh;?ln|k=v0l2NUKfg01>mioDFCj5`i7>(Uw})2#KlE(_>E$qj{l_ z(9pfbYA(j)_)zus#J?3Yc?duEK9PRpP z4skqthW*eBunVBpQBYDM|EwA5;)=Mw3A>g^#SK80j%|d?p`Rjq08+dpoATv?**3j&}JJY-~zJ{42btC3PLU}9p1Qh_72M-?L$7U*L zx{z_2ph6#jh}^kMKt%M2^wH$^@Awy(5FZ~OPzZy9?o({!XJt{dv1PzAA2$sH4>Ssl z8&EBcFHe$lq$9|R%|FA3FUQB90x;bqml*r1-KP_{N_hDAp(&D*b__~MPTSv-b*s$- zf&w2>6r(`}%9+X6sgjzS-+_`9;=BleR6xM*%GI7E&Y`2@;{(qnszRR6K>b_ojl#sn zK!Pv=$8E7GGc_R@DihjG#4Vz(8%*QW7 zLqjYqPb|vjr>EUE&e9DTl-L*zsOdS8uzTf#G6^zy!DP)a+T%MAq! z3%ojDUH9UEa9BC5)sEz3+q69 zl6KxPHUeM<0GtHYS8CdZhOgA;s2y` zoeDndzuW-afqonu_>SIwnRjK<+0!CdL5_{_zF^B!=P=6Eg+P#wTr3kskB%y6&Z%MnptFDh39)MNg%JXxxM|Ej=o^FsD8I4lX*Y{2xrvIcuL;ISPluTY;9{y?=6*8o{%abRzsh%kX z#W*{wS-}4d_iXusfbHT@8s}?%RTDFwopn~_)V)_l8cYzdGxeH%E`G|I0}njXPE%7; zxiO=`<1{;C@grihOy4m8rlzGe3$NZ=4|>SS!EyN9R~1kc@tnKX z=JWa)Yb~G)c5g1U!i=J`jw`$W}Mn^$mH;hpJ9`cJ9 zFP3MWOTbL5Nwba4h}Hx%4lSK#X6m;?A`n<_#;U;@?-Xv8e}ihQ1vtyx*iC^w)Y_L@`*J3B=S z^1Pm@GV{H0E*J!nJ!;j*BXyiZidV%Y%?)Y7j%OO;-r_#DJ0OT=X=Q~-7MNT6xfNwV z@NWjRn<^>5XWA+%UyPC-k&ry+r~E!iS@UL93&_c!@BpS%QgXhhaO?BzPqNY9eziC4 zyrHmEqN|+$PjaA3qSxJH(Yo+%^sz|qXR&e**zU29rO!(vfjx`+emw%ubbwtoI zc-yL@78+p1@?lBZ7jVCMwAJQ)1z6Zxo`2S=47xMGL0EWn`BE>~k`jV5e6joYCPomt)e+7RhH;-*t8yW-DJ#0GAm?R{EHd=>#E|?hJJ=*ZT zD+h7CmILt41ZZPwe?;MNPikDwPWT%9e#h^9RczSi)s5g4Z416GG?XG2SuV}v`O?4T zR<8&WP7)DmIX~LPmE;QF3~nl4y{-KhU}&6WjExh6&F(Lye)%vs(vN|Ksim#WU@7e3B@!MxV#2ULTZ;l2NCeCZOyk}>N!ir#sq( z8ZQfO-{Fd-i+@#p>pd{Bju(04uPks6oSBY|O{t~LX{#lvVY<#{&dfBIf*iY!yMB6x z4=7h1GRg=*J;zE4W?y&;fc)P?xjBf#B2suJPEU%ar>Co`96%BFT&&L&!sPdy^gjI2 z0g`y$S9MRmh^XkdM!n1G2wN)wy#v&FeutBfQBeo`3sjDHFY9IGUV3~hG*rqI#-~ag zZEx>cXC>q2=3XC3W+%W14-5N~LS@X zgw&=Pfd{6bs0d_xt+JQ8T3U5h8Hv4g1A}x_WaKkma}JUZj}oeNS%@H0Gkbr36rXhN zO6R(F@7_tI4EB!!$N25y&1^M`E?Hl*tP|DC=QS-3B-mQs=C1zP=O$=&wyA9H+4;vr zG{5ZZdVB_jsx;$9m%U=m67B1@x2l$wvs)A9$jHdrb+lSq(w*n`f)2B<+y<}y*DvFjtpTZG6M~*G&^lBNc8chX{O$v6kan>p=xbjbTEjV z#66~^5Fj4$5*bGXAhN|YWLt|K27_hCHy|(1Ukh#Fu4n8Z20G{A#yL92a@-rqT z<^ppaFOVGDy!T9huKpm6$CKWEeHge$AgR=@m_kBHWT3B~o;LLI_mvkdtvD5x$e;X8 z-@pI~2?=Z%psm9E{DiMcd(Y|E5(ig*^+Y~8=JQ0O{`O$O-f!Yery*AU%U(l6L*yfY z*^6n_k{L%@1BuT%r4t4EN|`R6$H4J2Xf83tgm8gI{+e66ra zU?i~L`wPt@%J7c~35|R?!D3NsgNd>-a&Bn?cXSKodW~sp(!@ETHj7oiz&|=VsJ(>m z7Mfi_u(_zDqN1#5Z>EG;_4xlMojWUmK`QF%J75La$MVEWg+|GPd+lMSfo;EBIH6G2 zQ!JR`&qUZR0`txlaSIw*!7C-t>&^abk%Zm3dh=dvGJbs!m8fT9PJ*3|UdG-pnQUh7{37^^EQz+nbu@s@5OOkM`Km!dCTP%|-k zAojhzgsGs(|62;#^-|H@UGl9;AFP$S%fF(cVo7*T2uv0$3a9@VMn5z(q#em{29RH` z)g!R>^s@b~yuYun&o_Rl-#ZX?`6ODf%ja;cMY%Y$(p)qVvAk1IoS*U$cGY_jPD`89 zmw_o3LQbQLX#PT literal 0 HcmV?d00001 diff --git a/deployment/v3/docs/images/mailserver-5.png b/deployment/v3/docs/images/mailserver-5.png new file mode 100644 index 0000000000000000000000000000000000000000..a678e21ddcaa1c1dfc230835cd6c7cfd6aba7d3a GIT binary patch literal 41984 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 literal 0 HcmV?d00001 diff --git a/deployment/v3/docs/images/mailserver-6.png b/deployment/v3/docs/images/mailserver-6.png new file mode 100644 index 0000000000000000000000000000000000000000..7aab6edec351d8a2af262ce2bc07ce7f865687cc GIT binary patch literal 28928 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 YHV(h1-69Wu(h!n<3wu-eO5gu~01do+jQ{`u literal 0 HcmV?d00001 diff --git a/deployment/v3/docs/images/mailserver-7.png b/deployment/v3/docs/images/mailserver-7.png new file mode 100644 index 0000000000000000000000000000000000000000..1947a6f053511e2fb8793bfcc32a405d818b7d18 GIT binary patch literal 52565 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

&)wAw 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 literal 0 HcmV?d00001 diff --git a/deployment/v3/docs/install-gui-desktop-on-ubuntu.md b/deployment/v3/docs/install-gui-desktop-on-ubuntu.md new file mode 100644 index 000000000..cc9f5c55f --- /dev/null +++ b/deployment/v3/docs/install-gui-desktop-on-ubuntu.md @@ -0,0 +1,42 @@ +# Install GUI desktop on ubuntu + +* Install `tightvncserver` & its dependency packages. + ``` + $ sudo apt-get update + $ sudo apt install -y gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal ubuntu-desktop + $ sudo apt-get install -y tightvncserver + ``` +* Setup `vncserver`. + ``` + $ vncserver + + You will require a password to access your desktops. + Password: + Warning: password truncated to the length of 8. + Verify: + Would you like to enter a view-only password (y/n)? n + xauth: file /home/ubuntu/.Xauthority does not exist + + New 'X' desktop is ip-172-31-13-234:1 + + Creating default startup script /home/ubuntu/.vnc/xstartup + Starting applications specified in /home/ubuntu/.vnc/xstartup + Log file is /home/ubuntu/.vnc/ip-172-31-13-234:1.log + ``` + ``` + $ vim ~/.vnc/xstartup + + #!/bin/sh + export XKL_XMODMAP_DISABLE=1 + export XDG_CURRENT_DESKTOP="GNOME-Flashback:GNOME" + export XDG_MENU_PREFIX="gnome-flashback-" + gnome-session --session=gnome-flashback-metacity --disable-acceleration-check & + ``` +* Restart `vncserver` via below commands: + ``` + $ vncserver -kill :1 + $ vncserver :1 + $ sudo reboot + ``` +* Ensure to expose tcp port `5901`. +* If the system undergoes a reboot, please execute the `vncserver :1` command to manually initiate the vncserver. diff --git a/deployment/v3/docs/rancher-view-only-user/README.MD b/deployment/v3/docs/rancher-view-only-user/README.MD new file mode 100644 index 000000000..57d8b02a1 --- /dev/null +++ b/deployment/v3/docs/rancher-view-only-user/README.MD @@ -0,0 +1,25 @@ +# Rancher View only user + + + +## Add view only user on cluster API using rancher + + + +Rancher, by default, has `Owner`, `Member`, and `Custom` cluster permission, but none of these grants read-only to a user. + +## Prerequisite, + + * You need to have admin access on the rancher itself (this is separate from the cluster-admin). + +## Create View only user + +Login as admin, go to `Users & Authentication` under `Configuration` -> `Create Cluster Role` + + * Name: give a name for a role i.e., view-only + * Under Grat Resources, select `get`, `list`, and `watch` as verbs and `*` for `Resources` and `API Groups` + +Save newly created role, and role `view_only` will be displayed as part of defined roles when adding a user to the cluster. + + +![](img/rancher_role.png) \ No newline at end of file diff --git a/deployment/v3/docs/rancher-view-only-user/img/rancher_role.png b/deployment/v3/docs/rancher-view-only-user/img/rancher_role.png new file mode 100644 index 0000000000000000000000000000000000000000..3b13bf46d4bf6b824afa51f39ed0b3f16f516d03 GIT binary patch literal 81071 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 + verify via below command: + ``` + $ host -t MX mail.soil.mosip.net + mail.soil.mosip.net mail is handled by 10 13.201.190.170. + ``` +* Run the below docker command to set up mail server. + ``` + docker run -d --name james -p 143:143 -p 587:587 apache/james:demo-3.8.0 + ``` +* Ensure to open firewall ports via below command: + ``` + sudo ufw allow 143/tcp + sudo ufw allow 587/tcp + ``` +* Login to James docker to create domain & user to James server. + ``` + ubuntu@ip-172-31-15-176:~$ docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 5bf8e2fd568e apache/james:demo-3.8.0 "./startup.sh" 7 minutes ago Up 7 minutes 25/tcp, 80/tcp, 0.0.0.0:143->143/tcp, :::143->143/tcp, 465/tcp, 993/tcp, 4000/tcp, 8000/tcp, 0.0.0.0:587->587/tcp, :::587->587/tcp james + + ubuntu@ip-172-31-15-176:~$ docker exec -it james bash + root@5bf8e2fd568e:~# + ``` + ``` + root@5bf8e2fd568e:~# james-cli -h 127.0.0.1 -p 9999 AddDomain mail.soil.mosip.net + AddDomain command executed sucessfully in 504 ms. + + root@5bf8e2fd568e:~# james-cli -h 127.0.0.1 -p 9999 AddUser admin@mail.soil.mosip.net + AddUser command executed sucessfully in 474 ms. + ``` +* Open `thunderbird` application to login in to your mail server account. +* Goto `Settings` ---> `Account Settings` ---> `Account Actions` ---> `Add Mail Account`. +* Provide server details, login credentials as shown below:
+ ![mailserver-4.png](images/mailserver-4.png) + ![mailserver-5.png](images/mailserver-5.png) +* Click on test/re-test to verify server accessibility.
+ ![mailserver-6.png](images/mailserver-6.png) +* Tick `permanently store this exception` and click on `Confirm Security Exception. + ![mailserver-7.png](images/mailserver-7.png) +* Tick `permanently store this exception` and click on `Confirm Security Exception. + You will receive this while sending a mail from your account.
+ ![mailserver-8.png](images/mailserver-8.png) +* Try sending/receiving mails from one account to another. + + +# Troubleshooting + +If you are experiencing difficulties with sending or receiving emails, it is possible that the mail server of either the sender or receiver has blocked your mail server. + For example: + ``` + Hi. This is the James mail server at 0062d7fb41a3. + I'm afraid I wasn't able to deliver your message to the following addresses. + This is a permanent error; I've given up. Sorry it didn't work out. Below + I include the list of recipients and the reason why I was unable to deliver + your message. + + Original email subject: as + + Failed recipient(s): + syedsalman041997@gmail.com + + Error message: + 550-5.7.26 This mail has been blocked because the sender is unauthenticated. + 550-5.7.26 Gmail requires all senders to authenticate with either SPF or DKIM. + 550-5.7.26 + 550-5.7.26 Authentication results: + 550-5.7.26 DKIM = did not pass + 550-5.7.26 SPF [mail.camdgc-dev.mosip.net] with ip: [164.52.204.214] = did not + 550-5.7.26 pass + 550-5.7.26 + 550-5.7.26 For instructions on setting up authentication, go to + 550 5.7.26 https://support.google.com/mail/answer/81126#authentication d12-20020a170903230c00b001db420e7552si10082865plh.65 - gsmtp + ``` + +To remove your mail server IP from the Office 365 Anti-Spam IP De-list Portal, please follow these steps: + +1. Access the portal through this link: [Office 365 Anti-Spam IP De-list Portal](https://sender.office.com/) +2. Enter your mail server Email ID, public IP, and click on the Submit button. +3. Look out for a confirmation email and click on the provided link. +4. The IP removal process typically takes around 30 minutes to complete. diff --git a/deployment/v3/external/README.md b/deployment/v3/external/README.md index e24de531b..6d4e6c5a4 100644 --- a/deployment/v3/external/README.md +++ b/deployment/v3/external/README.md @@ -17,7 +17,6 @@ * [ABIS](abis/README.md) * [Message Gateways](msg-gateway/README.md) * [docker secrets](docker-secrets/README.md) -* [captcha](captcha/README.md) * [Landing page](landing-page/README.md) ## Install * Run `install-all.sh` script to install in defined sequence. diff --git a/deployment/v3/external/all/install-all.sh b/deployment/v3/external/all/install-all.sh index c0b5dbc8f..9c4d5875e 100755 --- a/deployment/v3/external/all/install-all.sh +++ b/deployment/v3/external/all/install-all.sh @@ -31,7 +31,7 @@ function installing_all() { cd $ROOT_DIR/antivirus/clamav ./install.sh - cd $ROOT_DIR/activemq + cd $ROOT_DIR/activemq/ ./install.sh cd $ROOT_DIR/kafka @@ -51,8 +51,9 @@ function installing_all() { ./install.sh cd $ROOT_DIR/landing-page + ./install.sh - + cd $ROOT_DIR/captcha ./install.sh @@ -67,4 +68,3 @@ set -o nounset ## set -u : exit the script if you try to use an uninitialised set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes installing_all # calling function - diff --git a/deployment/v3/external/antivirus/clamav/install.sh b/deployment/v3/external/antivirus/clamav/install.sh index 206aa2e9b..34e8b3de6 100755 --- a/deployment/v3/external/antivirus/clamav/install.sh +++ b/deployment/v3/external/antivirus/clamav/install.sh @@ -7,10 +7,10 @@ if [ $# -ge 1 ] ; then fi NS=clamav -CHART_VERSION=2.4.1 +CHART_VERSION=3.1.0 echo Create $NS namespace -kubectl create ns $NS +kubectl create ns $NS function installing_Clamav() { echo Istio label diff --git a/deployment/v3/external/antivirus/clamav/values.yaml b/deployment/v3/external/antivirus/clamav/values.yaml index 2e815e143..a1f378af9 100644 --- a/deployment/v3/external/antivirus/clamav/values.yaml +++ b/deployment/v3/external/antivirus/clamav/values.yaml @@ -2,7 +2,7 @@ ## Increase in production replicaCount: 1 ## We are using official clamav docker instead of mailu/clamav that was present originally -image: - repository: clamav/clamav - tag: latest - pullPolicy: Always +#image: + # repository: clamav/clamav + # tag: 1.2 + # pullPolicy: Always diff --git a/deployment/v3/external/data-archive/README.md b/deployment/v3/external/data-archive/README.md new file mode 100644 index 000000000..cb97246cf --- /dev/null +++ b/deployment/v3/external/data-archive/README.md @@ -0,0 +1,62 @@ +# Database Archiving Configuration + +This configuration file is used for setting up database connections and defining archiving parameters. Please follow the guidelines below to fill in the required information. + +## Database Connections + +### Archive Database Connection (archive_db) + +- `db_name`: Name of the archive database. +- `host`: Destination host for the archive database. +- `port`: Port number for the archive database connection. +- `su_user`: Superuser for the archive database. +- `su_user_pwd`: Password for the superuser. +- `db_pwd`: Password for the archive database. +- `archivehost`: Destination host for the archive database. +- `archiveport`: Port number for the archive database connection. +- `archiveuname`: Archive database username. +- `archive_dbname`: Archive database name. +- `archive_schemaname`: Archive schema name. +- `archive_db_password`: Password for the archive database. + +### Source Database Connections (source_db) + +For each source database (audit, credential, esignet, ida, idrepo, kernel, master, pms, prereg, regprc, resident), provide the following information: + +- `source__host`: Source database host. +- `source__port`: Port number for the source database connection. +- `source__uname`: Source database username. +- `source__dbname`: Source database name. +- `source__schemaname`: Source schema name. +- `source__db_pass`: Password for the source database. + +- `provide_db_names_to_archive`: Comma-separated list of database names to archive (e.g., "AUDIT,CREDENTIAL,IDA,.....").(in CAPS) + + +## Container Volume Path +container_volume_path: Path where JSON files containing information about all databases will be stored + +## Archiving Information (all_db_tables_info) + +For each database, specify tables_info with details for archiving. Example: + +```yaml +audit: + tables_info: + - source_table: "app_audit_log" + archive_table: "mosip_audit_app_audit_log" + id_column: "log_id" + date_column: "log_dtimes" + retention_days: 30 + operation_type: "archive_delete" + +source_table: Name of the table in the source database. +archive_table: Name of the table in the archive database. +id_column: Column representing the unique identifier. +date_column: Column representing the date of the record. +retention_days: Number of days to retain the archived data. +operation_type: Type of operation for archiving (e.g., archive_delete, delete, none). +- Delete: Delete records from the source table. +- Archive and Delete: Archive records to an archive table and then delete them from the source table. +- Archive (No Delete): Archive records to an archive table without deleting them from the source table. +- None: Skip archival for the specified table. diff --git a/deployment/v3/external/data-archive/delete.sh b/deployment/v3/external/data-archive/delete.sh new file mode 100755 index 000000000..521fad2ed --- /dev/null +++ b/deployment/v3/external/data-archive/delete.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Uninstalls data-archive +## Usage: ./delete.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +function deleting_data-archive() { + NS=data-archive + while true; do + read -p "Are you sure you want to delete data-archive helm charts?(Y/n) " yn + if [ $yn = "Y" ] + then + helm -n $NS delete data-archive + break + else + break + fi + done + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +deleting_data-archive # calling function diff --git a/deployment/v3/external/data-archive/install.sh b/deployment/v3/external/data-archive/install.sh new file mode 100755 index 000000000..0ed86cd9d --- /dev/null +++ b/deployment/v3/external/data-archive/install.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# Installs data-archive +## Usage: ./install.sh [kubeconfig] + +if [ $# -ge 1 ]; then + export KUBECONFIG=$1 +fi + +NS=data-archive +CHART_VERSION=1.0.0 + +echo Create $NS namespace +kubectl create ns $NS + +function installing_data-archive() { + echo Updating repos + helm repo add mosip https://mosip.github.io/mosip-helm + helm repo update + + read -p "Is values.yaml for data-archive chart set correctly as part of Pre-requisites?(Y/n) " yn; + if [ "$yn" != "Y" ]; then + echo "ERROR: values.yaml not set correctly; EXITING;"; + exit 1; + fi + + read -p "Please enter the time(hr) to run the cronjob every day (time: 0-23) : " time + if [ -z "$time" ]; then + echo "ERROR: Time cannot be empty; EXITING;"; + exit 1; + fi + if ! [ $time -eq $time ] 2>/dev/null; then + echo "ERROR: Time $time is not a number; EXITING;"; + exit 1; + fi + if [ $time -gt 23 ] || [ $time -lt 0 ]; then + echo "ERROR: Time should be in range ( 0-23 ); EXITING;"; + exit 1; + fi + + read -p "Is archival running for sandbox installation? (Y/N): " archival_running + if [ "$archival_running" == "Y" ]; then + echo "Sandbox installation selected. This will use superuser PostgreSQL secrets for creating archivedb." + super_user_password=$(kubectl get secret --namespace postgres postgres-postgresql -o jsonpath={.data.postgres-password} | base64 --decode) + echo "Common secrets will be used as passwords for all the db users." + db_common_password=$(kubectl get secret --namespace postgres db-common-secrets -o jsonpath={.data.db-dbuser-password} | base64 --decode) + set_db_pwd="--set databases.archive_db.su_user_pwd=$super_user_password \ + --set databases.source_db.source_audit_db_pass=$db_common_password \ + --set databases.source_db.source_credential_db_pass=$db_common_password \ + --set databases.source_db.source_esignet_db_pass=$db_common_password \ + --set databases.source_db.source_ida_db_pass=$db_common_password \ + --set databases.source_db.source_idrepo_db_pass=$db_common_password \ + --set databases.source_db.source_kernel_db_pass=$db_common_password \ + --set databases.source_db.source_master_db_pass=$db_common_password \ + --set databases.source_db.source_pms_db_pass=$db_common_password \ + --set databases.source_db.source_prereg_db_pass=$db_common_password \ + --set databases.source_db.source_regprc_db_pass=$db_common_password \ + --set databases.source_db.source_resident_db_pass=$db_common_password \ + --set databases.archive_db.db_pwd=$db_common_password \ + --set databases.archive_db.archive_db_password=$db_common_password" + + elif [ "$archival_running" == "N" ]; then + echo "Other installation selected.This will Use individual secrets for db passwords from values.yaml" + set_db_pwd="" + else + echo "Incorrect input; EXITING;" + exit 1; + fi + + # Install data-archive + helm -n $NS install data-archive mosip/data-archive --set crontime="0 $time * * *" -f values.yaml $set_db_pwd --version $CHART_VERSION + + echo Installed data-archive + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +installing_data-archive # calling function diff --git a/deployment/v3/external/data-archive/values.yaml b/deployment/v3/external/data-archive/values.yaml new file mode 100644 index 000000000..64e3cd4f5 --- /dev/null +++ b/deployment/v3/external/data-archive/values.yaml @@ -0,0 +1,281 @@ +databases: + archive_db: + db_name: "mosip_archive" + host: "" + port: 5432 + su_user: "postgres" + su_user_pwd: "" + db_pwd: "" + dml: 0 + archivehost: "" + archiveport: 5432 + archiveuname: "archiveuser" + archive_dbname: "mosip_archive" + archive_schemaname: "archive" + archive_db_password: "" + source_db: + provide_db_names_to_archive: "AUDIT,CREDENTIAL,IDA" + source_audit_host: "" + source_audit_port: 5432 + source_audit_uname: "audituser" + source_audit_dbname: "mosip_audit" + source_audit_schemaname: "audit" + source_audit_db_pass: "" + source_credential_host: "" + source_credential_port: 5432 + source_credential_uname: "credentialuser" + source_credential_dbname: "mosip_credential" + source_credential_schemaname: "credential" + source_credential_db_pass: "" + source_esignet_host: "" + source_esignet_port: 5432 + source_esignet_uname: "esignetuser" + source_esignet_dbname: "mosip_esignet" + source_esignet_schemaname: "esignet" + source_esignet_db_pass: "" + source_ida_host: "" + source_ida_port: 5432 + source_ida_uname: "idauser" + source_ida_dbname: "mosip_ida" + source_ida_schemaname: "ida" + source_ida_db_pass: "" + source_idrepo_host: "" + source_idrepo_port: 5432 + source_idrepo_uname: "idrepouser" + source_idrepo_dbname: "mosip_idrepo" + source_idrepo_schemaname: "idrepo" + source_idrepo_db_pass: "" + source_kernel_host: "" + source_kernel_port: 5432 + source_kernel_uname: "kerneluser" + source_kernel_dbname: "mosip_kernel" + source_kernel_schemaname: "kernel" + source_kernel_db_pass: "" + source_master_host: "" + source_master_port: 5432 + source_master_uname: "masteruser" + source_master_dbname: "mosip_master" + source_master_schemaname: "master" + source_master_db_pass: "" + source_pms_host: "" + source_pms_port: 5432 + source_pms_uname: "pmsuser" + source_pms_dbname: "mosip_pms" + source_pms_schemaname: "pms" + source_pms_db_pass: "" + source_prereg_host: "" + source_prereg_port: 5432 + source_prereg_uname: "prereguser" + source_prereg_dbname: "mosip_prereg" + source_prereg_schemaname: "prereg" + source_prereg_db_pass: "" + source_regprc_host: "" + source_regprc_port: 5432 + source_regprc_uname: "regprcuser" + source_regprc_dbname: "mosip_regprc" + source_regprc_schemaname: "regprc" + source_regprc_db_pass: "" + source_resident_host: "" + source_resident_port: 5432 + source_resident_uname: "residentuser" + source_resident_dbname: "mosip_resident" + source_resident_schemaname: "resident" + source_resident_db_pass: "" + container_volume_path: "/all-db-info-json" + all_db_tables_info: + audit: + tables_info: + - source_table: "app_audit_log" + archive_table: "mosip_audit_app_audit_log" + id_column: "log_id" + date_column: "log_dtimes" + retention_days: 30 + operation_type: "archive_delete" + credential: + tables_info: + - source_table: "credential_transaction" + archive_table: "mosip_credential_credential_transaction" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 30 + operation_type: "archive_delete" + esignet: + tables_info: + - source_table: "consent_history" + archive_table: "mosip_esignet_consent_history" + id_column: "id" + date_column: "cr_dtimes" + retention_days: 30 + operation_type: "none" + ida: + tables_info: + - source_table: "credential_event_store" + archive_table: "mosip_ida_credential_event_store" + id_column: "event_id" + date_column: "cr_dtimes" + retension_days: 30 + operation_type: "archive_delete" + - source_table: "otp_transaction" + archive_table: "mosip_ida_otp_transaction" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 30 + operation_type: 'delete' + idrepo: + tables_info: + - source_table: "anonymous_profile" + archive_table: "mosip_idrepo_anonymous_profile" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 30 + operation_type: "archive_delete" + - source_table: "credential_request_status" + archive_table: "mosip_idrepo_credential_request_status" + id_column: "individual_id" + date_column: "cr_dtimes" + retension_days: 30 + operation_type: "archive_delete" + - source_table: "uin_draft" + archive_table: "mosip_idrepo_uin_draft" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 30 + operation_type: "archive_delete" + kernel: + tables_info: + - source_table: "otp_transaction" + archive_table: "mosip_kernel_otp_transaction" + id_column: "id" + date_column: "generated_dtimes" + retension_days: 7 + operation_type: "delete" + master: + tables_info: + - source_table: "bulkupload_transaction" + archive_table: "mosip_master_bulkupload_transaction" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 91 + operation_type: "archive_delete" + - source_table: "device_master_h" + archive_table: "mosip_master_device_master_h" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 365 + operation_type: "archive_delete" + - source_table: "machine_master_h" + archive_table: "mosip_master_machine_master_h" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + - source_table: "registration_center_h" + archive_table: "mosip_master_registration_center_h" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 365 + operation_type: "archive_delete" + - source_table: "user_detail_h" + archive_table: "mosip_master_user_detail_h" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + - source_table: "zone_user_h" + archive_table: "mosip_master_zone_user_h" + id_column: "usr_id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + pms: + tables_info: + - source_table: "auth_policy_h" + archive_table: "mosip_pms_auth_policy_h" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + - source_table: "secure_biometric_interface_h" + archive_table: "mosip_pms_secure_biometric_interface_h" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + - source_table: "partner_h" + archive_table: "mosip_pms_partner_h" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + prereg: + tables_info: + - source_table: "otp_transaction" + archive_table: "mosip_prereg_otp_transaction" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 30 + operation_type: "delete" + regprc: + tables_info: + - source_table: "abis_response_det" + archive_table: "mosip_regprc_abis_response_det" + id_column: "abis_resp_id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + - source_table: "abis_response" + archive_table: "mosip_regprc_abis_response" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + - source_table: "abis_request" + archive_table: "mosip_regprc_abis_request" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + - source_table: "reg_demo_dedupe_list" + archive_table: "mosip_regprc_reg_demo_dedupe_list" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + - source_table: "registration_transaction" + archive_table: "mosip_regprc_registration_transaction" + id_column: "regtrn_id" + date_column: "cr_dtimes" + retension_days: 183 + operation_type: "archive_delete" + resident: + tables_info: + - source_table: "otp_transaction" + archive_table: "mosip_resident_otp_transaction" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 30 + operation_type: "delete" + - source_table: "resident_grievance_ticket" + archive_table: "mosip_resident_grievance_ticket" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 365 + operation_type: "archive_delete" + - source_table: "resident_session" + archive_table: "mosip_resident_session" + id_column: "session_id" + date_column: "login_dtimes" + retension_days: 30 + operation_type: "archive_delete" + - source_table: "resident_transaction" + archive_table: "mosip_resident_transaction" + id_column: "id" + date_column: "cr_dtimes" + retension_days: 365 + operation_type: "archive_delete" + - source_table: "resident_user_actions" + archive_table: "mosip_resident_user_actions" + id_column: "ida_token" + date_column: "last_bell_notif_click_dtimes" + retension_days: 365 + operation_type: "archive_delete" \ No newline at end of file diff --git a/deployment/v3/external/docker-secrets/delete.sh b/deployment/v3/external/docker-secrets/delete.sh index 8ed9c267f..19ef13b31 100755 --- a/deployment/v3/external/docker-secrets/delete.sh +++ b/deployment/v3/external/docker-secrets/delete.sh @@ -11,7 +11,7 @@ function deleting_secrets() { read -p "Are you sure you want to delete regsecret?(Y/n) " yn if [ $yn = "Y" ] then - kubectl delete secret regsecret + kubectl delete secret regsecret break else break @@ -26,4 +26,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_secrets # calling function \ No newline at end of file +deleting_secrets # calling function diff --git a/deployment/v3/external/docker-secrets/install.sh b/deployment/v3/external/docker-secrets/install.sh index 1d9ee30d3..f428f99c9 100755 --- a/deployment/v3/external/docker-secrets/install.sh +++ b/deployment/v3/external/docker-secrets/install.sh @@ -14,7 +14,7 @@ function installing_secrets() { i=$((i+1)) echo "Enter docker registry URL (e.g. https://index.docker.io/v1/ for dockerhub)" read DOCKER_REGISTRY_URL - echo Enter docker registry username + echo Enter docker registry username read USERNAME echo Enter docker registry Password/Token read PASSWORD @@ -33,4 +33,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -installing_secrets # calling function \ No newline at end of file +installing_secrets # calling function diff --git a/deployment/v3/external/hsm/softhsm/README.md b/deployment/v3/external/hsm/softhsm/README.md index 84136930b..2d3887488 100644 --- a/deployment/v3/external/hsm/softhsm/README.md +++ b/deployment/v3/external/hsm/softhsm/README.md @@ -9,7 +9,7 @@ sh install.sh * Keys are created in the mounted PV which gets mounted at `/softhsm/tokens` inside the container. * Random PIN generated if not specified. Set `securityPIN` in `values.yaml`. -# Backup SoftHSM +## Backup SoftHSM #### Backup * Update the below variables @@ -35,3 +35,4 @@ sh install.sh * Execute the following command to restore SoftHSM from backup. ``` kubectl --kubeconfig=$KUBECONFIG -n $NS cp ./softhsm-kernel/tokens $POD_NAME:softhsm/tokens + ``` diff --git a/deployment/v3/external/hsm/softhsm/delete.sh b/deployment/v3/external/hsm/softhsm/delete.sh index e9aad7035..9e71e373d 100755 --- a/deployment/v3/external/hsm/softhsm/delete.sh +++ b/deployment/v3/external/hsm/softhsm/delete.sh @@ -14,6 +14,7 @@ function deleting_softhsm() { then helm -n $NS delete softhsm-kernel helm -n $NS delete softhsm-ida + helm -n $NS delete softhsm-idp break else break diff --git a/deployment/v3/external/iam/export.sh b/deployment/v3/external/iam/export.sh index 82a5a32be..d942f666c 100755 --- a/deployment/v3/external/iam/export.sh +++ b/deployment/v3/external/iam/export.sh @@ -77,4 +77,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -export_keycloak # calling function \ No newline at end of file +export_keycloak # calling function diff --git a/deployment/v3/external/iam/import-init-values.yaml b/deployment/v3/external/iam/import-init-values.yaml index 0ab23c4b6..bc58c7bf3 100644 --- a/deployment/v3/external/iam/import-init-values.yaml +++ b/deployment/v3/external/iam/import-init-values.yaml @@ -359,7 +359,6 @@ keycloak: assign_client_scopes: - send_binding_otp - wallet_binding - - name: mosip-resident-client mappers: [] saroles: @@ -501,11 +500,10 @@ keycloak: - PMS_USER - uma_authorization - offline_access - sa_client_roles: - - realm-management: ## realm-management client id - - view-users # realm-management client roles - - view-clients - - view-realm - - manage-users - + sa_client_roles: + - realm-management: ## realm-management client id + - view-users # realm-management client roles + - view-clients + - view-realms + - manage-users users: [] diff --git a/deployment/v3/external/iam/install.sh b/deployment/v3/external/iam/install.sh index 0f1a7dda4..1268c6ee2 100755 --- a/deployment/v3/external/iam/install.sh +++ b/deployment/v3/external/iam/install.sh @@ -19,7 +19,7 @@ function installing_keycloak() { helm repo update echo Installing - helm -n $NS install $SERVICE_NAME mosip/keycloak --version "7.1.18" --set image.repository=mosipid/mosip-artemis-keycloak --set image.tag=1.2.0.1 --set image.pullPolicy=Always -f values.yaml --wait + helm -n $NS install $SERVICE_NAME mosip/keycloak --version "7.1.18" --set image.repository=mosipqa/mosip-artemis-keycloak --set image.tag=develop --set image.pullPolicy=Always -f values.yaml --wait EXTERNAL_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-iam-external-host}) echo Install Istio gateway, virtual service diff --git a/deployment/v3/external/iam/keycloak_init.sh b/deployment/v3/external/iam/keycloak_init.sh index f4869efe6..92935074d 100755 --- a/deployment/v3/external/iam/keycloak_init.sh +++ b/deployment/v3/external/iam/keycloak_init.sh @@ -38,7 +38,7 @@ read_user_input(){ function initialize_keycloak() { NS=keycloak - CHART_VERSION=12.0.1 + CHART_VERSION=0.0.1-develop helm repo add mosip https://mosip.github.io/mosip-helm helm repo update diff --git a/deployment/v3/external/iam/upgrade-init-values.yaml b/deployment/v3/external/iam/upgrade-init-values.yaml index 1094cfea3..4060693e7 100644 --- a/deployment/v3/external/iam/upgrade-init-values.yaml +++ b/deployment/v3/external/iam/upgrade-init-values.yaml @@ -228,6 +228,7 @@ keycloak: - PUBLISH_REGISTRATION_PROCESSOR_WORKFLOW_COMPLETED_EVENT_GENERAL - PUBLISH_CREDENTIAL_STATUS_UPDATE_GENERAL - PUBLISH_REGISTRATION_PROCESSOR_WORKFLOW_PAUSED_FOR_ADDITIONAL_INFO_EVENT_GENERAL + - SUBSCRIBE_CREDENTIAL_ISSUED_INDIVIDUAL - name: mosip-resident-client mappers: [] saroles: @@ -238,6 +239,8 @@ keycloak: - uma_authorization - name: mosip-prereg-client mappers: [] + del_saroles: + - INDIVIDUAL saroles: - PREREG - REGISTRATION_PROCESSOR diff --git a/deployment/v3/external/iam/upgrade-init.sh b/deployment/v3/external/iam/upgrade-init.sh index d2bbfc525..6965ae5e9 100755 --- a/deployment/v3/external/iam/upgrade-init.sh +++ b/deployment/v3/external/iam/upgrade-init.sh @@ -17,7 +17,9 @@ function upgrade_init() { IAM_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-iam-external-host}) echo Initializing keycloak - helm -n $NS install keycloak-upgrade mosip/keycloak-init --set frontend=https://$IAM_HOST/auth -f upgrade-init-values.yaml --wait --wait-for-jobs --version $CHART_VERSION + helm -n $NS install keycloak-init mosip/keycloak-init --set frontend=https://$IAM_HOST/auth -f upgrade-init-values.yaml --version $CHART_VERSION + echo Initializing keycloak + helm -n $NS install keycloak-init mosip/keycloak-init --set frontend=https://$IAM_HOST/auth -f import-init-values.yaml --version $CHART_VERSION return 0 } @@ -27,4 +29,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -upgrade_init # calling function +import_init # calling function diff --git a/deployment/v3/external/iam/values.yaml b/deployment/v3/external/iam/values.yaml index f12a9cfb1..4bf598394 100644 --- a/deployment/v3/external/iam/values.yaml +++ b/deployment/v3/external/iam/values.yaml @@ -9,7 +9,7 @@ auth: extraEnvVars: - name: KEYCLOAK_EXTRA_ARGS - value: "-Dkeycloak.profile.feature.upload_scripts=enabled" + value: "-Dkeycloak.profile.feature.upload_scripts=enabled -Dkeycloak.profile.feature.token_exchange=enabled -Dkeycloak.profile.feature.admin_fine_grained_authz=enabled" #value: "-Dkeycloak.profile.feature.upload_scripts=enabled -Dkeycloak.import=/config/realm-mosip.json" ## Disable ingress as we use Istio diff --git a/deployment/v3/external/kafka/backup.sh b/deployment/v3/external/kafka/backup.sh new file mode 100755 index 000000000..8328deabd --- /dev/null +++ b/deployment/v3/external/kafka/backup.sh @@ -0,0 +1,178 @@ +#!/bin/sh +# backup kafka via Velero +## Usage: ./backup.sh kubeconfig +chk_status(){ + RESOURCE=$1 + count=$( velero $1 get | grep -Ec 'New|InProgress' ) + if [ $count -gt 0 ]; then + echo "$(tput setaf 1) Previous velero $RESOURCE job is still in either 'New' state or 'InProgress' state; $(tput sgr0)"; + printf "%s Please wait till velero job is either completed or failed.\n You can troubleshoot the issue; EXITING %s" $(tput setaf 1) $(tput sgr0) + exit 1; + fi +} +read_user_input(){ + if [ $# -lt 2 ]; then + echo "$(tput setaf 1) Variable & Message arguments not passed to read_user_input function; EXITING $(tput sgr0)"; + exit 1; + fi + if [ $# -gt 2 ]; then + DEFAULT=$3; ## default values for $VAR variable + fi + VAR=$1; ## variable name + MSG=$2; ## message to be printed for the given variable + read -p " Provide $MSG : " $VAR; + TEMP=$( eval "echo \${$VAR}" ); ## save $VAR values to a temporary variable + eval ${VAR}=${TEMP:-$DEFAULT}; ## set $VAR value to $DEFAULT if $TEMP is empty, else set $VAR value to $TEMP + if [ -z $( eval "echo \${$VAR}" ) ]; then + echo "$(tput setaf 1) $MSG not provided; EXITING $(tput sgr0)"; + exit 1; + fi + DEFAULT=''; ## reset `DEFAULT` variable to empty string +} + +print_heading(){ + HEADING=$1 + tput setaf 3 + printf '\n_%*.0s' $(( $(tput cols)*10/100 -1 )) "" | tr " " "=" | tr "_" " " + echo -n " $HEADING " + printf '%*.0s \n\n' $(( $(tput cols) - ${#HEADING} - $(tput cols)*10/100 -5 )) "" | tr " " "=" + tput sgr0 +} + +chk_exit_status(){ + /bin/sh -c "$1" + EXIT_STATUS=$? + if [ $EXIT_STATUS -gt 0 ]; then + END_MSG='EXITING'; + if [ "$2" = "skip" ]; then + shift + END_MSG='SKIPPING'; + RETURN='TRUE'; + fi + shift + for msg in "${@}";do + echo "$(tput setaf 1) $msg; $END_MSG $(tput sgr0)"; + done + if [ "$RETURN" = "TRUE" ]; then + return "1"; + fi + exit 1; + fi + return "0"; +} + +## The script starts from here +### Cluster +HEADING="Check Cluster Config File" +print_heading "$HEADING"; ## calling print_heading function +chk_exit_status "[ $# -eq 1 ]" "Kubernetes Cluster config file not provided" +chk_exit_status "[ -f $1 ]" "Kubernetes Cluster config file not found" +echo "$(tput setaf 2) Kubernetes Cluster file found $(tput sgr0)" + +### check whether MINIO client ( mc ), kubectl, & velero is installed +HEADING="Check packages installed" +print_heading "$HEADING"; ## calling print_heading function +chk_exit_status "which mc > /dev/null" "MINIO Client ( mc ) not installed"; +chk_exit_status "which velero > /dev/null" "Velero is not installed"; +chk_exit_status "which kubectl > /dev/null" "kubectl is not installed"; +echo "$(tput setaf 2) kubectl, minio client (mc), & velero packages are already installed !!! $(tput sgr0)" + +K8S_CONFIG_FILE=$1 +export KUBECONFIG=$K8S_CONFIG_FILE + +### S3 / MINIO +HEADING="S3 Setup" +print_heading "$HEADING"; ## calling print_heading function +read_user_input s3_server "S3 server"; ## calling read_user_input function +read_user_input s3_access_key "S3 access key"; +read_user_input s3_secret_key "S3 secret key"; +read_user_input s3_region "S3 region ( Default region = minio )" "minio"; + +# set S3 alias +s3_alias=s3_server +echo -n " " +CMD="mc alias set $s3_alias $s3_server $s3_access_key $s3_secret_key --api S3v2" +chk_exit_status "$CMD" "Not able to reach S3 SERVER" + +# create velero bucket, Ignore if already exist +bucket=$s3_alias/velero +#chk_exit_status "mc ls $bucket" "skip" "Not able to access bucket $bucket"; +echo -n " " +CMD="mc mb --ignore-existing $bucket" +chk_exit_status "$CMD" "Not able to create bucket on S3 SERVER" + + +# check velero is already deployed on the cluster +HEADING="Velero install" +print_heading "$HEADING"; ## calling print_heading function + +printf "[default]\naws_access_key_id = %s\naws_secret_access_key = %s\n" "$s3_access_key" "$s3_secret_key" > credentials-velero + +CMD="kubectl --kubeconfig=$K8S_CONFIG_FILE get deployment/velero -n velero" +chk_exit_status "$CMD" "skip" "Velero is not deployed on this cluster" +STATUS=$? +if ! [ "$STATUS" = "0" ];then + velero install \ + --provider aws \ + --plugins velero/velero-plugin-for-aws:v1.2.1 \ + --bucket velero \ + --secret-file ./credentials-velero \ + --backup-location-config region=$s3_region,s3ForcePathStyle="true",s3Url=$s3_server \ + --use-volume-snapshots=false \ + --default-volumes-to-restic \ + --kubeconfig $K8S_CONFIG_FILE \ + --use-restic | sed 's/^/ /g' +fi +echo "$(tput setaf 2) Velero deployed $(tput sgr0)" + +NO_OF_RETRIES=5 +HEADING="Check BackupStorageLocations validity" +print_heading "$HEADING"; ## calling print_heading function +for i in $(seq 1 $NO_OF_RETRIES); do + echo "$(tput setaf 6) [Trying : $i ] $(tput sgr 0)"; + printf "\tPlease wait for 5 seconds;\n"; + sleep 5; + BackupStorageLocationValid=$( kubectl --kubeconfig=$K8S_CONFIG_FILE logs deployment/velero -n velero |grep -c "BackupStorageLocations is valid" 2>&1 & ); + printf "\tBackupStorageLocationValid = %s" $BackupStorageLocationValid; + if [ "$BackupStorageLocationValid" -eq 0 ]; then + printf "%s\n\tBackupStorageLocation is invalid; Trying to connect S3 again %s\n" $(tput setaf 1) $(tput sgr0); + if [ $i -eq $NO_OF_RETRIES ]; then + printf "%s\n\tUnable to connect to S3 bucket; EXITING %s" $(tput setaf 1) $(tput sgr0); + printf "%s\n\tPlease check whether S3 bucket is accessible from kubernetes cluster \n\tAnd also check S3 login credentials %s\n" $(tput setaf 4) $(tput sgr0); + exit 1; + fi + continue; + fi + printf "%s\n\tBackupStorageLocation is valid !!!%s\n" $(tput setaf 2) $(tput sgr0); + break; +done + +## create backup operation +HEADING="Create Backup" +print_heading "$HEADING"; ## calling print_heading function +chk_status backup ## calling chk_status function to check any backup or restore jon is in New/InProgress state + +read_user_input SERVICE "k8s service to be taken for backup "; +read_user_input NAMESPACE "k8s service Namespace"; +BACKUP_NAME="$SERVICE-$( date +'%d-%m-%Y-%H-%M' )" + +#### Check whether all $SERVICE.$NAMESPACE pods are up +echo -e "$(tput setaf 2) [ Check whether all $SERVICE.$NAMESPACE pods are up ] $(tput sgr0)\n" +for name in zookeeper kafka; do + CMD="kubectl --kubeconfig=$K8S_CONFIG_FILE -n $NAMESPACE wait --for=condition=ready pod --timeout=30s -l app.kubernetes.io/name=$name"; + chk_exit_status "$CMD" "The $name pods failed to be ready by 5 minutes."; +done + +echo "$(tput setaf 2) [ Creating Backup ] $(tput sgr0)" +printf "\t" +velero backup create "$BACKUP_NAME" \ + --default-volumes-to-restic \ + --selector app.kubernetes.io/instance="$SERVICE" \ + --include-namespaces "$NAMESPACE" \ + --kubeconfig "$K8S_CONFIG_FILE" \ + --wait + +HEADING="List Backup" +print_heading "$HEADING"; ## calling print_heading function +printf "%s\n [ List Backups ] %s" $(tput setaf 2) $(tput sgr0) +velero --kubeconfig $K8S_CONFIG_FILE backup get | sed 's/^/\t/g' diff --git a/deployment/v3/external/kafka/restore.sh b/deployment/v3/external/kafka/restore.sh new file mode 100755 index 000000000..1bb20daf0 --- /dev/null +++ b/deployment/v3/external/kafka/restore.sh @@ -0,0 +1,223 @@ +#!/bin/bash +# restore kafka via Velero +## Usage: ./restore.sh kubeconfig +chk_status(){ + RESOURCE=$1 + count=$( velero --kubeconfig=$K8S_CONFIG_FILE $1 get | grep -Ec 'New|InProgress' ) + if [ $count -gt 0 ]; then + echo "$(tput setaf 1) Previous velero $RESOURCE job is still in either 'New' state or 'InProgress' state; $(tput sgr0)"; + printf "%s Please wait till velero job is either completed or failed.\n You can troubleshoot the issue; EXITING %s" $(tput setaf 1) $(tput sgr0) + exit 1; + fi +} +read_user_input(){ + if [ $# -lt 2 ]; then + echo "$(tput setaf 1) Variable & Message arguments not passed to read_user_input function; EXITING $(tput sgr0)"; + exit 1; + fi + if [ $# -gt 2 ]; then + DEFAULT=$3; ## default values for $VAR variable + fi + VAR=$1; ## variable name + MSG=$2; ## message to be printed for the given variable + read -p " Provide $MSG : " $VAR; + TEMP=$( eval "echo \${$VAR}" ); ## save $VAR values to a temporary variable + eval ${VAR}=${TEMP:-$DEFAULT}; ## set $VAR value to $DEFAULT if $TEMP is empty, else set $VAR value to $TEMP + if [ -z $( eval "echo \${$VAR}" ) ]; then + echo "$(tput setaf 1) $MSG not provided; EXITING $(tput sgr0)"; + exit 1; + fi + DEFAULT=''; ## reset `DEFAULT` variable to empty string +} + +print_heading(){ + HEADING=$1 + tput setaf 3 + printf '\n_%*.0s' $(( $(tput cols)*10/100 -1 )) "" | tr " " "=" | tr "_" " " + echo -n " $HEADING " + printf '%*.0s \n\n' $(( $(tput cols) - ${#HEADING} - $(tput cols)*10/100 -5 )) "" | tr " " "=" + tput sgr0 +} + +chk_exit_status(){ + /bin/sh -c "$1" + EXIT_STATUS=$? + if [ $EXIT_STATUS -gt 0 ]; then + END_MSG='EXITING'; + if [ "$2" = "skip" ]; then + shift + END_MSG='SKIPPING'; + RETURN='TRUE'; + fi + shift + for msg in "${@}";do + echo "$(tput setaf 1) $msg; $END_MSG $(tput sgr0)"; + done + if [ "$RETURN" = "TRUE" ]; then + return "1"; + fi + exit 1; + fi + return "0"; +} + +## The script starts from here +### Cluster +HEADING="Check Cluster Config File" +print_heading "$HEADING"; ## calling print_heading function +chk_exit_status "[ $# -eq 1 ]" "Kubernetes Cluster config file not provided" +chk_exit_status "[ -f $1 ]" "Kubernetes Cluster config file not found" +echo "$(tput setaf 2) Kubernetes Cluster file found $(tput sgr0)" + +### check whether MINIO client ( mc ), kubectl, & velero is installed +HEADING="Check packages installed" +print_heading "$HEADING"; ## calling print_heading function +chk_exit_status "which mc > /dev/null" "MINIO Client ( mc ) not installed"; +chk_exit_status "which velero > /dev/null" "Velero is not installed"; +chk_exit_status "which kubectl > /dev/null" "kubectl is not installed"; +echo "$(tput setaf 2) kubectl, minio client (mc), & velero packages are already installed !!! $(tput sgr0)" + +K8S_CONFIG_FILE=$1 +export KUBECONFIG=$K8S_CONFIG_FILE + +### S3 / MINIO +HEADING="S3 Setup" +print_heading "$HEADING"; ## calling print_heading function +read_user_input s3_server "S3 server"; ## calling read_user_input function +read_user_input s3_access_key "S3 access key"; +read_user_input s3_secret_key "S3 secret key"; +read_user_input s3_region "S3 region ( Default region = minio )" "minio"; + +# set S3 alias +s3_alias=s3_server +echo -n " " +CMD="mc alias set $s3_alias $s3_server $s3_access_key $s3_secret_key --api S3v2" +chk_exit_status "$CMD" "Not able to reach S3 SERVER" + +# create velero bucket, Ignore if already exist +bucket=$s3_alias/velero +echo -n " " +chk_exit_status "mc ls $bucket" "Not able to access bucket $bucket"; +#CMD="mc mb --ignore-existing $bucket" +#chk_exit_status "$CMD" "Not able to create bucket on S3 SERVER" + + +# check velero is already deployed on the cluster +HEADING="Velero install" +print_heading "$HEADING"; ## calling print_heading function + +printf "[default]\naws_access_key_id = %s\naws_secret_access_key = %s\n" "$s3_access_key" "$s3_secret_key" > credentials-velero + +CMD="kubectl --kubeconfig=$K8S_CONFIG_FILE get deployment/velero -n velero" +chk_exit_status "$CMD" "skip" "Velero is not deployed on this cluster" +STATUS=$? +if ! [ "$STATUS" = "0" ];then + velero install \ + --provider aws \ + --plugins velero/velero-plugin-for-aws:v1.2.1 \ + --bucket velero \ + --secret-file ./credentials-velero \ + --backup-location-config region=$s3_region,s3ForcePathStyle="true",s3Url=$s3_server \ + --use-volume-snapshots=false \ + --default-volumes-to-restic \ + --kubeconfig $K8S_CONFIG_FILE \ + --use-restic | sed 's/^/ /g' +fi +echo "$(tput setaf 2) Velero deployed $(tput sgr0)" + +NO_OF_RETRIES=5 +HEADING="Check BackupStorageLocations validity" +print_heading "$HEADING"; ## calling print_heading function +for i in $(seq 1 $NO_OF_RETRIES); do + echo "$(tput setaf 6) [Trying : $i ] $(tput sgr 0)"; + printf "\tPlease wait for 5 seconds;\n"; + sleep 5; + BackupStorageLocationValid=$( kubectl --kubeconfig=$K8S_CONFIG_FILE logs deployment/velero -n velero |grep -c "BackupStorageLocations is valid" 2>&1 & ); + printf "\tBackupStorageLocationValid = %s" $BackupStorageLocationValid; + if [ "$BackupStorageLocationValid" -eq 0 ]; then + printf "%s\n\tBackupStorageLocation is invalid; Trying to connect S3 again %s\n" $(tput setaf 1) $(tput sgr0); + if [ $i -eq $NO_OF_RETRIES ]; then + printf "%s\n\tUnable to connect to S3 bucket; EXITING %s" $(tput setaf 1) $(tput sgr0); + printf "%s\n\tPlease check whether S3 bucket is accessible from kubernetes cluster \n\tAnd also check S3 login credentials %s\n" $(tput setaf 4) $(tput sgr0); + exit 1; + fi + continue; + fi + printf "%s\n\tBackupStorageLocation is valid !!!%s\n" $(tput setaf 2) $(tput sgr0); + break; +done + +## create restore operation +HEADING="Create Restore" +print_heading "$HEADING"; ## calling print_heading function +chk_status restore ## calling chk_status function to check any backup or restore jon is in New/InProgress state + +read_user_input NS "Namespace to restore ( Default Namespace = kafka )" "kafka"; + +#### Update helm repos +HEADING="Update HELM repos"; +print_heading "$HEADING"; ## calling print_heading function +helm repo add kafka-ui https://provectus.github.io/kafka-ui | sed 's/^/ /g'; +helm repo add bitnami https://charts.bitnami.com/bitnami | sed 's/^/ /g'; +helm repo update | sed 's/^/ /g'; + +#### create namespace +HEADING="Create Namespace"; +print_heading "$HEADING"; ## calling print_heading function +kubectl --kubeconfig=$K8S_CONFIG_FILE create ns $NS | sed 's/^/ /g'; + +#### Install Kafka +HEADING="Install kafka"; +print_heading "$HEADING"; ## calling print_heading function +helm -n $NS install kafka bitnami/kafka -f values.yaml --wait | sed 's/^/ /g'; + +#### Install kafka-ui +HEADING='Install kafka-ui'; +print_heading "$HEADING"; ## calling print_heading function +helm -n $NS install kafka-ui kafka-ui/kafka-ui --set envs.config.KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka.$NS:9092 --set envs.config.KAFKA_CLUSTERS_0_ZOOKEEPER=kafka-zookeeper.$NS:2181 -f ui-values.yaml --wait | sed 's/^/ /g'; + +#### Install Istio addons +HEADING='Install Istio addons'; +print_heading "$HEADING"; ## calling print_heading function +KAFKA_UI_HOST=$(kubectl --kubeconfig=$K8S_CONFIG_FILE get cm global -o jsonpath={.data.mosip-api-internal-host}) +KAFKA_UI_NAME=kafka-ui +helm -n $NS install istio-addons chart/istio-addons --set kafkaUiHost=$KAFKA_UI_HOST --set installName=$KAFKA_UI_NAME | sed 's/^/ /g'; + +HEADING="List Backup"; +print_heading "$HEADING"; ## calling print_heading function +printf "%s\n [ List Backups ] %s" $(tput setaf 2) $(tput sgr0); +velero --kubeconfig $K8S_CONFIG_FILE backup get | sed 's/^/\t/g'; + +HEADING="Restore Kafka from Backup"; +print_heading "$HEADING"; ## calling print_heading function +printf "%s\n [ List Backups ] %s" $(tput setaf 2) $(tput sgr0); +velero --kubeconfig $K8S_CONFIG_FILE backup get | sed 's/^/\t/g'; + +printf "%s\n [ Check backup existence ] %s\n\t" $(tput setaf 2) $(tput sgr0); +read_user_input BACKUP_NAME "Backup Name"; +CMD="velero --kubeconfig $K8S_CONFIG_FILE backup get | grep -E '(^|\s)$BACKUP_NAME($|\s)'"; +chk_exit_status "$CMD" "\t Backup Name not found"; + +printf "%s\n [ Remove Kafka & Zookeeper statefulset ] %s\n\t" $(tput setaf 2) $(tput sgr0); +CMD="kubectl --kubeconfig $K8S_CONFIG_FILE -n $NS --ignore-not-found=true delete statefulset kafka kafka-zookeeper"; +chk_exit_status "$CMD" "\t Backup Name not found"; +#### Check whether all kafka.$NAMESPACE pods are terminated +printf "\n%s [ Check whether all kafka.$NS pods are terminated ] %s\n" $(tput setaf 2) $(tput sgr0) +for name in kafka zookeeper; do + CMD="kubectl --kubeconfig=$K8S_CONFIG_FILE -n $NS wait --for=delete pod --timeout=300s -l app.kubernetes.io/name=$name"; + chk_exit_status "$CMD" "The $name pods failed to be ready by 5 minutes."; +done + +printf "%s\n [ Restore Kafka ] %s\n\t" $(tput setaf 2) $(tput sgr0); +RESTORE_NAME="restore-$BACKUP_NAME-$( date +'%d-%m-%Y-%H-%M' )"; +velero restore --kubeconfig $K8S_CONFIG_FILE create $RESTORE_NAME --from-backup $BACKUP_NAME --namespace-mappings default:$NS --wait; + +printf "%s\n [ Update Namespace in statefulset environmental variables ] %s\n\t" $(tput setaf 2) $(tput sgr0); +kubectl -n $NS get statefulset kafka-zookeeper -o yaml | sed "s/default.svc.cluster.local/$NS.svc.cluster.local/g" | kubectl -n $NS apply -f -; +kubectl -n $NS get statefulset kafka -o yaml | sed "s/default.svc.cluster.local/$NS.svc.cluster.local/g" | kubectl -n $NS apply -f - ; + +HEADING="List Restores"; +print_heading "$HEADING"; ## calling print_heading function +printf "%s\n [ List Restores ] %s\n" $(tput setaf 2) $(tput sgr0); +velero --kubeconfig $K8S_CONFIG_FILE restore get | sed 's/^/\t/g'; + diff --git a/deployment/v3/external/landing-page/copy_cm.sh b/deployment/v3/external/landing-page/copy_cm.sh index 2b3664898..b168e7026 100755 --- a/deployment/v3/external/landing-page/copy_cm.sh +++ b/deployment/v3/external/landing-page/copy_cm.sh @@ -17,4 +17,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/external/landing-page/delete.sh b/deployment/v3/external/landing-page/delete.sh index aa1bc0e8c..a86f11fda 100755 --- a/deployment/v3/external/landing-page/delete.sh +++ b/deployment/v3/external/landing-page/delete.sh @@ -21,4 +21,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -landing_page # calling function \ No newline at end of file +landing_page # calling function diff --git a/deployment/v3/external/landing-page/install.sh b/deployment/v3/external/landing-page/install.sh index b55c64814..17fe37a95 100755 --- a/deployment/v3/external/landing-page/install.sh +++ b/deployment/v3/external/landing-page/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=landing-page -CHART_VERSION=12.0.1 +CHART_VERSION=12.0.2 echo Create $NS namespace kubectl create ns $NS @@ -42,6 +42,8 @@ function landing_page() { ESIGNET=$(kubectl get cm global -o jsonpath={.data.mosip-esignet-host}) SMTP=$(kubectl get cm global -o jsonpath={.data.mosip-smtp-host}) HEALTHSERVICES=$(kubectl get cm global -o jsonpath={.data.mosip-healthservices-host}) + INJIWEB=$(kubectl get cm global -o jsonpath={.data.mosip-injiweb-host}) + INJIVERIFY=$(kubectl get cm global -o jsonpath={.data.mosip-injiverify-host}) echo Installing landing page helm -n $NS install landing-page mosip/landing-page --version $CHART_VERSION \ @@ -59,15 +61,18 @@ function landing_page() { --set landing.regclient=$REGCLIENT \ --set landing.postgres.host=$POSTGRES \ --set landing.postgres.port=$POSTGRES_PORT \ - --set landing.pmp=$PMP \ --set landing.compliance=$COMPLIANCE \ + --set landing.pmp=$PMP \ --set landing.resident=$RESIDENT \ --set landing.esignet=$ESIGNET \ --set landing.smtp=$SMTP \ --set landing.healthservices=$HEALTHSERVICES \ + --set landing.injiweb=$INJIWEB \ + --set landing.injiverify=$INJIVERIFY \ --set istio.host=$DOMAIN kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + echo Installed landing page return 0 } diff --git a/deployment/v3/external/landing-page/restart.sh b/deployment/v3/external/landing-page/restart.sh index 5a3942e19..4b9ab4bef 100755 --- a/deployment/v3/external/landing-page/restart.sh +++ b/deployment/v3/external/landing-page/restart.sh @@ -10,6 +10,7 @@ function landing_page() { NS=landing-page kubectl -n $NS rollout restart deploy + kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status echo Restarted landing page pod @@ -22,4 +23,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -landing_page # calling function \ No newline at end of file +landing_page # calling function diff --git a/deployment/v3/external/landing-page/template/landing.html b/deployment/v3/external/landing-page/template/landing.html index 1817881e8..c406b1e2b 100644 --- a/deployment/v3/external/landing-page/template/landing.html +++ b/deployment/v3/external/landing-page/template/landing.html @@ -1,115 +1,115 @@ - - -MOSIP - - - - -

-
- -

MOSIP Deployment

-

dev3

-

Version: develop

-
-
-
- - - - - - - -
-

-
-
- - - - - - - - - - - - - -
External APIhttps://api.sandbox.mosip.net
Internal APIhttps://api-internal.sandbox.mosip.net
- - postgres.sandbox.mosip.net:5432
-
-

-
- -
- - - - + + +MOSIP + + + + +
+
+ +

MOSIP Deployment

+

dev3

+

Version: develop

+
+
+
+ + + + + + + +
+

+
+
+ + + + + + + + + + + + + +
External APIhttps://api.sandbox.mosip.net
Internal APIhttps://api-internal.sandbox.mosip.net
+ + postgres.sandbox.mosip.net:5432
+
+

+
+ +
+ + + + diff --git a/deployment/v3/external/msg-gateway/README.md b/deployment/v3/external/msg-gateway/README.md index c13dc6d43..8429ec6c4 100644 --- a/deployment/v3/external/msg-gateway/README.md +++ b/deployment/v3/external/msg-gateway/README.md @@ -4,6 +4,10 @@ The information of your SMTP and SMS gateways is created here. Create these con If you would like to use Gmail SMTP. You can follow the procedure from [here](../../docs/create-gmail-app-password.md) +If you would like to use mock-smtp. You can follow the procedure form [here](../../mosip/mock-smtp/README.md). + +If you would like to use Gmail SMTP. You can follow the procedure from [here](../../docs/create-gmail-app-password.md) + Run ```sh ./install.sh diff --git a/deployment/v3/external/msg-gateway/install.sh b/deployment/v3/external/msg-gateway/install.sh index 31398ac68..2f1241d70 100755 --- a/deployment/v3/external/msg-gateway/install.sh +++ b/deployment/v3/external/msg-gateway/install.sh @@ -56,7 +56,6 @@ function msg_gateway() { echo smtp and sms related configurations set. return 0 } - # set commands for error handling. set -e set -o errexit ## set -e : exit the script if any statement returns a non-true return value diff --git a/deployment/v3/external/oauth2-proxy/README.md b/deployment/v3/external/oauth2-proxy/README.md index 8242523ff..c6c0da688 100644 --- a/deployment/v3/external/oauth2-proxy/README.md +++ b/deployment/v3/external/oauth2-proxy/README.md @@ -1,31 +1,41 @@ ## Install Oauth2-Proxy in cluster. -This directory contains files that can be used to install oauth2-proxy in a given cluster. This will also install and setup a new realm in keycloak, `istio`. (If such a realm is already present it needs to be deleted manually. (TODO: develop this to use pre-existing istio realm)) +This directory contains files that can be used to install oauth2-proxy in a given cluster. ### Installation: -```sh -./install.sh -``` -After installation is done, go to `istio` realm in keycloak and create required users and assign appropriate roles - -### Applying Policies +- Login to MOSIP cluster keycloak (ex: `iam.sandbox.mosip.net`) as `admin`. +- Click on *Add Realm*, on top left of admin console. +- Click on *Select File* on Import. And select the `istio-realm.json` file in this directory. +- Give *name* as `istio`. Switch on *Enabled*. +- Click *Create*. +- After the realm is created, configure the *frontendUrl* on *Realm Settings* page of the `istio` realm. (Example: `frontendUrl: https://iam.sandbox.mosip.net/auth`) +- Then navigate to *Clients* page, and to the `istio-auth-client`. +- Go to *Credentials* section, and *Regenerate Secret*. +- Copy the new secret for further use. +- Then run the install script: + ```sh + ./install.sh + ``` +- After installation is done, go to `istio` realm in keycloak and create required users and assign appropriate roles. + +### Applying and removing policies -- There are two policies provided in the `sample-auth-policy.yaml`, they work like this. First the CUSTOM auth policy will authenticate the incoming request (this custom auth provider is oauth2-proxy), then the second DENY filter will deny the request if it didnt receive the appropriate role binding. - After installation, use the following script to apply policies on cluster. -```sh -./apply_policy.sh sample-auth-policy.yaml -``` -- These policy are just regular istio resources and can be applied manually without the script also (like `kubectl apply -f`). -- But the script replaces varibles like `h__mosip-api-internal-host__h`, `h__mosip-kibana-host__h`, etc from global configmap in cluster, before applying. So that one doesnt have to care about the hostname while applying. -- To remove the policies; `kubectl delete -f sample-auth-policy.yaml` + ```sh + ./apply_policy.sh sample-auth-policy.yaml + ``` +- To remove the policies; + ```sh + kubectl delete -f sample-auth-policy.yaml + ``` ### Setting appropriate roles for urls Edit the sample-auth-policy.yaml for setting roles for each set of hosts and uris, and apply the policy -### To Uninstall -``` -kubectl delete ns oauth2-proxy +### Uninstall +```sh +./delete.sh ``` Also dont forget to remove the policies seperately. `kubectl delete -f sample-auth-policy.yaml` @@ -34,3 +44,5 @@ Also dont forget to remove the policies seperately. `kubectl delete -f sample-au - Find the conf of `istio` realm in `istio-realm.json` file. - Find the conf of oauth2-proxy installation in the `oauth2-proxy.yaml` file - Find the istiod configuration of external authorization in the istio-operator file. +- There are two policies provided in the `sample-auth-policy.yaml`, they work like this. First the CUSTOM auth policy will authenticate the incoming request (this custom auth provider is oauth2-proxy), then the second DENY filter will deny the request if it didnt receive the appropriate role binding. +- Using the `apply_policy.sh` script, replaces variables like `h__mosip-api-internal-host__h`, `h__mosip-kibana-host__h`, etc in the policy, before applying (values taken from global configmap of cluster). diff --git a/deployment/v3/external/oauth2-proxy/apply_policy.sh b/deployment/v3/external/oauth2-proxy/apply_policy.sh index e95ca03ce..4ab096332 100755 --- a/deployment/v3/external/oauth2-proxy/apply_policy.sh +++ b/deployment/v3/external/oauth2-proxy/apply_policy.sh @@ -11,8 +11,12 @@ cp $1 $temp_file for host_var in $(cat $temp_file | grep -oP '(?<=h__).*(?=__h)'); do host_name="$(kubectl get cm global -o jsonpath={.data.$host_var})" - sed -i "s/h__${host_var}__h/$host_name/g" $temp_file + sed -i "s;h__${host_var}__h;${host_name};g" $temp_file done +jwks_uri=$(cat $temp_file | grep -oP '(?<=rjwks__).*(?=__rjwks)') +remote_local_jwks=$(curl -s "$jwks_uri") +sed -i "s;rjwks__${jwks_uri}__rjwks;${remote_local_jwks};g" $temp_file + kubectl apply -f $temp_file rm $temp_file diff --git a/deployment/v3/external/oauth2-proxy/delete.sh b/deployment/v3/external/oauth2-proxy/delete.sh new file mode 100755 index 000000000..91fb765a5 --- /dev/null +++ b/deployment/v3/external/oauth2-proxy/delete.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +NS=oauth2-proxy + +if [ $# -ge 1 ]; then + export KUBECONFIG=$1 +fi + +function Deleting_oauth2_proxy() { + kubectl delete -n $NS -f oauth2-proxy.yaml + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +Deleting_oauth2_proxy_oauth2_proxy # calling function +} \ No newline at end of file diff --git a/deployment/v3/external/oauth2-proxy/install.sh b/deployment/v3/external/oauth2-proxy/install.sh index 7660e1823..1a92ab239 100755 --- a/deployment/v3/external/oauth2-proxy/install.sh +++ b/deployment/v3/external/oauth2-proxy/install.sh @@ -1,63 +1,57 @@ #!/bin/bash -ROOT_DOMAIN=".mosip.net" +NS=oauth2-proxy if [ $# -ge 1 ]; then export KUBECONFIG=$1 fi -if ! java -version > /dev/null 2> /dev/null; then - echo "java is missing. Please install java"; exit 1; +if [ -z "$INSTALLATION_NAME" ]; then + INSTALLATION_NAME=$(kubectl get cm global -ojsonpath={.data.installation-name}) + read -p "Current installation name (default: $INSTALLATION_NAME) : " TO_REPLACE + INSTALLATION_NAME=${TO_REPLACE:-$INSTALLATION_NAME} + unset TO_REPLACE fi -if ! jq --version > /dev/null 2> /dev/null; then - echo "jq is missing. Please install jq"; exit 2; +if [ -z "$IAM_HOST" ]; then + IAM_HOST=$(kubectl get cm keycloak-host -n keycloak -ojsonpath={.data.keycloak-external-host}) + read -p "Keycloak host name (default: $IAM_HOST) : " TO_REPLACE + IAM_HOST=${TO_REPLACE:-$IAM_HOST} + unset TO_REPLACE fi -if ! [ -d "keycloak-15.0.2" ]; then - echo "Downloading keycloak admin cli" && wget -q --show-progress "https://github.com/keycloak/keycloak/releases/download/15.0.2/keycloak-15.0.2.zip" && - echo "Download Success. Unzipping.." && unzip -q "keycloak-15.0.2.zip" && - rm "keycloak-15.0.2.zip" > /dev/null +if [ -z "$istio_client_id" ]; then + istio_client_id="istio-auth-client" + read -p "Keycloak istio auth client name (default: $istio_client_id) : " TO_REPLACE + istio_client_id=${TO_REPLACE:-$istio_client_id} + unset TO_REPLACE fi -KCADM_SH="./keycloak-15.0.2/bin/kcadm.sh" -KCADM_CFG="$KCADM_SH.config" - -INSTALLATION_NAME=$(kubectl get cm global -ojsonpath={.data.installation-name}) -read -p "Current installation name (default: $INSTALLATION_NAME) : " TO_REPLACE -INSTALLATION_NAME=${TO_REPLACE:-$INSTALLATION_NAME} -unset TO_REPLACE - -IAM_HOST=$(kubectl get cm keycloak-host -n keycloak -ojsonpath={.data.keycloak-host}) -read -p "Keycloak host name (default: $IAM_HOST) : " TO_REPLACE -IAM_HOST=${TO_REPLACE:-$IAM_HOST} -unset TO_REPLACE - -IAM_ADMIN_PASS=$(kubectl get secret keycloak -n keycloak -ojsonpath={.data.admin-password} | base64 --decode) -read -p "Keycloak admin password (leave empty to take from secret) : " TO_REPLACE -IAM_HOST=${TO_REPLACE:-$IAM_HOST} -unset TO_REPLACE - -echo "Creating Keycloak Realm, Istio. And the required client and roles" -$KCADM_SH config credentials --server https://$IAM_HOST/auth --realm master --user admin --password $IAM_ADMIN_PASS --config $KCADM_CFG -$KCADM_SH create realms -s realm=istio -s enabled=true --config $KCADM_CFG; if [ $? -ne 0 ]; then echo "Realm Already Exists. Please delete it."; exit 3; fi -realm_create_output=$($KCADM_SH create partialImport -r istio -s ifResourceExists=SKIP -o -f istio-realm.json --config $KCADM_CFG) +if [ -z "$istio_client_secret" ]; then + read -p "Keycloak istio auth client secret : " istio_client_secret + if [ -z "$istio_client_secret" ]; then + exit "Give valid client secret." + fi +fi -istio_client_id="istio-auth-client" -istio_client_id_ID=$(echo $realm_create_output | jq '.results' | jq ".[] | select(.resourceName==\"$istio_client_id\")" | jq -r '.id') -$KCADM_SH create clients/$istio_client_id_ID/client-secret -r istio --config $KCADM_CFG -istio_client_secret=$($KCADM_SH get clients/$istio_client_id_ID/client-secret -r istio --config $KCADM_CFG | jq -r '.value') +if [ -z "$ROOT_DOMAIN" ]; then + ROOT_DOMAIN=".mosip.net" + read -p "Root Domain for oauth2-proxy cookie (default: $ROOT_DOMAIN) : " TO_REPLACE + ROOT_DOMAIN=${TO_REPLACE:-$ROOT_DOMAIN} + unset TO_REPLACE +fi TEMP_MANIFEST=./.manifest.yaml.tmp cp oauth2-proxy.yaml $TEMP_MANIFEST +cookie_secret=$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_' | base64) + sed -i "s/___ISTIO_CLIENT_ID___/$istio_client_id/g" $TEMP_MANIFEST sed -i "s/___ISTIO_CLIENT_SECRET___/$istio_client_secret/g" $TEMP_MANIFEST sed -i "s/___IAM_HOST___/$IAM_HOST/g" $TEMP_MANIFEST sed -i "s/___ROOT_DOMAIN___/$ROOT_DOMAIN/g" $TEMP_MANIFEST sed -i "s/___INSTALLATION_NAME___/$INSTALLATION_NAME/g" $TEMP_MANIFEST - -NS=oauth2-proxy +sed -i "s/___COOKIE_SECRET___/$cookie_secret/g" $TEMP_MANIFEST echo Creating namespace kubectl create ns $NS @@ -71,7 +65,7 @@ function installing_oauth2_proxy() { #helm -n $NS install oauth2-proxy bitnami/oauth2-proxy -f values-oauth2-proxy.yaml --set configuration.clientID=$istio_client_id --set configuration.clientSecret=$istio_client_secret #helm -n $NS install oauth2-proxy bitnami/oauth2-proxy -f values-oauth2-proxy.yaml - rm $TEMP_MANIFEST $KCADM_CFG + rm $TEMP_MANIFEST return 0 } @@ -81,4 +75,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -installing_oauth2_proxy # calling function \ No newline at end of file +installing_oauth2_proxy # calling function diff --git a/deployment/v3/external/oauth2-proxy/istio-realm.json b/deployment/v3/external/oauth2-proxy/istio-realm.json index 5e6343b50..43463fc22 100644 --- a/deployment/v3/external/oauth2-proxy/istio-realm.json +++ b/deployment/v3/external/oauth2-proxy/istio-realm.json @@ -84,6 +84,30 @@ "containerId": "istio", "attributes": {} }, + { + "id": "d9d0681c-a8e4-4a8f-bbc8-2bd15b8b5e93", + "name": "swagger_access", + "composite": false, + "clientRole": false, + "containerId": "istio", + "attributes": {} + }, + { + "id": "d9d0681c-a8e4-4a8f-bbc8-2bd15b8b5e94", + "name": "kibana_access", + "composite": false, + "clientRole": false, + "containerId": "istio", + "attributes": {} + }, + { + "id": "d9d0681c-a8e4-4a8f-bbc8-2bd15b8b5e95", + "name": "kafka_ui_access", + "composite": false, + "clientRole": false, + "containerId": "istio", + "attributes": {} + }, { "id": "3ad79da3-1773-4f88-a1e2-965d7c3dbadf", "name": "uma_authorization", diff --git a/deployment/v3/external/oauth2-proxy/oauth2-proxy.yaml b/deployment/v3/external/oauth2-proxy/oauth2-proxy.yaml index 386fe15c2..f6632ef84 100644 --- a/deployment/v3/external/oauth2-proxy/oauth2-proxy.yaml +++ b/deployment/v3/external/oauth2-proxy/oauth2-proxy.yaml @@ -1,92 +1,105 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: oauth2-proxy-confmap -data: - oauth2_proxy.cfg: | - email_domains = ["*"] - redirect_url = "https://___IAM_HOST___/oauth2/callback" - silence_ping_logging = true - skip_provider_button = true - whitelist_domains = ["___ROOT_DOMAIN___"] - cookie_domains = ["___ROOT_DOMAIN___"] - cookie_name = "_oauth2_proxy____INSTALLATION_NAME___" - alpha.cfg: | - injectRequestHeaders: - - name: X-Forwarded-Groups - values: - - claim: groups - - name: X-Forwarded-User - values: - - claim: user - - name: X-Forwarded-Email - values: - - claim: email - - name: X-Forwarded-Preferred-Username - values: - - claim: preferred_username - - name: Authorization - values: - - claim: id_token - prefix: 'Bearer ' - injectResponseHeaders: - - name: X-Auth-Access-Token - values: - - claim: access_token - - name: X-Auth-Request-User - values: - - claim: user - - name: X-Auth-Request-Email - values: - - claim: email - - name: X-Auth-Request-Preferred-Username - values: - - claim: preferred_username - - name: X-Auth-Request-Groups - values: - - claim: groups - - name: Authorization - values: - - claim: id_token - prefix: 'Bearer ' - providers: - - clientID: "___ISTIO_CLIENT_ID___" - clientSecret: "___ISTIO_CLIENT_SECRET___" - id: keycloak-oidc-istio - provider: keycloak-oidc - oidcConfig: - emailClaim: email - groupsClaim: groups - userIDClaim: email - insecureAllowUnverifiedEmail: true - insecureSkipNonce: true - issuerURL: https://___IAM_HOST___/auth/realms/istio - server: - BindAddress: 0.0.0.0:4180 - upstreamConfig: - upstreams: - - id: static_200 - path: / - static: true - staticCode: 200 ---- +apiVersion: v1 +kind: ConfigMap +metadata: + name: oauth2-proxy-confmap + labels: + app.kubernetes.io/name: oauth2-proxy +data: + oauth2_proxy.cfg: | + email_domains = ["*"] + redirect_url = "https://___IAM_HOST___/oauth2/callback" + silence_ping_logging = true + skip_provider_button = true + whitelist_domains = ["___ROOT_DOMAIN___"] + cookie_domains = ["___ROOT_DOMAIN___"] + cookie_name = "_oauth2_proxy____INSTALLATION_NAME___" + skip_jwt_bearer_tokens = true + alpha.cfg: | + injectRequestHeaders: + - name: X-Forwarded-Groups + values: + - claim: groups + - name: X-Forwarded-User + values: + - claim: user + - name: X-Forwarded-Email + values: + - claim: email + - name: X-Forwarded-Preferred-Username + values: + - claim: preferred_username + - name: Authorization + values: + - claim: id_token + prefix: 'Bearer ' + injectResponseHeaders: + - name: X-Auth-Access-Token + values: + - claim: access_token + - name: X-Auth-Request-User + values: + - claim: user + - name: X-Auth-Request-Email + values: + - claim: email + - name: X-Auth-Request-Preferred-Username + values: + - claim: preferred_username + - name: X-Auth-Request-Groups + values: + - claim: groups + - name: Authorization + values: + - claim: id_token + prefix: 'Bearer ' + providers: + - clientID: "___ISTIO_CLIENT_ID___" + clientSecret: "___ISTIO_CLIENT_SECRET___" + id: keycloak-oidc-istio + provider: keycloak-oidc + oidcConfig: + emailClaim: email + groupsClaim: groups + userIDClaim: email + insecureAllowUnverifiedEmail: true + insecureSkipNonce: true + issuerURL: https://___IAM_HOST___/auth/realms/istio + server: + BindAddress: 0.0.0.0:4180 + upstreamConfig: + upstreams: + - id: static_200 + path: / + static: true + staticCode: 200 +--- +apiVersion: v1 +kind: Secret +metadata: + name: oauth2-proxy-secret + labels: + app.kubernetes.io/name: oauth2-proxy +type: Opaque +data: + OAUTH2_PROXY_COOKIE_SECRET: ___COOKIE_SECRET___ +--- apiVersion: apps/v1 kind: Deployment metadata: name: oauth2-proxy labels: - app: oauth2-proxy + app.kubernetes.io/name: oauth2-proxy spec: replicas: 1 strategy: type: RollingUpdate selector: matchLabels: - app: oauth2-proxy + app.kubernetes.io/name: oauth2-proxy template: metadata: labels: - app: oauth2-proxy + app.kubernetes.io/name: oauth2-proxy spec: containers: - name: oauth2-proxy @@ -95,9 +108,9 @@ spec: args: - --config=/bitnami/oauth2-proxy/conf/oauth2_proxy.cfg - --alpha-config=/bitnami/oauth2-proxy/conf/alpha.cfg - env: - - name: OAUTH2_PROXY_COOKIE_SECRET - value: "WFhYWFhYWFhYWFhYWFhYWA==" + envFrom: + - secretRef: + name: oauth2-proxy-secret ports: - containerPort: 4180 name: http @@ -139,11 +152,11 @@ kind: Service metadata: name: oauth2-proxy labels: - app: oauth2-proxy + app.kubernetes.io/name: oauth2-proxy spec: type: ClusterIP selector: - app: oauth2-proxy + app.kubernetes.io/name: oauth2-proxy ports: - name: http port: 80 diff --git a/deployment/v3/external/oauth2-proxy/sample-auth-policy.yaml b/deployment/v3/external/oauth2-proxy/sample-auth-policy.yaml index 856e59ca8..f56f297f5 100644 --- a/deployment/v3/external/oauth2-proxy/sample-auth-policy.yaml +++ b/deployment/v3/external/oauth2-proxy/sample-auth-policy.yaml @@ -1,29 +1,32 @@ -apiVersion: security.istio.io/v1beta1 -kind: AuthorizationPolicy -metadata: - name: sample-httpbin-authn-policy - namespace: istio-system -spec: - selector: - matchLabels: - istio: ingressgateway-internal - action: CUSTOM - provider: - name: oauth2-proxy - rules: - - to: - - operation: - hosts: ["h__mosip-api-internal-host__h"] - paths: ["/httpbin*"] ---- -# # The following AuthorizationPolicy is not supported by istio yet. +# # The following AuthorizationPolicys are not supported by istio yet. # # Hence an envoyfilter is written manually -# # In future once support is added replace the subsequent envoyfilter with this authorizationPolicy (or similar one). +# # In future once support is added replace the subsequent envoyfilter with this authorizationPolicys (or similar ones). +# apiVersion: security.istio.io/v1beta1 +# kind: AuthorizationPolicy +# metadata: +# name: sample-ext-custom-authn-policy +# namespace: istio-system +# spec: +# selector: +# matchLabels: +# istio: ingressgateway-internal +# action: CUSTOM +# provider: +# name: oauth2-proxy +# rules: +# - to: +# - operation: +# hosts: ["h__mosip-api-internal-host__h"] +# paths: ["/httpbin*"] +# - operation: +# hosts: ["h__mosip-api-internal-host__h"] +# paths: [ "*swagger*" ] +# --- # # apiVersion: security.istio.io/v1beta1 # kind: AuthorizationPolicy # metadata: -# name: sample-httpbin-authz-policy +# name: sample-ext-custom-authz-policy # namespace: istio-system # spec: # selector: @@ -38,11 +41,11 @@ spec: # when: # - key: request.headers[x-auth-request-groups] # notValues: ["*role:httpbin_access*"] ---- +# --- apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: - name: sample-httpbin-authz-filter + name: sample-ext-custom-authz-filter namespace: istio-system spec: workloadSelector: @@ -57,9 +60,182 @@ spec: filterChain: filter: name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" patch: - operation: ADD - filterClass: AUTHZ + operation: INSERT_BEFORE + value: + name: envoy.filters.http.rbac + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC + shadow_rules: + action: DENY + policies: + "istio-ext-authz-ns[istio-system]-policy[sample-ext-custom-authn-policy]-rule[0]": + permissions: + - and_rules: + rules: + - header: + name: ":authority" + string_match: + exact: h__mosip-api-internal-host__h + ignore_case: true + - url_path: + path: + prefix: "/httpbin" + - and_rules: + rules: + - header: + name: ":authority" + string_match: + exact: h__mosip-api-internal-host__h + ignore_case: true + - url_path: + path: + contains: "swagger" + - header: + name: ":authority" + string_match: + exact: h__mosip-kibana-host__h + ignore_case: true + - header: + name: ":authority" + string_match: + exact: h__mosip-kafka-host__h + ignore_case: true + principals: + - any: true + shadow_rules_stat_prefix: istio_ext_authz_ + - applyTo: HTTP_FILTER + match: + context: GATEWAY + listener: + portNumber: 8080 + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: envoy.filters.http.ext_authz + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz + http_service: + server_uri: + uri: "http://oauth2-proxy.oauth2-proxy.svc.cluster.local" + cluster: "outbound|80||oauth2-proxy.oauth2-proxy.svc.cluster.local" + timeout: "600s" + authorization_request: + allowed_headers: + patterns: + - exact: authorization + ignore_case: true + - exact: cookie + ignore_case: true + headers_to_add: + - key: X-Auth-Request-Redirect + value: "https://%REQ(:authority)%%REQ(:path)%" + authorization_response: + allowed_upstream_headers: + patterns: + - exact: authorization + ignore_case: true + - exact: path + ignore_case: true + - exact: x-auth-access-token + ignore_case: true + - exact: x-auth-request-user + ignore_case: true + - exact: x-auth-request-email + ignore_case: true + - exact: x-auth-request-preferred-username + ignore_case: true + - exact: x-auth-request-groups + ignore_case: true + allowed_client_headers: + patterns: + - exact: content-type + ignore_case: true + - exact: set-cookie + ignore_case: true + transport_api_version: V3 + filter_enabled_metadata: + filter: envoy.filters.http.rbac + path: + - key: istio_ext_authz_shadow_effective_policy_id + value: + string_match: + prefix: istio-ext-authz + - applyTo: HTTP_FILTER + match: + context: GATEWAY + listener: + portNumber: 8080 + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: envoy.filters.http.jwt_authn + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication + providers: + oauth2-istio-0: + issuer: "https://h__mosip-iam-external-host__h/auth/realms/istio" + audiences: + - istio-auth-client + local_jwks: + inline_string: 'rjwks__https://h__mosip-iam-external-host__h/auth/realms/istio/protocol/openid-connect/certs__rjwks' + payload_in_metadata: istio_jwt_payload + forward: true + rules: + - match: + headers: + - name: ":authority" + exact_match: h__mosip-api-internal-host__h + prefix: "/httpbin" + requires: + provider_name: oauth2-istio-0 + - match: + headers: + - name: ":authority" + exact_match: h__mosip-api-internal-host__h + - name: ":path" + contains_match: "swagger" + prefix: "/" + requires: + provider_name: oauth2-istio-0 + - match: + headers: + - name: ":authority" + exact_match: h__mosip-kibana-host__h + prefix: "/" + requires: + provider_name: oauth2-istio-0 + - match: + headers: + - name: ":authority" + exact_match: h__mosip-kafka-host__h + prefix: "/" + requires: + provider_name: oauth2-istio-0 + - applyTo: HTTP_FILTER + match: + context: GATEWAY + listener: + portNumber: 8080 + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE value: name: envoy.filters.http.rbac.mydeny typed_config: @@ -71,25 +247,101 @@ spec: permissions: - and_rules: rules: - - or_rules: - rules: - - header: - name: ":authority" - exact_match: h__mosip-api-internal-host__h - - or_rules: - rules: - - url_path: - path: - prefix: "/httpbin" - # - url_path: - # path: - # prefix: "/hmmm" + - header: + name: ":authority" + string_match: + exact: h__mosip-api-internal-host__h + ignore_case: true + - url_path: + path: + prefix: "/httpbin" + principals: + - and_ids: + ids: + - not_id: + or_ids: + ids: + - metadata: + filter: envoy.filters.http.jwt_authn + path: + - key: istio_jwt_payload + - key: realm_access_roles + value: + list_match: + one_of: + string_match: + exact: httpbin_access + "swaggerPolicy": + permissions: + - and_rules: + rules: + - header: + name: ":authority" + string_match: + exact: h__mosip-api-internal-host__h + ignore_case: true + - url_path: + path: + contains: swagger + principals: + - and_ids: + ids: + - not_id: + or_ids: + ids: + - metadata: + filter: envoy.filters.http.jwt_authn + path: + - key: istio_jwt_payload + - key: realm_access_roles + value: + list_match: + one_of: + string_match: + exact: swagger_access + "kibanaPolicy": + permissions: + - header: + name: ":authority" + string_match: + exact: h__mosip-kibana-host__h + ignore_case: true + principals: + - and_ids: + ids: + - not_id: + or_ids: + ids: + - metadata: + filter: envoy.filters.http.jwt_authn + path: + - key: istio_jwt_payload + - key: realm_access_roles + value: + list_match: + one_of: + string_match: + exact: kibana_access + "kafkaUiPolicy": + permissions: + - header: + name: ":authority" + string_match: + exact: h__mosip-kafka-host__h + ignore_case: true principals: - and_ids: ids: - not_id: or_ids: ids: - - header: - name: x-auth-request-groups - contains_match: 'role:httpbin_access' + - metadata: + filter: envoy.filters.http.jwt_authn + path: + - key: istio_jwt_payload + - key: realm_access_roles + value: + list_match: + one_of: + string_match: + exact: kafka_ui_access diff --git a/deployment/v3/external/object-store/cred.sh b/deployment/v3/external/object-store/cred.sh index f0dd0dcd4..dc2bc4a03 100755 --- a/deployment/v3/external/object-store/cred.sh +++ b/deployment/v3/external/object-store/cred.sh @@ -16,9 +16,9 @@ function installing_Cred() { echo Istio label kubectl label ns $NS istio-injection=enabled --overwrite - echo Plesae select the type of object-store to be used: - echo 1: for minio native using helm charts - echo 2: for s3 object store + echo Select the type of object-store to be used: + echo 1: For minio native using helm charts + echo 2: For any other s3 object store like AWS while read -p "Please choose the correct option as mentioned above(1/2)" choice do if [ $choice = "1" ] @@ -33,11 +33,12 @@ function installing_Cred() { break elif [ $choice = "2" ] then - read -p "Please enter the S3 user key " USER - read -p "Please enter the S3 secret key" PASS - read -p "Please enter the S3 region" REGION + read -p "Enter the S3 user key " USER + read -p "Enter the S3 secret key" PASS + read -p "Enter the S3 region" REGION read -p "Please provide pretext value : " PRETEXT_VALUE kubectl -n s3 create configmap s3 --from-literal=s3-user-key=$USER --from-literal=s3-region=$REGION --dry-run=client -o yaml | kubectl apply -f - + kubectl -n s3 create secret generic s3 --from-literal=s3-user-secret=$PASS --dry-run=client -o yaml | kubectl apply -f - kubectl -n s3 create secret generic s3 --from-literal=s3-user-secret=$PASS --from-literal=s3-pretext-value=$PRETEXT_VALUE --dry-run=client -o yaml | kubectl apply -f - echo object-store secret and config map is set now. break @@ -56,4 +57,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -installing_Cred # calling function \ No newline at end of file +installing_Cred # calling function diff --git a/deployment/v3/external/object-store/minio/delete.sh b/deployment/v3/external/object-store/minio/delete.sh index 69c100dff..a8176bf47 100755 --- a/deployment/v3/external/object-store/minio/delete.sh +++ b/deployment/v3/external/object-store/minio/delete.sh @@ -28,4 +28,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_Minio # calling function \ No newline at end of file +deleting_Minio # calling function diff --git a/deployment/v3/external/object-store/minio/images/minio-dashboard.png b/deployment/v3/external/object-store/minio/images/minio-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..d55566ff1bfa40af94da6176b657a43e68a834a2 GIT binary patch literal 73396 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

iuWdK7r~NiUyPNzn@k%3 zOlF@28=b#>y7sZqmvkGY)~VsNy>qMG$@zqbi&EzpE!x%Y4$Oqv5VH5_NoQLHDWenx zYwxll*)qT3JQIuc{@seO4xhoiZ|7!8!++4Z!-@s5lDcFzpB~eFCHQfYHfa(FmA$`J zcuOplmEUA4R(Oc0advsNMTB~^9ZR=eNSvmQ-nVr>|85^)=C}SA0}-LYwEO~9>o%IX z?y4kHgB0gr>$78-A~3v2wJUAM2_wf9Sri z$5}N#+DZoxcQmo8)+X5KFbD!zNhmGhj~zpZ7Qh=UOgn}x`Ab0t-d!W0xc0IGNf0mXeG0lLHXpKpfOdWNP|RqH?B`^w;ClG z@MXCApaiQMBgoazBT90KhyB!BH>PG6UOc$mh#0EdjZuf)cuE#LP}GG?bj)C zvT6qjIL}z^D-AZ6O1@BK%8P#ae4-15!H z*(&LV@w-k5Z3c~L-qkB;W{tAo@S^)Ak~Ea2<0?i#z6|L^PP`M4)w*7K^ukThB<7b} z&@ku$*WKw!vl@y?vlXjzY5Pq>)7CQ-0*NI;o)JdUp#lXyiYK0=LeO%dp1K^sBB!SY z>$v{az0Y=h#pezydZnYD%nwB04{rN9s}vabEk@Q{OzEnMf66m5?ncv&$jU3BcajMESr$Cx#YR~kY_f&Z+N>f=7`j=gv2ja>jYO9* zCuN~;u342onwHf0OZqQ)W1E)bVQ;Es8KZs~?7H6=;C*9{f6V}WVofRV7b-E=q>LCx zs9|9}`#LN)Strw1ym4aJ0G<+)r%^sV5Hj&(4LK0l>VU_&jD}WS9QA6Q6OhhS?z&80 z+VU3sx}VR*9h-MOckSeMx6Qipg?C17*36BGn5tCGfv0aW!yP2l6crc1y}Ls{rsK*# zziTRAN+(&)M-Q?dz#8i99=gh=bf=|J=`FTkc!#0=>T{2E26g+yZAhg9)uvvyPP?nG z#8o(Q?l-2Kef`WXdym-==6H0``9Ku^sYog<@iTkRf*5E{5PveJ@v^9sKNIMDcdd9>#{gNI#p&9YMo_1e`#M|<+ zKBSW}AD841(cdGUP_TpBXHZ|4#o!DCyg)YE%v=J}bzW~@c*64+zHs#YLE*4Sl4lk_ zTJpS=er%7bD%?J&s@kRd${QJ~FoPj7yFVQGoH5@&{Qd`QrW)kn<)i5Yb!g5_4 zT#bXZ$ebt=U*|^NCZDEOy3<5hTX2~27BrqPeFRh=Amc@W1vLsui#SDSjQbtGGwa8m zFEt^`=R#9PZ5cW0xIPUg%AwlA#V)tg-o$-!QQn;(3mva~t?^E?FN51u9>lHlLH`!J z#yMTaxXAt@5H9AGpfei*J>WQ{BV!op_oTFcplunG+O|9pzCztqQ12DPI^*uFee-xn zm^*b%pyu+@sfOYe3L;Mx{(3SlQ9E#5#ff}4wQ?$I;EucH6`jos_tq(R%k@5oflJTy zbyxEZ&lcafc!X?sS*IxfmOy@!<$_H*tanC0Er5hG@TXg~zxB#H2o18XjMYB%wQ#YD-Vr9g zuc0&$5#d%{n^0BlWnp<-X>U(>q~|8&xI=sf4BaljH~E*RRW$w)glJ99{dxy#W!fdZ z$V(E-YGj>9Tz#GB-&j5~SIgtnH#9eL%hpiO`Ud)gE;_``EFQ~Lg!Xbq-FOQ|OJU2G z>0A*O?mUNT--Q$})-g`vW{8L9(oNO=`6+RV!zE@yv;7_e|a zlRzDFnD-~^+WXoDt38)OHTy5}RvwQ9UTF<29_fm{Os!{7ra3-6TurS3EKOxVHbfUH?wUUU9PTy<%~aPF5_PHTRJa>54ry+TL1t&J({^+zC+?#6dE zc4jJP_Dr!kDWfP(>fzYFJLJ^XgvO2j1M(@yt<~>Zsz+J|^c>EgLVDV5bRYJ@gqSRK zO=;H1eanMFjWNxPvp!Njp6zdgsKc)H!#xDVvBoVr^~ZlGqu?!v@CN16y-3t$ul^J7 zR_>#ND9jU~oOc5%9-}8im);p=IY=%}4V1%TXran6MnzMPfZ!`? zQ=ioOQqypbzYcyXynF34uL9rN|T!6mC|CfAI#ivZX3f{)?cYnuq74Sr78^_zvX)}O49jm zRpI{8iznL}A6GFZXhIwF``HrZj<{1JchQI+N)2vqh^G8#>{Q7qB2DI+eBlOdr-u1s zwG~K{H@QfXFWO4chCmSJ37dI}bLUjF)NtbL@#_A)Bh9E;l;W~M=!>`g6ET5CpzEu@ z9mwu|Mfo`o{0p1e?=R>vw=uIK#Tv`05S%agw9E_&^~7XA@_~IFG^xmO z#<(ZAsGq}NbzILD?ucC1Wulf*%Uv8o5OG!WBd!}KhalEo*xUV7Stik^9OvG$TQ(x-S#gQa-k6Ui_+mGX^E0gmFsmf!C%zaY*OLU zBRPc9k{8Z}PtXi<5;s~v_^7Y*#)fYfUq+cK>Bn=Js>2pa3ufmNN+gX9&N3QJfA2~w zNm2LDXj@eYFN{b4mH1Pb5EQn%G7Shu-?wX==7tud{dK8x9(lj_T#!TPhu z1{KU3KHql=S8LgM;3<;JdN~|kRd>?!CmEw;jtbKk8Bk`|$s8y1h293gR;4@;BKg`jV z-@fOcxbyt(@6V#@2K7HC9RbQ|9hpR|t-kdR-C%;jxyK+<#OBCo?%D%d(1Uv?nrN^dsi+nsy(SL3!#9gw{(dXIaRstWylt#qh_o8mEUi5d&A+ z>oEPHD{Z^EyK4RG>g($-irJMz&k_W!0!eQkjQzyguE7@5x+hoH*ZSc3P9FnIL|a2* zvQ`Vzvf4l^q@CE^>2xIq2Pb@8jJ&Y1f&fv<=ikvU837noyh-Ed)m>;4p^mG2MfrO6YN7ZNjq7bda~!8rWoqxQ_sroKPt_1^AqW8wDEgrnml zFoLs=QJQgySScqZsU+Hp?LW3Rpcma?S;H=z&NR06OTA|${T|$>3h6))?XEZrn%Azn z993Dn_6Hq>RO&h1KRP=k-Ty7~s>}j%#RoJiB}{%4JF~0W#xt{wFPk2wOE~5~XckR7 zAb?lzim;=?04;&|$g)=G!fO9Q2B^W~rIiY@T|od(Xivn0vnaCp#{q)QT29XU7otNd zIAC9`7-4EOP`R^#pp=$8G#xXap%fT0b>VosL8I)C95tr2E$XVcc73mL135J(UkK&w8!+r* z2$>t7H#+`D(3u8!s1MUYnXTlp=BCq8uQ2ojWT5TKVBz;}+rkcSe27>{%L6Yd-Q^n(paA z2j_^ZiGF&G?H`ZfBO?JUo_Ah!Ysyfc6mQfm0E8lCM-q#3P|c0Oedeg*j%|qPyBT#?D=%y4-M93c<;J?QGd6 z`?U%&?GO%x-D@Yu>OaLhcsi2eonF-NZ(A?}sOrC0M!tf;Lzn?bH^rP*wj>~W&rU^z_pV$)9g|rW!CKIl`tl6A z7iTOMRwG4lf(3f(vsaPVd5jW9k1p)WQrIRVP4n_v*H|ND<5Q2xJcW7mnK&S<+PwN@ zc0sT4?1jcJS@SB(%_ql>;qflN#}+%(fg8O_@cFDPvZF%9l#of8-=lZsOO-LDDS%u! zo(lBWWT(N&4yPK(^E+1Yfz9px$_*}S_ALdeD2`)>mx&w?fnR7`k#w zLua+vqA~Y#NiU=8C}SwT40Cn5^zP-|(N-xNK_+`?_WVjTbyT@vVOo22%Wxh;2t{Az z26WxVyS*{zynD?C)IlHotJ}o0H!6-i;a3i`xT2Slm<*ie!a2UY&f3qKz}bvc-w3!R z7QFeTHiY!Tx@=q;s$AJXGzV!0W@NKxT7Qht$GyB-N%sd^3svXe|61-)I3f!v9^_ z>(Hk!<)1MuNYUgCev(z0RgYhlB-ne3l1gh(mQA#R(;8qY!;Wv6@Kz@vPzq}#Ykw_i zt|xLh5e4;67Hq${sl^14b%UcGL)yYMHdV93p3omiEAZ_Gf1&tpB;yuSK zBlrB7inAgLWDvyrbD6g*6x*{-en`GtHK9GO68ZH`U%TqyKsEI*B~5Y>plb$e6L}^) z(eFhcS)eUxtKv4nB&2;d@K7?D9Sbd)gUHE!1h^-@e;bb1dy=j6sGX$iM!$t_x)BNW zw`#DeIl$gJhibk^4_uP>Ic44((YukNYF+-;Y)iGfV*IsJ60pyBuKBoYj_g;VLSd&X zYh8TXcWMmKp$exz=D_%ex}IrsXX+gF95dFonj!y_KUOZz+fz?Z$bMCRz=UMK)~R=F z`&tpr0EA20p{$yrhQ?b-NN>p7AczlV_(wT+z%m4~(U#=zKSHWQNAez zF61nWVjIs{vx{bjQFiOJz>M0jMcBX8;kIh9TR-={)?NkhGIavn18PBI^13<#+#Zuz z%f&oT3zoJ`ilm8-{$k1jHNk>ww*R}$a_h+u46u$P=9)YeW}i79X+`pqMDMT6zLhH) z;AoRG?kq*1M|P_>^v^orx2J!9{!0NomU;2dt?g*(x=I1`7tFW|fiF%qSTCqr|-TFxj zIGYv)HfIO+dVF#_dZxk7rBv6m6!WH3O@$sr8rwfn9M;}}lLg6<{K^tFtT+jad*acf zsM*=DY#qq%*hYQd$7E=gYQ_+ZipgC@=BnL@kmu;H{~qLl^ByRdLZAmhZ$M>sVkhr@a5^>JKWPV|zr+&CZmA{Uo&VAk!? zI!nZxl)lsb)X{<*bv@q7@YG|~*^)FL>&fz7lwbSI$~D*4u)vw$pUe~wNn0Ow?+eCt z2KO-twKl8}@q{OYjpHpVZD)C!hs&P~I6Z!oJL|som|7JU589K>2+|WY3NcCHaKDfc zj#n2LpKesl3|SP7N$`Ymj=17HNL4Qwk`Bm}ehPO7%;l%n8sdHy>!Zy`daZL&f$WU6fqItNiL<*49$i?llq# z5NiG_I~(f?tAlJs!8}4`o&c;I2#fr%=^3ir$LoTC^?ir3yA=7N z;#3yv1CcNyxEV%ig2QWIyNbPRV`o4Km#j*nX;;m(a0O0a9meyN=W=BU4+Crkh=Xz| zi1k;IE5S{N@iymye%Q7O- zvVElg*~XC}{$K8!x4oE60T#(z^s>E$g_8UHcm=W8fyKY`$I)XCX{NeeM^VyrdQcH; zXFYz-BXFowx@*5^LhZg4ROJTB#)0GGelNME%%aL{c~`y8SKs4&>mRy1Aac=4z=1}{ z*9w-NRdF zxHgQ2TDdo~0^q;8nFd}Z)z?qE91R%#@o0JBUsom2v-?E_qqO^Me5-UFsDM1xD$wog1@$sC| zdj;_=2Ya>1{YM5IYMg_`ub;Ji&@%D+_(8>YRW_Wx$=<6k598g-M zu(0xtRH{yDO~z%T{tp`D-4{49i@3d24ekG@(qpa}k4aM^j51TFMd~*q~0!3qcqCA5s`D_NOfxQb`*R zR?AP|9+~Z;_e?!M_TwR#%Ry?~KF7PgqMCAHL~FEfk++wrlmjj8hQ?uhi!iS0%@H?u zS#*?W+OPgZkOFtj?{Z@`vysuqxRSZ%lnghl~31uUo}kO3e`-wp_w{u7M6#${T|giA@wU<7E+IyT=z z64fLilH&mZ2A~z5eeR|Rjbg5NUbM4RO=u{0s~-%$>qIi#8$TQO{+LX4qerQi#aY*w z-lTPC>Yn=Z-L1!=&KWHEFL`aR=kpRCdQr$H&|mmV zXeaAT;w=zqOr9NbK=Pii3W|B?1=Dpm=&lH3oScUl~CH=O< z?^C5Ay^e9ak|O_xE})q53&fT_X^9a_$x11GdPYy}-Z^=CWoR{wDZ*z>#Y#q|Z-mW3 z$xq$Aa6P18eJNXP(N1{f2=(2F^#&R47(;u}6_}bGUD-rf_cQEx?I0hv-EZn^=j~er zAdc0tqgS>ZmB0-VUh^)%q|D44dP;vF8onPvm2#RIeQLQPzSK+V_8G*YzrHAC=$1kg z0U6Oop>$**vqKu3xG^aU!(m~lg)=WL2A1|a-aVMXiH<*8nsgfPxUPXBDh#CDaFD9C zF+Da_OdhE_&L^NArRlX~ny%Vg95#8Y`i|gZ(R7@Z;zKT6tv?>B$smx^l|mDMgpZfqTJdao$VpLCf6x zYRPFd;F&~E`493ce{S1rC8fV!hgQ8p;5G>K4!VX&{X7Ejl>dAq%9i6ITp0P0XeS*j z?twRVj@Dc{n7$bN;-`&f^$B7{31ZDfdH*KM`FEHLmgp;hxP{4}zG-c0pyszm8auPbDh)XQF??6FghdyEzB7jxit7UJN=Ysc~ZidQ{yHMumW0W4%O@ z+#MF7>(Ul-x26Nn?~P6?mkW`O9()cmvvP8t*L|)V0%Dlb;R}-mVv= z>dYBx9Kzo^ycF8Gyaj*+xu%HT*qq=#2;$z#4HH~(Ep%CGm<6J7)#;N5PhbsFpT9L$nni z$CipTKk!TNCiYAk^EdVldY%-7UJ2C0tNNpD$F$t;nPaK~zKA{!YGU@aI}pms(rO3g z!rmj`xS8wweg@5-Se>+F2>J>JFf5SGFf$U~YJu zg6>S?4k@TaB({QQny&*J>v}e&U+%{UmO1S`>*WpU{Dj@dJN*a4=$d42?lXH|9e#h7=paxo3yfM?aPS{~ z9DlWMqt`4aIe}PG){ky?MD)h}w%8D{CZO!0&&6rzX1lw4T`ScWP=##*uFv1?vKdk9 z6%c#iryd_8RtOf%@x6!>H-6*qxiivAK)VJ0#G58?#sG2#N)L3zy3L+h)%I9TZ@mSI z4Xg(T!v+^rnFaP+i@(kJ!F9T7S2S(T6KiRkA$QC3VV6_#k&4%t3Br~b_nO2v!PlPP zl-3^+Nz#bwwfxJAyX*QcI(C_GFC5Ju?aJNn9ivFpz^aGcV!@u3% z^P#lV`10L$5Mm`bB(Axyy*|+bm{AB_^>o8c$aS%Y%L}3p05)^p{z;E!2&ruF=+Z&l zCN?VI`KZ`6R|{naM=`yhB6+NdI!oM#r!&9%wI(msRABqn{Vdn_RwNMms56V0UXPP$ zbeO<}P_NlrH)X%QNGNPdiEq0ZqAqeA^ez@oRNM6d0FNjhy*$!zUFd*+jxR`w4TwTYa%-r zH#<~7YxbqX-pv$fR@+eL-fC#Ze+>slga^F7{BW>eOQ0f82}k)-{H*V2gsW8Bne%R+ zLp!I=BvyfRlz@A1b2Y`XZ|9s$T9V&d?{hN8GeBEX%$9TsLG|11+)rO%lLv>YU2ILD zUp3EP--9)%t4daP-AzzsrrmE_rS-Q;b3|uFs;Pl1PG!3a{TjQS*=}zJgp9L)UTH&@ zPlTFg7WKF0zx2$Om>~9c@?~u}oYW8UL=Y9`8}G+IDZgBcN-Er-smoAiO4TtaqKJ7% z@;yKGoyLxcC&cxcj~frH0&|aPJ=HnaESk21H1`Evl24DDOO{jfa7TY=KeuH!qWgN) z0Nsptu$NoTd3vHeE>hYojGYgOu3G5XUd96h@}V&tJW4_mwU||~iWMgr(EHkF%ki=U zyT$bCjjEU^pOg$q_JBedF-t_$rzClBWRK*k^nAaZa8qyB;@R^+nn= zL}bnQEX-WwIWPA>?qT<$fo~E;KX*IC zNUM`?tQ@8eEb8%mLrdQ+ekl!cyU$Py!|I&x6xXqCHm%n;e1tvD(;>gkA$Vys-&2N( zJfq>a5BifVD%q|LMLmM(Lvb*JX9H#A1_9}UOqP*v7UDNRfp!jCu1XNieETC-i7 z^U~~)K)>zoJTdpf%VCZdbH*NQKgWtaUSD4@;0&}k{)?zp?zE@085m=j@RgOUQtqfb zOMT@!>=V<~C}iB#D3Rawf$jcgDP>{7l?QokD5V`Uc|SU7vbe&?Zs=6H2BcFwvP}Ew zsDwl2Sfa?%r`5eG;|>2Gd+#09- zz>1<$q!R*BDKS)~*I+@At^|nGC_S`D34w&bZwF4XJm)> z;KhnQ+5Gj*u?E#Kym!0r!!+~8z1?Pw3th3Yil=gm+Q&ETFbxPTJN3Ta>76%U5;N>pqX~omhIPd!P8hNT+T- z6od>YWjjBE)F=yT2qQu4rr9|wG37akUz+t-kMXZ+9VMs)WB8Znp{d4&M>oM;EsDxM zYClW+d?AlOEN668(a)VfW&-ibWxo2jJCHc5-mJEeFzI;c81$|4SYdUQ6u)~+b)r`i z=|wL&cQd~8JQnj}H7dIWqB2momR{E7?AuY42#|I>$qRYt>1;d;PDs|Z5-JrW9iI$I^=y_|UOu}L#z zZ=Igt25em#(OV5Fmq3z-ZRo(i6B~Z-q-CS*L6n4(GEWF{{tx_p-aN`5&3}lSpX(PJ z-d8GiN&EL&&z7cm1rBIb5dC_5gzSb~*^fK_q#W!3?M)zyI9s*UWbl-+jb7jI3tVaJ z3(m`c*=Q@hSZY%zpHplFh-|Rwgs+MGjJa6jrmHMYCWoOi0@>3uGw?V%u>Bbz&_T}G zlj_BI^t!|m$OS`(x@j(Qc;F%_U+i`joxaw`siO6d zaUH@?=3*CpAm*9+sN1oJTz_>pZ)5W>fx4=y#k7y_C=!*vtwjx>9gsKAn7hCPk#0>c z(J(FyCI-$k_AM;1^ac%cSekr(LwiaP?fenDa5jp|_t;tF!FcsbiLe}`CSf@;9-+f{ z+Z7-N=5-Vnpk~A8%dqzyeMho?ljV_rfHfIiRGZ6X9jjhhV3s8AYrtocqj<4+E9*=1 z00rXiq^Jbaw)LZ?a-*bUh3zG*UiG>W(Y%4$VVlUxb2Ve{TL|q^&%Fo=S6qTtj+tf9 zKI7UJI9=_~aFy^_@34zS(zoP}t80}8@@-U50Zhg-%h8pyO-yWSGnNHdC&aj*4`NHD zqIP9vJtXd&vaOXvAVKPIfS`qq1{?r&!_9m`uz;zHAcwa|qUudy<=(UTT7*Wqn#xYr z6RC?A(E%!73dtZXE??`L?A9(_K=#Rb3~?{VMW*Q{SzmAC1)csoB%tI6B2afU?H(w{ zCnqWz>2*HLiQj36hBDhuN?g&waI1z?!JBieFV-80z|$E~%gpeAUd!0O_D&6Gwr;fO zlRaU_J-7##F5C-gmOpL7(Qn%9C)RQnC67SXy~qUXq2P{*Nm&Lv;QFs^%Ersj_?Pt0 zSLW($x!|L)bYaYAzQdiXh7(7Z^gRZ5g9)9NOjz8)n*UV`gSlmWjc}6u!dTcw8^npf%($@&=6&*$xc^{8L4L%}8XskCH z)ST3#&f}NPPHmA!HT7NZGY)1C#_9di$e5!&M!|%|U#WIxd!wm*1b1M4&LFAX547ti zrQo}W+L$zxzX(f}*vv@EB2bx~IIOxO#yy@pn`)4R-eUrGZ7>nk=AfD?&GlMx7Hh(O z<-`r!ATq=yd?f}$p4{4nGsi&VqXBgwjVG|=gyG>QX`A=SPOq;NT#XdqByG$Y%9Qk~ zIXwIaVcajds}uhwD=%BO2j`G(936qj$Kby(vmOu$Tx0zTphOX@)94gCAKk6OydV#2~_^V9nfP2$o(xRdBGMQV|WND&B^zkkn`G8km`C@gTE|&U; zG=p6)1P$~bX60U8;9j^F$SZ`ys0#p&u3`63(oE{orH+S)c+m0>lE!~93zQyMl}Z^_ z?$ERfZZznuE-2F0FaSjZ`0j*L_)81D!)>;-a@`bmq1=ioj?)AbQj>vS3Z$2V)obfw z$t|a*Dis+HzLb#V*7~Retm#S{i9CL!u85XtR!>UcB$HqLL6ib3LFUXTk0Gc?sWh9< zUu-5y(uAN)Gp2bi!vqj|37xBmn4NO8c?_ttw#THvYyTrnDX8E}4+wooT*}%`GMzR~ z)gp=(gp^=YjB>`h_tnM9hJ-74MWzM2HM??myZVlfDP7`L@h8VTck>yNqcwmNT_LrO z_+)893YJOZ;l@}=7^O~b?}S&Hf64S zt(EL5>NIyk2Q8=v_^t}YY46Wv@LexIeQdc_zw!XYPjDqeoG1hMBkQ@ew+m@hju^(I zO_Cq;EiYPC{wFpS;EIzxtKa7v;S{s3cghNj;H#d;%TAmIUII`iD#-%&i`vlB2D7U~ z!y$L@9UkK64B!v`Y`?w_s1eckR@46S!3-y59JFn$1P+sjcj|EBYI9{zM5GD*;nyeF z6u>5%A$S`>)dPy7b9erriSqGBq%RvRETK~8>AM-!;ayC}qKxL!8R{W?tD|D?L^H|= z-|Y5bSanwY*E{~97R>U|W=Aos7Ipae?2Lnd6Co4nj7`4L90Fr*ll_x?;GD5_`eA@% z41tb+W_(gBp1af?w3!|8d2j<3)DbcCsD6>1P2MT!6z8I=EwT%jv_e8c+$IJ^O}8FC z*FW7lA+YRb&ZIvcC7()fMvV-sEO=mylG37{XZas%b8Mt5Ze?`u$L48cMP~9M7fUoS zMysvb;Bz4}^fZtSjx8HQp2y*!Zl#Yau|&KeaJZmU4Br>6s9{tC%)lC>+QYH81YvP5 zng6zl#_9azy=?qFn&^Zr3^i_`03C2$eDP;T4B zw9JJ>SPhe+yKwtY^~nx+=zP8mJ56|^6!V< zJN53*SW64UT8$uLNK&D7Pgs**>8Q#HT~SIc^l|$wTKbP6KCw&caJ@7-RtlawW}Z~q zvlsVzP-i+`HS>Tk8Z#?XhWjS$(FKzRh>Ta6>M-TSof8wvDyW<3?WSEN%olUGVOiQX zUO6_J{a0PWUj!pyGRlAw(9ZN(($kPvWeO ziXagPV`;*!uj&>GfVGe%;u=ZpR+Ux0!lB3z>$QF(4_so4_Ml zGxae+anJQJ(g@v+0(W+tWPe0hKHHB2^YWK(lhT)gxIP(bzX8xzVi5dd8>rF&0kzb*cm?~usMV)~R|uAzmVw4AG@ciR zo@!_@zHe4n1(@i5e>?bntpFNPSA~xhgottC1cZ-r0zS80D??*{2*zHi24C-}1H7_k z=*?1kKRjG<<>6kS;DSBg)8NIyus{Ded|+227>le0dsuof0SEA;?;d_{<>Ao(K{EOn z2llWW;76;(e|-23_QP9sBGA!*TbnaF7$yvTd0=UT|Juk~q~iQ*@?gbU{`bo)n)_}| z$ZgMF&q>cE&utGmNWVTf8d|*f?C#V)^AqQy(p%eaDFi!!ML}n=*C!RfBM(eM7~1~@ zySx}UO{(ObmS_cbL2E;%@1o<*_MO@5cAJ>5{OtqhHJazrFK4aW2o^;jqXcSSq!HYg zpGgCW!WaE7ET3ySnaLkGyPd_?;JEAL*^zQeH)YXx`&l)W#m5WA`z*I?6jcKs0-H&{ zp1g0g*?G-_{~+#sxc`Mfg}nKt9)`R?itIe|UPni(yzZ6ay*rH1S0xVKIl_K~u1C%~ z?f))GTTw;@bsE_l zB6wvhO+DEnPTsvU;=oy%hogEMU*ABR8QYxPxW2XF8DrPUNU+&Owja>qx_oCi%=hV7 zU)&_B_5GKB9NYJbt0L%oQz+$tMx%JTq`+@$zkgl$Kzzu5*eqKP|BJD~M0A|kW=P+d zty&@X1SMbGi8}l|UXvzt=i-U)Ul*a0_wf?>XTPu;|~t?o@=M+<#L0NB?GQiQigWS-yz!SG$Zte_z5i-@i_Ky5Y=!FvE8r z|1h?YJa^QD1D;!68|isPgv)#680w7S<55>;N-x8*u`0^)`Z?uFWK#t18mv3{Y0=gf zML8a5QdZ2lPWrP+X>TjW%dNEBVS+}Bb14-O&Tw*Yf~FH!?F~!~tRM>W(^m^j>O6i1l@UE_gy*IB^!vPPmR#J5s)_E>;Cz%7%@$>; z9+-j-cW40yIB?Z*NF4n^fjd4i_`1a-Z#UE>5$&`p$Omip385T2hP38pL@6zh!MG=d zjQU5eP6Y>|Li#bo`TQ@HNadM`&sTc5NH#h{nCNBVuD@2hooA+@mwiCJx15cQf1u2 zJ2?+U>ay>DT}?`?XnU)YLpdt+)>JX$7lBlL7a5D+fN=w!oiz{d8NA<~m@5o7?r?At zSt#a?bt{$CcDlaexW3Wts=`<6%SCgSbyeQXnD*Tsvo~gNyuX9)Zj^DiJCoB~?i;}{ z$K#WPlh@A`ZofR6Lp)X87~$oIaV+l2=O6BI2y5W^a^O=w|9trPCPf8e<*`b_RLl)| zZN3oiZPlZN5)qqD`B{)719(~X^Huj!(&Xrk`vn>`Tx6Vg_>oIhbDf4Hqy-Z@uMRud zLR}8OY8d&@14Wn|>xxWtPGDr}NV~yOs?d36Z^yJzRSVno8h09rU&eOGB4}9_km~rH zB$!>lnse{yTwV17F~up__QY>Xz4XsaUK@I8!@iM*w6xQ%WBEhglxM0+-A6K1n&7NL zc+1#Af8RC7sPlRONH&-<1LA={FpaN==*U-Vr{1qhiBtT zi8E!sSaF^&D%pVtYkkQ(iYJT5PU{9W7xmt5<&Q#jCB^KAVGF}VHi~*(PUtuUe1ycy zD#|&W%~35(Ylr)Nr`>@=FOPKQr{F~Yt^*%S^K66An_ziP--a*T+h0n&a45QXPv>XfmJD;Fh9@pb*PR(4V|SZF%Hl_Js0rMTrMq_xrNAeugRR{$+z^1 zFBbi5z$I|ua)Q}y1!g-HWqu|;=y}FAmi_b@(wDFMaC4zBoNa}D(2`I!Qu1QLOA7tqov6)-#!MX-)a^&G1h6+w zBb$hM-0(?MHD1JQl+{yCh3`*F`cmg<4)N^4lf^l?%NI8Yq#FLA_)!X~(@}0En_!Sr zUB$xi)0CMC;q*4DHe_eKf@|>^=|AJay=PpuxO~v4A+$-$p-K}_Pj+=EWJP-Qx8UA- zjYx8)%hxA$n&W%&%+kf&qQ1x^dfrFIP?^V%6S{ zDc2*3gDPnoE>6x_RcFO?-lko9(aumxYl`qvxq3+R;OfR^@!@rGr;d#)o*8oO7AL3D8_bBu^nxAAKnWPn-4WX0-hwUg^QXm3uQ3n5laQm#7m ziN|8(O}*NkXy|%i zdtK;)yh9_*qR0L^Eh&hzAH7%4J#oRGv?Og;b$mETf6l`#R{x3>!XRpv!r1?|@U6rg zgoF3jV_PocS*IN(Y6_N$l4zKc9>DWd$WGO4STZ2;f%GD_11TaUwYvP-WB?CO~!Dt z>GD-HTtmC|56`tp5E`a{*K3z`?dfp8C8yab+0&)wg$14}#O|+n`O&An7n(J+uupC6 zTCa?~O2!eUUTlkSaPxlDaKD;DH4Q;5x$@3t&Xfq4l?Ot+-3LAdd=~Gx#msin#ACEQz5W8}k+w+FspYQ% z9QzJf)%=DLt~4F$5cN^Ds+99U2gC*^sG^dS(y?L&DGWj(1C?vrPn5RxY`07d_qwtP z?%kJU7W;`2v=7H21U)sZ_CcXdy*mxor;4jB?8Mm@qg*~)4}W_4(yQjnlU6qi$u?MC z;QTq6m~bPJ!gz^aKRzNJ5`l)bjzyKG;klouP3^zuVq0jdr=# zKRYs{gZ}s>W=}*UAr14&NIw+ zFtts?ecQ*c7ROGWt&+=IKQ)^b8xn6OH+e15fr_Gx?dZZat;4-Cp4iZPEMpFNI0>l5 zD;LrkOD#)o%<>r{k2|{`UUz8Uo}NS4aP=6uKTafM|Gvp#8OP}2K)X%Fgn7d3Vj;hj zP@+?_HSvQ$IwIY%v9-Q;lqZqAz#F7Uy0YEQW+?a2P1Q|s;j=P47UcCIAhbA&3ex!u zf%2f4>mR`?^zV73S-8iaeN1S84k^`a3&~Oz_UopL@5CBvO9i_+JUk)WpAQ%~ndr1D z#MWq$HYb}IV-7=r86E%LY`(%XXh_?bS<1{Dyd?g%Fj1iqEx|ZLp=Wegs@)TLcdgfw zch=JMBjL=`W#5nr3jC7-LZO)MWd>QE8;2ur1}mL>!4?vNCIRrYifW3Qv#K_ESwq8d0aJ@wBFkT1tq?_kM}C_r7{L zVl&YS+Chd^63Q(kSsS@d-{v<}qB_66Y;@TPj%j;E5y;m4u@3IP?V(c^IBHd0$w;fN z0lU6do5S%dAk2!d9@5Z4qc>A|qDZOIu1eeDs3=^2k^>1^s*mcK33|UARP%6QC_Uhw z-`SWt#p9a;BcoEK`m0g{x}s(|4yWDUi4pn@$_}7R$<^72(KIb?0vKn$7lk-p2AxXL z%p>u*sUz}O+9NJnK*OFjRmP(ar(CFl0ZD z8Zz9u9kP5pl8Ho3%G}F)>glIjdcnr!SCK;H7^LF7$62S?RM_*hOvu|=#3nej zFWyZ3CC&9~rmW-odky6H1ztY*B#$h#0_)5*e~h#H${GxOFxlIi+oTpdDpC zI2M=V@aL2={p^p)VV&b(HMU07ndH>>cA|{R93vZey*c#Y-o^gYh8;YI*PdwxaqL{}>)T$r{e)SY_iH)5?py>Lf#dR6#s)=7N#%>- zeep$zu-5kWx?a}|`|7hkOYXaCL^!0O^jal(gj4f{iUZw6&7DgD`y-%HC4u`kVJEJP zX%BVW{MK!^7ZJ`orQ_azz1cHCj-T+`7Wr~UzMha@`zie9C7h-zws|SEXb6!238cuF zp4tDH+CbxwXEXAldTgkdov#K2&>Mf8S|Fv zVRsVk+W7Le2&C%#?!7g&F#(ISdU?2!BFd<|{NomqUgca3gk3@bj?NcXAtn`YVnC92 zduf}w-#6;83qlLJ{o+YR?(cf_S}!bkERQ6RZY7b-eLacq)ySac?Osa?=?hv6sWo{7 zAJdSgQ5|e8Df)G6 zspWjiN5{DczQbbn4XRu3ZS!`ZB;ZeYG5`2wi;HWQ(Ed+Zqye*B zr<_ZY<9=4`=ueG7vQ#z5riMtDFld;EMP02EQTDK!_cxM4H+2z)5AKK1;2oFZgcYmt zt@TOF_4d#`?X5beh8{3U_OU?MBunN?hsRzJdT-j=RVy{V-nlyGm-K=mpSA`IJMCuA zPJN;oCx1kU;+V$S&Ei6;LA{4ec$_Ep=TV*96Y%K8xQNKb`?6gjnTL;YGzQwPOnqD? zVf}xcdc1SO-f+1I#cSzVwq4e)^{h|+*3SWx5Y1~oB26E2=J*O$`)`ng1VsdLK(r?p zM@a~B_{|``NIz7u%x1`zRix&imUAw(G6?k2{UF7E#v{N}8878PsYc?b4tEE+Cy_>^ z`p>~8g{^{K%e=FnC|2&XuKdqI{_}svYUDtThfUjYlm6M15gf&*gz!dAD|uv^zq`Ln z?JR@QPMXRQ@jR-4P;z;5Ail^hD-$)yvCz_iic^3@0s%6dIU8DBQURPUy6t;h=MU6s z1x6w|Krz*qFmwFMFzCd!+Y&4v*dyZMR)sb}cv3LY5XCa`bz(V`yjWH!sbrW@euF{)ZrAVu*9bn16FZ50dylaTd85#NLmlbgq*7cfg@2m6g})KRyepWKDx z+FooDlbQ9{@Ise&#hljkr@9bOF)(#I`*3l^{-UH{C&vN@@mR`Q4bWBR5L9PEwd-YfGMa4Trb&L z;u^!6a?GNdHGcF!hBgQq`1M}JiCdW-CXZw~z)csBxUs?f(6p`w z^V#CxwiVTiWKOionk3Vl$vhWDpgF}9H|56kG>W3?8BmX79l2}_Yh}!jPs-OhHWeE; zl{Cy;PiSiD$JqdkHT>V}(q0J!_eDFogE9zYLkCM5OAM3;A%K5PIVUdbSh0Ch&O*HZ z;9^G0CZe14bW@2me2z1|igL?d@_n>z+Cnx0`O&1`t}V@V8ZRSz3GIhmO0JjJCZCIr zCr+zhaxJ>{c5j!qYR1?`rg=K=`d(pddyc8W*)c^&FWyNNwG;f*A$c8{|DE8uYaq~? z=Ioe<8w~POmyf+yaD4-T=9E>`$w49ZqfWFml6@lWQ{V_?2IpO%-cDR-bWTW@Vtmcz z`ZWj8hL4`APl}BX%MLf&V%kZYisl(?ojc_!Q!w^HXZizdY@!!j@)T{D*xM*)ShlT1 zm5yL3#VgRnT$6?X4*O6yg6qP`x}CqH)jyz@t43T#1e)N4fyTikYKqF_W)xZU`=T?O z<)F(ZAw-p3IIK!?nYhJry6Xdn9QbH!iC()-ph0{ZCk~}$$f1wP?tWpShEKyiW?%1+ zR&NCN7+pv>7K%t; zpAH8G%$>%~c^ypp!9>0Fp+%8Tu^*|!#&k3eePluy zrDa;jDJI{+ZzGl4LU>KAjotdvfVfPUU0*ViZZQy-hwKd7j`hU)k3P~HoB{4DAQ@N3 zMd;8gwNlpMvv{dtZsQr^n#Sknrd~2$syq6#8u2 z1R<%k7aEt;?e?PK`oMm(slM}O^9}3w%UudZc^ol_n>%2ANxg7Lq-*fy9-dU{b9~{Z z&Y`~7)BWq}2ZP(xUp96K6g7DARgQ2k_uu^A>3jNe(>|Q*Gi-L?Y<$HvXsvuImN*>O zwNBSY9>pe3$bSs-k;fq!;EIgw5|Tn=>kVfN(y*(!{VQ=!rnV)>=}9p6<+L->|Bd%d zr`>O-jA2G8(`opQ`${(Q9ggTxb_5cwX0W_5qZ8f&fa& zOYu!eT_X&y7UwvwGxIHI_0QV|#6JA$td?6wxa@A8llXG^2M<#8J7vK=i0ncT0B_&= zJ%RMk2?}#?-%tBtbDaAwuair7qOgulvq1vr*B6E!{wrbmFLE&X8-rnGNndmlNAb+G z*TLa_!8iJqm4t^WJ>Zr#_QQTZ82$6k0~9k(Y=F;fW;W$mK(Y)JzC7#9i%)yTourQ$ zy7Ubo@N5{B|xp(}dvsLp_fAv})0GmDql8oMI)ZyaNv`Nh8( zjsDqhl5DGvey<_|t&@bD^mYdY7wU2bAN*6gaPGggU0lgmgxLKal>c+s6LSJwuhRrE zRCeHK0#pd{&U;MAdn6#z;%C zuL?SifE;U#!khk_#`qWW2h|$5q%W<94Jk+YmGOCtW5J0oFj?m`C1Jc;HdfupKpSEW z(Q#_ezr=k3{QqAi4T+$bR*BZqjZU5{G2t-G3(^4}-zT;IIlD*vO%R$mx-TsrEqB(# z`2?`1@VBxret`P_d6)dZIPEKPPD2j#sq|8Mhff^JqXqLuXUl*x3#uL`Ccp|1%SH0DI3=xRnyID~^4&67S!fxPBl$hA$-{v+ zYx-SzJ-lreVk65s+EC-YHRn5;XQn?r;J9|}o-^y`{PsWZRiP*aUL^z+`o_5N!+Eal zFAZ9rw+xSYAM4Da8~8{exa}f_?EgMK{I2L|6~5V}gMpR=B8Ilulw5M|4Z@4|STl>e zEf>Po;h=J{^1nC;=p95b00I*)iJa}(zM%ghO`BOVf@kVu*0*Z^Sz}0i^Uroq;#%Kq z(}vhjHsj0kQ_&@bXusIiM-s zJZDrVt*OQ#Api6arw#20-x*S6YNG5LRLGMJBNCL_a^9|;76T-s^P-i`GY7C zeDVm1gU5^a%JPFuFF;=B_{`ve2xanONb`rS5$LqEb4u4QM`vyFNNVt1%;ZZ(b;%2& zP^t6~9}uM1u4JAhWDrimI?1h%^dn{0=gC^YK}GU|KOkK;_R14YUq+rSovrBb`2c_5 zuu0wR!`D8MX-*OA_a~!ey*P{wlK4El)yW>W29mOE zX!D~0Pox9RN|o8xnRX9J0C4fmG+O6+T7~GNS$EXo<|q2{hrezvBgZZ=AE@ZJf-9DB zR??@Fd=U>ZejNtB=;wov6=)(lGdnnOkAF5aXTBtoD|k9iJO%f84t*wX>mUir2DbNw zr!{&{^g0vl#MwKBR8P#1uXQA}Hx*TGe%u?U<=%Zt8wQkM5hwv0)W62qX2Z2@A5})i z098aS)A-L`kduM)G7+9t+_5pqAaE6>w{NSlmbqN zF05(4Y-kllF}6pr2pVXt=2vZBXoj?=e!NyQF2WLK!{#}dE>qz~q@{V_^619@(RRw6 zX>7Ne9#m;jm4)hbTgp42slyGeW?a@1GW-|ByLvwzu4KMdTjS`)$E)ByLi~*I7;z z6WtjB)%uOafsa|e1c7$KJQ}t3u!nL^nyE=b0%SiMUpmN=l`=$%0(-HJeoCEeCWlRjYl2fQ~k2@50 zjC_z}m|mxY>6K>fj9(bpT;kS;!BoLB3fB%cZHRf#M%LLW2K8b;g8!Gy-a<1*mYe+h zH;!`Jq^FT~y?q69@P(pgk+5eOL9 zr!aooiJ5aSz9`LRf=lI@!S2*+Z|EBw8d|&{?(a)tL!vftsfvtc1!CJ4kcxBTYTnZA z2AHM!r-LoSX=QfP7?HuL=mc@ss2RVIrnnThq~ft-#F#kTTOk zXo|e+hgAZg%-3`Mz-Rq@l#t(u3X}bkT|!t}cjOt^At^7%MwjLZSA_5N?p%trDS2O1 zAqIghArJO0oCNj6IlUW48>sRDI@?%*&uXqC<*ymcx^@sOCSQg=PPS~a{j@y|Evct1 zSiE;PXhnbnoZCwOu#EO(fu5C&v0;xXUMC$3vn?x`3OAju+ z^Uj^kbUW9?U#JsYegBfzJk2V|lVB4YKh019@=zHK+fE$aBCqRK1&&Cr`2beZ8ja<%ehi zOIk4gY1&t(rbS$X0s1%g-gQ(ht|~GtXZVcGGZwHeGV=9LYD{5{>XThft?k%JIe8($ z-P!Bj9R|KRr3w$fyuMb|gsjT4R&P(ibK}x&E9K9Iy36Nl#Iwq;apI`_N5m1MmgM{d z{X}{cu(>I$`TToHg`7BsyL(@L&#NxGcMmNFBRkbmN&yMpw_SuAGo ziY|P_+1hZ3Ay?=w`;0;4uQohA3y z03)K_9=JW}ti7ILzdZ9dJf5WB6+&$1va!W70tVy!Tx_T6$t5jPP;eXil6stj%}lFb z2+=l^m7X>rUl#ga5UT!^MI_1bs@f;nhMob{2o?Ru{g{#g89q%AD8FU?`SllUViOeF zV6+O70*5Xp9WiR%HLG`Co#mgfWj)BK$jsHu4XzoIG;>t-iTAH~`{70kyxss)daV&A z@5_Az1d~5&mzS?C$)aU6LDhdlcv_Pl$BgRG9w49%3^mq#9+DA2utb&hK!$`L@AIi) z5v;9QeX-QIgx$bJ>_qW{YzCR|RhJWa?&Go#`WIQh>jnM8m2&cj1$O}T68gha5R)rE zig_f$YE*cg)xANg(1qgBD(j`5<0K9rt%E>q&iChU3Wl+++r6{&ohnF_zS7+=TL5K& zOBV-OoJmy_o%ZdOi3+MkHW&L^<+L(d4}>Hss1~q3xb(F$x^rm>6Rtf~KyeoU&Ah5B zCdvQH!G${oA=aj}DDT^A4O*`0VC2rrNE@{5`%k&+oau%<$yzCqd^)cJx^!s>K0QfT zrm0S@h`}i{Ufsf)BKqa-3zXJ8hr_ISBH||6>@+z~a{qW2SN7~~mcRRG3P}~hybhUe zj~^1g^V^$(C&jB#fjMn}oB6OT+39g}!`2Ayr`EQfi{nnpW}SiKTbbnEW<0Xnm@>9A z#gE^@K9JWWEXU2L&scqFu?SiJxoa}I`2soFdaP9+6ELSg%#AyhIqc6Ei>>3z9450q z8TrY-M7bUZ^QC&%lvc0?VS>z;M`H##TQ0w}fiSuvcYGltSXv z*K1uWRuzbZ%#PVoR5D%$MvAuTlZ}W|2s!-|iey?c(!%4vA;cQhSG+}r^6da^sNjy4&cEV&)QKg3O$|ZEEX=wRPJSO!Yi4 zIyN{e=IB`zR=W|t^)Kz{JuEgM=~g32o{Ep>&}oFZPv=W%N*U5<(Y^A$9RuL7IRs8= z{pVdbbe_R;KY57t)2!}RwIN(R@2-3k4a^Vi?(K2q-kk1Ylb{f+t9rnrf@Vl?=}1TH zAZ6Glx~@cTuxiVChh5JN3@~%$0lE4m?vE2yOgv^~+UZI|O}^J~y`LYjo6oig{*)HX zc)p*3#d%NhDx^2?yeVgOsWX!LSEj!<$Z(G3Qo?Y_&_mmmS|QsMYz$42J#ULoG`e)7 zcx2M1D*{sLA2GQWkiPE{PCq^ZOvbTQlQCLJR{wgFwXU%A`u*k)F51Wk1nVwi_Z^T+ zO_7BfN|)#YEH&T$WwnEB1k34!_isDiI$*r4+EHu$tegd zkw}+mlQZl|cfjL1hwv7Ou<0IW^!oDSFO!T%q{Q|*^gkNq*I+9`$Oqr zw5dw7Wvm##)p0RCXPW~H0afu|GfPx~qVPE&8;goIn!X|&MK!ZPsHH2q#zshywho4?3?u}6DHk0k`z=&GbRR(Ks3Ub z1W7aQ^I=BGL|Gl%<9d0~?D7(YZ`1D94r(thsLd33&#kd#pYxV0d|vr)4uQ3Z-?8#2 zY7P$`BF`PU_M<+0q|@H`guqC(3Mk= z#A6WWvn~06SVjwH(CShlXhD04K|`bEjQ^%K#z1ZHh4s>6EWP2L%m)RbD@(}F?gXq@ zPQYqw^es*f<2D!7@+%m#z$L*tBE9F|P>R}ui7 zf=ASVmL3v>7N`-fMY1%ruOl8dcc0d^G4$`T0R`AdQcDbguG4K}I!$2D6=}N^ zkGh7ILY&zPwABG#*rFhGXZMD03LNBZu3&b_`jIy+?@yTS*J?DF?sF^)7#yRRv@O~L zn{gA}p}>^$cAR4JTf4bMaNTw6Jt(8pA2sJg$qL+K z^fnT7uK(5L`%`svSyYP7z^C7Cav-Zf0G1Dn<@E(Ip zK>nXFxs{pw+SfzL&C#YFT-nFvYqwOu3Ok4y7GiwI$t>rvAj=nAACW~@Fo zMrj+$Dg$a<`>No{JR9kVQ}FVH4i%QWcjj)jsK(nd?jZ0UWk;1!pyWt^j>*W^J``#$2RpN^l*7#M)(+0!7xmX* zSkbmbg&G1PvOe=}#=t-h;nF42<%pnPs=uuCW1aD!YF8U zsbWB9{z$$r@>Lm_u@2f*Vc;9>0K^t*tbitZB#7{OB(k5s3zi5+>Qlh7sB6l zx1N2lWxR~JWJ(|+o>OBVWDEn+o9;W|xhr*^2JF^aj@zJ#mFy1?iw}#mS7d*nSgebE zEb**9$m6bNzZ_@R;t~YxCPFBB(JUYm{+qb82mr)bjb{3rl&Ct8Hu}>RpvBS58 zDn6~CI@X(D1vndV!|&d_YX(Z*)~Z}vwlaz>Nf!WC+uzL>eZe z+?W6BmUm)kp%e_ejn*BU^be*W*vM6aBmhA?zD{_P<^u{XDf_n@e9=M%hTR}!&qBKp zH`taZ+pMyK&hjg`Hc>w$?ECQ(p|_~A35fgv5L+w|8%PW!BH?b0=jh$(K{&IwDd6L~ z4*R`l@Zv9!A1By=36)DH{0eA)UC)NX7C^6e_!YLm*qb0?=;G)5o5{^F8O?>IRRQWY zN7#5IiP#p1Y3cAszFv`3mrpsRYlAg}mOXfz7I1V8$^@XfZ-iNaf`e;FxBB|HaT>bD zeXaP=OK3cNEu?5YxF_K|$&5V)nSW86AHf9|Fv8py~*icSu=(08r#&cI>HY zl^75Z2*BI<&*o<>_48yu{Y-AKcRliEMccdPx3(|{PcvYoyqMGCdtUgN>AoM}B~ zL#>v*I0XeW8Kv6=G@EjmgHd}Ktm(2et9VPl5SLvyvyko_Gqmi*{*BrgeW2Mt>@NJ( zvqhWaaFoB-8uFISY)@7i$E*>{UKg-u+M}-E)$;YY%^fwMCw@COE=BRf7(4+S6MAHZ zbvz=q7d;)XzsdbTU~j)kLKdOpZ4tkvS83mdA>!fW8gqcp1IPDmkPznpfAJF|MD<$a zO)J8%&rRgTx890hx(NguzH_pdUT?Nhe{dA?l#Q|HJS+*cL`Xa_FFpI0hMgee_yf-y zlAB{Qz!}8_1m70IWa`*pn`FR3Xo(J6$0i9C>wAW}wr3Ms(_pW0C&vh~Oy4~?DNXZZ zmRlY?gvYGs0V&oW+viV6z8G4Ql0J>+nAS|px&cOWI`59|t(8}k-gT=V&0c4$xN$`l zRxHA?>Tb0f`pjV4O5Wk*3X1WGSju1&GtP9a84@;NdtSQhxbaAqdZW8~S%d$@mpP^f zP&x}BaJv4tGJ$MASkqu8j?JBWx$y8X|3~qs5eIj(OOd^#=-WxZrd!?t&jlL~czao{ z5TU(Y^aF5k!XNPCo1=Xl?Jdz;1xY~oHdYi!?c%cTQGo-w2okzpe$itc@Ie;cip)$| z1PZ6}_X>xqR=VQpHJFv>UwM4<$EtN=*BC~|qMKLuK{*p}AecZ;f^*{U`p;QWowgt| z6rIMM{K9wa*g|Wd)j(Ho8weM#kdKH$ft4CzvhCAcuvkUeJOCr?z=#Xw=jIvLy@(Pr zzzc7>>#Tt|-q>;x5Dxs%)W2c&*RttGbF)I{oP3_E52;*d!k38Vr=SZE&FEcJ)r`(x9p7Cbx$JKwm+&-sa*l{|u~NRUwvTd-r$jdM9f8(nR=T8K2~aasFuG zS!+KQ*O0?a{hahUS86mm{m$-R0ghcGt9Lu(=Xw$_-nfo0?oO6gpL{Y^D#m!tW-`>@ z`}jSYMfGOztCrRU@ck*wp9Z^jgL*iul1QTG?Y+l7PZYkq^$S}W)d`Y|tQ*`Jl7!jP z60`NHgqHlIl0^LT_2L4;z=rS>#X01DW{kOe)A}N|U>kSaMyWvfb+5tV_}rl^a#yoS zB5`6p*`vI)|D#F#u#qwTcfIq(UX^%KckalaPETsSt+(?-*+s5rY`>&3Gp;wJ_ijDg zR;zsrx$4ohN4pP9tLa1T_=&rf9J;WAjHx3#&th zIlXp-)0u2bXZo=!QJC7m+H+4<^m(wxNi@*Fp|`&;=#TsrPq;qO{Fbjc&(*~a5E;v& ztol>#i_(s5dhyMEUf!gud3JSg+6b;k(py(8$Fa!(z_JpZu&R(LFL@kgO{f+8)Sd@A zzAxPa6Fn=hVW`7L`Qg&Jif+(5Y&sDx$Ya@?j*~@cBlS3+NSn%#vO-x=b&!zTo@U1F z@-u(Q4Y069+qkV%%P%EtMIW~~(+#nSSspi4#LkRj&NM_Qb7jxDo;sH*ylU8{CVAMl zb<>J@F#utN;0p(qgQ6s)fj+Y*4c0Vq7zFh%LN};MujXEJVpGNB-s38fFWvd~K5HjW zO8E6MLKb%2sXD2cv##;x-y3+zag@9}#4RRs>YLX~(G7RAz0B{X{!X>1&aN`De+{9$ z%6_feVi z5^%j9Jl3(j52gFs3f{#Huzs2{_gk7OPN!UZ`WyPDfkeOi{6e^RRV`! zK|Z$b^W5n@p6;{+?#p&+x)yhAM9#9^z0;}iaEds*DL#bf?>C#g`G$~%(e8~7!6h7; z(da)t+qtTO8%~>6)t8eScc*G4G5Yp{EzSUBV_ZR&W?RLX4*8*vf>>dOY=;kHft5;n z(q%Wa_TfZX66eX>-L?+>Z~oTa2#-CHvVl0n7^@Mgi~jb--|^cR{B0`=y$|4AZ056s|f-)wQ=+JQxadej_A|Ankt(YDRc zFO@Rn0xLSR)^P7TJ7c_|te4wz!<7n1@wTt+78s<-*@|~~({-(4H4w`j&#~e(($boO z%J!G93$X1kOA4?>OUH}mIG!_PK3=R)Oz9oZL7jBM-au-)O@!lZF@XuRYwo;}780nO zv5gB4AU+yw=BtI7I``$MB5oPIN#8!jZ*7pr^68zx4+^b@D}Pb@fU08%+sVoTW?6`V z@+Sw%o%N&FabWc9VpO2Fm1%5HM#7@)H;8knBHEop`W(-3*x`id6z(g}g5vN}=;uz4 z80iuZ88JcgRXzFEK_$! z746KkL()9{UcUjc5!>{wauqqVy)7JYYeL_&wp|y7q9CA=BQCX{J6j43=*vnAUR2>T z4gyv!;-YVx(v=3&ka!{W?0}~KMjgN^wt~ay52d(rC7>)E4|3}InCiDN>WhkC=u8f^ z+f^C+AGR|JpFTI@{3Bczc>p-SBs5n1(O)c0fHo=f8v|sJqmN0;xD){p1kh!P&1%=M zB`D~h0QMJ5(rpcGodlHQ^&v-~M|JnB z!*9B5SIlid3*EC{p5*SBniQB3y;Jonpu-qqUEOScw2Ry;>E%VOn>5&xa@qf`F|{3A z;$uHCJ0+!d|UG0EK#nzNl(4O`0mvWA@N-$@A(=(!il zi}0~|ZPG@_oBldk%d(ZEdf+J=MLALIU5$rE?-jyIwH;|}nKfm!z7yNv7(8lYX)wA! zz*&kU1+_?#)1hWJDnCrC1j9qS)au~1N7GCXZ%s%rvaGc6S81xeCENNAo!FY~RsNDa zHSKx9UmCH01m*gHoa$_uAucg;MAC`=j?soMsL3%V09kNFG79Jx>X6P%v9=7QyzG+MNS1EP9^tECo(R2NA-! zmpYniTbyJpy<;zsNVc*{gC`WlN!K)n=xX$v>B$}hrP=^tD!i&5P**l`xv9RU&Tld2 zowIgt4|Ao<(}^IEA>HGiim%WWyqbJuq|v<1V?@AtX^UqCj{@_^h4 z=?zoug&EhDm%r)n|-p~55cfuxt zx-X!&3go+sI#D4gGSfRJazba)x`w!d&I6>Qz7|#15O0~2DpM|akzTN^uh&8#qukNh z_KxNIph-d*o+<}s+a#;>8}<4o+hH`X$w=Ql<8ZjV=9iAxYHLKsGc-z~C7X)Q_RvWH zuKHn9_DN;*MQ6Q|SUvx^Pj}p$_1;t4DzC@O*lf7CdKq?DUwdESjxF_1nSE2vdDEEZ z7B7DgR_u{QuzPe+9N-?B9|Wn%>2FTpnFXhRx4b}CF6Uymr{{=7dkH@dDN!n&CbC9! z_x!^HDHf^waY8r5nZ4Y9BaOUA06eL>pZ2Vx>|)}~^RWHmg1r~@{7hM(L7Z?isy(g3K}M&r z3-4idg%lIilf6E<{>edwz#Xf-It!B&Ilxsq0LW6N!?K;+pod6@zv`Ioonf~jK@{pq z;OW#{{mP^iWIZqUvI!`5`MT@wyj^c>j}^#(Hmo2yKUPI9gE99TK(<=V-Z<0iVQw*A zwKrXOma}Iw@^Wt~P_=EqD_6=`HX;ktUCSE;;4_~j%v(ZO=0&|_3rYKPGUE`?O@{{nX^ZXW=3QIvY>^W(tK#shR1C_1K!l3enO9-wR8%!#G1gU57}^-z z`_NKmiL&C+{!mWQx2(>#B`UhZ8hTk^X70QEL1tS(I}E>D1wLN|2})q~^iJ$gwA zG#@(Jlt$=x@vrfo9~Pf$Ya@hsw7ufKaVt(C)b{jWDLDM1Vt$9|>4TJ!BML2G0~uJx-Cm%fxh+7p z1gK>4>57%=OC#awiJ~4Qt#YOgJk$S|nRq8gd(>^}lX8Igzs=G3*p9)sV78<%!vPa+ z-W;!_Kc?FE&UsKlAfg z?u(3Rd60(RMRTS3Ot+mUWy4-lisn?0>ZBLMsEAu2;uO;W^4>C?tCJ&4-Vc(-z5^v= zeKCc^3cbW)*tteCbw>^L_bkc4u~$;l&kF!NH&ZeYR*;evHwioAtXgL?`H-8f%IWb> z#yVoSpL#0gWI6}? zJ>Aa5z2q)Vl<}05q{!{Y=r@=5Ik=_^)&$nfir8I-Gm5=XcX1&K!%|(4#pL^lh3mc* z?Af|W!D=FPV4g~tC~<3kx}$1-V6L$?d(N+uwd{#`d^HfpZep@EuAuUloSH4B8^46H z14z8cmG(-Wg47`|kzPfndTv-oF6fA}Modh|RrRiTH$-EMqUnfA@bv1cb=3U;Jz^G;wwO1>8NW!_k2&m)fCBaVcX0>0FtI_A#{0aK-4~5z zNKn{J1q^dH{-6QUL@Ks86e1+ABMNvpP}g)`B4z4hI5y-#H}J;B%ns4DmGltJ|Lu?{ zcYoLKRfxpR2`zMhl52XRJIH}KNGiJ8^MSPC;KS#CAYJdVL@C+o5}m>A@<)PfGzLP3 zQWZ_(W~-AzB%_bQ8+s!AVSn}>OrCGP_xdH}xr^PbEdigZ2=nar@$RZ~QlBxV$vGg~ zZX)}DvsQ2{X4cvD>j?&@1MG>uM?4#+&hrI7&1d<&zF;_d=xex6v(O4Q{RmX%RqsWFqDs%iUvXs2Z7%lwplW3t)->G~>M{jU6=tV59ZCM6Cv zfPUOWJcN48o29&Lieg&rwIcUScKd5zy1HX542B=rV9p;x1R8UH-Q42;ZBp&W`rCw= zZbHXZOpg(pW}(PvY4{0pY2$sIG(dproCr?iZK{Y40;N6Z)Vx30##Ab8jouRt`OV0* zLWU2eMuf1jm+V^s9cSv5%)j#m2&HuQxxxPPbhWzY^&VjSOUiX|-AY`sYde)3WUpcA zQA_@vW5SII7?Kvl<kd57{1f zkoz#ZPzS&k3Q+3*`)6maOMD?Mv(@M?93*~EQutrYdVWeCd3NW4ru5+^mup|p%0M=F zGl1k$^EN%qkI}>XZjv?BY{zfs`9*(0yH6w`_3XT|&w*zkn-`whdTvFHbJPn}*>SGF z`9zK0^{Ig^;4XP#!B`f!T-KgHC0iFUco4W#)$3&d5YUlbMZ8TRxV5il-_F`vD)-{7YO?f%YgS^Gm7*0RI0b@QK>*D>MfcH}N_N zxE%!aIRR)F2UOR84Z=N+UOa8+bojr~>1{{7QeuFY4)jv9Zy4>v6$VPa24;nq*9OGc z^a0O5Sq#1+CTnD(^d+U#&eb#=-MjqhzZ-@FCDO~7{%i8=yZ93HzhBzt2LR+Tz<-Ow zv_%?@c1U=!7dZ^h*%5q~R-gK#|5Bp1XI}jS$q@VW%#O(EDTVxFE^GJXtRV^ic4o^5tJgc1^WZ6fFXQDd@MetX ztv&?w&l-HHrYq$Ds8^P|9P9?`07X#?ZyBt;LEEpb-f-rE>NtX0M;&V9y*Cj1LTl+0 zQmq88cCC5AB(6Ih(9@y684Z4f0S^kCF8(Va1T0|8M9u_OS!=8>l$R({i1eH3$F&bi zS?kNWnJcmJVXo#%)cEVrduacbB8eckq#FPO z?hLPT&N|A=3jRjv6IA1IX~>z@b!o;X>`>mD2n~9-_qOZx$Dhl#T(@WH`5gbP-}tLn zOnyx*o_2YxN43vedssk_JFFctUYGgS>eL0w%w9d(tRh4Fj&rA=k&)j`4bNBk2 zhg=`rdA#PtrCWKcHvJ}-d3vAlI>|@BNS^-v_1^Vbk|ui5cPetM47L=KXHpsMos%C_ z%HxKe>RUi#%wW~}=o3NnlVvaGC+h+kS0(o!1=_=nR9stPzfm$z5m|bVa6Z-I)#Y+! zNrPQly`(iD%$E}hTg7)9_{qs)@#j)5gFQVjj^M$uRBI9Bo;{M0z}4;c7Cq`3eCoxo zhjvUVMc~Kpu!K3kJd!Py=6m!6`0<^sf3{!k=q5oB7~zbT1!+F-F}Yv?)PVwhOpVDG zeFEx(hy<4mvM%?C+5N?}rzY}YVeBOkcWJI`4l%QR5OQZDqV2dai~kha!JhBbW#H%V zZP<;&Pz#Zrh#p11lx%ilBlyA{-WT(Ch+B7=WA=Clyxh1Z%cm)QPJKL{yO#6InyiX7 z!0*tNQA{i5gX+xSMXzs`v4exS7SR*oz%#q+e0=%ud3{(?Cc?BRT(`kK(o zA$dzA{89jQNrSm`*~P*B*(Kl3OTh2r_|Lx&Rl-ik&pwe=RLt?B%4##EB5@CX1GvkP zpC9qL{;B7uBP~Dn%=a>USK=B0q%0`yV19j$m&hNPJ-}y{p9|&t&Hl?GJ3PRMuv4b&?hcm#N%oEwIey3bE9uQtNG=#pg0p!kK(3vhG5_bmS5Q9yCeP6L;mZt<3AIf&u=_V z<%H)nG=Oi4AQ_W^`tV3^sOzwfEQt9))@4~vzWYSVqek#!>Z=Iy%d=}6oezq2DI{KzEzl&w2sx9v<^b1OUfiR|wEQir~t z`gdos&K1GhZgfno=p7+lgNRkbA{xP+KRr-T+OVS9#M1`v7j&WK=S>+29C2GI2Z^pk z%_6Mm)_Wm6DKpdBelh`5l7XHBB9^88acac{$!_6~G>hvk$D{%;j;T#om~>u=mllU5 zYW&-TBwcBXs^Bs1piZBe3lK7K!`MaYq{sfgwQ_m~O^*G(+odIbV1`aEEM}-=8cjY# zo2YZMa1#e9w?}f@OlWL)-BXMz^nDe`!@0C>6`e~%YUup{v7WI_uJZTW3QFz8#?TN0s z3#O0Cjwr#HE_%{n{)$jX#_wgm%njbtZ>PNPtPf&(nvlk}{#2H5x8y(@x`8o#iXTcc zh17`$b-9JiLDbt>z=?WunNm@^ttD+nJZ?a*?ZY5t6X=C3%mYV!A?XOhc?0cFF=|Ul z{7kkN6_CcyVt8TavKVgeQ%%1CcJJp~n1!vykI4f}cN= zXAHCdm6jbUIw@ z$UNE=&6$Y4N&PX2`p|lk}N~D4-Z7!o0Au82-#7Eo9`4 z&xeQg4ig_|4QPH?m+tjSA#Y7(LAYhf#l`x*&4Rbo3(d6==QJJ!uWIeY7f7zr{`M_j@PFm6Cdm(eT z_Q?3Lf;pJqHgVfpo&HX3R^$Jc$< z%~@IMVdP2QC1y!9vtSk9sdWZ!6}5J$3)glrfY-VY!Ni#L&t$)9(G#wSHDTFWzy4EO zZDV8vrJ=CE!&AVtYKFq@vd8NV*Gcp7?cSyQ9(Du#GxZLZ#RnSUqs+wiuj0GjLtc~W zx+z+OH|!nZIK~F$n_sL@InS#utl zZ2$WApP4<}l?m8VsKpWu&@9>`RcCrdcF7Ti`S^a5K1dSw{q^etzr_MzFXF%mLRW;3 z?`0?y^0;pj5dIQ-zt_uK{cl6%i5(TV0Q_GO`Ah=74iFB6VhQP|W)t`RWuU+YzEeiY zR#?3bVCC(1XV^tN(*u}Pq&5n|v$1*07+_zgiUl8EY%8Aa?rO)!cL{{(hpaH|_jRHC ze7o~?i%7X+fDn$o4CMBGHuvA#<*eVyVn>1faB}6!%K=AqT%wbPUSZR{hz-B+Juu1b zgBZ^MmdWRRT?p-G=Ck|GjNmrD>)A4uA*m_A20z?PW?KK$@LM4i8JAY^U63@Uq4NU) z2~hH~!!myYS#VcY-Xz=v4`_W=kWwH-z!N^c{RuzW`R`B}Sa#)2`T>1yllZ#xVgq$W zGmf6F2oj>;P}yu<93^+eNO8*10(@^TovR87 z_~na0DC-%)cnI<=4@=96d_6lx^BD8ieV9aH*=i&6`UY_H4Y}z*Ya1wk1ctDFBV&W2 z62{tBS6&Ym z{|o3YkF_)*&|GUHCA6o@D_$0gv*qL4``Z9}c-@!Fm@>?RX24?zmjS^RLB6^hEKtii zm#hIpY^3)$DZkd%jt($J>kfLEJz+21j})>2ZI>_6(>yyRcGgnh(CVjkk|OJ!23zH zk{lH@T5wz*D!MPID75rOrwt5QDBQZAkI#6oJr=h&6|JXI9(}(hJ9m(N*cKDt~F6!OF? zwW7)+F7k*=>%)-FQPiFqyryH~lBzy4f9W)3w>4$Ekrf4V1EeNE>U&h{4=_clMu>d4uKFxc7HgiRpho&xmx z%fp0R$6H8LH&L}L2&1ba{j??1N_@t8!zNHkTw!@PUTcs;rfp`rmY`3aDXJu{eM5sAnlk)d|QO_C90eFMoWR9B1&6NKO{NE1A|b&fgf9hdsb3bXEl^F zX94AP1-MIYdsF*2?I@c2)m%tNAgeDWUp+tOq#}Kw$*zljLU)5!Z+!JlV>ermeBF{c z7E-@(PJlJ2ej&FbgK{gw-^~|32Gay`r+xYaM>F=w0t{LA#`(OKzdJ*P`|86E!7PmlE4M&e1O@&*5h<8eF%vZkT3fbj{fd%>fmM~+H)BF~nSzlzX z77`tEGRHqVW#7?9fHhR^E+mD-bkNp;O!;bRos6J*bZK+_3mJpwg+LM9y!uRa8OV}@ zt9W%t*o+0{V4hh%;e2J^IK?=P9IuoEDviWdY2I!il849C+U?w;W*rpC&dj0Tewh9b zinn{>Qh?6PXy@r0(!sL>hdcb6uf=Yx>@rQ^UQ3(XkWfcfq<5d}W$i@H^l}F?kiFbL z?h=iiY{#bjUI`$}md+(7sz34;yi>Tk`lE&_A79KJXD%z^s-2XgDb0N>b#(Z5Cr{Mi z;}<=Qb5P}_hm?woW*-tZDV)4=w) z`Cry*MjAWK$;=UaITiv}f=5^LJ#si(9>O^%Um~qoIYHW69v0X)cOld`#(h%b;h-Cq z93gVj-Na>MI(?mV5m`wVW?K>?S9Wzo9_&7RP}ICL{={T8fj*O^jCS{lGVaoN#Co!L zbkdq%P0@7eSzV7B8OrcV_Idn+PWj1QVV@5qUq1_ri4Ac#8+#<-nJp^zhwtldGrO6q z+VDMR(ed|N=H=!Dgb}S($&}E%tJgR1T?ZQ$k!qU9HmwKI+k~6fD!jyp8oSTF?t~NV zJX37v^m{;J6~-bscN2!Nic_(zzbz|-J+1&svBoh3XWyFCEnOefSWvq!@yIme{yHdR zHQ%Yyz1CQj8!G^-82Y6E7wo6UP0wiArA`qQlS79IeI0Rb;hU0B+x)J?t0h@P-+1Bl zve_{CgyJxD{KVx1*zw=5y^e`ts20g+aJ?2cLj_|{W6ZK5KV*f6<$?0nu;x1h(pKm_ zfcyDU-;stsSQhBRkKD!_HSjkW0C}Q1!IKzBZ3DPDNzG|6Z&jDpK&^W<9<=?yYG?sD zHrB3>6H$Paj*%k512(M%ox}7$RUJO4m+?aOlUjSofQ-W(a)j(jb3Q)L*WWJeyI_$> zyh> z<{?EftB?p)%;W*iD`*p2$HT7F3@UgS={4xF9DQ6F=klUZFM>A4O_HON>}N&y#W{Dj z)fuE#@%pd5Ntmw=_e+iPK=6VCqjz2G+FACo^gM*xha8A9bv9a zH}u1Z-Dj1)!1t4aYc)lY;TF+LZ_DJopAVR~wKr;gm^fj)UQp+S2okCY9T5|H(*VBw zjmP;FK>y(U@SN=EJ))x}b;si!>BjqkRDo!A=s#&72 z8Y)!qAZVA>KrTQT03IxuZX9qwgKz4)8lR;v>a?^VuA!nS>5+USTD9`@q}|gq#|rAQ z^hSIqJ`Av!R5Dd*gQI1exKsCLw;Zn);~tk!XGM_iRq4QkgHKoTqx1|$Oe(cA?3T*7 zF~LldSop z8}rwL;9i4QR5oI!SOSiNX%QcEv@#B7RN4_@ww@f61(ldIfIEhC6`|yXrYnft7ltIj z8w;e-X0<(@w5-Sk_CH)KAYHX@T5FyS z>1?@`pQKj0|B;HT)HK#wS47ARI+Xrk7O)Z-jbP=Y9ZH|0#yHT* zgSsQeGSyp4elg+8R55==Ek2`1S;Wq@tMGZK}s$ z($#ij?eKOF1S*X3Zur=P9dl}XH|z>J?>cFB6k9c!rB2N#@PhUz^*3iq^j*aDY@^73 zl>BcbzM{k62C`l+Jp0CrQzIrqI+#eDJP_QQ!H^aGG!jYvG+Eu@TyScU!p>fF;NQ{2 z6$3H69DouU1;k=h9(kpl)UDLS?Y!(t+~W!r-JThCD?jk||BLvHVF#`A#pg&R*Xv1U z3i9Mna}xhcP$kd*2^;(H#BxBiSxwN)WM*9V|3;SnzaClo!LEZ5KX?)=Ss)<1^LW6fmNaRXpBgg9>(V7*mKM=|JF6*|k67Es_K418M1E2p#1wQ}(E}j5JK+SG9 z@(?;_TjeGImm5@VgO~Sx<|_Q2i-J|i^Qo++Dr0K zvXZ(RCh=7`U?O1q#L}wW+|{yfS}DIesB~ej%g!$kNiZmxOM$g(lPJuXd zz+Tn)5e&n=wg|WAxqTou%3=J;t8HT-_*y_>dVl&jY>Ev;zXU8pH`wV)n7tAB=3uP z4ZHKQI{&(*zCG=n(T}@cOh|_sy`u=j{i^Cp9g>a$zEX|lpjKD{=}+u6S8JftoZlqw zNi^BsQLRgqait7i4FBk*M80>pKAH@lA1|MfPGx&_Mab--2!TW-XLbeFT>qL*Tsa5B z^BoMy$C)8Ycq&txa2i!Z+@#mr^hxL4P9)09Rp4p*apvZ}I;7pTG#h&reOL0an8xso zDhTon9sts9+T^Gi09gtQhYvPTq&7w5j7^3+*2sBOBP~U?6+hxpe2ibMkow{wu6yhC zFb(8zO|r z<`^_k`r&GM?%yWP|1B@nAqzU$pP@mluK!gOiB?eG%hejb6rP(=Y8R1TzRght=@ON4 zROqO!RCva<8{C-~j8^O2(AJ5M6$@jvPCfSnr*pE{ZCF?r__4o6fKAL70@A;v!Q4fV zlCsP-$ecb!HIHW&$+g#VhGboC*qHm2z(B@mFZMc`S7$BN865oSa59i7Pd39gFWx)^ za5oyEX~$|81*@03d#695m@*^v;iG7mD5>3FNh9ARtA4!rL`75a4)d&XQNV4aH0CRu z?YOG82eo+4@P;+rfdeYX4?|OOfwaGM*CQ`in}6}92A%Vs8Iy7~d!Ai>>Ls#$1^UXr z%mlC4QEdvOs8YcxHP#XUwTQ=)0{gC{V*kO1`r*^3C_$c67w6GSY}*eGGe_Wk;wan% z34ZF>PPKu#ox@YWvjRPgKQ{cA*~LS!&B*pC{=0_vjn;vdsyMb3|G}JkGFj|bq?rB+ z@zQVgVuTmRHsZr(d$ooDgM!9;NQH3)g~?&~WC9K4+!hTFiV9|@O3bIniI6m$ufs0c z-QO>Z;ft?Y6prVx_5g#v5#n}b*rDgT**-Xd25=MZKW1(rd+{fu9UkHkzGxsuEtTkR5f;>V zHCK0Y&ELbVoC9@tB?jl4xs=>6XA3$qyJH&imG5{kveLqXF{!H6WBlA=eoCvJG+z#c zR4+72!g|+1#J!)4Jjq~IMn|aVyg>?oJI=o(q#^1i`zR7kn^bXq~QTnivvzBFr=iqsQF!-6w9KlOI zkx}bGy{oW`Z`cN8H8l&{N(%pO^~u0X`4I8UMl#l?Y~yz2J&Y5cZ~VL)@W9nqP0XkfsO_JaIYJ4k@{nylu(Wh&hS<>SI_Ue2+}r~Nul1#W-EP8AaHo?#=a0Gf~nzL+;g0 zQ$^Xsf)~xNKv&%<2_O#B2un{j(=KMmj{*m$Sx?j(8zLOtkXSfv``tbN!MV|zyfnwq z*c~v0Y4!k*Z!mc?P7J8%UJc}t-#0GLAxW9f+}$q_yWw1p3L6g)AflED5UrV7>17(1GfNokrypAL z%N)q0;H04NyKha>)Ze-^Wsrl8GM>)Vhcj!%Dijqke7>9fHVMtMG+Y-xDum9aCT44i z!yD&@h99$N)D2lS0dnf^Ya;`GL-?!yoM<3c8fq#Y{%KZ0e_HC|tNRQwnDYnm=+%6? zJ(jsBrZs8)`4HPVLBG~?g0sdI5=$B~Ic>`jJ9rbfK}(;d78MXrGC-0J{Nd#RT{SLp ztk$^(BAy*4S^V;q>DJ16GMxR^tIUPLarZzjuF}P(eLIyOGl#m2OXAR3FeegQzgw*R zQ%YsmyCEdN7dpu!rkERE9#4Y5ZbKIrOr4{t%{u58w+;DoXb`r?h?t=Ok~w#5N-ZoP z4^pVWOh2}KUI9InES@Y&7BG4sR%LkbyEU6Ku4q7*2Y@Ep?WNI8e!n7fw7wXK?*%8U zMQkFsgYe;GxZj-AdBcr<$4lohFt#Q@s9C#AsHsUj>bA}Xw^UJ7*+Iu^JfNayq7H@P zgzZD*X1T4U$c+kv3lr;kQj7t6)hJ2!xk3O|a zY6c#onJBxjOuumW+FV8uOv+gLCax#z=Xv+2e6d2dFg9bcnCp|m61kSs?r!BQUQsuN zRdJ$+b$H|4=SKb1@$bxayTyUb_}SyU-RpN_)8|}3?{G^uz2}=$f@V{FEj-y>YK#Ga zCHBIk0dlR8z3QJvpKlwQxL6BWGHy2@S!ujSrG8*y>vA;CYVT2$Qu{gML6?5XZSvYP z^xDAi#TeBzC_Q&bxj#SyraHIa%q`~Q^9@|yGphQ6CwyF3-QUDh8PLe})x(d81q(dW znL(a5?P_UP5gugdc>ro6a>K4TmwxP344HEwqwLbM?h8r3=8AzV`5f1zBM<6B4h@W4 z`j<_*D>f0tV8ltomP|-{KiKMKSkA?Upidb?F#Q2=#yH^VaF6jOcCZif3SW1ddgpBg zW+p{&mltNCc<#-^3LX7*-#wuh(g&<*C?HnJOomwB8JrPUV<0Ygh5T&Plew zZZ)3S*6Qmy$Q~n12bykQ`>^)SRK%q4Aaa-F*`5?TzKdPwlFa8>2Mjm$Ql%@ozc+v> z%e3Tw!mOs3f@Wfh;~O5R;G5dkbB!eYh{mv83)Dx5PjG-rgVcv{bQ)0>aXJ>)<+v2|qL?prx$@v}-K2 zP0YTWr9x${;oE&U(++E!J0=z1^452hN`}pxQxlnlo50_k(sqNcI;7^RF$Dkt|7ZE2 zP*y$!aVUK0{ZY=&wmJ2uHtF!GtsLNf4B@F8uJ;O$RjQ&}>bXK8a<9>h?j~~mu%)7u{#HbNl?wxQSQzh9D8Vu?{NB;cRrN4nJ&iazx zj|ldn4kbdxUI-d>)_t^E7I;g;64EiAxB+)?0dP30XT9`B>3u;p9~*lo;S0d|d){Q! zvk!d;MqV_B04lu(U!B0@Mh9FStkc8lAa}2*1OVDo{mi5t>G_D5xjy1CDQEXEs1~n) zR0;8&*v%aSE}NxcG0Bc66M!|tC~$h_^qC!_V(5+#1FUu4hV#R3Q(vfr_%8&qZTAWz zfg4w>la_v#v~;bB9w61j=sCO=q!YaYo-&-gq;NI(75d|~CP0f&0}eOe&XVAa`8G+^ zL(kNThXeeEf;-+^mW&+avF@)(ssn?qO6&%dA@>;Fr~}W~HB3@S3RnPJ7lfdjU*%Bv zAJLRO-|pkg?goxuY%B15K&|ikzxVvd`_L*j@uIE&)3#j7mPkf}K z>uRj9f#2@-kHOfp)uBb$fV+@)Q&Gr_;XGiw(Rj7DsW_D@K)p!p-c}}|4bW>czavmS zFzU?Hk!BCg*;KL~3>>eX5n!WI4Z`Ytc;7So%j-%pzxTh9fK^g=;&QIPt(aXQpW!V) zuzOOythTm%C~njW_JKB~kmV@>tN0%2-1~cPFWYbQd!m>3B${Tg>W>QX+4uf6Zxk4( z`D8FhJix}%D>Y;WblTGjx)RaQTR?@`7X;e?2wli%7u$Ay4>3u6i_dTTe5ZDvs}2cD zPC*+0_~WvJ$85()6b({ij14>;0-HWpuQcqnn3KTnh`gf-fZ6^^0C=$GK;yu$?GI1d z|0nS!9;bWo#J8l59Tt*wQ}xOCIue3ddiB-ktE2t5_|BHO<#NWnn#6PaXbRF7EIgqt z31T?K$j_q&k6MxHn^e-FW6^9|W&V}5wM47fQC^{m^7(ig8sIZ*aN4U_RO3_(*%feq zmx3O!s`_~x4(3xca*0qle@BP6Ccm-U{cM)nqyhQT;>Q=$nBAT9QVX$ssNr6!;@Mr_~TB6BSGlQv0p z@)JE@n5NK003h+Fv6(0V;SxOKkLss9=l9@N*Gaf=04JBr*d?c;~t+6}Kx!n!zrChgQM$zz&)lluYl{avlxlrIy#Vf;_>^pe{AtF2~ z$a**G77W~vqju~HKvH!PGEEA|fGt7K0P51v*{@f`c(mE08heV8(n?^aq6?TE=urb2 ztW-ToC8R&-R)}!MexA`!eDpqo-IT}+cGxd1Muqr@`z_4*B?$3P1Pz^V#P8>NsQaWQ zwjk@hG8y$5N`*lmNDcsvZLsEvQEMyJ@kRYCzkq+sAp7FslDxP?F@dwJtMR!t%3xxR z*05DdL2DtQHp@m5<(hN3*Wa*zSD}$5HsUc4+w#OiQn6!U;RUIU$NT8$1h^J^$aaCo zxn8I+7-1Hk3MASAIt%@J1*f{-@p*R!OJq+((UMXDHN_Dx?$LECJ7aN*GM&dfNXKuG z_%$qt*hq;CP~8pCO#rSj!S@0Xw3Izp9XkAEYAf$%pJdqZG^KD<`a~*Dj9O<$l@s9G zy^hDJ)$Oo8WZVFzPt4a>*D(%QtyiQ+E0>I)Pzz^|O$jnzC0@RmL)q%s6}Be7FfYbb zW!8<)mtT6RD`T{rM4cqKJk{h+UL6K{pfYLa2>1R7nE%n+de(H~P~Dn&k9nu)kK7EA zrK#aK!f*+O$s*COn_x>+OpbG+12XSy6KlMQ^SxqaX6Qy&5E@rV(Dk&!9ksR&xZp-J zvm_We4P%YAdGtf9pMJM@()H71U0enEfj5^KyNev%B@60x*HZxX`uDAFb6n`ylziN8 zmKo6eG<7o8_}EjkNw}|Ht{1y@m3ga!n|!NqlrpZKejNyr54}1W9^sqx&)xqzhls?d!{h{;dgrGT@#n(wvKU-~@vrg86tiTEnu zxwdfE=uU`T4yi*6mObl2#lWBKoHTfR<_+grrw6pMKYkEhX-NeHAd7vfYtqyx4y_EQ{<8O|~s72(#ip9T^4v4?-j*WYbs zM%t>(P7jELgfKq6z(Yx}p%Z{+mFvlUh z%IFyTTyi4?s9$UV7z`h>FG)_++ckj^kKbq!;xKM6rUxkrbPYk13`G z#*$(PGdcJ8KCz;n8oy9k( zyr1NY1ROKz`UMmNC?U(zuX)rlqQvQ*&|w9{+Q-5{Bl%?i&8q(@W2GXT0x z&7-a->v`p?kr7aVAi({r=Wi6VS6qnC)Bu$T9-p1B8_6Y1;uruuKWXdo?v;Rw2++7D zmExzYZ6qs(nDBk?{l8r0|e;tRmLOa(K&xVbq}({cD${!iH*4qYv`aiwZ*hsn+s zFF<8qBM)QPnpKaBm)=3v%ufoxG9Wt&8Gqg?fFz%LIA^govx=@|wCZK7vfLeZ6AG~V z9cbypz6kYeh>17z3fw(s@_ppO)mTaOa8w<)e*v_iN2vi^Q;l^gmo>BEG@=d;P$xw~ zZ{pgun7y#Ri)pSi3h0`oEk#*MZx~hmG z9WDcq2njk8oezK_Q@RiLOA|v#QctN)EKpu;WP0@klQ@3Z;CoI}h$6S-X9 zp!Jr}ltzjn>{z8}PDJ`OGxf*M-}sK0xc4?Od;Nst_1c0};V=Cvjg+#w=jT5fJB`cX zfE0Rfl3HY%s&#$vtmX6pw>+N|^(R0;FeKb!M%ySFc z-a8`5ln$frbG>ab_k0^km3RU=B)bd;!JmUWHD`p{H;B#uifp~HTD;{A&7)kXlc}_R zht`7k^`n(h`_}g+FW+j+4f#6UZEP=}?RDkeyKI4n1;C-=laty4qLek& zOUgn^c1i;r{o6Pw9zGLFt^%wOHu+L&b53)zM$ z4>fi&*GV(6;561G+5*5Qmtuc#t7&D=(<;;TD$0U=hBWlLzcgBnlXZcOTBZ7ok8?pv zb~@eEm`W%3n*dq)-1-hXwPILcjTfpae@{Pl-|HRUDH(B_8Y_7$JFIST?3i1f z6iuGnBB&|EIMMF$uqLU1z)P8j%Yn)-gR8)U&Ta~N!$q5;YW9E$ML0#jF84v_f-|pe z2#jiLB;d*H@7S^2m%wW0W|cP>20cz1wIuut@om9ltF2wdaGpA(4xT4*F`Bo5FxdXc zyG-j7awWyDuRnQhc*T>-CQJt8yj#>7&1@_9ppgG=T8^ej#*tK8JgmfAF~WMH|RZ zymzx-#b+D(k3vbn41P}V0_KY<%BzQ6ZnhBN;3~j*7tR^QMyvD-`%<&!2FzQBa-CRO z?Zi){v}r))(i18AaD_Jk*07D3qo1tZ(%x2_5$UUHjS?#=gE^Gr&EmDI=R`LG%I3s> zF8O>o)PRZ$EQm%^Zn$h25x|NZ3S!llXk>S+108XC$C~A*NUP>u9opG)7rlya{OWQ@ z`1`ulABk}eP=VS@Es~r%8|cTt<0D5j*qFK+t~6WI$x$6;Z+C38&j7$^7=tP!1%5u? z-+%JOA9{?8-x0ft(>(IQn55V(e0|%=`XFEUKp9hxyJyf-6d5VXGmW)Q=Cn27Ldm%4 z6w@*t>%ByE29}%?Dru)SAo|Nqkyue z;{ROa+a1G;UK&=GlL97s|hcNt;wzr(1 zJ62$2_W*!g57J%k$M7PL!7S@xy3b>Pej&C1pz#m)_l)qYZ(BxHB{cwIKDHA%d8j0w z%61;8v&J6a4{o$j2n?mBQxUeRH3Iy6LFiEPDaG1mNLSW zDtYa5=d#G^w~e9=kC}GdhFkIT#a>2N;Heqy)`vs`wqiy)=+DmQOP9pn7AVyrVo>K> z-K=j3306s?n6>|rma8Qv-Ef#Mey@aL(bYj$@$y}7$~EO>O?3j#VXod$PTQ|YHvr0t z(w1S-KU$!C!@>zLnF(8i46@3u$~-S3Ld&ix1AGzT);_hKgNkZT+(Ko0&9t4)-8M1l zZ874ksV!W+V3m(Lgch7G$nnbZIfMyvh{Kzp2)!0F3BMzLIR*0YtWgWmB3C$Z@Tlo%Z>EQ&fV_^w?e*santQ10^YcsM zQcxG&>}{l_RPa$ln-Oc;YxM=2qY~Ey0e8jju-pdpy+NG#n^H3oR4*Ns-8h)|J7Vm> zf45^m2~xh_@!<-;4A^l@Ma_`%CDJHRGTJsc=$-F6=sMh{+-`53q<)1YQCnp#Fx7_$ zDr{>lNXhXdod-V=d`VNtd*Qxy?Q2E;>qEcXG#=RJMniCYXg#inOR88!l5<0)Ca$do zIn{pUl^Le1##e#eixXR0FXorB2L7M+&NQmYbKB$eXho4hZ}l?CU}+bMA}R(Vm_)>a zT7@z@5YSR&5P}eP^bKq3VaNC;6fLB{h! z+gs|rUFXaFa@IN@leMyvJv{q)_Ve!lFNU?)^k~+hxXm%Jh?S zjFb3|DB5g;9-dH?b}GMi!8G@=sbAfyNw~r}8tF|9-iMH{uI5zLG=>Y^?*@g5>}l;Cp{LU&g@euOt19aK zgz-*QwReuToUadZpR80FY}jQF2IiE`L|2a3k+n@P#>^Q>;_4kgwWD(Og|VNJ^4C`Z zf8m;N^5n-M>9+^g0d1v+r=~7{vjVC;2qeypDDJ98%!Og`*U{3CigJBwoR-e}>X#2{kh`7LEysdFr~{-) z*AGfbithmVQJ~{g(TT<}T^lj2(}{#gXh3j2I-{&DYM(zA7f9F|B4$}ZNoEGrMP_n) zKeFIe`FW!1qz>B5tgHQ&G!oLNK1kkKOZwhPB)G~6xjzg@@1nTu+O&s=rV%@b2KH6H z4eg7N{O0t1o?@2xM9AuD)Hf?c)bHMJ|2cqBS(?FAguMI=zI`e>IxymtL%w3acwn=0 z;F-{^A)t`J07Rno>BF~8DKBn%i$`J!6HRySj6x&1FU9JCr^l=MJx)^U>--6J%|}~E z_>_9mcO)Z`J-x-tDt^a0zxV7N9l_2!J~g{w7rwm79&^{2&E9CvpFtLef(0KoQv#|# z+3xb4m7ww;FWVcAJsW_<4u`eam9AmZK0PfY{nXg*C$zTuspZ+?f{qTHl*zp~IDALG z2`JF(V)4ywY)Qf0e>tAPbsNbFwgYs;wWg;SCV%s2Z{>U_*KI9O{l5y%tL5eX&2|0X z&wu|F=Cq=c{kt$7-Wiko&*c68D{@2zV>s(2dD~+&_s7a+c_h(nT})OaPw^bVidHEA z8gg8c{si!L!E}E*rY(b0DOS8GPt1r>cV4Okr6l=3i^2q^tH&;hGrU`P>xQzsX^@}A z3JzENbz&<|fuQZ@BwbAapjftig#Vi)Gi0md7p=VK&5#J4xP;m=xZrbt(3a5?W$jjg zY>6}*%FU-}2N~L8y8JpNHzB7h>`;pW+#*&mIyg}r1m`*r%yEfnbzx{4lR8vFa$_RL zZJ3UwbtpzI%&SC{9_yrzt#x&EAA3fOXug5SdMvLOSR{4If9R0*da6d&8N}w*tomrB zeD&-_54kAsX>zxGS>@vp5Y<<{HAQgSWM08Z5{VoQ?63Uw6WbqbU#2LH5Xt0Lb033) z*~e|{Z>=Dytn;&6VjcB$S;iQDd)qTZcww7?yILL_CnY@M`I8v^MLCQ8Y;)LkDV%%D;Tii_&xzE}at$=?ZvHw)uv<3C8I?sk3cSmwlps!PAW>Hl0bf2eDAIOD0EZuf8o zYG@lD8epc~zsb7m))p0Vwzi)uA?q*$T(MdDCTT_$th;<;bnK7+^83Uo4`!zO!=B}u z;Jy#?7niW7j&6B;CHbhOSW6c&e8pqBv%Y(9VJf7tRX}d;;;h{~^@J~eTjVMq_LkMv z1~*`TjpoaaoS@AcAd8dnrx-dEYO-)D<>|*!BcncWeK(B$qvZ#V+zn_{n%sGQD9Znd zEAxP(Xb|FJ25CCHtL^o#ZpeuA;gH6J;V6aNAHw=J?xS=G_e^MQX5d^~RDtARYsEP9 zmOG_ptf%?}jg_rQ6S+MZX%!cf$XS@i+Uo4wTOJD*~iY|oTV)5YFuSf1ix+vgD_S!KRM1aDlyq9%LV zfxs{Wb>RuI5PWwXjN@^tt>IKJ4427o4`)#3`f&J%2p(5d$V`+m$PMg18x>MBCP5#I zjxN&bDJpfa-FPH*zQ(Ph!h=_>!X1O)S!DJQg`w0C&*4j$ItarTgN(*$HnS)pZ8o7(!;!>A3^pIXi1~H8mkitco53{F?{4lbGPMg{AG}c18OBkLvv`}u-m2a`9%k=8N1n=Ub zU`uFLQ+NivO1|Loo&U(u$8R2)cXxUXG7kSv^;I$ba)rw70i>)P=sV7el{5 z(dJ;)ZzpcMRK-h@rNb~Hhp3NXnZs*1qiE4_&sbYmzVLbCJPPu#tXd6rnhs;E5~55k zc7rACOAq=CfgWj+`A#L00FsdS8oUAdptsqL%h1MBQ3}=%#Aimv;*Q=>Ns!FWKGV=# z6YCjTQhmipywkqG@c_(C5uWmoE%HpnrMtOCNp9svvB7;6&}9e@Qme;156nWj3^OH)Bq)FQNd~cJz?aTSOwrOw8)cYHsp_lk2_}{u6OyFIZV8a zk9(Dphb6&@P`?B514YZ08@CS!NL`m~gC5pIFCRmF;u8jd*&W3e3OfOmMevrm57ENAv?TvHw+y8j+!zy4&P_yxu z5d`K^5gK56;lij9kIDtp&;r#oEyFY^c8J0oPQR3;79(fVYmD}UfM-lTdi1-w1Km@s zaG}JNz;+-AEM?%ujy1+UefB_ys=4KHaPJDnT3NPg=2r4&fW##eL5;pEx$nvbf{uo@ zlg;FhcL^sLj<*MTGHzQ5HD3v@U6Z}p!=6%2w3?f)8T%u|J`h8B;kmT>BNFUfr!rfe zHXrfBh0MsjEWs;6wQ9cX4C2;!i6>jU6l$z3w?dB<;%oG^K0^}UdUd8AI&kw;jR4i- z+^U`v6})5iS~cxuu(eeLdS1S*OhpJl%x+8To1+}HXnkgeEll-l|JDd#TzPpAClMA zWhhSC36nlYV)5on+5Jb&+{008p9oN7z+Xfc!xYB!5zq$K&B&V2N({E1#|~%sQkQoq zNn!^sOx&4EEt|Nqj@=_=>iZF2lLXaWQFutW3dj0P4E+Xj3Q6>Go8r&B2+!_ge*h7=HEq zoMf^CHT>FnS_zs}ZktxjrJehIm$}-RdyW~9zoUNJJwbpnMDTtHzKUMN?bJ2))Hk{W zvB~&H~PTMEREA-h@F;AhynJiA?b5@_-H@(e=3UfL7w64 zs-LiSb8L!7Y`h<+6>SW#C{@SlF4Jq#XN5NVbAmo_*!g-}Dlxa%sLl^uA*Q+@;l10m z8>b|IgaoXyeLTK@uSK%;(ix19@yf2+z29gI_u2u2kXslSl*?}YMwe{*bagf9lXOv? zP8!H>FAY#RJmcYWY?2os-#kKovHRDhcDfv^hF-L)kj#P16G+sF(Qp8{wEYhdruud2 zeFH(%q=0}6h`8zc>z+F*EqG{S9kpm1{7+WhOez2X literal 0 HcmV?d00001 diff --git a/deployment/v3/external/object-store/minio/install.sh b/deployment/v3/external/object-store/minio/install.sh index bf3f677eb..e0db36b6c 100755 --- a/deployment/v3/external/object-store/minio/install.sh +++ b/deployment/v3/external/object-store/minio/install.sh @@ -14,7 +14,7 @@ kubectl label ns $NS istio-injection=enabled --overwrite function installing_minio() { echo Installing minio - helm -n minio install minio mosip/minio --version 10.1.6 + helm -n minio install minio mosip/minio -f values.yaml --version 10.1.6 echo Installing gateways and virtualservice EXTERNAL_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-minio-host}) diff --git a/deployment/v3/external/object-store/minio/values.yaml b/deployment/v3/external/object-store/minio/values.yaml new file mode 100755 index 000000000..7dbf1a22c --- /dev/null +++ b/deployment/v3/external/object-store/minio/values.yaml @@ -0,0 +1,9 @@ +metrics: + serviceMonitor: + enabled: true + +extraEnvVars: + - name: MINIO_PROMETHEUS_URL + value: "http://rancher-monitoring-prometheus.cattle-monitoring-system:9090" + - name: MINIO_PROMETHEUS_JOB_ID + value: "minio" diff --git a/deployment/v3/external/postgres/README.md b/deployment/v3/external/postgres/README.md index 602e96d2d..27b425db1 100644 --- a/deployment/v3/external/postgres/README.md +++ b/deployment/v3/external/postgres/README.md @@ -40,7 +40,6 @@ To initialized a specific db disable init of all others in `init_values.yaml` by ``` psql -h -p -U -f .dump ``` - ## DB Commons secret and postgres-postgresql secret creation * Base64 Encoding and YAML Creation Script: @@ -98,4 +97,3 @@ helm delete postgres-upgrade -n postgres ``` sed -i 's/LOCALE/LC_COLLATE/g' .dump ``` - diff --git a/deployment/v3/external/postgres/init_db.sh b/deployment/v3/external/postgres/init_db.sh index c234c8472..f052a1c3a 100755 --- a/deployment/v3/external/postgres/init_db.sh +++ b/deployment/v3/external/postgres/init_db.sh @@ -8,7 +8,7 @@ fi function initialize_db() { NS=postgres - CHART_VERSION=12.0.1-develop + CHART_VERSION=0.0.1-develop helm repo update while true; do read -p "CAUTION: all existing data will be lost. Are you sure?(Y/n)" yn diff --git a/deployment/v3/external/postgres/init_values.yaml b/deployment/v3/external/postgres/init_values.yaml index 48bc0a89e..90ba43e62 100644 --- a/deployment/v3/external/postgres/init_values.yaml +++ b/deployment/v3/external/postgres/init_values.yaml @@ -4,52 +4,60 @@ dbUserPasswords: databases: mosip_master: enabled: true - branch: v1.2.0.1 + branch: develop mosip_audit: enabled: true - branch: v1.2.0.1 + branch: develop mosip_keymgr: enabled: true - branch: v1.2.0.1 + branch: develop mosip_kernel: enabled: true - branch: v1.2.0.1 + branch: develop mosip_idmap: enabled: true - branch: v1.2.0.1 + branch: develop mosip_prereg: enabled: true - branch: v1.2.0.1 + branch: develop mosip_idrepo: enabled: true - branch: v1.2.0.1 + branch: develop mosip_ida: enabled: true - branch: v1.2.0.1 + branch: develop mosip_credential: enabled: true - branch: v1.2.0.1 + branch: develop mosip_regprc: enabled: true - branch: v1.2.0.1 + branch: develop mosip_pms: enabled: true - branch: v1.2.0.1 + branch: develop mosip_hotlist: enabled: true - branch: v1.2.0.1 + branch: develop mosip_resident: enabled: true - branch: v1.2.0.1 + branch: develop + + mosip_otp: + enabled: true + branch: develop + + mosip_digitalcard: + enabled: true + branch: develop diff --git a/deployment/v3/external/postgres/install.sh b/deployment/v3/external/postgres/install.sh index 960578d03..9366c44ec 100755 --- a/deployment/v3/external/postgres/install.sh +++ b/deployment/v3/external/postgres/install.sh @@ -15,9 +15,8 @@ kubectl label ns $NS istio-injection=enabled --overwrite function installing_postgres() { echo Installing Postgres - helm -n $NS install postgres bitnami/postgresql --version 12.11.1 -f values.yaml --wait + helm -n $NS install postgres bitnami/postgresql --version 13.1.5 -f values.yaml --wait echo Installed Postgres - echo Installing gateways and virtual services POSTGRES_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-postgres-host}) helm -n $NS install istio-addons chart/istio-addons --set postgresHost=$POSTGRES_HOST --wait diff --git a/deployment/v3/external/postgres/values.yaml b/deployment/v3/external/postgres/values.yaml index bbeb1d66f..a38f1c3a1 100644 --- a/deployment/v3/external/postgres/values.yaml +++ b/deployment/v3/external/postgres/values.yaml @@ -11,7 +11,6 @@ primary: requests: cpu: 3000m memory: 3000Mi - audit: logHostname: true logConnections: true diff --git a/deployment/v3/mosip/README.md b/deployment/v3/mosip/README.md index ce8fd7ad8..d1351dcb9 100644 --- a/deployment/v3/mosip/README.md +++ b/deployment/v3/mosip/README.md @@ -12,12 +12,16 @@ The steps here install all MOSIP provided services - core and reference implemen ## Install Install in the following order: -* [Config Server Secrets](conf-secrets/README.md) +* [Landing page](landing-page/README.md) +* [Docker secrets](docker-secrets/README.md) +* [Prereg captcha](captcha/README.md) * [Config Server](config-server/README.md) +* [captcha](../mosip/captcha/README.md) * [Artifactory](artifactory/README.md) * [Key Manager](keymanager/README.md) * [WebSub](websub/README.md) -* [Mock-smtp](mock-smtp/README.md) +* [Masterdata-loader](masterdata-loader/README.md) +* [Kernel](kernel/README.md) * [Masterdata-loader](masterdata-loader/) * [Kernel](kernel/README.md) * [Mock Biosdk](biosdk/README.md) @@ -36,7 +40,7 @@ Install in the following order: * [Mosip File Server](mosip-file-server/README.md) * [Resident Services](resident/README.md) * [Registration Client](regclient/README.md) -## Install +* [Restart Cron](https://github.com/mosip/mosip-infra/tree/develop/deployment/v3/mosip/restart-cron) The same can be achieved by running `all/install-all.sh`. ``` cd all diff --git a/deployment/v3/mosip/admin/README.md b/deployment/v3/mosip/admin/README.md index 67984445f..23d6e4aa6 100644 --- a/deployment/v3/mosip/admin/README.md +++ b/deployment/v3/mosip/admin/README.md @@ -4,7 +4,6 @@ ``` ./install.sh ``` - ## Admin proxy Admin service accesses other services like Materdata and Keymanager and currently there is only one URL that is used to connect to both these services. This will get fixed in future versions, but as a an interim solution, Admin Proxy docker has been created, which is basically an Nginx proxy connecting to the above services with these URLs: ``` diff --git a/deployment/v3/mosip/admin/delete.sh b/deployment/v3/mosip/admin/delete.sh index 0e4225aaa..bacc21ffd 100755 --- a/deployment/v3/mosip/admin/delete.sh +++ b/deployment/v3/mosip/admin/delete.sh @@ -12,7 +12,7 @@ function deleting_admin() { read -p "Are you sure you want to delete ALL Admin helm charts?(Y/n) " yn if [ $yn = "Y" ] then - kubectl delete -n $NS -f admin-proxy.yaml + kubectl delete -n $NS -f admin-proxy.yaml helm -n $NS delete admin-hotlist helm -n $NS delete admin-service helm -n $NS delete admin-ui @@ -30,4 +30,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_admin # calling function \ No newline at end of file +deleting_admin # calling function diff --git a/deployment/v3/mosip/all/delete-all.sh b/deployment/v3/mosip/all/delete-all.sh index 5efffb8dc..de5cc20c0 100755 --- a/deployment/v3/mosip/all/delete-all.sh +++ b/deployment/v3/mosip/all/delete-all.sh @@ -29,8 +29,11 @@ function Deleting_all() { "artifactory" "websub" "biosdk" + "partner-onboarder" + "restart-cron" "mock-smtp" ) + echo Deleting MOSIP services. for i in "${module[@]}" diff --git a/deployment/v3/mosip/all/install-all.sh b/deployment/v3/mosip/all/install-all.sh index a9bc06c1f..3f9c7001f 100755 --- a/deployment/v3/mosip/all/install-all.sh +++ b/deployment/v3/mosip/all/install-all.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi -function installing_all() { +function Installing_all() { ROOT_DIR=`pwd`/../ declare -a module=("conf-secrets" @@ -30,10 +30,13 @@ function installing_all() { "admin" "ida" "print" + "mosip-file-server" + "resident" "partner-onboarder" "mosip-file-server" "resident" "regclient" + "restart-cron" ) echo Installing MOSIP services @@ -55,4 +58,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -installing_all # calling function +Installing_all # calling function diff --git a/deployment/v3/mosip/artifactory/delete.sh b/deployment/v3/mosip/artifactory/delete.sh index 9c29d09c6..ffd65f8cd 100755 --- a/deployment/v3/mosip/artifactory/delete.sh +++ b/deployment/v3/mosip/artifactory/delete.sh @@ -27,4 +27,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_artifactory # calling function \ No newline at end of file +deleting_artifactory # calling function diff --git a/deployment/v3/mosip/artifactory/install.sh b/deployment/v3/mosip/artifactory/install.sh index 34768435d..9c41154a1 100755 --- a/deployment/v3/mosip/artifactory/install.sh +++ b/deployment/v3/mosip/artifactory/install.sh @@ -7,10 +7,10 @@ if [ $# -ge 1 ] ; then fi NS=artifactory -CHART_VERSION=12.0.2 +CHART_VERSION=0.0.1-develop echo Create $NS namespace -kubectl create ns $NS +kubectl create ns $NS function installing_artifactory() { echo Istio label diff --git a/deployment/v3/mosip/artifactory/restart.sh b/deployment/v3/mosip/artifactory/restart.sh index e3d57332d..b82a3d039 100755 --- a/deployment/v3/mosip/artifactory/restart.sh +++ b/deployment/v3/mosip/artifactory/restart.sh @@ -12,7 +12,7 @@ function Restarting_artifactory() { kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status - echo Restarted artifactory services + echo Restarted Artifactory services return 0 } @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_artifactory # calling function \ No newline at end of file +Restarting_artifactory # calling function diff --git a/deployment/v3/mosip/biosdk/delete.sh b/deployment/v3/mosip/biosdk/delete.sh index dd3edf41a..a0e1e9df1 100755 --- a/deployment/v3/mosip/biosdk/delete.sh +++ b/deployment/v3/mosip/biosdk/delete.sh @@ -27,4 +27,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_biosdk # calling function \ No newline at end of file +deleting_biosdk # calling function diff --git a/deployment/v3/mosip/biosdk/install.sh b/deployment/v3/mosip/biosdk/install.sh index 64f30e65f..b245d88ea 100755 --- a/deployment/v3/mosip/biosdk/install.sh +++ b/deployment/v3/mosip/biosdk/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=biosdk -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -22,7 +22,8 @@ function installing_biosdk() { ./copy_cm.sh echo Installing Biosdk server - helm -n $NS install biosdk-service mosip/biosdk-service -f values.yaml --version $CHART_VERSION + helm -n $NS install biosdk-service mosip/biosdk-service -f values.yaml --version $CHART_VERSION + echo Biosdk service installed sucessfully. return 0 } diff --git a/deployment/v3/mosip/bqatsdk/install.sh b/deployment/v3/mosip/bqatsdk/install.sh index 78885a9ed..0ea8a9918 100755 --- a/deployment/v3/mosip/bqatsdk/install.sh +++ b/deployment/v3/mosip/bqatsdk/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=bqatsdk -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -23,7 +23,7 @@ function installing_bqatsdk() { echo Installing Bqatsdk server helm -n $NS install bqatsdk-service mosip/biosdk-service \ - --set extraEnvVars[0].name="server_servlet_context_env" \ + --set extraEnvVars[0].name="server_servlet_context_path_env" \ --set extraEnvVars[0].value="/bqatsdk-service" \ --set extraEnvVars[1].name="spring_application_name_env" \ --set extraEnvVars[1].value="bqat-sdk" \ diff --git a/deployment/v3/mosip/captcha/README.md b/deployment/v3/mosip/captcha/README.md new file mode 100644 index 000000000..1105308a8 --- /dev/null +++ b/deployment/v3/mosip/captcha/README.md @@ -0,0 +1,11 @@ +# Pre-registration Portal Captcha + +## Pre-requisites +* Create a google recaptcha v2 ("I am not a Robot") from Google [Recaptcha Admin](https://www.google.com/recaptcha). +* Give the domain name as your PreReg domain name. Example "prereg.sandbox.xyz.net". + +## Install +Create the configmap and secret in `prereg` namespace by running the following: +```sh +./install.sh [kubeconfig] +``` diff --git a/deployment/v3/mosip/captcha/copy_cm.sh b/deployment/v3/mosip/captcha/copy_cm.sh new file mode 100755 index 000000000..be231e2f2 --- /dev/null +++ b/deployment/v3/mosip/captcha/copy_cm.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Copy configmaps from other namespaces +# DST_NS: Destination namespace + +function copying_cm() { + COPY_UTIL=./copy_cm_func.sh + DST_NS=captcha + + $COPY_UTIL configmap global default $DST_NS + $COPY_UTIL configmap artifactory-share artifactory $DST_NS + $COPY_UTIL configmap config-server-share config-server $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +copying_cm # calling function \ No newline at end of file diff --git a/deployment/v3/mosip/captcha/copy_cm_func.sh b/deployment/v3/mosip/captcha/copy_cm_func.sh new file mode 100755 index 000000000..1bbad7126 --- /dev/null +++ b/deployment/v3/mosip/captcha/copy_cm_func.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# Copy configmap and secret from one namespace to another. +# ./copy_cm_func.sh [name] +# Parameters: +# resource: configmap|secret +# name: Optional new name of the configmap or secret in destination namespace. This may be needed if there is +# clash of names + +if [ $1 = "configmap" ] +then + RESOURCE=configmap +elif [ $1 = "secret" ] +then + RESOURCE=secret +else + echo "Incorrect resource $1. Exiting.." + exit 1 +fi + + +if [ $# -ge 5 ] +then + kubectl -n $4 delete --ignore-not-found=true $RESOURCE $5 + kubectl -n $3 get $RESOURCE $2 -o yaml | sed "s/namespace: $3/namespace: $4/g" | sed "s/name: $2/name: $5/g" | kubectl -n $4 create -f - +else + kubectl -n $4 delete --ignore-not-found=true $RESOURCE $2 + kubectl -n $3 get $RESOURCE $2 -o yaml | sed "s/namespace: $3/namespace: $4/g" | kubectl -n $4 create -f - +fi + + + + diff --git a/deployment/v3/mosip/captcha/delete.sh b/deployment/v3/mosip/captcha/delete.sh new file mode 100755 index 000000000..544b1555b --- /dev/null +++ b/deployment/v3/mosip/captcha/delete.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Uninstalls all captcha helm charts +function deleting_captcha() { + while true; do + read -p "Are you sure you want to delete all captcha helm charts?(Y/n) " yn + if [ $yn = "Y" ] + then + helm -n captcha delete captcha + break + else + break + fi + done + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +deleting_captcha # calling function \ No newline at end of file diff --git a/deployment/v3/mosip/captcha/get_logs.sh b/deployment/v3/mosip/captcha/get_logs.sh new file mode 100755 index 000000000..4a1697e21 --- /dev/null +++ b/deployment/v3/mosip/captcha/get_logs.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# pod name +kubectl -n captcha logs -f $1 | grep -v "/v1/captcha/actuator/health" | grep -v "/v1/captcha/actuator/prometheus" \ No newline at end of file diff --git a/deployment/v3/mosip/captcha/install.sh b/deployment/v3/mosip/captcha/install.sh new file mode 100755 index 000000000..72f60f520 --- /dev/null +++ b/deployment/v3/mosip/captcha/install.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Creates configmap and secrets for Prereg Captcha +# Creates configmap and secrets for resident Captcha +## Usage: ./install.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +NS=captcha +CHART_VERSION=0.0.1-develop + +PREREG_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-prereg-host}) +RESIDENT_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-resident-host}) +ESIGNET_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-esignet-host}) + +echo Create $NS namespace +kubectl create ns $NS + +function Prereg_Captcha() { + echo Please enter the recaptcha admin site key for domain $PREREG_HOST + read SITE_KEY + echo Please enter the recaptcha admin secret key for domain $PREREG_HOST + read SECRET_KEY + echo Please enter the recaptcha admin site key for domain $RESIDENT_HOST + read RSITE_KEY + echo Please enter the recaptcha admin secret key for domain $RESIDENT_HOST + read RSECRET_KEY + echo Please enter the recaptcha admin site key for domain $ESIGNET_HOST + read ESITE_KEY + echo Please enter the recaptcha admin secret key for domain $ESIGNET_HOST + read ESECRET_KEY + + echo Setting up captcha secrets + kubectl -n $NS create secret generic mosip-captcha --from-literal=prereg-captcha-site-key=$SITE_KEY --from-literal=prereg-captcha-secret-key=$SECRET_KEY --from-literal=resident-captcha-site-key=$RSITE_KEY --from-literal=resident-captcha-secret-key=$RSECRET_KEY --from-literal=esignet-captcha-site-key=$ESITE_KEY --from-literal=esignet-captcha-secret-key=$ESECRET_KEY --dry-run=client -o yaml | kubectl apply -f - +} + +function installing_captcha() { + echo Istio label + + kubectl label ns $NS istio-injection=disabled --overwrite + helm repo update + + echo Copy configmaps + sed -i 's/\r$//' copy_cm.sh + ./copy_cm.sh + + echo Installing captcha + helm -n $NS install captcha mosip/captcha --version $CHART_VERSION + + echo Installed captcha service + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes + +Prereg_Captcha # calling function +installing_captcha # calling second function diff --git a/deployment/v3/mosip/captcha/restart.sh b/deployment/v3/mosip/captcha/restart.sh new file mode 100755 index 000000000..eaf4bf056 --- /dev/null +++ b/deployment/v3/mosip/captcha/restart.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Restart the captcha services +## Usage: ./restart.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +function Restarting_captcha() { + NS=captcha + kubectl -n $NS rollout restart deploy + + kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + + echo Restarted captcha services + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +Restarting_captcha # calling function \ No newline at end of file diff --git a/deployment/v3/mosip/conf-secrets/install.sh b/deployment/v3/mosip/conf-secrets/install.sh index 3ff2cdd51..3c1c2e2bf 100755 --- a/deployment/v3/mosip/conf-secrets/install.sh +++ b/deployment/v3/mosip/conf-secrets/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=conf-secrets -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/config-server/README.md b/deployment/v3/mosip/config-server/README.md index 1d8899cf7..87b23a7b5 100644 --- a/deployment/v3/mosip/config-server/README.md +++ b/deployment/v3/mosip/config-server/README.md @@ -13,6 +13,19 @@ Config server serves all properties required by MOSIP modules. This must be inst ./install.sh ``` +## Delete +* To delete config-server. +```sh +./delete.sh +``` + +## Enable config-server to pull configurations from local git repository. - +Enable Config-server to Pull Configurations from Local Repository: +* While running the install script the user will be prompted to decide whether the config-server should pull configurations from a local repository (NFS). +* If the user choose to use local git repository then the user will be asked to provide the NFS path(Dir where local repository is cloned) and the NFS server IP. +* If the user choose to not to pull configurations from a local repository (NFS) then the configurations will be pulled from remote repository which is defined in values.yaml file. +Note: +* Before choosing to pull configurations from a local repository (NFS) the user must clone the config-server repository manually into the nfs server where the configurations can be maintained. +* And checkout to the specific branch from where the configurations need to be taken. diff --git a/deployment/v3/mosip/config-server/copy_cm.sh b/deployment/v3/mosip/config-server/copy_cm.sh index ae5c122c4..42b611e24 100755 --- a/deployment/v3/mosip/config-server/copy_cm.sh +++ b/deployment/v3/mosip/config-server/copy_cm.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copy configmaps from other namespaces - + function copying_cm() { COPY_UTIL=../../utils/copy_cm_func.sh DST_NS=config-server # DST_NS: Destination namespace @@ -20,4 +20,3 @@ set -o nounset ## set -u : exit the script if you try to use an uninitialised set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes copying_cm # calling function - diff --git a/deployment/v3/mosip/config-server/install.sh b/deployment/v3/mosip/config-server/install.sh index 2fe714933..73e1903c2 100755 --- a/deployment/v3/mosip/config-server/install.sh +++ b/deployment/v3/mosip/config-server/install.sh @@ -7,10 +7,29 @@ if [ $# -ge 1 ] ; then fi NS=config-server -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop -read -p "Is conf-secrets module installed?(Y/n) " yn -if [ $yn = "Y" ]; then read -p "Is values.yaml for config-server chart set correctly as part of Pre-requisites?(Y/n) " yn; fi +read -p "Is conf-secrets module installed?(Y/n) " conf_installed +read -p "Do you want to enable config-server to pull configurations from local repository?(Y/n)( Default: n )" repo_enabled + +if [[ -z $repo_enabled ]]; then + repo_enabled=n +fi + +if [ "$repo_enabled" = "Y" ]; then + LOCALREPO="true" + read -p "Provide the NFS path where the local repository is cloned/maintained: " path + NFS_PATH="$path" + + read -p "Provide the NFS IP address of the server where the local repository is cloned: " ip + NFS_SERVER="$ip" +else + LOCALREPO="false" + NFS_PATH="" + NFS_SERVER="" +fi + +if [ $conf_installed = "Y" ]; then read -p "Is values.yaml for config-server chart set correctly as part of Pre-requisites?(Y/n) " yn; fi if [ $yn = "Y" ] then echo Create $NS namespace @@ -35,9 +54,14 @@ if [ $yn = "Y" ] sed -i 's/\r$//' copy_secrets.sh ./copy_secrets.sh - echo Installing config-server - helm -n $NS install config-server mosip/config-server -f values.yaml --wait --version $CHART_VERSION - echo Installed Config-server. + echo "Installing config-server" + helm -n $NS install config-server mosip/config-server \ + --set localRepo.enabled="$LOCALREPO" \ + --set volume.nfs.path="$NFS_PATH" \ + --set volume.nfs.server="$NFS_SERVER" \ + -f values.yaml \ + --wait --version $CHART_VERSION + echo "Installed Config-server". else echo Exiting the MOSIP installation. Please meet the pre-requisites and than start again. kill -9 `ps --pid $$ -oppid=`; exit diff --git a/deployment/v3/mosip/config-server/restart.sh b/deployment/v3/mosip/config-server/restart.sh index db27be57e..ad2e5f04e 100755 --- a/deployment/v3/mosip/config-server/restart.sh +++ b/deployment/v3/mosip/config-server/restart.sh @@ -6,7 +6,6 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi - function config_server() { NS=config-server kubectl -n $NS rollout restart deploy @@ -23,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -config_server # calling function \ No newline at end of file +config_server # calling function diff --git a/deployment/v3/mosip/config-server/values.yaml b/deployment/v3/mosip/config-server/values.yaml index ee64d32f6..73cc1bb9f 100644 --- a/deployment/v3/mosip/config-server/values.yaml +++ b/deployment/v3/mosip/config-server/values.yaml @@ -7,3 +7,12 @@ gitRepo: ## User name of user who has access to the private repo. Ignore for public repo username: "" token: "" + +localRepo: + enabled: false # Set this to "true" inorder to Enable config-server to pull configurations from local git repo. + spring_profiles_active: "native" + spring_cloud_config_server_native_search_locations: "file:///var/lib/config_repo" + spring_cloud_config_server_accept_empty: true + spring_cloud_config_server_git_force_pull: false + spring_cloud_config_server_git_refreshRate: 0 + spring_cloud_config_server_git_cloneOnStart: false diff --git a/deployment/v3/mosip/credential-feeder/.gitignore b/deployment/v3/mosip/credential-feeder/.gitignore new file mode 100644 index 000000000..ee3892e87 --- /dev/null +++ b/deployment/v3/mosip/credential-feeder/.gitignore @@ -0,0 +1 @@ +charts/ diff --git a/deployment/v3/mosip/credential-feeder/.helmignore b/deployment/v3/mosip/credential-feeder/.helmignore new file mode 100644 index 000000000..f0c131944 --- /dev/null +++ b/deployment/v3/mosip/credential-feeder/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/deployment/v3/mosip/credential-feeder/README.md b/deployment/v3/mosip/credential-feeder/README.md new file mode 100644 index 000000000..2e9532251 --- /dev/null +++ b/deployment/v3/mosip/credential-feeder/README.md @@ -0,0 +1,6 @@ +# Credentialfeeder + +## Install +```sh +./install.sh +``` diff --git a/deployment/v3/mosip/credential-feeder/copy_cm.sh b/deployment/v3/mosip/credential-feeder/copy_cm.sh new file mode 100755 index 000000000..7c226fb79 --- /dev/null +++ b/deployment/v3/mosip/credential-feeder/copy_cm.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Copy configmaps from other namespaces +# DST_NS: Destination namespace + +function copying_cm() { + COPY_UTIL=../../utils/copy_cm_func.sh + DST_NS=credentialfeeder + + $COPY_UTIL configmap global default $DST_NS + $COPY_UTIL configmap artifactory-share artifactory $DST_NS + $COPY_UTIL configmap config-server-share config-server $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +copying_cm # calling function diff --git a/deployment/v3/mosip/credential-feeder/delete.sh b/deployment/v3/mosip/credential-feeder/delete.sh new file mode 100755 index 000000000..fbcbedbce --- /dev/null +++ b/deployment/v3/mosip/credential-feeder/delete.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Uninstalls idrepo services +## Usage: ./delete.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +function deleting_credentialfeeder() { + NS=credentialfeeder + while true; do + read -p "Are you sure you want to delete idrepo helm chart?(Y/n) " yn + if [ $yn = "Y" ] + then + helm -n $NS delete credentialfeeder + break + else + break + fi + done + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +deleting_credentialfeeder # calling function diff --git a/deployment/v3/mosip/credential-feeder/install.sh b/deployment/v3/mosip/credential-feeder/install.sh new file mode 100755 index 000000000..703da39e7 --- /dev/null +++ b/deployment/v3/mosip/credential-feeder/install.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Installs idrepo +## Usage: ./install.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +NS=credentialfeeder +CHART_VERSION=1.0.0 + +echo Create $NS namespace +kubectl create ns $NS + +function installing_credentialfeeder() { + echo Istio label + kubectl label ns $NS istio-injection=enabled --overwrite + helm repo add mosip https://mosip.github.io/mosip-helm + helm repo update + + echo Copy configmaps + sed -i 's/\r$//' copy_cm.sh + ./copy_cm.sh + + echo Running credentialfeeder job + helm -n $NS install credentialfeeder mosip/credentialfeeder --version $CHART_VERSION --wait --wait-for-jobs + + echo Installed credentialfeeder + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +installing_credentialfeeder # calling function diff --git a/deployment/v3/mosip/databreachdetector/copy_cm.sh b/deployment/v3/mosip/databreachdetector/copy_cm.sh new file mode 100755 index 000000000..487ea261a --- /dev/null +++ b/deployment/v3/mosip/databreachdetector/copy_cm.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copy configmaps from other namespaces +# DST_NS: Destination (current) namespace + +function copying_cm() { + COPY_UTIL=../../utils/copy_cm_func.sh + DST_NS=databreachdetector + + $COPY_UTIL configmap global default $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +copying_cm # calling function + + + diff --git a/deployment/v3/mosip/databreachdetector/copy_secrets.sh b/deployment/v3/mosip/databreachdetector/copy_secrets.sh new file mode 100755 index 000000000..0616cf183 --- /dev/null +++ b/deployment/v3/mosip/databreachdetector/copy_secrets.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Copy secrets from other namespaces +# DST_NS: Destination namespace + +function copying_secrets() { + COPY_UTIL=../../utils/copy_cm_func.sh + DST_NS=databreachdetector + $COPY_UTIL secret s3 s3 $DST_NS + $COPY_UTIL secret postgres-postgresql postgres $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +copying_secrets # calling function \ No newline at end of file diff --git a/deployment/v3/mosip/databreachdetector/delete.sh b/deployment/v3/mosip/databreachdetector/delete.sh new file mode 100755 index 000000000..b76972568 --- /dev/null +++ b/deployment/v3/mosip/databreachdetector/delete.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Uninstalls print service +## Usage: ./delete.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +function deleting_databreachdetector() { + NS=databreachdetector + while true; do + read -p "Are you sure you want to delete print helm chart?(Y/n) " yn + if [ $yn = "Y" ] + then + helm -n $NS delete databreachdetector + break + else + break + fi + done + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +deleting_databreachdetector # calling function diff --git a/deployment/v3/mosip/databreachdetector/install.sh b/deployment/v3/mosip/databreachdetector/install.sh new file mode 100755 index 000000000..30f7f2e34 --- /dev/null +++ b/deployment/v3/mosip/databreachdetector/install.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Installs sample print service +## Usage: ./restart.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + + +NS=databreachdetector +CHART_VERSION=0.0.1-develop + +echo Create $NS namespace +kubectl create ns $NS + +function installing_databreachdetector() { + echo Istio label + kubectl label ns $NS istio-injection=disabled --overwrite + helm repo update + + echo Copy configmaps + sed -i 's/\r$//' copy_cm.sh + kubectl -n $NS delete --ignore-not-found=true cm s3 + ./copy_cm.sh + + echo Copy secrets + sed -i 's/\r$//' copy_secrets.sh + ./copy_secrets.sh + + DB_HOST=$( kubectl -n default get cm global -o json |jq -r '.data."mosip-postgres-host"' ) + S3_USER_KEY=$( kubectl -n s3 get cm s3 -o json |jq -r '.data."s3-user-key"' ) + S3_REGION=$( kubectl -n s3 get cm s3 -o json |jq -r '.data."s3-region"' ) + + echo Installing databreachdetector + helm -n $NS install databreachdetector mosip/databreachdetector --wait --version $CHART_VERSION \ + --set databreachdetector.configmaps.db.db-server="$DB_HOST" \ + --set databreachdetector.configmaps.s3.s3-bucket-name='secure-datarig' \ + --set databreachdetector.configmaps.s3.s3-region="$S3_REGION" \ + --set databreachdetector.configmaps.s3.s3-host='minio.minio:9000' \ + --set databreachdetector.configmaps.s3.s3-user-key="$S3_USER_KEY" + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +installing_databreachdetector # calling function diff --git a/deployment/v3/mosip/datashare/delete.sh b/deployment/v3/mosip/datashare/delete.sh index abfbb918a..636038d4c 100755 --- a/deployment/v3/mosip/datashare/delete.sh +++ b/deployment/v3/mosip/datashare/delete.sh @@ -27,4 +27,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_datashare # calling function \ No newline at end of file +deleting_datashare # calling function diff --git a/deployment/v3/mosip/datashare/install.sh b/deployment/v3/mosip/datashare/install.sh index 3fde89ff8..c475724ab 100755 --- a/deployment/v3/mosip/datashare/install.sh +++ b/deployment/v3/mosip/datashare/install.sh @@ -8,7 +8,6 @@ fi NS=datashare CHART_VERSION=12.0.1 - echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/datashare/restart.sh b/deployment/v3/mosip/datashare/restart.sh index 649141dbd..f38dbcb75 100755 --- a/deployment/v3/mosip/datashare/restart.sh +++ b/deployment/v3/mosip/datashare/restart.sh @@ -11,6 +11,7 @@ function Restarting_datashare() { kubectl -n $NS rollout restart deploy kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + echo Restarted datashare services return 0 } @@ -21,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_datashare # calling function \ No newline at end of file +Restarting_datashare # calling function diff --git a/deployment/v3/mosip/ida/delete.sh b/deployment/v3/mosip/ida/delete.sh index ce306ad49..4a400a2bd 100755 --- a/deployment/v3/mosip/ida/delete.sh +++ b/deployment/v3/mosip/ida/delete.sh @@ -30,4 +30,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_ida # calling function \ No newline at end of file +deleting_ida # calling function diff --git a/deployment/v3/mosip/ida/install.sh b/deployment/v3/mosip/ida/install.sh index a3856f774..bea94cfab 100755 --- a/deployment/v3/mosip/ida/install.sh +++ b/deployment/v3/mosip/ida/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=ida -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -35,20 +35,55 @@ function installing_ida() { ENABLE_INSECURE='--set enable_insecure=true'; fi + default_enable_volume=false + read -p "Would you like to enable volume (true/false) : [ default : false ] : " enable_volume + enable_volume=${enable_volume:-$default_enable_volume} + + IDA_KEYGEN_HELM_ARGS='--set springConfigNameEnv="id-authentication" --set softHsmCM="softhsm-ida-share"' + IDA_HELM_ARGS='' + if [[ $enable_volume == 'true' ]]; then + + default_volume_size=100M + read -p "Provide the size for volume [ default : 100M ]" volume_size + volume_size=${volume_size:-$default_volume_size} + + default_volume_mount_path='/home/mosip/config/' + read -p "Provide the mount path for volume [ default : '/home/mosip/config/' ] : " volume_mount_path + volume_mount_path=${volume_mount_path:-$default_volume_mount_path} + + PVC_CLAIM_NAME='ida-keygen-keymanager' + IDA_KEYGEN_HELM_ARGS="--set persistence.enabled=true \ + --set volumePermissions.enabled=true \ + --set persistence.size=$volume_size \ + --set persistence.mountDir=\"$volume_mount_path\" \ + --set springConfigNameEnv='id-authentication' \ + --set persistence.pvc_claim_name=\"$PVC_CLAIM_NAME\" \ + " + IDA_HELM_ARGS="--set persistence.enabled=true \ + --set volumePermissions.enabled=true \ + --set persistence.mountDir=\"$volume_mount_path\" \ + --set persistence.existingClaim=\"$PVC_CLAIM_NAME\" \ + --set extraEnvVarsCM={'global','config-server-share','artifactory-share'} \ + " + fi + echo "IDA KEYGEN HELM ARGS $IDA_KEYGEN_HELM_ARGS" + echo "IDA HELM ARGS $IDA_HELM_ARGS" + echo Running ida keygen - helm -n $NS install ida-keygen mosip/keygen --wait --wait-for-jobs --version $CHART_VERSION -f keygen_values.yaml + helm -n $NS install ida-keygen mosip/keygen $IDA_KEYGEN_HELM_ARGS --wait --wait-for-jobs --version $CHART_VERSION echo Installing ida auth - helm -n $NS install ida-auth mosip/ida-auth --version $CHART_VERSION $ENABLE_INSECURE + helm -n $NS install ida-auth mosip/ida-auth $IDA_HELM_ARGS --version $CHART_VERSION $ENABLE_INSECURE echo Installing ida internal - helm -n $NS install ida-internal mosip/ida-internal --version $CHART_VERSION $ENABLE_INSECURE + helm -n $NS install ida-internal mosip/ida-internal $IDA_HELM_ARGS --version $CHART_VERSION $ENABLE_INSECURE echo Installing ida otp - helm -n $NS install ida-otp mosip/ida-otp --version $CHART_VERSION $ENABLE_INSECURE + helm -n $NS install ida-otp mosip/ida-otp $IDA_HELM_ARGS --version $CHART_VERSION $ENABLE_INSECURE kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status - echo Intalled ida services + + echo Installed ida services return 0 } diff --git a/deployment/v3/mosip/ida/restart.sh b/deployment/v3/mosip/ida/restart.sh index c619b1c28..5887e2a04 100755 --- a/deployment/v3/mosip/ida/restart.sh +++ b/deployment/v3/mosip/ida/restart.sh @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_ida # calling function \ No newline at end of file +Restarting_ida # calling function diff --git a/deployment/v3/mosip/idrepo/copy_cm.sh b/deployment/v3/mosip/idrepo/copy_cm.sh index 623d11108..63432ab60 100755 --- a/deployment/v3/mosip/idrepo/copy_cm.sh +++ b/deployment/v3/mosip/idrepo/copy_cm.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/mosip/idrepo/delete.sh b/deployment/v3/mosip/idrepo/delete.sh index 3ed3fe3f0..0becc82c0 100755 --- a/deployment/v3/mosip/idrepo/delete.sh +++ b/deployment/v3/mosip/idrepo/delete.sh @@ -31,4 +31,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_idrepo # calling function \ No newline at end of file +deleting_idrepo # calling function diff --git a/deployment/v3/mosip/idrepo/install.sh b/deployment/v3/mosip/idrepo/install.sh index 6f9901f64..7b87e9b93 100755 --- a/deployment/v3/mosip/idrepo/install.sh +++ b/deployment/v3/mosip/idrepo/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=idrepo -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -37,6 +37,7 @@ function installing_idrepo() { helm -n $NS install vid mosip/vid --version $CHART_VERSION kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + echo Installed idrepo services return 0 } diff --git a/deployment/v3/mosip/image-compressor/install.sh b/deployment/v3/mosip/image-compressor/install.sh index 4b6fcd302..79d685b89 100644 --- a/deployment/v3/mosip/image-compressor/install.sh +++ b/deployment/v3/mosip/image-compressor/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=image-compressor -CHART_VERSION=12.0.1-B3 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -23,7 +23,7 @@ function installing_imagecompressor() { echo Installing imagecompressor server helm -n $NS install image-compressor mosip/biosdk-service \ - --set extraEnvVars[0].name="server_servlet_context_env" \ + --set extraEnvVars[0].name="server_servlet_context_path_env" \ --set extraEnvVars[0].value="/image-compressor" \ --set extraEnvVars[1].name="spring_application_name_env" \ --set extraEnvVars[1].value="image-compressor" \ diff --git a/deployment/v3/mosip/kernel/copy_cm.sh b/deployment/v3/mosip/kernel/copy_cm.sh index c0a53de79..c152cf88b 100755 --- a/deployment/v3/mosip/kernel/copy_cm.sh +++ b/deployment/v3/mosip/kernel/copy_cm.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/mosip/kernel/delete.sh b/deployment/v3/mosip/kernel/delete.sh index 973a85695..e803e59ff 100755 --- a/deployment/v3/mosip/kernel/delete.sh +++ b/deployment/v3/mosip/kernel/delete.sh @@ -6,7 +6,6 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi - function deleting_kernel() { NS=kernel while true; do @@ -36,4 +35,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_kernel # calling function \ No newline at end of file +deleting_kernel # calling function diff --git a/deployment/v3/mosip/kernel/install.sh b/deployment/v3/mosip/kernel/install.sh index be9a99069..203d7672b 100755 --- a/deployment/v3/mosip/kernel/install.sh +++ b/deployment/v3/mosip/kernel/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=kernel -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/kernel/restart.sh b/deployment/v3/mosip/kernel/restart.sh index 73d6d8b18..b286217c1 100755 --- a/deployment/v3/mosip/kernel/restart.sh +++ b/deployment/v3/mosip/kernel/restart.sh @@ -21,4 +21,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_kernel # calling function \ No newline at end of file +Restarting_kernel # calling function diff --git a/deployment/v3/mosip/key-migration-utility/README.md b/deployment/v3/mosip/key-migration-utility/README.md new file mode 100644 index 000000000..de2cd886c --- /dev/null +++ b/deployment/v3/mosip/key-migration-utility/README.md @@ -0,0 +1,9 @@ +# HSM Key Migrator + +## Install +The HSM Key migrator is done by running the below script: +``` +./install.sh +``` + + diff --git a/deployment/v3/mosip/key-migration-utility/copy_cm.sh b/deployment/v3/mosip/key-migration-utility/copy_cm.sh new file mode 100755 index 000000000..bc227055b --- /dev/null +++ b/deployment/v3/mosip/key-migration-utility/copy_cm.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Copy configmaps from other namespaces +# DST_NS: Destination (current) namespace + +function copying_cm() { + COPY_UTIL=../../utils/copy_cm_func.sh + DST_NS=key-migration-utility + + module=$1 + $COPY_UTIL configmap global default $DST_NS + $COPY_UTIL configmap artifactory-share artifactory $DST_NS + $COPY_UTIL configmap config-server-share config-server $DST_NS + $COPY_UTIL configmap softhsm-$module-share softhsm $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes + +if [[ $# -lt 1 ]]; then + echo "SoftHsm module name not passed; EXITING;" + exit 0; +fi +copying_cm $1 # calling function + + + diff --git a/deployment/v3/mosip/key-migration-utility/delete.sh b/deployment/v3/mosip/key-migration-utility/delete.sh new file mode 100755 index 000000000..ab5a9fa30 --- /dev/null +++ b/deployment/v3/mosip/key-migration-utility/delete.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Uninstalls key-migration-utility +## Usage: ./delete.sh [kubeconfig] + +if [ $# -ge 2 ] ; then + export KUBECONFIG=$2 +fi + +function deleting_hsm_key_migrator() { + NS=key-migration-utility + module=$1 + while true; do + read -p "Are you sure you want to delete key-migration-utility helm chart?(Y/n) " yn + if [ $yn = "Y" ] + then + helm -n $NS list + helm -n $NS delete "key-migration-utility-$module" + break + else + break + fi + done + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +if [[ $# -lt 1 ]]; then + echo "SoftHsm module name not passed; EXITING;" + exit 0; +fi +deleting_hsm_key_migrator $1 # calling function diff --git a/deployment/v3/mosip/key-migration-utility/install.sh b/deployment/v3/mosip/key-migration-utility/install.sh new file mode 100755 index 000000000..3a38764be --- /dev/null +++ b/deployment/v3/mosip/key-migration-utility/install.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Installs key-migration-utility +## Usage: ./install.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +NS=key-migration-utility +CHART_VERSION=0.0.1-develop + +echo Creating $NS namespace +kubectl create ns $NS + +function installing_key_migration_utility() { + + helm repo update + + read -p "please provide module name for migration (ex: kernel, ida, esignet, etc.) : " module + + if [[ -z $module ]]; then + echo "module is empty; EXITING;" + exit 0 + fi + + read -p "please provide properties file name (ex: migration ) : " config_prop + + if [[ -z $config_prop ]]; then + echo "config properties is empty; EXITING;" + exit 0 + fi + + echo Copy configmaps + sed -i 's/\r$//' copy_cm.sh + ./copy_cm.sh $module + + echo Installing key-migration-utility + helm -n $NS install key-migration-utility-$module mosip/key-migration-utility \ + --set softHsmCM=softhsm-$module-share \ + --set springConfigNameEnv=$config_prop \ + --wait --wait-for-jobs \ + --version $CHART_VERSION + + echo Installed key-migration-utility services + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +installing_key_migration_utility # calling function diff --git a/deployment/v3/mosip/keymanager/delete.sh b/deployment/v3/mosip/keymanager/delete.sh index 189d302fa..f548b3870 100755 --- a/deployment/v3/mosip/keymanager/delete.sh +++ b/deployment/v3/mosip/keymanager/delete.sh @@ -28,4 +28,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_keymanager # calling function \ No newline at end of file +deleting_keymanager # calling function diff --git a/deployment/v3/mosip/keymanager/idle_timeout_envoyfilter.yaml b/deployment/v3/mosip/keymanager/idle_timeout_envoyfilter.yaml index fd45a91d7..9a8fd4992 100644 --- a/deployment/v3/mosip/keymanager/idle_timeout_envoyfilter.yaml +++ b/deployment/v3/mosip/keymanager/idle_timeout_envoyfilter.yaml @@ -16,5 +16,5 @@ spec: value: name: envoy.filters.network.tcp_proxy typed_config: - '@type': type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy idle_timeout: 0s diff --git a/deployment/v3/mosip/keymanager/install.sh b/deployment/v3/mosip/keymanager/install.sh index b682c7ddb..6321b5848 100755 --- a/deployment/v3/mosip/keymanager/install.sh +++ b/deployment/v3/mosip/keymanager/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=keymanager -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Creating $NS namespace kubectl create ns $NS @@ -22,11 +22,45 @@ function installing_keymanager() { sed -i 's/\r$//' copy_cm.sh ./copy_cm.sh + default_enable_volume=false + read -p "Would you like to enable volume (true/false) : [ default : false ] : " enable_volume + enable_volume=${enable_volume:-$default_enable_volume} + + KERNEL_KEYGEN_HELM_ARGS='--set springConfigNameEnv="kernel" --set softHsmCM="softhsm-kernel-share"' + KERNEL_HELM_ARGS='' + if [[ $enable_volume == 'true' ]]; then + + default_volume_size=100M + read -p "Provide the size for volume [ default : 100M ]" volume_size + volume_size=${volume_size:-$default_volume_size} + + default_volume_mount_path='/home/mosip/config/' + read -p "Provide the mount path for volume [ default : '/home/mosip/config/' ] : " volume_mount_path + volume_mount_path=${volume_mount_path:-$default_volume_mount_path} + + PVC_CLAIM_NAME='kernel-keygen-keymanager' + KERNEL_KEYGEN_HELM_ARGS="--set persistence.enabled=true \ + --set volumePermissions.enabled=true \ + --set persistence.size=$volume_size \ + --set persistence.mountDir=\"$volume_mount_path\" \ + --set springConfigNameEnv='kernel' \ + --set persistence.pvc_claim_name=\"$PVC_CLAIM_NAME\" \ + " + KERNEL_HELM_ARGS="--set persistence.enabled=true \ + --set volumePermissions.enabled=true \ + --set persistence.mountDir=\"$volume_mount_path\" \ + --set persistence.existingClaim=\"$PVC_CLAIM_NAME\" \ + --set extraEnvVarsCM={'global','config-server-share','artifactory-share'} \ + " + fi + echo "KERNEL KEYGEN HELM ARGS $KERNEL_KEYGEN_HELM_ARGS" + echo "KERNEL HELM ARGS $KERNEL_HELM_ARGS" + echo Running keygenerator. This may take a few minutes.. - helm -n $NS install kernel-keygen mosip/keygen --wait --wait-for-jobs --version $CHART_VERSION -f keygen_values.yaml + helm -n $NS install kernel-keygen mosip/keygen $KERNEL_KEYGEN_HELM_ARGS --wait --wait-for-jobs --version $CHART_VERSION echo Installing keymanager - helm -n $NS install keymanager mosip/keymanager --version $CHART_VERSION + helm -n $NS install keymanager mosip/keymanager $KERNEL_HELM_ARGS --wait --version $CHART_VERSION kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status echo Installed keymanager services diff --git a/deployment/v3/mosip/keymanager/restart.sh b/deployment/v3/mosip/keymanager/restart.sh index f56665af8..1199194b6 100755 --- a/deployment/v3/mosip/keymanager/restart.sh +++ b/deployment/v3/mosip/keymanager/restart.sh @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_keymanager # calling function \ No newline at end of file +Restarting_keymanager # calling function diff --git a/deployment/v3/mosip/masterdata-loader/README.md b/deployment/v3/mosip/masterdata-loader/README.md new file mode 100644 index 000000000..02c133167 --- /dev/null +++ b/deployment/v3/mosip/masterdata-loader/README.md @@ -0,0 +1,7 @@ +# Masterdataloader + +## Install +* To incorporate your own master data, modify the `install.sh` with your `GithubBranch`, `GithubRepo` and `XlsfolderPath: /home/mosip/`. +``` +./install.sh +``` diff --git a/deployment/v3/mosip/masterdata-loader/copy_secrets.sh b/deployment/v3/mosip/masterdata-loader/copy_secrets.sh index 1014f12a4..be615ff5f 100755 --- a/deployment/v3/mosip/masterdata-loader/copy_secrets.sh +++ b/deployment/v3/mosip/masterdata-loader/copy_secrets.sh @@ -15,4 +15,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_secrets # calling function \ No newline at end of file +copying_secrets # calling function diff --git a/deployment/v3/mosip/masterdata-loader/install.sh b/deployment/v3/mosip/masterdata-loader/install.sh index d90826249..c67a84df8 100755 --- a/deployment/v3/mosip/masterdata-loader/install.sh +++ b/deployment/v3/mosip/masterdata-loader/install.sh @@ -6,13 +6,13 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi +NS=masterdata-loader +CHART_VERSION=0.0.1-develop echo WARNING: This need to be executed only once at the begining for masterdata deployment. If reexecuted in a working env this will reset the whole master_data DB tables resulting in data loss. echo Please skip this if masterdata is already uploaded. read -p "CAUTION: Do you still want to continue(Y/n)" yn if [ $yn = "Y" ] then - NS=masterdata-loader - CHART_VERSION=12.0.1 helm delete masterdata-loader -n $NS echo Create $NS namespace kubectl create ns $NS @@ -33,7 +33,11 @@ if [ $yn = "Y" ] ./copy_secrets.sh echo Loading masterdata - helm -n $NS install masterdata-loader mosip/masterdata-loader --set mosipDataGithubBranch=v1.2.0.1 --version $CHART_VERSION --wait + helm -n $NS install masterdata-loader mosip/masterdata-loader \ + --set mosipDataGithubBranch="develop" \ + --set mosipDataGithubRepo="https://github.com/mosip/mosip-data" \ + --set mosipDataXlsfolderPath="\/home/mosip/mosip-data/mosip_master/xlsx" \ + --version $CHART_VERSION --wait --wait-for-jobs else break diff --git a/deployment/v3/mosip/mock-abis/delete.sh b/deployment/v3/mosip/mock-abis/delete.sh index 2a5e9b227..c7b839ce3 100755 --- a/deployment/v3/mosip/mock-abis/delete.sh +++ b/deployment/v3/mosip/mock-abis/delete.sh @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_abis # calling function \ No newline at end of file +deleting_abis # calling function diff --git a/deployment/v3/mosip/mock-abis/install.sh b/deployment/v3/mosip/mock-abis/install.sh index 8348ad66d..b2cb95ed7 100755 --- a/deployment/v3/mosip/mock-abis/install.sh +++ b/deployment/v3/mosip/mock-abis/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=abis -CHART_VERSION=12.0.2 +CHART_VERSION=12.0.x-develop echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/mock-abis/restart.sh b/deployment/v3/mosip/mock-abis/restart.sh index 16ccc1b84..14391f7bf 100755 --- a/deployment/v3/mosip/mock-abis/restart.sh +++ b/deployment/v3/mosip/mock-abis/restart.sh @@ -8,7 +8,7 @@ fi function Restarting_abis() { NS=abis - kubectl -n $NS rollout restart deploy + kubectl -n $NS rollout restart deploy kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_abis # calling function \ No newline at end of file +Restarting_abis # calling function diff --git a/deployment/v3/mosip/mock-mv/delete.sh b/deployment/v3/mosip/mock-mv/delete.sh index 02a2dca32..fb6001cd5 100755 --- a/deployment/v3/mosip/mock-mv/delete.sh +++ b/deployment/v3/mosip/mock-mv/delete.sh @@ -1,6 +1,5 @@ #!/bin/bash # Uninstalls mock mv - function deleting_mockmv() { NS=abis while true; do @@ -22,4 +21,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_mockmv # calling function \ No newline at end of file +deleting_mockmv # calling function diff --git a/deployment/v3/mosip/mock-mv/install.sh b/deployment/v3/mosip/mock-mv/install.sh index d71dde3cb..cef945e5a 100755 --- a/deployment/v3/mosip/mock-mv/install.sh +++ b/deployment/v3/mosip/mock-mv/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=abis -CHART_VERSION=12.0.2 +CHART_VERSION=12.0.x-develop echo Create $NS namespace kubectl create ns $NS @@ -25,7 +25,9 @@ function installing_mockmv() { helm -n $NS install mock-mv mosip/mock-mv --version $CHART_VERSION kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status - echo Intalled mock-mv services + + echo Installed mock-mv services + return 0 } diff --git a/deployment/v3/mosip/mock-mv/restart.sh b/deployment/v3/mosip/mock-mv/restart.sh index 8b1a10814..f872b8f78 100755 --- a/deployment/v3/mosip/mock-mv/restart.sh +++ b/deployment/v3/mosip/mock-mv/restart.sh @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_mockmv # calling function \ No newline at end of file +Restarting_mockmv # calling function diff --git a/deployment/v3/mosip/mock-smtp/README.md b/deployment/v3/mosip/mock-smtp/README.md index decd1f4b8..c210d5f8f 100644 --- a/deployment/v3/mosip/mock-smtp/README.md +++ b/deployment/v3/mosip/mock-smtp/README.md @@ -29,4 +29,4 @@ The chart here installs a Mock SMTP and Mock SMS accessed over an https URL. * Install ```sh ./install.sh -``` \ No newline at end of file +``` diff --git a/deployment/v3/mosip/mock-smtp/delete.sh b/deployment/v3/mosip/mock-smtp/delete.sh index e9b540753..9a05c7a5a 100755 --- a/deployment/v3/mosip/mock-smtp/delete.sh +++ b/deployment/v3/mosip/mock-smtp/delete.sh @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -mock_smtp # calling function \ No newline at end of file +mock_smtp # calling function diff --git a/deployment/v3/mosip/mock-smtp/install.sh b/deployment/v3/mosip/mock-smtp/install.sh index a36cd32f2..0c6fdb796 100755 --- a/deployment/v3/mosip/mock-smtp/install.sh +++ b/deployment/v3/mosip/mock-smtp/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=mock-smtp -CHART_VERSION=1.0.0 +CHART_VERSION=12.0.x-develop echo Create $NS namespace kubectl create ns $NS @@ -15,7 +15,7 @@ kubectl create ns $NS function mock_smtp() { echo Istio label kubectl label ns $NS istio-injection=enabled --overwrite - # helm repo update + helm repo update echo "Copy configmaps" sed -i 's/\r$//' copy_cm.sh diff --git a/deployment/v3/mosip/mock-smtp/restart.sh b/deployment/v3/mosip/mock-smtp/restart.sh index 108bd68d4..1334aee6d 100755 --- a/deployment/v3/mosip/mock-smtp/restart.sh +++ b/deployment/v3/mosip/mock-smtp/restart.sh @@ -11,6 +11,7 @@ function Restarting_smtp() { kubectl -n $NS rollout restart deploy kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + echo Restarted mock-smtp services return 0 } @@ -21,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_smtp # calling function \ No newline at end of file +Restarting_smtp # calling function diff --git a/deployment/v3/mosip/mosip-file-server/delete.sh b/deployment/v3/mosip/mosip-file-server/delete.sh index aec896f91..0a566d441 100755 --- a/deployment/v3/mosip/mosip-file-server/delete.sh +++ b/deployment/v3/mosip/mosip-file-server/delete.sh @@ -27,4 +27,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_mfs # calling function \ No newline at end of file +deleting_mfs # calling function diff --git a/deployment/v3/mosip/mosip-file-server/install.sh b/deployment/v3/mosip/mosip-file-server/install.sh index faf2dc255..0120c8754 100755 --- a/deployment/v3/mosip/mosip-file-server/install.sh +++ b/deployment/v3/mosip/mosip-file-server/install.sh @@ -8,7 +8,7 @@ fi NS=mosip-file-server -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/mosip-file-server/restart.sh b/deployment/v3/mosip/mosip-file-server/restart.sh index 45d34083d..5e04e509d 100755 --- a/deployment/v3/mosip/mosip-file-server/restart.sh +++ b/deployment/v3/mosip/mosip-file-server/restart.sh @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_mfs # calling function \ No newline at end of file +Restarting_mfs # calling function diff --git a/deployment/v3/mosip/mosip-file-server/values.yaml b/deployment/v3/mosip/mosip-file-server/values.yaml new file mode 100644 index 000000000..165e37423 --- /dev/null +++ b/deployment/v3/mosip/mosip-file-server/values.yaml @@ -0,0 +1,24 @@ +image: + registry: docker.io + repository: mosipdev/mosip-file-server + tag: develop + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: Always + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +regclient: + version: 1.2.1-SNAPSHOT + mountDir: /home/mosip/build_files/ + ## Currently this is hardcoded. Will change in the future + cryptoKey: bBQX230Wskq6XpoZ1c+Ep1D+znxfT89NxLQ7P4KFkc4= + upgradeServerUrl: https://regclient.sandbox.xzy.net + ## Here we check the health of syncdata service. The service must be accessible over internal channel. + healthCheckUrl: http://api-internal.sandbox.v3box1.net/v1/syncdata/actuator/health diff --git a/deployment/v3/mosip/mosipcertmanager/README.md b/deployment/v3/mosip/mosipcertmanager/README.md new file mode 100644 index 000000000..d35d89e33 --- /dev/null +++ b/deployment/v3/mosip/mosipcertmanager/README.md @@ -0,0 +1,17 @@ +# mosipcertmanager +Helm chart for installing mosipcertmanager + +## Introduction +It's a cronjob that checks DBs for partner certificate expiry dates and renews the certificates if expired. + +## Install +RUN Install script +``` +./install.sh +``` + +# TL;DR +```console +$ helm repo add mosip https://mosip.github.io +$ helm install my-release mosip/mosipcertmanager +``` \ No newline at end of file diff --git a/deployment/v3/mosip/mosipcertmanager/copy_cm.sh b/deployment/v3/mosip/mosipcertmanager/copy_cm.sh new file mode 100755 index 000000000..a551f6844 --- /dev/null +++ b/deployment/v3/mosip/mosipcertmanager/copy_cm.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copy configmaps from other namespaces +# DST_NS: Destination (current) namespace + +function copying_cm() { + COPY_UTIL=../../utils/copy_cm_func.sh + DST_NS=mosipcertmanager + + $COPY_UTIL configmap global default $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +copying_cm # calling function + + + diff --git a/deployment/v3/mosip/mosipcertmanager/copy_secrets.sh b/deployment/v3/mosip/mosipcertmanager/copy_secrets.sh new file mode 100755 index 000000000..3b3654353 --- /dev/null +++ b/deployment/v3/mosip/mosipcertmanager/copy_secrets.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Copy secrets from other namespaces +# DST_NS: Destination namespace + +function copying_secrets() { + COPY_UTIL=../../utils/copy_cm_func.sh + DST_NS=mosipcertmanager + $COPY_UTIL secret s3 s3 $DST_NS + $COPY_UTIL secret postgres-postgresql postgres $DST_NS + $COPY_UTIL secret keycloak-client-secrets keycloak $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +copying_secrets # calling function \ No newline at end of file diff --git a/deployment/v3/mosip/mosipcertmanager/delete.sh b/deployment/v3/mosip/mosipcertmanager/delete.sh new file mode 100755 index 000000000..b089ab29b --- /dev/null +++ b/deployment/v3/mosip/mosipcertmanager/delete.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Uninstalls print service +## Usage: ./delete.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +function deleting_mosipcertmanager() { + NS=mosipcertmanager + while true; do + read -p "Are you sure you want to delete print helm chart?(Y/n) " yn + if [ $yn = "Y" ] + then + helm -n $NS delete mosipcertmanager + break + else + break + fi + done + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +deleting_mosipcertmanager # calling function diff --git a/deployment/v3/mosip/mosipcertmanager/install.sh b/deployment/v3/mosip/mosipcertmanager/install.sh new file mode 100755 index 000000000..321116361 --- /dev/null +++ b/deployment/v3/mosip/mosipcertmanager/install.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Installs sample print service +## Usage: ./restart.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + + +NS=mosipcertmanager +CHART_VERSION=0.0.1-develop + +echo Create $NS namespace +kubectl create ns $NS + +function installing_mosipcertmanager() { + echo Istio label + kubectl label ns $NS istio-injection=disabled --overwrite + helm repo update + + echo Copy configmaps + sed -i 's/\r$//' copy_cm.sh + ./copy_cm.sh + + echo Copy secrets + sed -i 's/\r$//' copy_secrets.sh + ./copy_secrets.sh + + echo Installing mosipcertmanager + helm -n $NS install mosipcertmanager mosip/mosipcertmanager --wait --version $CHART_VERSION + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +installing_mosipcertmanager # calling function diff --git a/deployment/v3/mosip/packetmanager/delete.sh b/deployment/v3/mosip/packetmanager/delete.sh index af4c734da..825abecf3 100755 --- a/deployment/v3/mosip/packetmanager/delete.sh +++ b/deployment/v3/mosip/packetmanager/delete.sh @@ -27,4 +27,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_packetmanager # calling function \ No newline at end of file +deleting_packetmanager # calling function diff --git a/deployment/v3/mosip/packetmanager/restart.sh b/deployment/v3/mosip/packetmanager/restart.sh index 550dff7de..c5068b29a 100755 --- a/deployment/v3/mosip/packetmanager/restart.sh +++ b/deployment/v3/mosip/packetmanager/restart.sh @@ -11,6 +11,7 @@ function Restarting_packetmanager() { kubectl -n $NS rollout restart deploy kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + echo Restarted packetmanager services return 0 } @@ -21,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_packetmanager # calling function \ No newline at end of file +Restarting_packetmanager # calling function diff --git a/deployment/v3/mosip/partner-onboarder/README.md b/deployment/v3/mosip/partner-onboarder/README.md index 3c2105d40..b5712d727 100644 --- a/deployment/v3/mosip/partner-onboarder/README.md +++ b/deployment/v3/mosip/partner-onboarder/README.md @@ -39,6 +39,3 @@ Loads certs for default partners for sandbox. Refer [mosip-onboarding repo](http 3. Upload of certificate will not be allowed to update other domain certificate Resolution: This is expected when you try to upload `ida-cred` certificate twice. It should only run once and if you see this error while uploading a second time it can be ignored as the cert is already present. - - - diff --git a/deployment/v3/mosip/partner-onboarder/copy_cm.sh b/deployment/v3/mosip/partner-onboarder/copy_cm.sh index f7fd8e571..95c00f665 100755 --- a/deployment/v3/mosip/partner-onboarder/copy_cm.sh +++ b/deployment/v3/mosip/partner-onboarder/copy_cm.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/mosip/partner-onboarder/copy_secrets.sh b/deployment/v3/mosip/partner-onboarder/copy_secrets.sh index 2ae4ff548..ea9000590 100755 --- a/deployment/v3/mosip/partner-onboarder/copy_secrets.sh +++ b/deployment/v3/mosip/partner-onboarder/copy_secrets.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_secrets # calling function \ No newline at end of file +copying_secrets # calling function diff --git a/deployment/v3/mosip/partner-onboarder/install.sh b/deployment/v3/mosip/partner-onboarder/install.sh index 0b3306ab1..bc799ae3d 100755 --- a/deployment/v3/mosip/partner-onboarder/install.sh +++ b/deployment/v3/mosip/partner-onboarder/install.sh @@ -21,7 +21,21 @@ if [ "$flag" = "n" ]; then fi NS=onboarder -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop + +echo "Do you have public domain & valid SSL? (Y/n) " +echo "Y: if you have public domain & valid ssl certificate" +echo "n: If you don't have a public domain and a valid SSL certificate. Note: It is recommended to use this option only in development environments." +read -p "" flag + +if [ -z "$flag" ]; then + echo "'flag' was provided; EXITING;" + exit 1; +fi +ENABLE_INSECURE='' +if [ "$flag" = "n" ]; then + ENABLE_INSECURE='--set onboarding.configmaps.onboarding.ENABLE_INSECURE=true'; +fi echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/pms-migration-utility/copy_cm.sh b/deployment/v3/mosip/pms-migration-utility/copy_cm.sh index 478f2bbcb..5e00f883f 100755 --- a/deployment/v3/mosip/pms-migration-utility/copy_cm.sh +++ b/deployment/v3/mosip/pms-migration-utility/copy_cm.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/mosip/pms/copy_cm.sh b/deployment/v3/mosip/pms/copy_cm.sh index 0d3e9be49..9fbd381ff 100755 --- a/deployment/v3/mosip/pms/copy_cm.sh +++ b/deployment/v3/mosip/pms/copy_cm.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/mosip/pms/delete.sh b/deployment/v3/mosip/pms/delete.sh index 6d480a977..1db0145b7 100755 --- a/deployment/v3/mosip/pms/delete.sh +++ b/deployment/v3/mosip/pms/delete.sh @@ -15,6 +15,7 @@ function deleting_pms() { helm -n $NS delete pms-partner helm -n $NS delete pms-policy helm -n $NS delete pmp-ui + helm -n $NS delete pmp-reactjs-ui break else break @@ -29,4 +30,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_pms # calling function \ No newline at end of file +deleting_pms # calling function diff --git a/deployment/v3/mosip/pms/install.sh b/deployment/v3/mosip/pms/install.sh index 4213e2ed1..a20b848f6 100755 --- a/deployment/v3/mosip/pms/install.sh +++ b/deployment/v3/mosip/pms/install.sh @@ -7,11 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=pms -CHART_VERSION=12.0.1 -PMP_UI_CHART_VERSION=12.0.2 - -API_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-api-internal-host}) -PMP_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-pmp-host}) +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -27,21 +23,39 @@ function installing_pms() { INTERNAL_API_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-api-internal-host}) PMP_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-pmp-host}) + PMP_NEW_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-pmp-reactjs-ui-new-host}) + + PARTNER_MANAGER_SERVICE_NAME="pms-partner" + POLICY_MANAGER_SERVICE_NAME="pms-policy" echo Installing partner manager - helm -n $NS install pms-partner mosip/pms-partner --set istio.corsPolicy.allowOrigins\[0\].prefix=https://$PMP_HOST --version $CHART_VERSION + helm -n $NS install $PARTNER_MANAGER_SERVICE_NAME mosip/pms-partner \ + --set istio.corsPolicy.allowOrigins\[0\].prefix=https://$PMP_HOST \ + --set istio.corsPolicy.allowOrigins\[1\].prefix=https://$PMP_NEW_HOST \ + --version $CHART_VERSION echo Installing policy manager - helm -n $NS install pms-policy mosip/pms-policy --set istio.corsPolicy.allowOrigins\[0\].prefix=https://$PMP_HOST --version $CHART_VERSION + helm -n $NS install $POLICY_MANAGER_SERVICE_NAME mosip/pms-policy \ + --set istio.corsPolicy.allowOrigins\[0\].prefix=https://$PMP_HOST \ + --set istio.corsPolicy.allowOrigins\[1\].prefix=https://$PMP_NEW_HOST \ + --version $CHART_VERSION echo Installing pmp-ui - helm -n $NS install pmp-ui mosip/pmp-ui --set pmp.apiUrl=https://$INTERNAL_API_HOST/ --set istio.hosts=["$PMP_HOST"] --version $PMP_UI_CHART_VERSION + helm -n $NS install pmp-ui mosip/pmp-ui --set pmp.apiUrl=https://$INTERNAL_API_HOST/ --set istio.hosts=["$PMP_HOST"] --version $CHART_VERSION + + echo Installing pmp-reactjs-ui-new + helm -n $NS install pmp-reactjs-ui mosip/pmp-reactjs-ui \ + --set pmp_new.react_app_partner_manager_api_base_url="https://$INTERNAL_API_HOST/v1/partnermanager" \ + --set pmp_new.react_app_policy_manager_api_base_url="https://$INTERNAL_API_HOST/v1/policymanager" \ + --set pmp_new.pms_partner_manager_internal_service_url="http://$PARTNER_MANAGER_SERVICE_NAME.$NS/v1/partnermanager" \ + --set pmp_new.pms_policy_manager_internal_service_url="http://$POLICY_MANAGER_SERVICE_NAME.$NS/v1/policymanager" \ + --set istio.hosts=["$PMP_NEW_HOST"] --version $CHART_VERSION kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status echo Installed pms services - echo "Admin portal URL: https://$PMP_HOST/pmp-ui/" + echo "Partner management portal URL: https://$PMP_HOST/pmp-ui/" return 0 } diff --git a/deployment/v3/mosip/pms/restart.sh b/deployment/v3/mosip/pms/restart.sh index 7f83a7c9f..8d11b9581 100755 --- a/deployment/v3/mosip/pms/restart.sh +++ b/deployment/v3/mosip/pms/restart.sh @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_pms # calling function \ No newline at end of file +Restarting_pms # calling function diff --git a/deployment/v3/mosip/prereg/delete.sh b/deployment/v3/mosip/prereg/delete.sh index c84d782c7..dc0714790 100755 --- a/deployment/v3/mosip/prereg/delete.sh +++ b/deployment/v3/mosip/prereg/delete.sh @@ -1,6 +1,5 @@ #!/bin/bash # Uninstalls all prereg helm charts - function deleting_prereg() { while true; do read -p "Are you sure you want to delete all prereg helm charts?(Y/n) " yn @@ -8,7 +7,6 @@ function deleting_prereg() { then kubectl -n prereg delete -f rate-control-envoyfilter.yaml helm -n prereg delete prereg-gateway - helm -n prereg delete prereg-captcha helm -n prereg delete prereg-application helm -n prereg delete prereg-batchjob helm -n prereg delete prereg-booking @@ -28,4 +26,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_prereg # calling function \ No newline at end of file +deleting_prereg # calling function diff --git a/deployment/v3/mosip/prereg/install.sh b/deployment/v3/mosip/prereg/install.sh index 79276563c..6d7072be7 100755 --- a/deployment/v3/mosip/prereg/install.sh +++ b/deployment/v3/mosip/prereg/install.sh @@ -29,9 +29,6 @@ function installing_prereg() { echo Install prereg-gateway helm -n $NS install prereg-gateway mosip/prereg-gateway --set istio.hosts[0]=$PREREG_HOST --version $CHART_VERSION - echo Installing prereg-captcha - helm -n $NS install prereg-captcha mosip/prereg-captcha --version $CHART_VERSION - echo Installing prereg-application helm -n $NS install prereg-application mosip/prereg-application --version $CHART_VERSION diff --git a/deployment/v3/mosip/prereg/restart.sh b/deployment/v3/mosip/prereg/restart.sh index a8df25e79..1f6f9fab2 100755 --- a/deployment/v3/mosip/prereg/restart.sh +++ b/deployment/v3/mosip/prereg/restart.sh @@ -6,7 +6,6 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi - function Restarting_prereg() { NS=prereg kubectl -n $NS rollout restart deploy @@ -23,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_prereg # calling function \ No newline at end of file +Restarting_prereg # calling function diff --git a/deployment/v3/mosip/print/delete.sh b/deployment/v3/mosip/print/delete.sh index ab0022578..3fa35effc 100755 --- a/deployment/v3/mosip/print/delete.sh +++ b/deployment/v3/mosip/print/delete.sh @@ -27,4 +27,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_print # calling function \ No newline at end of file +deleting_print # calling function diff --git a/deployment/v3/mosip/print/install.sh b/deployment/v3/mosip/print/install.sh index 00c4e120d..7b64b9092 100755 --- a/deployment/v3/mosip/print/install.sh +++ b/deployment/v3/mosip/print/install.sh @@ -9,7 +9,6 @@ fi NS=print CHART_VERSION=12.0.1 - echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/print/restart.sh b/deployment/v3/mosip/print/restart.sh index d83382d15..76fd74423 100755 --- a/deployment/v3/mosip/print/restart.sh +++ b/deployment/v3/mosip/print/restart.sh @@ -6,12 +6,12 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi - function Restarting_print() { NS=print kubectl -n $NS rollout restart deploy kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + echo Restarted print services return 0 } diff --git a/deployment/v3/mosip/regclient/README.md b/deployment/v3/mosip/regclient/README.md index 2464481b1..4bec9fd41 100644 --- a/deployment/v3/mosip/regclient/README.md +++ b/deployment/v3/mosip/regclient/README.md @@ -10,6 +10,9 @@ The chart here installs a regclient downloader accessed over an http URL. ```sh ./install.sh ``` +## Download +The download URL will be available at `https://your-reglient-host`. Example: `https://reglient.sandbox.xyz.net`. + ## Customization If you want to add extra environment variables to the regclient docker do follow the below mentioned steps. 1. Add the variables in extraEnvVars section of the sample 'values.yaml.sample' file given. diff --git a/deployment/v3/mosip/regclient/install.sh b/deployment/v3/mosip/regclient/install.sh index a9d899f75..a0b7e2794 100755 --- a/deployment/v3/mosip/regclient/install.sh +++ b/deployment/v3/mosip/regclient/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=regclient -CHART_VERSION=12.0.2 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/regclient/values.yaml.sample b/deployment/v3/mosip/regclient/values.yaml.sample new file mode 100644 index 000000000..417a33cca --- /dev/null +++ b/deployment/v3/mosip/regclient/values.yaml.sample @@ -0,0 +1,3 @@ +extraEnvVars: + - name: client_certificate_env + value: mosip_cer.cer diff --git a/deployment/v3/mosip/regproc/delete.sh b/deployment/v3/mosip/regproc/delete.sh index 02a382d1d..ad4824e93 100755 --- a/deployment/v3/mosip/regproc/delete.sh +++ b/deployment/v3/mosip/regproc/delete.sh @@ -1,6 +1,5 @@ #!/bin/bash # Uninstalls all regproc helm charts - function deleting_regproc() { NS=regproc while true; do @@ -22,6 +21,7 @@ function deleting_regproc() { helm -n $NS delete regproc-notifier helm -n $NS delete regproc-trans helm -n $NS delete regproc-reprocess + helm -n $NS delete regproc-landingzone break else break @@ -36,4 +36,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_regproc # calling function \ No newline at end of file +deleting_regproc # calling function diff --git a/deployment/v3/mosip/regproc/install.sh b/deployment/v3/mosip/regproc/install.sh index 806c628fe..2e08dd181 100755 --- a/deployment/v3/mosip/regproc/install.sh +++ b/deployment/v3/mosip/regproc/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=regproc -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -70,7 +70,8 @@ function installing_regproc() { helm -n $NS install regproc-landingzone mosip/regproc-landingzone --version $CHART_VERSION kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status - echo Intalled regproc services + + echo Installed regproc services return 0 } diff --git a/deployment/v3/mosip/regproc/restart.sh b/deployment/v3/mosip/regproc/restart.sh index 84ae32390..cf622fa0b 100755 --- a/deployment/v3/mosip/regproc/restart.sh +++ b/deployment/v3/mosip/regproc/restart.sh @@ -6,7 +6,6 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi - function Restarting_regproc() { NS=regproc kubectl -n $NS rollout restart deploy @@ -23,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_regproc # calling function \ No newline at end of file +Restarting_regproc # calling function diff --git a/deployment/v3/mosip/regproc/topic/create_topics.sh b/deployment/v3/mosip/regproc/topic/create_topics.sh new file mode 100755 index 000000000..a495c6857 --- /dev/null +++ b/deployment/v3/mosip/regproc/topic/create_topics.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# + +function create_topics() { + read -p "Enter IAM username: " iam_user + + # This username is hardcoded in sql scripts + DB_PWD=$(kubectl get secret --namespace postgres db-common-secrets -o jsonpath={.data.db-dbuser-password} | base64 --decode) + DB_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-api-internal-host}) + DB_PORT=5432 + + echo Creating topics + cd lib + python3 create_topics.py $DB_HOST $DB_PWD $iam_user ../topics.xlsx +return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +create_topics # calling function diff --git a/deployment/v3/mosip/resident/copy_cm.sh b/deployment/v3/mosip/resident/copy_cm.sh index 8fdbecbfb..bcb63d042 100755 --- a/deployment/v3/mosip/resident/copy_cm.sh +++ b/deployment/v3/mosip/resident/copy_cm.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/mosip/resident/delete.sh b/deployment/v3/mosip/resident/delete.sh index 8661168a4..6be4efb9d 100755 --- a/deployment/v3/mosip/resident/delete.sh +++ b/deployment/v3/mosip/resident/delete.sh @@ -1,6 +1,5 @@ #!/bin/bash # Uninstalls resident - function deleting_resident() { NS=resident while true; do @@ -9,6 +8,7 @@ function deleting_resident() { then helm -n $NS delete resident helm -n $NS delete resident-ui +# kubectl delete -n $NS -f resident-ui break else break diff --git a/deployment/v3/mosip/resident/install.sh b/deployment/v3/mosip/resident/install.sh index ded8fe9ff..f8c819a75 100755 --- a/deployment/v3/mosip/resident/install.sh +++ b/deployment/v3/mosip/resident/install.sh @@ -7,8 +7,8 @@ if [ $# -ge 1 ] ; then fi NS=resident -CHART_VERSION=12.0.1 -RESIDENT_UI_CHART_VERSION=0.0.1 +CHART_VERSION=0.0.1-develop +RESIDENT_UI_CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -25,14 +25,12 @@ function installing_resident() { echo Copy secrets sed -i 's/\r$//' copy_secrets.sh ./copy_secrets.sh - echo Setting up dummy values for Resident OIDC Client ID kubectl create secret generic resident-oidc-onboarder-key -n $NS --from-literal=resident-oidc-clientid='' --dry-run=client -o yaml | kubectl apply -f - ./copy_cm_func.sh secret resident-oidc-onboarder-key resident config-server kubectl -n config-server set env --keys=resident-oidc-clientid --from secret/resident-oidc-onboarder-key deployment/config-server --prefix=SPRING_CLOUD_CONFIG_SERVER_OVERRIDES_ kubectl -n config-server get deploy -o name | xargs -n1 -t kubectl -n config-server rollout status - echo "Do you have public domain & valid SSL? (Y/n) " echo "Y: if you have public domain & valid ssl certificate" echo "n: If you don't have a public domain and a valid SSL certificate. Note: It is recommended to use this option only in development environments." @@ -50,6 +48,7 @@ function installing_resident() { API_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-api-internal-host}) RESIDENT_HOST=$(kubectl get cm global -o jsonpath={.data.mosip-resident-host}) + echo Installing Resident helm -n $NS install resident mosip/resident --set istio.corsPolicy.allowOrigins\[0\].prefix=https://$RESIDENT_HOST --version $CHART_VERSION $ENABLE_INSECURE diff --git a/deployment/v3/mosip/resident/restart.sh b/deployment/v3/mosip/resident/restart.sh index 971281dbb..ba0e7d86f 100755 --- a/deployment/v3/mosip/resident/restart.sh +++ b/deployment/v3/mosip/resident/restart.sh @@ -6,12 +6,12 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi - function Restarting_resident() { NS=resident kubectl -n $NS rollout restart deploy kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + echo Restarted resident services return 0 } @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_resident # calling function \ No newline at end of file +Restarting_resident # calling function diff --git a/deployment/v3/mosip/restart-cron/README.md b/deployment/v3/mosip/restart-cron/README.md index fb6751faf..0ce99d996 100644 --- a/deployment/v3/mosip/restart-cron/README.md +++ b/deployment/v3/mosip/restart-cron/README.md @@ -3,11 +3,13 @@ ## Introduction RESTART_CRON chart deploys a CronJob that runs on a schedule specified in the values.yaml file. The CronJob restarts deployments in the specified namespaces using the kubectl rollout restart command and waits for them to reach the desired state using the kubectl rollout status command.. -For now this cronjob is being used to restart packetcreator and authdemo service in a cluster, It can be used to restart other services aswell. +For now this cronjob is being used to restart idgenerator service in a cluster, It can be used to restart other services like packetcreator and authdemo as well. + +Idgenerator service will restart every after four hour in a cluster. ## Prerequisites -* Auth demo, Packetcreator and DSLRIG to be running in the same cluster. -* If Auth demo and Packetcreator service is not running in the same cluster then update the values.yaml file by enabling the only service which is present or which you want to restart. +* Auth demo, Packetcreator, Idgenerator and DSLRIG to be running in the same cluster. +* If Auth demo, Idgenerator and Packetcreator service is not running in the same cluster then update the values.yaml file by enabling the only service which is present or which you want to restart. * Set `values.yaml` to run cronjob for restarting specific services. * run `./install.sh`. diff --git a/deployment/v3/mosip/restart-cron/install.sh b/deployment/v3/mosip/restart-cron/install.sh index 92e94493b..0ec9f3950 100755 --- a/deployment/v3/mosip/restart-cron/install.sh +++ b/deployment/v3/mosip/restart-cron/install.sh @@ -13,7 +13,7 @@ echo Create $NS namespace kubectl create ns $NS function installing_restart-cron() { - echo "This script installs cronjob which restarts packetcreator and authdemo service and other services based on configurations in value.yaml file, Do you want to install? (Y/n) " + echo "This script installs cronjob which restarts packetcreator, Idgenerator and authdemo service and other services based on configurations in value.yaml file, Do you want to install? (Y/n) " echo "Y: if you wish to install this cronjob in your cluster" echo "n: if you don't want to install this cronjob in your cluster" read -p "" flag @@ -26,27 +26,13 @@ function installing_restart-cron() { read -p "Is values.yaml for restart-cron chart set correctly as part of Pre-requisites?(Y/n) " yn; if [ $yn = "Y" ]; then - read -p "Please enter the time(hr) to run the cronjob every day (time: 0-23) : " time - if [ -z "$time" ]; then - echo "ERROT: Time cannot be empty; EXITING;"; - exit 1; - fi - if ! [ $time -eq $time ] 2>/dev/null; then - echo "ERROR: Time $time is not a number; EXITING;"; - exit 1; - fi - if [ $time -gt 23 ] || [ $time -lt 0 ] ; then - echo "ERROR: Time should be in range ( 0-23 ); EXITING;"; - exit 1; - fi - echo Istio label kubectl label ns $NS istio-injection=disabled --overwrite helm repo update - echo Installing restart-cron + echo Installing restart-cron idgenerator helm -n $NS install restart-cron mosip/restart-cron \ - --set schedule.crontime="0 $time * * *" \ + --set schedule.crontime="0 */4 * * 1-5" \ -f values.yaml \ --version $CHART_VERSION echo Installed restart-cron. diff --git a/deployment/v3/mosip/restart-cron/values.yaml b/deployment/v3/mosip/restart-cron/values.yaml index 730c7114f..a9c9f9027 100644 --- a/deployment/v3/mosip/restart-cron/values.yaml +++ b/deployment/v3/mosip/restart-cron/values.yaml @@ -1,7 +1,10 @@ namespaces: - name: packetcreator - enabled: true + enabled: false deploymentName: packetcreator - name: authdemo + enabled: false + deploymentName: authdemo + - name: kernel enabled: true - deploymentName: authdemo \ No newline at end of file + deploymentName: idgenerator diff --git a/deployment/v3/mosip/tusd/copy_cm.sh b/deployment/v3/mosip/tusd/copy_cm.sh index 25f50c00a..4ff8b236f 100755 --- a/deployment/v3/mosip/tusd/copy_cm.sh +++ b/deployment/v3/mosip/tusd/copy_cm.sh @@ -19,6 +19,3 @@ set -o nounset ## set -u : exit the script if you try to use an uninitialised set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes copying_cm # calling function - - - diff --git a/deployment/v3/mosip/tusd/install.sh b/deployment/v3/mosip/tusd/install.sh index 265376ea2..0156b0f0e 100755 --- a/deployment/v3/mosip/tusd/install.sh +++ b/deployment/v3/mosip/tusd/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=tusd -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/mosip/websub/delete.sh b/deployment/v3/mosip/websub/delete.sh index 9b6d56fe0..ff5108eac 100755 --- a/deployment/v3/mosip/websub/delete.sh +++ b/deployment/v3/mosip/websub/delete.sh @@ -28,4 +28,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_websub # calling function \ No newline at end of file +deleting_websub # calling function diff --git a/deployment/v3/mosip/websub/restart.sh b/deployment/v3/mosip/websub/restart.sh index c7ebb0f4a..f9184180b 100755 --- a/deployment/v3/mosip/websub/restart.sh +++ b/deployment/v3/mosip/websub/restart.sh @@ -6,12 +6,12 @@ if [ $# -ge 1 ] ; then export KUBECONFIG=$1 fi - function Restarting_websub() { NS=websub kubectl -n $NS rollout restart deploy kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + echo Restarted websub services return 0 } @@ -22,4 +22,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -Restarting_websub # calling function \ No newline at end of file +Restarting_websub # calling function diff --git a/deployment/v3/terraform/aws/README.md b/deployment/v3/terraform/aws/README.md new file mode 100644 index 000000000..c014f3b20 --- /dev/null +++ b/deployment/v3/terraform/aws/README.md @@ -0,0 +1,100 @@ +# Fetch variables via ENV variables + +``` +$ export TF_VAR_CLUSTER_NAME=dev +$ export TF_LOG="DEBUG" +$ export TF_LOG_PATH="/tmp/terraform.log" +``` + +* TF_VAR_ : is a syntax +* CLUSTER_NAME=dev : is variable and its value + + +# Terraform Setup for MOSIP Infrastructure + +## Overview +This Terraform configuration script set up the infrastructure for MOSIP (Modular Open Source Identity Platform) on AWS. +The setup includes security groups, an NGINX server, and a Kubernetes (K8S) cluster. + +## Requirements +* Terraform version: `v1.8.4` +* AWS Account +* AWS CLI configured with appropriate credentials + ``` + $ export AWS_ACCESS_KEY_ID= + $ export AWS_SECRET_ACCESS_KEY= + $ export TF_VAR_SSH_PRIVATE_KEY= + ``` + +## Files +* `main.tf`: Main Terraform script that defines providers, resources, and output values. +* `variables.tf`: Defines variables used in the Terraform scripts. +* `outputs.tf`: Provides the output values. +* `locals.tf`: Defines a local variable `SECURITY_GROUP` containing configuration parameters required for setting up security groups for Nginx and Kubernetes cluster nodes. +* `env.tfvars`: tfvars file is used to set the actual values of the variables. + +## Setup +* Initialize Terraform. + ``` + terraform init + ``` +* Review and modify variable values: + * Ensure `locals.tf` contains correct values for your setup. + * Update values in `env.tfvars` as per your organization requirement. +* Terraform validate & plan the terraform scripts: + ``` + terraform validate + ``` + ``` + terraform plan -var-file="./env.tfvars + ``` +* Apply the Terraform configuration: + ``` + terraform apply -var-file="./env.tfvars + ``` + +## Destroy +To destroy AWS resources, follow the steps below: +* Ensure to have `terraform.tfstate` file. + ``` + terraform destroy -var-file=./env.tfvars + ``` + +## Modules + +#### aws-resource-creation +This module is responsible for creating the AWS resources needed for the MOSIP platform, including security groups, an NGINX server, and a Kubernetes cluster nodes. + +* Inputs: + * `CLUSTER_NAME`: The name of the Kubernetes cluster. + * `AWS_PROVIDER_REGION`: The AWS region for resource creation. + * `SSH_KEY_NAME`: The name of the SSH key for accessing instances. + * `K8S_INSTANCE_TYPE`: The instance type for Kubernetes nodes. + * `NGINX_INSTANCE_TYPE`: The instance type for the NGINX server. + * `MOSIP_DOMAIN`: The domain name for the MOSIP platform. + * `ZONE_ID`: The Route 53 hosted zone ID. + * `AMI`: The Amazon Machine Image ID for the instances. + * `SECURITY_GROUP`: Security group configurations. + +#### nginx-setup +This module sets up NGINX and configures it with the provided domain and SSL certificates. + +* Inputs: + * `NGINX_PUBLIC_IP`: The public IP address of the NGINX server. + * `MOSIP_DOMAIN`: The domain name for the MOSIP platform. + * `MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST`: List of private IP addresses of the Kubernetes nodes. + * `MOSIP_PUBLIC_DOMAIN_LIST`: List of public domain names. + * `CERTBOT_EMAIL`: The email ID for SSL certificate generation. + * `SSH_KEY_NAME`: SSH private key used for login (i.e., file content of SSH pem key). + +## Outputs +The following outputs are provided: + +* `K8S_CLUSTER_PUBLIC_IPS`: The public IP addresses of the Kubernetes cluster nodes. +* `K8S_CLUSTER_PRIVATE_IPS`: The private IP addresses of the Kubernetes cluster nodes. +* `NGINX_PUBLIC_IP`: The public IP address of the NGINX server. +* `NGINX_PRIVATE_IP`: The private IP address of the NGINX server. +* `MOSIP_NGINX_SG_ID`: The security group ID for the NGINX server. +* `MOSIP_K8S_SG_ID`: The security group ID for the Kubernetes cluster. +* `MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST`: The private IP addresses of the Kubernetes cluster nodes. +* `MOSIP_PUBLIC_DOMAIN_LIST`: The public domain names. diff --git a/deployment/v3/terraform/aws/env.tfvars b/deployment/v3/terraform/aws/env.tfvars new file mode 100644 index 000000000..4942a5b19 --- /dev/null +++ b/deployment/v3/terraform/aws/env.tfvars @@ -0,0 +1,9 @@ +MOSIP_DOMAIN = "tf5.mosip.net" +MOSIP_EMAIL_ID = "syed.salman@technoforte.co.in" +AWS_PROVIDER_REGION = "ap-south-1" +CLUSTER_NAME = "TF5" +K8S_INSTANCE_TYPE = "t2.micro" +NGINX_INSTANCE_TYPE = "t2.micro" +ZONE_ID = "Z090954828SJIEL6P5406" +AMI = "ami-0a7cf821b91bcccbc" +SSH_KEY_NAME = "mosip-aws" diff --git a/deployment/v3/terraform/aws/locals.tf b/deployment/v3/terraform/aws/locals.tf new file mode 100644 index 000000000..5762f0114 --- /dev/null +++ b/deployment/v3/terraform/aws/locals.tf @@ -0,0 +1,80 @@ +locals { + SECURITY_GROUP = { + NGINX_SECURITY_GROUP = [ + { + description : "SSH login port" + from_port : 22, + to_port : 22, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + }, + { + description : "HTTP port" + from_port : 80, + to_port : 80, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + }, + { + description : "HTTPS port" + from_port : 443, + to_port : 443, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + }, + { + description : "Minio console port" + from_port : 9000, + to_port : 9000, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + }, + { + description : "Postgres port" + from_port : 5432, + to_port : 5432, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + } + ] + K8S_SECURITY_GROUP = [ + { + description : "K8s port" + from_port : 6443, + to_port : 6443, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + }, + { + description : "SSH login port" + from_port : 22, + to_port : 22, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + }, + { + description : "HTTP port" + from_port : 80, + to_port : 80, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + }, + { + description : "HTTPS port" + from_port : 443, + to_port : 443, + protocol : "TCP", + cidr_blocks = ["0.0.0.0/0"], + ipv6_cidr_blocks = ["::/0"] + } + ] + } +} \ No newline at end of file diff --git a/deployment/v3/terraform/aws/main.tf b/deployment/v3/terraform/aws/main.tf new file mode 100644 index 000000000..0f589668b --- /dev/null +++ b/deployment/v3/terraform/aws/main.tf @@ -0,0 +1,42 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "5.48.0" + } + } +} + +# provider "aws" { +# Profile `default` means it will take credentials AWS_SITE_KEY & AWS_SECRET_EKY from ~/.aws/config under `default` section. +# profile = "default" +# region = "ap-south-1" +# } +provider "aws" { + region = var.AWS_PROVIDER_REGION +} + +module "aws-resource-creation" { + source = "./modules/aws-resource-creation" + CLUSTER_NAME = var.CLUSTER_NAME + AWS_PROVIDER_REGION = var.AWS_PROVIDER_REGION + SSH_KEY_NAME = var.SSH_KEY_NAME + K8S_INSTANCE_TYPE = var.K8S_INSTANCE_TYPE + NGINX_INSTANCE_TYPE = var.NGINX_INSTANCE_TYPE + MOSIP_DOMAIN = var.MOSIP_DOMAIN + ZONE_ID = var.ZONE_ID + AMI = var.AMI + + SECURITY_GROUP = local.SECURITY_GROUP +} + +module "nginx-setup" { + depends_on = [module.aws-resource-creation] + source = "./modules/nginx-setup" + NGINX_PUBLIC_IP = module.aws-resource-creation.NGINX_PUBLIC_IP + MOSIP_DOMAIN = var.MOSIP_DOMAIN + MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST = module.aws-resource-creation.MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST + MOSIP_PUBLIC_DOMAIN_LIST = module.aws-resource-creation.MOSIP_PUBLIC_DOMAIN_LIST + CERTBOT_EMAIL = var.MOSIP_EMAIL_ID + SSH_PRIVATE_KEY = var.SSH_PRIVATE_KEY +} diff --git a/deployment/v3/terraform/aws/modules/aws-resource-creation/README.md b/deployment/v3/terraform/aws/modules/aws-resource-creation/README.md new file mode 100644 index 000000000..477da3903 --- /dev/null +++ b/deployment/v3/terraform/aws/modules/aws-resource-creation/README.md @@ -0,0 +1,98 @@ +# Terraform Script for AWS Infrastructure with Certbot and NGINX + +## Overview +This Terraform script sets up an AWS infrastructure that includes: + +* IAM roles and policies for Certbot to modify Route 53 DNS records. +* Security groups for NGINX and Kubernetes instances. +* EC2 instances for NGINX and Kubernetes. +* Route 53 DNS records for managing domain names. +* Certbot for SSL certificate generation. + +## Requirements + +* Terraform version: `v1.8.4` +* AWS Account +* AWS CLI configured with appropriate credentials + ``` + $ export AWS_ACCESS_KEY_ID= + $ export AWS_SECRET_ACCESS_KEY= + ``` +* Ensure SSH key created for accessing EC2 instances on AWS. + +## Files +* `certbot-ssl-certgen.tf`: Defines IAM roles, policies, and instance profiles for Certbot. +* `aws.tfvars`: Contains variable values for AWS infrastructure configuration. +* `main.tf`: Main Terraform script that defines providers, resources, and output values. +* `variables.tf`: Defines variables used in the Terraform scripts. + +## Setup +* Initialize Terraform + ``` + terraform init + ``` +* Review and modify variable values: + * Ensure `aws.tfvars` contains correct values for your setup. + * Verify `variables.tf` for any additional configuration needs. +* Terraform validate & plan the terraform scripts: + ``` + terraform validate + ``` + ``` + terraform plan -var-file="aws.tfvars" + ``` +* Apply the Terraform configuration: + ``` + terraform apply -var-file="aws.tfvars" + ``` + +## Destroy +To destroy AWS resources, follow the steps below: +* Ensure to have `terraform.tfstate` file. + ``` + terraform destroy + ``` + +## Terraform Scripts + +#### certbot-ssl-certgen.tf +* Defines resources for setting up IAM roles and policies for Certbot: + * `aws_iam_role.certbot_role`: IAM role for Certbot with EC2 assume role policy. + * `aws_iam_policy.certbot_policy`: IAM policy allowing Certbot to modify Route 53 records. + * `aws_iam_role_policy_attachment.certbot_policy_attachment`: Attaches the policy to the role. + * `aws_iam_instance_profile.certbot_profile`: Creates an instance profile for the IAM role. + +#### aws.tfvars +* Contains configuration variables for the AWS infrastructure +* Ensure the AMI ID `ami-xxxxxxxxxxxxxxxxx` is available in your specified region. +* The `user_data` script for the NGINX instance mounts an EBS volume at `/srv/nfs`. +* Modify the security group rules as per your security requirements. + +#### main.tf +* Defines the main resources and provider configuration: + * `Providers`: AWS provider configuration. + * `Security Groups`: aws_security_group.security-group for NGINX and Kubernetes. + * `EC2 Instances`: + * **aws_instance.NGINX_EC2_INSTANCE** for NGINX. + * **aws_instance.K8S_CLUSTER_EC2_INSTANCE** for Kubernetes. + * `Route 53 Records`: + * **aws_route53_record.MAP_DNS_TO_IP** for A records. + * **aws_route53_record.MAP_DNS_TO_CNAME** for CNAME records. + +#### outputs.tf +* Provides useful information after infrastructure creation. + +#### variables.tf +* Defines input variables used across the Terraform scripts + +#### Outputs +The script provides the following output values: + +* `K8S_CLUSTER_PUBLIC_IPS`: Public IPs of Kubernetes cluster nodes. +* `K8S_CLUSTER_PRIVATE_IPS`: Private IPs of Kubernetes cluster nodes. +* `NGINX_PUBLIC_IP`: Public IP of the NGINX instance. +* `NGINX_PRIVATE_IP`: Private IP of the NGINX instance. +* `MOSIP_NGINX_SG_ID`: Security group ID for NGINX. +* `MOSIP_K8S_SG_ID`: Security group ID for Kubernetes. +* `MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST`: Comma-separated list of Kubernetes cluster nodes private IPs which will be used by Nginx terraform scripts. +* `MOSIP_PUBLIC_DOMAIN_LIST`: Comma-separated list of public domains configured in Route 53 which will be used by Nginx terraform scripts. diff --git a/deployment/v3/terraform/aws/modules/aws-resource-creation/certbot-ssl-certgen.tf b/deployment/v3/terraform/aws/modules/aws-resource-creation/certbot-ssl-certgen.tf new file mode 100644 index 000000000..f6ec412c8 --- /dev/null +++ b/deployment/v3/terraform/aws/modules/aws-resource-creation/certbot-ssl-certgen.tf @@ -0,0 +1,48 @@ +resource "aws_iam_role" "certbot_role" { + name = "certbot-route53-role" + assume_role_policy = < instance.public_ip } +} +output "K8S_CLUSTER_PRIVATE_IPS" { + value = { for key, instance in aws_instance.K8S_CLUSTER_EC2_INSTANCE : "${local.K8S_EC2_NODE.tags.Name}-${key + 1}" => instance.private_ip } +} +output "NGINX_PUBLIC_IP" { + value = aws_instance.NGINX_EC2_INSTANCE.public_ip +} +output "NGINX_PRIVATE_IP" { + value = aws_instance.NGINX_EC2_INSTANCE.private_ip +} +output "MOSIP_NGINX_SG_ID" { + value = aws_security_group.security-group["NGINX_SECURITY_GROUP"].id +} +output "MOSIP_K8S_SG_ID" { + value = aws_security_group.security-group["K8S_SECURITY_GROUP"].id +} +output "MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST" { + value = join(",", aws_instance.K8S_CLUSTER_EC2_INSTANCE[*].private_ip) +} +output "MOSIP_PUBLIC_DOMAIN_LIST" { + value = join(",", concat( + [local.MAP_DNS_TO_IP.API_DNS.name], + [for cname in local.MAP_DNS_TO_CNAME : cname.name if contains([cname.records], local.MAP_DNS_TO_IP.API_DNS.name)] + )) +} diff --git a/deployment/v3/terraform/aws/modules/aws-resource-creation/variables.tf b/deployment/v3/terraform/aws/modules/aws-resource-creation/variables.tf new file mode 100644 index 000000000..11804e52c --- /dev/null +++ b/deployment/v3/terraform/aws/modules/aws-resource-creation/variables.tf @@ -0,0 +1,205 @@ +variable "AWS_PROVIDER_REGION" { type = string } +variable "CLUSTER_NAME" { type = string } +variable "SSH_KEY_NAME" { type = string } +variable "SECURITY_GROUP" { + type = map(list(object({ + description = string + from_port = number + to_port = number + protocol = string + cidr_blocks = list(string) + ipv6_cidr_blocks = list(string) + } + ))) +} +variable "K8S_INSTANCE_TYPE" { + type = string + validation { + condition = can(regex("^[a-z0-9]+\\..*", var.K8S_INSTANCE_TYPE)) + error_message = "Invalid instance type format. Must be in the form 'series.type'." + } +} +variable "AMI" { + type = string + validation { + condition = can(regex("^ami-[a-f0-9]{17}$", var.AMI)) + error_message = "Invalid AMI format. It should be in the format 'ami-xxxxxxxxxxxxxxxxx'" + } +} +variable "NGINX_INSTANCE_TYPE" { + type = string + validation { + condition = can(regex("^[a-z0-9]+\\..*", var.NGINX_INSTANCE_TYPE)) + error_message = "Invalid instance type format. Must be in the form 'series.type'." + } +} +variable "MOSIP_DOMAIN" { type = string } +variable "ZONE_ID" { type = string } + +# NGINX TAG NAME VARIABLE +locals { + TAG_NAME = { + NGINX_TAG_NAME = "${var.CLUSTER_NAME}-NGINX-NODE" + } +} + + +# DNS CONFIGURATION +locals { + MAP_DNS_TO_IP = { + API_DNS = { + name = "api.${var.MOSIP_DOMAIN}" + type = "A" + zone_id = var.ZONE_ID + ttl = 300 + records = aws_instance.NGINX_EC2_INSTANCE.tags.Name == local.TAG_NAME.NGINX_TAG_NAME ? aws_instance.NGINX_EC2_INSTANCE.public_ip : "" + #health_check_id = true + allow_overwrite = true + } + API_INTERNAL_DNS = { + name = "api-internal.${var.MOSIP_DOMAIN}" + type = "A" + zone_id = var.ZONE_ID + ttl = 300 + records = aws_instance.NGINX_EC2_INSTANCE.tags.Name == local.TAG_NAME.NGINX_TAG_NAME ? aws_instance.NGINX_EC2_INSTANCE.private_ip : "" + #health_check_id = true + allow_overwrite = true + } + } +} +locals { + MAP_DNS_TO_CNAME = { + MOSIP_HOMEPAGE_DNS = { + name = var.MOSIP_DOMAIN + type = "CNAME" + zone_id = var.ZONE_ID + ttl = 300 + records = local.MAP_DNS_TO_IP.API_INTERNAL_DNS.name + #health_check_id = true + allow_overwrite = true + } + ADMIN_DNS = { + name = "admin.${var.MOSIP_DOMAIN}" + type = "CNAME" + zone_id = var.ZONE_ID + ttl = 300 + records = local.MAP_DNS_TO_IP.API_INTERNAL_DNS.name + #health_check_id = true + allow_overwrite = true + } + PREREG_DNS = { + name = "prereg.${var.MOSIP_DOMAIN}" + type = "CNAME" + zone_id = var.ZONE_ID + ttl = 300 + records = local.MAP_DNS_TO_IP.API_DNS.name + #health_check_id = true + allow_overwrite = true + } + RESIDENT_DNS = { + name = "resident.${var.MOSIP_DOMAIN}" + type = "CNAME" + zone_id = var.ZONE_ID + ttl = 300 + records = local.MAP_DNS_TO_IP.API_DNS.name + #health_check_id = true + allow_overwrite = true + } + ESIGNET_DNS = { + name = "esignet.${var.MOSIP_DOMAIN}" + type = "CNAME" + zone_id = var.ZONE_ID + ttl = 300 + records = local.MAP_DNS_TO_IP.API_DNS.name + #health_check_id = true + allow_overwrite = true + } + } +} + + +# EC2 INSTANCE DATA: NGINX & K8S NODES +locals { + NGINX_INSTANCE = { + ami = var.AMI + instance_type = var.NGINX_INSTANCE_TYPE + associate_public_ip_address = true + key_name = var.SSH_KEY_NAME + user_data =<<-EOF +#!/bin/bash + +# Log file path +echo "[ Set Log File ] : " +LOG_FILE="/tmp/ebs-volume-mount.log" + +# Redirect stdout and stderr to log file +exec > >(tee -a "$LOG_FILE") 2>&1 + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes + +## Mount EBS volume +echo "[ Mount EBS volume to /srv/nfs directory ] : " +file -s /dev/xvdb +mkfs -t xfs /dev/xvdb +mkdir -p /srv/nfs +echo "/dev/xvdb /srv/nfs xfs defaults,nofail 0 2" >> /etc/fstab +mount -a +EOF + tags = { + Name = local.TAG_NAME.NGINX_TAG_NAME + Cluster = var.CLUSTER_NAME + } + security_groups = [ + aws_security_group.security-group["NGINX_SECURITY_GROUP"].id + ] + + root_block_device = { + volume_size = 30 + volume_type = "gp3" + delete_on_termination = true + encrypted = false + tags = { + Name = local.TAG_NAME.NGINX_TAG_NAME + Cluster = var.CLUSTER_NAME + } + } + ebs_block_device = [{ + device_name = "/dev/sdb" + volume_size = 10 + volume_type = "gp3" + delete_on_termination = true + encrypted = false + tags = { + Name = local.TAG_NAME.NGINX_TAG_NAME + Cluster = var.CLUSTER_NAME + } + }] + } + K8S_EC2_NODE = { + ami = var.AMI + instance_type = var.K8S_INSTANCE_TYPE + associate_public_ip_address = true + key_name = var.SSH_KEY_NAME + count = 1 + tags = { + Name = "${var.CLUSTER_NAME}-node" + Cluster = var.CLUSTER_NAME + } + security_groups = [ + aws_security_group.security-group["K8S_SECURITY_GROUP"].id + ] + + root_block_device = { + volume_size = 30 + volume_type = "gp3" + delete_on_termination = true + encrypted = false + + } + } +} diff --git a/deployment/v3/terraform/aws/modules/nginx-setup/README.md b/deployment/v3/terraform/aws/modules/nginx-setup/README.md new file mode 100644 index 000000000..00050940a --- /dev/null +++ b/deployment/v3/terraform/aws/modules/nginx-setup/README.md @@ -0,0 +1,77 @@ +## Terraform & Shell Script for Nginx Setup with SSL + +## Overview +This Terraform configuration script sets up a Nginx server with SSL certificates on an AWS EC2 instance. +It fetches SSL certificates using Certbot and integrates with Kubernetes infrastructure from a specified GitHub repository + +## Requirements + +* Terraform version: `v1.8.4` +* AWS Account +* AWS CLI configured with appropriate credentials + ``` + $ export AWS_ACCESS_KEY_ID= + $ export AWS_SECRET_ACCESS_KEY= + ``` +* Ensure SSH key created for accessing EC2 instances on AWS. +* Ensure you have access to the private SSH key that corresponds to the public key used when launching the EC2 instance. +* Domain and DNS: Ensure that you have a domain and that its DNS is managed by Route 53. +* Git is installed on the EC2 instance. + +## Files +* `main.tf`: Main Terraform script that defines providers, resources, and output values. +* `nginx-setup.sh`: This scripts install and setup nginx configuration. + +## Setup +* Initialize Terraform + ``` + terraform init + ``` +* Terraform validate & plan the terraform scripts: + ``` + terraform validate + ``` + ``` + terraform plan -var-file="aws.tfvars" + ``` +* Apply the Terraform configuration: + ``` + terraform apply -var-file="aws.tfvars" + ``` + +## Destroy +To destroy AWS resources, follow the steps below: +* Ensure to have `terraform.tfstate` file. + ``` + terraform destroy + ``` + +## Input Variables +* `NGINX_PUBLIC_IP`: The public IP address of the EC2 instance where Nginx will be set up. +* `MOSIP_DOMAIN`: The domain for which the wildcard SSL certificates will be generated. +* `MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST`: A comma-separated list of Kubernetes cluster node's private IP addresses for Nginx configuration. +* `MOSIP_PUBLIC_DOMAIN_LIST`: A comma-separated list of public domain names associated for Nginx configuration. +* `CERTBOT_EMAIL`: Email address to be used for SSL certificate registration with Certbot. + +## Local Variables +The script `main.tf` defines a local variable NGINX_CONFIG containing various configuration parameters required for setting up Nginx and obtaining SSL certificates. + +## Terraform Scripts + +#### main.tf + +* **null_resource "Nginx-setup"**: This resource performs the following actions: + * `Triggers`: Sets up triggers based on the hash of the Kubernetes cluster nodes' private IP list and the public domain list. + * `Connection`: Defines the SSH connection parameters for the EC2 instance. + * `File Provisioner`: Uploads the nginx-setup.sh script to the EC2 instance. + * `Remote Exec Provisioner`: Executes the necessary commands to: + * Set environment variables. + * Run the nginx-setup.sh script. + +#### nginx-setup.sh: +This script performs the following actions: + * Logs the script execution. + * Installs Nginx and SSL dependencies. + * Obtains SSL certificates using Certbot. + * Enables and starts the Nginx service. + * Clones the specified Kubernetes infrastructure repository and runs the Nginx setup script from it. diff --git a/deployment/v3/terraform/aws/modules/nginx-setup/main.tf b/deployment/v3/terraform/aws/modules/nginx-setup/main.tf new file mode 100644 index 000000000..c1b83b2e9 --- /dev/null +++ b/deployment/v3/terraform/aws/modules/nginx-setup/main.tf @@ -0,0 +1,62 @@ +variable "NGINX_PUBLIC_IP" { type = string } +variable "MOSIP_DOMAIN" { type = string } +variable "MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST" { type = string } +variable "MOSIP_PUBLIC_DOMAIN_LIST" { type = string } +variable "CERTBOT_EMAIL" { type = string } +variable "SSH_PRIVATE_KEY" { type = string } + +locals { + NGINX_CONFIG = { + mosip_domain = var.MOSIP_DOMAIN + env_var_file = "/etc/environment" + cluster_nginx_certs="/etc/letsencrypt/live/${var.MOSIP_DOMAIN}/fullchain.pem" + cluster_nginx_cert_key="/etc/letsencrypt/live/${var.MOSIP_DOMAIN}/privkey.pem" + cluster_node_ips=var.MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST + cluster_public_domains=var.MOSIP_PUBLIC_DOMAIN_LIST + cluster_ingress_public_nodeport="30080" + cluster_ingress_internal_nodeport="31080" + cluster_ingress_postgres_nodeport="31432" + cluster_ingress_minio_nodeport="30900" + cluster_ingress_activemq_nodeport="31616" + certbot_email=var.CERTBOT_EMAIL + k8s_infra_repo_url="https://github.com/mosip/k8s-infra.git" + k8s_infra_branch="main" + working_dir="/home/ubuntu/" + nginx_location="./k8s-infra/mosip/on-prem/nginx" + } + + nginx_env_vars = [ + for key, value in local.NGINX_CONFIG : + "echo 'export ${key}=${value}' | sudo tee -a ${local.NGINX_CONFIG.env_var_file}" + ] +} + +resource "null_resource" "Nginx-setup" { + triggers = { + # node_count_or_hash = module.ec2-resource-creation.node_count + # or if you used hash: + node_hash = md5(var.MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST) + public_dns_hash = md5(var.MOSIP_PUBLIC_DOMAIN_LIST) + } + connection { + type = "ssh" + host = var.NGINX_PUBLIC_IP + user = "ubuntu" # Change based on the AMI used + private_key = var.SSH_PRIVATE_KEY # content of your private key + } + provisioner file { + source = "./modules/nginx-setup/nginx-setup.sh" + destination = "/tmp/nginx-setup.sh" + } + provisioner "remote-exec" { + inline = concat( + local.nginx_env_vars, + [ + "echo \"export cluster_nginx_internal_ip=\"$(curl http://169.254.169.254/latest/meta-data/local-ipv4)\"\" | sudo tee -a ${local.NGINX_CONFIG.env_var_file}", + "echo \"export cluster_nginx_public_ip=\"$(curl http://169.254.169.254/latest/meta-data/local-ipv4)\"\" | sudo tee -a ${local.NGINX_CONFIG.env_var_file}", + "sudo chmod +x /tmp/nginx-setup.sh", + "sudo bash /tmp/nginx-setup.sh" + ] + ) + } +} \ No newline at end of file diff --git a/deployment/v3/terraform/aws/modules/nginx-setup/nginx-setup.sh b/deployment/v3/terraform/aws/modules/nginx-setup/nginx-setup.sh new file mode 100644 index 000000000..c73e2490f --- /dev/null +++ b/deployment/v3/terraform/aws/modules/nginx-setup/nginx-setup.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Log file path +echo "[ Set Log File ] : " +sudo mv /tmp/nginx-setup.log /tmp/nginx-setup.log.old || true +LOG_FILE="/tmp/nginx-setup.log" +ENV_FILE_PATH="/etc/environment" +source $ENV_FILE_PATH +env | grep cluster + +# Redirect stdout and stderr to log file +exec > >(tee -a "$LOG_FILE") 2>&1 + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes + +## Install Nginx, ssl dependencies +echo "[ Install nginx & ssl dependencies packages ] : " +sudo apt-get update +sudo apt install -y software-properties-common +sudo add-apt-repository universe +sudo apt update +sudo apt-get install nginx letsencrypt certbot python3-certbot-nginx python3-certbot-dns-route53 -y + +## Get ssl certificate automatically +echo "[ Generate SSL certificates from letsencrypt ] : " +sudo certbot certonly --dns-route53 -d "*.${mosip_domain}" -d "${mosip_domain}" --non-interactive --agree-tos --email "$certbot_email" + +## start and enable Nginx +echo "[ Start & Enable nginx ] : " +sudo systemctl enable nginx +sudo systemctl start nginx + +cd $working_dir +git clone $k8s_infra_repo_url -b $k8s_infra_branch || true # read it from variables +cd $nginx_location +./install.sh + diff --git a/deployment/v3/terraform/aws/outputs.tf b/deployment/v3/terraform/aws/outputs.tf new file mode 100644 index 000000000..df188a8f2 --- /dev/null +++ b/deployment/v3/terraform/aws/outputs.tf @@ -0,0 +1,24 @@ +output "K8S_CLUSTER_PUBLIC_IPS" { + value = module.aws-resource-creation.K8S_CLUSTER_PUBLIC_IPS +} +output "K8S_CLUSTER_PRIVATE_IPS" { + value = module.aws-resource-creation.K8S_CLUSTER_PRIVATE_IPS +} +output "NGINX_PUBLIC_IP" { + value = module.aws-resource-creation.NGINX_PUBLIC_IP +} +output "NGINX_PRIVATE_IP" { + value = module.aws-resource-creation.NGINX_PRIVATE_IP +} +output "MOSIP_NGINX_SG_ID" { + value = module.aws-resource-creation.MOSIP_NGINX_SG_ID +} +output "MOSIP_K8S_SG_ID" { + value = module.aws-resource-creation.MOSIP_K8S_SG_ID +} +output "MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST" { + value = module.aws-resource-creation.MOSIP_K8S_CLUSTER_NODES_PRIVATE_IP_LIST +} +output "MOSIP_PUBLIC_DOMAIN_LIST" { + value = module.aws-resource-creation.MOSIP_PUBLIC_DOMAIN_LIST +} \ No newline at end of file diff --git a/deployment/v3/terraform/aws/variables.tf b/deployment/v3/terraform/aws/variables.tf new file mode 100644 index 000000000..03fbebd34 --- /dev/null +++ b/deployment/v3/terraform/aws/variables.tf @@ -0,0 +1,46 @@ +variable "AWS_PROVIDER_REGION" { type = string } +variable "CLUSTER_NAME" { type = string } +variable "SSH_PRIVATE_KEY" { type = string } +variable "MOSIP_DOMAIN" { + description = "MOSIP DOMAIN : (ex: sandbox.xyz.net)" + type = string + validation { + condition = can(regex("^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\\.)+[a-zA-Z]{2,}$", var.MOSIP_DOMAIN)) + error_message = "The domain name must be a valid domain name, e.g., sandbox.xyz.net." + } +} + +variable "MOSIP_EMAIL_ID" { + description = "Email ID used by certbot to generate SSL certs for Nginx node" + type = string + validation { + condition = can(regex("^\\S+@\\S+\\.\\S+$", var.MOSIP_EMAIL_ID)) + error_message = "The email address must be a valid email format (e.g., user@example.com)." + } +} + +variable "SSH_KEY_NAME" { type = string } +variable "K8S_INSTANCE_TYPE" { + type = string + validation { + condition = can(regex("^[a-z0-9]+\\..*", var.K8S_INSTANCE_TYPE)) + error_message = "Invalid instance type format. Must be in the form 'series.type'." + } +} + +variable "NGINX_INSTANCE_TYPE" { + type = string + validation { + condition = can(regex("^[a-z0-9]+\\..*", var.NGINX_INSTANCE_TYPE)) + error_message = "Invalid instance type format. Must be in the form 'series.type'." + } +} +variable "AMI" { + type = string + validation { + condition = can(regex("^ami-[a-f0-9]{17}$", var.AMI)) + error_message = "Invalid AMI format. It should be in the format 'ami-xxxxxxxxxxxxxxxxx'" + } +} + +variable "ZONE_ID" { type = string } \ No newline at end of file diff --git a/deployment/v3/testrig/apitestrig/copy_cm.sh b/deployment/v3/testrig/apitestrig/copy_cm.sh index 61c8e5d7b..c7ca53b85 100755 --- a/deployment/v3/testrig/apitestrig/copy_cm.sh +++ b/deployment/v3/testrig/apitestrig/copy_cm.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/testrig/apitestrig/copy_secrets.sh b/deployment/v3/testrig/apitestrig/copy_secrets.sh index 5c4fa0f44..76601da79 100755 --- a/deployment/v3/testrig/apitestrig/copy_secrets.sh +++ b/deployment/v3/testrig/apitestrig/copy_secrets.sh @@ -17,4 +17,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_secrets # calling function \ No newline at end of file +copying_secrets # calling function diff --git a/deployment/v3/testrig/apitestrig/delete.sh b/deployment/v3/testrig/apitestrig/delete.sh index 6a28aa852..1c737f567 100755 --- a/deployment/v3/testrig/apitestrig/delete.sh +++ b/deployment/v3/testrig/apitestrig/delete.sh @@ -27,4 +27,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -deleting_apitestrig # calling function \ No newline at end of file +deleting_apitestrig # calling function diff --git a/deployment/v3/testrig/apitestrig/install.sh b/deployment/v3/testrig/apitestrig/install.sh index 57cccbde0..e39a46f32 100755 --- a/deployment/v3/testrig/apitestrig/install.sh +++ b/deployment/v3/testrig/apitestrig/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=apitestrig -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -45,7 +45,7 @@ function installing_apitestrig() { echo "ERROR: Time should be in range ( 0-23 ); EXITING;"; exit 1; fi - + echo "Do you have public domain & valid SSL? (Y/n) " echo "Y: if you have public domain & valid ssl certificate" echo "n: If you don't have a public domain and a valid SSL certificate. Note: It is recommended to use this option only in development environments." @@ -60,6 +60,16 @@ function installing_apitestrig() { ENABLE_INSECURE='--set enable_insecure=true'; fi + read -p "Please provide the retention days to remove old reports ( Default: 3 )" reportExpirationInDays + + if [[ -z $reportExpirationInDays ]]; then + reportExpirationInDays=3 + fi + if ! [[ $reportExpirationInDays =~ ^[0-9]+$ ]]; then + echo "The variable \"reportExpirationInDays\" should contain only number; EXITING"; + exit 1; + fi + read -p "Please provide slack webhook URL to notify server end issues on your slack channel : " slackWebhookUrl if [ -z $slackWebhookUrl ]; then @@ -67,24 +77,24 @@ function installing_apitestrig() { exit 1; fi - valid_inputs=("yes" "no") - eSignetDeployed="" + valid_inputs=("yes" "no") + eSignetDeployed="" - while [[ ! " ${valid_inputs[@]} " =~ " ${eSignetDeployed} " ]]; do - read -p "Is the eSignet service deployed? (yes/no): " eSignetDeployed - eSignetDeployed=${eSignetDeployed,,} # Convert input to lowercase - done + while [[ ! " ${valid_inputs[@]} " =~ " ${eSignetDeployed} " ]]; do + read -p "Is the eSignet service deployed? (yes/no): " eSignetDeployed + eSignetDeployed=${eSignetDeployed,,} # Convert input to lowercase + done - if [[ $eSignetDeployed == "yes" ]]; then - echo "eSignet service is deployed. Proceeding with installation..." - else - echo "eSignet service is not deployed. hence will be skipping esignet related test-cases..." - fi + if [[ $eSignetDeployed == "yes" ]]; then + echo "eSignet service is deployed. Proceeding with installation..." + else + echo "eSignet service is not deployed. hence will be skipping esignet related test-cases..." + fi echo Installing apitestrig helm -n $NS install apitestrig mosip/apitestrig \ --set crontime="0 $time * * *" \ - -f values.yaml \ + -f values.yaml \ --version $CHART_VERSION \ --set apitestrig.configmaps.s3.s3-host='http://minio.minio:9000' \ --set apitestrig.configmaps.s3.s3-user-key='admin' \ @@ -95,7 +105,8 @@ function installing_apitestrig() { --set apitestrig.configmaps.apitestrig.ENV_USER="$ENV_USER" \ --set apitestrig.configmaps.apitestrig.ENV_ENDPOINT="https://$API_INTERNAL_HOST" \ --set apitestrig.configmaps.apitestrig.ENV_TESTLEVEL="smokeAndRegression" \ - --set apitestrig.secrets.apitestrig.slack-webhook-url="$slackWebhookUrl" \ + --set apitestrig.configmaps.apitestrig.reportExpirationInDays="$reportExpirationInDays" \ + --set apitestrig.configmaps.apitestrig.slack-webhook-url="$slackWebhookUrl" \ --set apitestrig.configmaps.apitestrig.eSignetDeployed="$eSignetDeployed" \ --set apitestrig.configmaps.apitestrig.NS="$NS" \ $ENABLE_INSECURE diff --git a/deployment/v3/testrig/apitestrig/values.yaml b/deployment/v3/testrig/apitestrig/values.yaml index f0af09ca5..dc15566f4 100644 --- a/deployment/v3/testrig/apitestrig/values.yaml +++ b/deployment/v3/testrig/apitestrig/values.yaml @@ -1,18 +1,17 @@ modules: - - name: prereg + prereg: enabled: true - - name: masterdata + masterdata: enabled: true - - name: idrepo + idrepo: enabled: true - - name: partner + partner: enabled: true - - name: resident + resident: enabled: true - - name: auth + auth: enabled: true - - name: esignet + esignet: enabled: true - - name: mimoto - enabled: true - + mimoto: + enabled: true \ No newline at end of file diff --git a/deployment/v3/testrig/dslrig/copy_cm.sh b/deployment/v3/testrig/dslrig/copy_cm.sh index 36e401766..9134d8701 100755 --- a/deployment/v3/testrig/dslrig/copy_cm.sh +++ b/deployment/v3/testrig/dslrig/copy_cm.sh @@ -18,4 +18,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_cm # calling function \ No newline at end of file +copying_cm # calling function diff --git a/deployment/v3/testrig/dslrig/copy_secrets.sh b/deployment/v3/testrig/dslrig/copy_secrets.sh index b889b72e5..519462ce7 100755 --- a/deployment/v3/testrig/dslrig/copy_secrets.sh +++ b/deployment/v3/testrig/dslrig/copy_secrets.sh @@ -17,4 +17,4 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true set -o nounset ## set -u : exit the script if you try to use an uninitialised variable set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes -copying_secrets # calling function \ No newline at end of file +copying_secrets # calling function diff --git a/deployment/v3/testrig/dslrig/install.sh b/deployment/v3/testrig/dslrig/install.sh index 17906f448..c0fef9b8a 100755 --- a/deployment/v3/testrig/dslrig/install.sh +++ b/deployment/v3/testrig/dslrig/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=dslrig -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS @@ -15,12 +15,6 @@ kubectl create ns $NS function installing_dslrig() { ENV_NAME=$( kubectl -n default get cm global -o json |jq -r '.data."installation-domain"') - read -p "Please provide NFS host : " NFS_HOST - read -p "Please provide NFS pem file for SSH login : " NFS_PEM_FILE - read -p "Please provide user for SSH login : " NFS_USER - echo -e "[nfs_server]\nnfsserver ansible_user=$NFS_USER ansible_host=$NFS_HOST ansible_ssh_private_key_file=$NFS_PEM_FILE" env_name="$ENV_NAME" > hosts.ini - ansible-playbook -i hosts.ini nfs-server.yaml - read -p "Please enter the time(hr) to run the cronjob every day (time: 0-23) : " time if [ -z "$time" ]; then echo "ERROT: Time cannot be empty; EXITING;"; @@ -98,8 +92,6 @@ function installing_dslrig() { --set dslorchestrator.configmaps.dslorchestrator.USER="$USER" \ --set dslorchestrator.configmaps.dslorchestrator.ENDPOINT="https://$API_INTERNAL_HOST" \ --set dslorchestrator.configmaps.dslorchestrator.packetUtilityBaseUrl="$packetUtilityBaseUrl" \ - --set persistence.nfs.server="$NFS_HOST" \ - --set persistence.nfs.path="/srv/nfs/mosip/dsl-scenarios/$ENV_NAME" \ --set dslorchestrator.configmaps.dslorchestrator.reportExpirationInDays="$reportExpirationInDays" \ --set dslorchestrator.configmaps.dslorchestrator.NS="$NS" \ $ENABLE_INSECURE diff --git a/deployment/v3/testrig/packetcreator/README.md b/deployment/v3/testrig/packetcreator/README.md index 806e388b5..3a121385d 100644 --- a/deployment/v3/testrig/packetcreator/README.md +++ b/deployment/v3/testrig/packetcreator/README.md @@ -9,12 +9,13 @@ Packetcreator will create packets for DSL orchestrator. ```sh ./install.sh ``` +* During the execution of the `install.sh` script, a prompt appears requesting information regarding the presence of a public domain and a valid SSL certificate on the server. +* If the server lacks a public domain and a valid SSL certificate, it is advisable to select the `n` option. Opting it will enable the `init-container` with an `emptyDir` volume and include it in the deployment process. +* The init-container will proceed to download the server's self-signed SSL certificate and mount it to the specified location within the container's Java keystore (i.e., `cacerts`) file. +* This particular functionality caters to scenarios where the script needs to be employed on a server utilizing self-signed SSL certificates. + ## Uninstall * To uninstall Packetcreator, run `delete.sh` script. ```sh ./delete.sh ``` -* During the execution of the `install.sh` script, a prompt appears requesting information regarding the presence of a public domain and a valid SSL certificate on the server. -* If the server lacks a public domain and a valid SSL certificate, it is advisable to select the `n` option. Opting it will enable the `init-container` with an `emptyDir` volume and include it in the deployment process. -* The init-container will proceed to download the server's self-signed SSL certificate and mount it to the specified location within the container's Java keystore (i.e., `cacerts`) file. -* This particular functionality caters to scenarios where the script needs to be employed on a server utilizing self-signed SSL certificates. diff --git a/deployment/v3/testrig/packetcreator/install.sh b/deployment/v3/testrig/packetcreator/install.sh index 1ce167222..a40dd6903 100755 --- a/deployment/v3/testrig/packetcreator/install.sh +++ b/deployment/v3/testrig/packetcreator/install.sh @@ -7,19 +7,13 @@ if [ $# -ge 1 ] ; then fi NS=packetcreator -CHART_VERSION=12.0.1 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS function installing_packetcreator() { - read -p "Please provide NFS host : " NFS_HOST - read -p "Please provide NFS pem file for SSH login : " NFS_PEM_FILE - read -p "Please provide user for SSH login : " NFS_USER - echo -e "[nfs_server]\nnfsserver ansible_user=$NFS_USER ansible_host=$NFS_HOST ansible_ssh_private_key_file=$NFS_PEM_FILE" > hosts.ini - ansible-playbook -i hosts.ini nfs-server.yaml - echo "Select the type of Ingress controller to be used (1/2): "; echo "1. Ingress"; echo "2. Istio"; @@ -67,7 +61,6 @@ function installing_packetcreator() { echo Installing packetcreator helm -n $NS install packetcreator mosip/packetcreator \ $( echo $list ) \ - --set persistence.nfs.server="$NFS_HOST" \ --wait --version $CHART_VERSION $ENABLE_INSECURE echo Installed packetcreator. return 0 @@ -80,4 +73,3 @@ set -o nounset ## set -u : exit the script if you try to use an uninitialised set -o errtrace # trace ERR through 'time command' and other functions set -o pipefail # trace ERR through pipes installing_packetcreator # calling function - diff --git a/deployment/v3/testrig/uitestrig/install.sh b/deployment/v3/testrig/uitestrig/install.sh index c0d06c769..b4f07d88e 100755 --- a/deployment/v3/testrig/uitestrig/install.sh +++ b/deployment/v3/testrig/uitestrig/install.sh @@ -7,7 +7,7 @@ if [ $# -ge 1 ] ; then fi NS=uitestrig -CHART_VERSION=12.0.2 +CHART_VERSION=0.0.1-develop echo Create $NS namespace kubectl create ns $NS diff --git a/deployment/v3/utils/bqatsdk_jar_build/README.md b/deployment/v3/utils/bqatsdk_jar_build/README.md new file mode 100644 index 000000000..1bec7acc2 --- /dev/null +++ b/deployment/v3/utils/bqatsdk_jar_build/README.md @@ -0,0 +1,90 @@ +# Build Process for BQAT SDK Jar + +## Overview +The process involves building the BQAT SDK jar locally and then adding it to the Artifactory pod. + +1. **Clone Repository**: + Clone the bqat-sdk repository to your local machine. + ```bash + git clone https://github.com/JanardhanBS-SyncByte/bqat-sdk + ``` + +2. **Switch Branch**: + Navigate to the cloned repository and checkout to the required branch (e.g., develop). + ```bash + cd bqat-sdk/ + git checkout develop + ``` + +3. **Build with Maven**: + Ensure you are in the directory containing the `pom.xml` file, then build it using Maven. + ```bash + mvn clean install -Dgpg.skip + ``` + +4. **Zip the Jar**: + Zip the generated jar file with its dependencies. + ```bash + zip bqat-sdk-0.0.2-jar-with-dependencies.zip bqat-sdk-0.0.2-jar-with-dependencies.jar + ``` + +5. **Modify Artifactory Deployment Provide Root Access For The Pod**: + Update the Artifactory deployment file in the environment to ensure the pod runs with root access. + ```yaml + schedulerName: default-scheduler + securityContext: + runAsUser: 0 + ``` + +6. **Export Jar to Artifactory Pod**: + Copy the built jar to the Artifactory pod in the designated namespace (replace artifactory pod name respectively "eg:artifactory-bqatsdk-577459987c-67pht"). + ```bash + kubectl -n bqatsdk cp /path/to/bqat-sdk-0.0.2-jar-with-dependencies.zip artifactory-bqatsdk-577459987c-67pht:/usr/share/nginx/html + ``` + +7. **Verify Jar in Pod**: + Access the pod using Execute shell and verify if the jar is successfully copied . + ```bash + ls /usr/share/nginx/html + ``` + +8. **Login to Node**: + log in to the node where the pod is running. + +9. **Check Docker**: + View active Docker containers. + ```bash + docker ps + ``` + +10. **Docker Login**: + If required, log in to Docker with your credentials. + ```bash + docker login + ``` + +11. **Commit Changes**: + Commit the changes to Artifactory Docker image. + ```bash + docker commit CONTAINERID IMAGE + ``` + +12. **Push to Docker Repo**: + Push the changes to the Docker repository. + ```bash + docker push IMAGE + ``` +**NOTE: Push the image to required docker hub** + +13. **Deploy Artifactory Image**: + After pushing changes to docker hub, deploy the Artifactory pod in the `bqatsdk` namespace with the new image created. + +14. **Map New Artifactory zip_file_path in bqatsdk-service YAML file **: + ``` + - name: biosdk_zip_file_path + value: >- + http://artifactory-bqatsdk.bqatsdk:80/bqat-sdk-0.0.2-jar-with-dependencies.zip + ``` + + +This standardizes the process for building and deploying the BQAT SDK jar. \ No newline at end of file diff --git a/deployment/v3/utils/info/README.md b/deployment/v3/utils/info/README.md new file mode 100644 index 000000000..ba383e55d --- /dev/null +++ b/deployment/v3/utils/info/README.md @@ -0,0 +1,9 @@ +# info + +Displays the image, imageId and Helm chart versions used for every deployment in the cluster across all namespaces. + +Host: /info +## Install +```sh +./install.sh +``` diff --git a/deployment/v3/utils/info/delete.sh b/deployment/v3/utils/info/delete.sh new file mode 100644 index 000000000..3378c085f --- /dev/null +++ b/deployment/v3/utils/info/delete.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Uninstalls info +# Usage: ./delete.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +function deleting_info() { + NS=info + while true; do + read -p "Are you sure you want to delete info helm chart?(Y/n) " yn + if [ $yn = "Y" ] + then + helm -n $NS delete info + break + else + break + fi + done + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +deleting_info # calling function diff --git a/deployment/v3/utils/info/install.sh b/deployment/v3/utils/info/install.sh new file mode 100644 index 000000000..9b1c9715f --- /dev/null +++ b/deployment/v3/utils/info/install.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Installs info +## Usage: ./install.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +NS=info +CHART_VERSION=0.0.1-develop + +echo Create $NS namespace +kubectl create ns $NS + +function installing_info() { + echo Istio label + kubectl label ns $NS istio-injection=enabled --overwrite + helm repo update + + echo Installing info + helm -n $NS install info mosip/info --version $CHART_VERSION + + kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + + echo Installed info service + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +installing_info # calling function diff --git a/deployment/v3/utils/info/restart.sh b/deployment/v3/utils/info/restart.sh new file mode 100644 index 000000000..8f76351a0 --- /dev/null +++ b/deployment/v3/utils/info/restart.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Restart the info +## Usage: ./restart.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +function Restarting_info() { + NS=info + kubectl -n $NS rollout restart deploy + + kubectl -n $NS get deploy -o name | xargs -n1 -t kubectl -n $NS rollout status + + echo Restarted info + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +Restarting_info # calling function diff --git a/deployment/v3/utils/prop_migrator/Overview.md b/deployment/v3/utils/prop_migrator/Overview.md index b1f61f44d..68924cb04 100644 --- a/deployment/v3/utils/prop_migrator/Overview.md +++ b/deployment/v3/utils/prop_migrator/Overview.md @@ -145,5 +145,3 @@ Note: - It is highly recommended to create backups of your property files before running this script, as it modifies the files in place. - The `manual-configuration.csv` file can be used to manually update the property files based on the required configuration actions mentioned in the file. - ----- diff --git a/deployment/v3/utils/prop_migrator/README.md b/deployment/v3/utils/prop_migrator/README.md index 9741154cf..dc6ff5eac 100644 --- a/deployment/v3/utils/prop_migrator/README.md +++ b/deployment/v3/utils/prop_migrator/README.md @@ -147,6 +147,3 @@ Note: - It is highly recommended to create backups of your property files before running this script, as it modifies the files in place. - The `manual-configuration.csv` file can be used to manually update the property files based on the required configuration actions mentioned in the file. - ----- - diff --git a/deployment/v3/utils/prop_migrator/file_comparator.py b/deployment/v3/utils/prop_migrator/file_comparator.py index 354443fee..749f391a1 100755 --- a/deployment/v3/utils/prop_migrator/file_comparator.py +++ b/deployment/v3/utils/prop_migrator/file_comparator.py @@ -134,4 +134,4 @@ writer.writerow(item) print("latest_file_only.csv created successfully.") -print("Script completed successfully.") \ No newline at end of file +print("Script completed successfully.") diff --git a/deployment/v3/utils/prop_migrator/knowledge/latest-Value-takes-priority.csv b/deployment/v3/utils/prop_migrator/knowledge/latest-Value-takes-priority.csv index 6d351dbef..8a182dfaf 100644 --- a/deployment/v3/utils/prop_migrator/knowledge/latest-Value-takes-priority.csv +++ b/deployment/v3/utils/prop_migrator/knowledge/latest-Value-takes-priority.csv @@ -1,4 +1,6 @@ Property file name,key +admin-default.properties,mosip.kernel.database.hostname +admin-default.properties,mosip.kernel.database.port admin-default.properties,authmanager.base.url admin-default.properties,mosip.admin.accountmgmt.auth-manager-base-uri admin-default.properties,auth.server.validate.url @@ -24,6 +26,9 @@ application-default.properties,auth-token-generator.rest.issuerUrl application-default.properties,mosip.kernel.keymanager.cert.url application-default.properties,auth.server.admin.validate.url application-default.properties,mosip.kernel.auth.appid-realm-map +application-default.properties,packetmanager.default.priority +application-default.properties,provider.packetreader.mosip +application-default.properties,provider.packetwriter.mosip application-default.properties,hazelcast.config application-default.properties,CRYPTOMANAGER_DECRYPT application-default.properties,CRYPTOMANAGER_ENCRYPT @@ -44,6 +49,7 @@ Data-share-default.properties,data.share.token.request.issuerUrl Data-share-default.properties,mosip.data.share.prependThumbprint kernel-default.properties,mosip.kernel.syncdata.auth-manager-base-uri kernel-default.properties,mosip.kernel.sms.gateway +kernel-default.properties,mosip.kernel.notification.email.from kernel-default.properties,spring.mail.host kernel-default.properties,spring.mail.username kernel-default.properties,spring.mail.password @@ -74,6 +80,7 @@ kernel-default.properties,db_3_DS.keycloak.port kernel-default.properties,db_3_DS.keycloak.username kernel-default.properties,db_3_DS.keycloak.password kernel-default.properties,mosip.keycloak.admin.secret.key +kernel-default.properties,mosip.kernel.prereg.realm-id kernel-default.properties,mosip.kernel.prereg.secret.key kernel-default.properties,kernel.uin.transfer-scheduler-minutes kernel-default.properties,kernel.uin.transfer-scheduler-hours @@ -86,6 +93,8 @@ kernel-default.properties,mosip.kernel.authtoken.OTP.internal.url kernel-default.properties,mosip.kernel.authtoken.REFRESH.internal.url kernel-default.properties,mosip.kernel.auth.sendotp.url kernel-default.properties,syncdata.websub.callback.url.ca-cert +hotlist-default.properties,mosip.hotlist.db.url +hotlist-default.properties,mosip.hotlist.db.port hotlist-default.properties,mosip.hotlist.db.password hotlist-default.properties,mosip.hotlist.allowedIdTypes hotlist-default.properties,mosip.hotlist.topic-to-publish @@ -95,6 +104,8 @@ hotlist-default.properties,mosip.idrepo.audit.rest.uri hotlist-default.properties,mosip.hotlist.encryptor.rest.uri hotlist-default.properties,mosip.hotlist.decryptor.rest.uri hotlist-default.properties,mosip.hotlist.audit.rest.uri +id-authentication-default.properties,mosip.ida.database.hostname +id-authentication-default.properties,mosip.ida.database.port id-authentication-default.properties,mosip.ida.database.password id-authentication-default.properties,mosip.ida.auth.clientId id-authentication-default.properties,mosip.ida.auth.secretKey @@ -117,6 +128,8 @@ id-authentication-default.properties,ida-websub-partner-service-callback-secret id-authentication-default.properties,ida-websub-hotlist-callback-secret id-authentication-default.properties,mosip.kernel.tokenid.uin.salt id-authentication-default.properties,mosip.kernel.tokenid.partnercode.salt +id-repository-default.properties,mosip.idrepo.db.url +id-repository-default.properties,mosip.idrepo.db.port id-repository-default.properties,mosip.idrepo.db.identity.password id-repository-default.properties,mosip.idrepo.db.vid.password id-repository-default.properties,kernel.retry.retryable.exceptions @@ -132,6 +145,8 @@ id-repository-default.properties,mosip.idrepo.credential.request.rest.uri id-repository-default.properties,mosip.idrepo.credential.request.rest.timeout id-repository-default.properties,mosip.idrepo.retrieve-by-uin.rest.uri id-repository-default.properties,mosip.idrepo.vid-generator.rest.uri +id-repository-default.properties,mosip.credential.service.database.hostname +id-repository-default.properties,mosip.credential.service.database.port id-repository-default.properties,mosip.credential.service.jdbc.password id-repository-default.properties,credential.request.token.request.appid id-repository-default.properties,credential.request.token.request.clientId @@ -151,6 +166,7 @@ id-repository-default.properties,PARTNER_EXTRACTION_POLICY id-repository-default.properties,credential.service.token.request.issuerUrl id-repository-default.properties,object.store.s3.accesskey id-repository-default.properties,object.store.s3.secretkey +id-repository-default.properties,object.store.s3.url id-repository-default.properties,object.store.s3.region mimoto-default.properties,public.url mimoto-default.properties,mosip.resident.base.url @@ -158,14 +174,20 @@ mimoto-default.properties,mosip.event.hubUrl mimoto-default.properties,token.request.issuerUrl mimoto-default.properties,AUDIT mimoto-default.properties,MASTER +mimoto-default.properties,mosip.optional-languages mimoto-default.properties,CREATEDATASHARE mimoto-default.properties,DECRYPTPINBASSED mimoto-default.properties,mosip.iam.adapter.clientsecret mimoto-default.properties,auth.server.admin.issuer.uri mimoto-default.properties,mosip.iam.adapter.issuerURL +mock-abis-default.properties,abis.return.duplicate +partner-management-default.properties,mosip.pmp.database.hostname +partner-management-default.properties,mosip.pmp.database.port partner-management-default.properties,mosip.pmp.database.password partner-management-default.properties,mosip.authdevice.database.password partner-management-default.properties,mosip.regdevice.database.password +partner-management-default.properties,hibernate.show_sql +partner-management-default.properties,hibernate.format_sql partner-management-default.properties,mosip.pmp.auth.secretKey partner-management-default.properties,pms.cert.service.token.request.issuerUrl partner-management-default.properties,pmp.ca.certificaticate.upload.rest.uri @@ -176,6 +198,11 @@ partner-management-default.properties,pmp.allowed.credential.types partner-management-default.properties,mosip.iam.module.login_flow.scope partner-management-default.properties,PASSWORDBASEDTOKENAPI pre-registration-default.properties,mosip.database.ip +partner-management-default.properties,mosip.iam.module.clientID +partner-management-default.properties,mosip.iam.module.login_flow.scope +partner-management-default.properties,PASSWORDBASEDTOKENAPI +pre-registration-default.properties,mosip.database.ip +pre-registration-default.properties,mosip.database.port pre-registration-default.properties,logging.level.com.zaxxer.hikari pre-registration-default.properties,mosip.adult.age pre-registration-default.properties,demographic.service.env @@ -183,6 +210,7 @@ pre-registration-default.properties,document.service.env pre-registration-default.properties,booking.service.env pre-registration-default.properties,preregistration.timespan.rebook pre-registration-default.properties,preregistration.timespan.cancel +pre-registration-default.properties,batch.service.env pre-registration-default.properties,mosip.batch.token.authmanager.password pre-registration-default.properties,batch.appointment.cancel pre-registration-default.properties,masterdata.service.env @@ -190,6 +218,7 @@ pre-registration-default.properties,holiday.exceptional.url pre-registration-default.properties,working.day.url pre-registration-default.properties,mosip.kernel.masterdata.validdoc.rest.uri pre-registration-default.properties,notification.service.env +pre-registration-default.properties,notification.url pre-registration-default.properties,email.service.env pre-registration-default.properties,sms.service.env pre-registration-default.properties,audit.service.env @@ -202,20 +231,26 @@ pre-registration-default.properties,mosip.base.url pre-registration-default.properties,ui.config.params pre-registration-default.properties,preregistration.ui.version pre-registration-default.properties,mosip.preregistration.captcha.secretkey +pre-registration-default.properties,mosip.preregistration.captcha.resourse.url +print-default.properties,mosip.event.callBackUrl print-default.properties,mosip.event.secret print-default.properties,PDFSIGN print-default.properties,registration.processor.identityjson print-default.properties,mosip.print.prependThumbprint +registration-default.properties,mosip.registration.consent_ara registration-default.properties,mosip.registration.consent_fra registration-default.properties,mosip.mdm.enabled registration-default.properties,mosip.kernel.transliteration.arabic-language-code +registration-default.properties,mosip.kernel.transliteration.franch-language-code registration-default.properties,mosip.registration.reset_password_url +registration-processor-default.properties,mosip.registration.processor.database.hostname registration-processor-default.properties,registration.processor.zone registration-processor-default.properties,cluster.manager.file.name registration-processor-default.properties,camel.secure.active.flows.file.names registration-processor-default.properties,mosip.regproc.workflow.complete.topic registration-processor-default.properties,token.request.secretKey registration-processor-default.properties,INTERNALAUTH +registration-processor-default.properties,REVERSEDATASYNC registration-processor-default.properties,DEVICEVALIDATEHISTORY registration-processor-default.properties,IDREPOSITORY registration-processor-default.properties,IDREPOGETIDBYUIN @@ -229,16 +264,21 @@ registration-processor-default.properties,GETVIDSBYUIN registration-processor-default.properties,ENCRYPTURL registration-processor-default.properties,ENCRYPTIONSERVICE registration-processor-default.properties,DIGITALSIGNATURE +registration-processor-default.properties,NGINXDMZURL registration-processor-default.properties,CRYPTOMANAGERDECRYPT registration-processor-default.properties,SMSNOTIFIER registration-processor-default.properties,EMAILNOTIFIER registration-processor-default.properties,PMS +registration-processor-default.properties,registration.processor.queue.username registration-processor-default.properties,registration.processor.queue.password +registration-processor-default.properties,registration.processor.queue.url +registration-processor-default.properties,registration.processor.reprocess.minutes registration-processor-default.properties,IDAUTHENCRYPTION registration-processor-default.properties,IDAUTHPUBLICKEY registration-processor-default.properties,IDAUTHCERTIFICATE registration-processor-default.properties,ida-internal-auth-uri registration-processor-default.properties,ida-internal-get-certificate-uri +registration-processor-default.properties,packetmanager.base.url registration-processor-default.properties,DATASHARECREATEURL registration-processor-default.properties,DATASHAREGETEURL registration-processor-default.properties,mosip.regproc.eventbus.kafka.bootstrap.servers @@ -263,10 +303,12 @@ registration-processor-default.properties,mosip.regproc.message.sender.eventbus. registration-processor-default.properties,mosip.regproc.printing.eventbus.kafka.max.poll.records registration-processor-default.properties,mosip.regproc.packet.classifier.tag-generators registration-processor-default.properties,mosip.regproc.packet.classifier.tagging.metainfo.operationsdata.tag-labels +registration-processor-default.properties,registration.processor.queue.manual.adjudication.request resident-default.properties,mosip.resident.service.status.check.id resident-default.properties,DECRYPT_API_URL resident-default.properties,resident.secretKey resident-default.properties,KERNELAUTHMANAGER +resident-default.properties,REGPROCPRINT resident-default.properties,INTERNALAUTHTRANSACTIONS resident-default.properties,KERNELENCRYPTIONSERVICE resident-default.properties,IDAUTHCREATEVID @@ -275,7 +317,9 @@ resident-default.properties,IDREPOGETIDBYRID resident-default.properties,RIDGENERATION resident-default.properties,MIDSCHEMAURL resident-default.properties,SYNCSERVICE +resident-default.properties,PACKETRECEIVER resident-default.properties,AUTHTYPESTATUSUPDATE +resident-default.properties,REGISTRATIONSTATUSSEARCH resident-default.properties,POLICY_REQ_URL resident-default.properties,OTP_GEN_URL resident-default.properties,CREDENTIAL_STATUS_URL @@ -285,4 +329,82 @@ resident-default.properties,CREDENTIAL_TYPES_URL resident-default.properties,PARTNER_API_URL resident-default.properties,resident.identityjson Syncdata-default.properties,licensekeymanager_database_password +registration-processor-default.properties,registration.processor.reprocess.minutes: +registration-processor-default.properties,mosip.kernel.virus-scanner.port: +registration-processor-default.properties,registration.processor.queue.username: +registration-default.properties,mosip.registration.num_of_fingerprint_retries +registration-default.properties,mosip.registration.num_of_iris_retries +registration-default.properties,mosip.registration.num_of_face_retries +registration-default.properties,mosip.registration.leftslap_fingerprint_threshold +registration-default.properties,mosip.registration.rightslap_fingerprint_threshold +registration-default.properties,mosip.registration.thumbs_fingerprint_threshold +registration-default.properties,mosip.registration.iris_threshold +registration-default.properties,mosip.registration.document_size +registration-default.properties,mosip.registration.pre_reg_no_of_days_limit +registration-default.properties,mosip.registration.capture_time_out +registration-default.properties,mosip.registration.reg_pak_max_cnt_apprv_limit +registration-default.properties,mosip.registration.reg_pak_max_time_apprv_limit +registration-default.properties,mosip.registration.audit_log_deletion_configured_days +registration-default.properties,mosip.registration.reg_deletion_configured_days +registration-default.properties,mosip.registration.pre_reg_deletion_configured_days +registration-default.properties,mosip.registration.sync_transaction_no_of_days_limit +registration-default.properties,mosip.registration.last_export_registration_config_time +registration-default.properties,mosip.registration.registration_packet_store_location +registration-default.properties,mosip.registration.registration_pre_reg_packet_location +registration-default.properties,mosip.registration.mds.deduplication.enable.flag +registration-default.properties,mosip.registration.mdm.portRangeFrom +registration-default.properties,mosip.registration.mdm.portRangeTo +registration-default.properties,mosip.registration.server_profile +application-default.properties,mosip.right_to_left_orientation +application-default.properties,mosip.kernel.keygenerator.symmetric-key-length +application-default.properties,mosip.kernel.keygenerator.asymmetric-key-length +application-default.properties,mosip.kernel.keygenerator.asymmetric-algorithm-name +application-default.properties,mosip.kernel.keygenerator.symmetric-algorithm-name +application-default.properties,mosip.kernel.crypto.symmetric-algorithm-name +application-default.properties,mosip.kernel.crypto.asymmetric-algorithm-name +application-default.properties,mosip.kernel.crypto.gcm-tag-length +application-default.properties,mosip.kernel.crypto.hash-symmetric-key-length +application-default.properties,mosip.kernel.crypto.hash-algorithm-name +application-default.properties,mosip.kernel.crypto.sign-algorithm-name +application-default.properties,mosip.kernel.crypto.hash-iteration +application-default.properties,mosip.kernel.data-key-splitter +application-default.properties,mosip.kernel.signature.signature-request-id +application-default.properties,mosip.kernel.signature.signature-version-id +application-default.properties,mosip.kernel.prid.restricted-numbers +application-default.properties,mosip.kernel.prid.length +application-default.properties,mosip.kernel.prid.sequence-limit +application-default.properties,mosip.kernel.prid.repeating-block-limit +application-default.properties,mosip.kernel.prid.repeating-limit +application-default.properties,mosip.kernel.prid.not-start-with +application-default.properties,mosip.kernel.uin.length +application-default.properties,mosip.kernel.uin.restricted-numbers +application-default.properties,mosip.kernel.uin.length.repeating-block-limit +application-default.properties,mosip.kernel.uin.length.sequence-limit +application-default.properties,mosip.kernel.uin.length.repeating-limit +application-default.properties,mosip.kernel.uin.length.conjugative-even-digits-limit +application-default.properties,mosip.kernel.uin.length.reverse-digits-limit +application-default.properties,mosip.kernel.uin.length.digits-limit +application-default.properties,mosip.kernel.vid.restricted-numbers +application-default.properties,mosip.kernel.vid.not-start-with +application-default.properties,mosip.kernel.vid.length.repeating-limit +application-default.properties,mosip.kernel.vid.length.repeating-block-limit +application-default.properties,mosip.kernel.vid.length.sequence-limit +application-default.properties,mosip.kernel.vid.length +application-default.properties,mosip.kernel.registrationcenterid.length +application-default.properties,mosip.kernel.machineid.length +application-default.properties,mosip.kernel.rid.length +application-default.properties,mosip.kernel.rid.timestamp-length +application-default.properties,mosip.kernel.rid.sequence-length +application-default.properties,mosip.kernel.otp.expiry-time +application-default.properties,mosip.primary-language +application-default.properties,mosip.secondary-language +application-default.properties,mosip.kernel.applicant.type.age.limit +application-default.properties,mosip.idrepo.identity.allowedBioAttributes +application-default.properties,mosip.idrepo.identity.bioAttributes application-default.properties,mosip.supported-languages +application-default.properties,mosip.stage.environment +application-default.properties,mosip.keycloak.max-no-of-users +application-default.properties,mosip.recommended.centers.locCode +application-default.properties,mosip.country.code +application-default.properties,mosip.notification.timezone +application-default.properties,mosip.kernel.filtervalue.max_columns diff --git a/deployment/v3/utils/prop_migrator/knowledge/new-property-with-decent-default-value.csv b/deployment/v3/utils/prop_migrator/knowledge/new-property-with-decent-default-value.csv index c0b8bc8cb..288a891ae 100644 --- a/deployment/v3/utils/prop_migrator/knowledge/new-property-with-decent-default-value.csv +++ b/deployment/v3/utils/prop_migrator/knowledge/new-property-with-decent-default-value.csv @@ -62,6 +62,45 @@ admin-default.properties,mosip.iam.end-session-endpoint-path application-default.properties,mosip.recommended.centers.locCode application-default.properties,mosipbox.public.url application-default.properties,mosip.api.internal.url +<<<<<<< HEAD +======= +application-default.properties,mosip.kernel.authmanager.url +application-default.properties,mosip.kernel.masterdata.url +application-default.properties,mosip.kernel.keymanager.url +application-default.properties,mosip.kernel.auditmanager.url +application-default.properties,mosip.kernel.notification.url +application-default.properties,mosip.kernel.idgenerator.url +application-default.properties,mosip.kernel.otpmanager.url +application-default.properties,mosip.kernel.syncdata.url +application-default.properties,mosip.kernel.pridgenerator.url +application-default.properties,mosip.kernel.ridgenerator.url +application-default.properties,mosip.idrepo.identity.url +application-default.properties,mosip.idrepo.vid.url +application-default.properties,mosip.admin.hotlist.url +application-default.properties,mosip.admin.service.url +application-default.properties,mosip.admin.ui.url +application-default.properties,mosip.pms.policymanager.url +application-default.properties,mosip.pms.partnermanager.url +application-default.properties,mosip.pms.ui.url +application-default.properties,mosip.idrepo.credrequest.generator.url +application-default.properties,mosip.idrepo.credential.service.url +application-default.properties,mosip.datashare.url +application-default.properties,mosip.mock.biosdk.url +application-default.properties,mosip.regproc.biosdk.url +application-default.properties,mosip.idrepo.biosdk.url +application-default.properties,mosip.regproc.workflow.url +application-default.properties,mosip.regproc.status.service.url +application-default.properties,mosip.regproc.transaction.service.url +application-default.properties,mosip.packet.receiver.url +application-default.properties,mosip.websub.url +application-default.properties,mosip.consolidator.url +application-default.properties,mosip.file.server.url +application-default.properties,mosip.ida.internal.url +application-default.properties,mosip.ida.auth.url +application-default.properties,mosip.ida.otp.url +application-default.properties,mosip.resident.url +application-default.properties,mosip.artifactory.url +>>>>>>> [DSD-2904] added property migrator application-default.properties,config.server.file.storage.uri application-default.properties,mosip.idobjectvalidator.masterdata.rest.uri application-default.properties,mosip.kernel.idobjectvalidator.identity.id-schema-version-path @@ -75,6 +114,10 @@ application-default.properties,auth.server.admin.issuer.uri application-default.properties,mosip.kernel.auth.appids.realm.map application-default.properties,mosip.kernel.keymanager-service-CsSign-url application-default.properties,mosip.kernel.transliteration.english-language-code +<<<<<<< HEAD +======= +application-default.properties,mosip.kernel.transliteration.french-language-code +>>>>>>> [DSD-2904] added property migrator application-default.properties,mosip.kernel.syncdata-service-get-tpm-publicKey-url application-default.properties,mosip.kernel.keymanager-service-csverifysign-url application-default.properties,packetmanager.packet.signature.disable-verification @@ -96,6 +139,10 @@ data-share-default.properties,auth.server.admin.allowed.audience data-share-default.properties,mosip.auth.filter_disable data-share-default.properties,object.store.s3.accesskey data-share-default.properties,object.store.s3.secretkey +<<<<<<< HEAD +======= +data-share-default.properties,object.store.s3.url +>>>>>>> [DSD-2904] added property migrator data-share-default.properties,object.store.s3.region data-share-default.properties,object.store.s3.readlimit kernel-default.properties,softhsm.kernel.pin @@ -418,9 +465,52 @@ kernel-default.properties,auth.allowed.urls application-default.properties,mosip.recommended.centers.locCode application-default.properties,mosipbox.public.url application-default.properties,mosip.api.internal.url +<<<<<<< HEAD application-default.properties,config.server.file.storage.uri application-default.properties,mosip.idobjectvalidator.masterdata.rest.uri application-default.properties,mosip.kernel.idobjectvalidator.identity.id-schema-version-path +======= +application-default.properties,mosip.kernel.authmanager.url +application-default.properties,mosip.kernel.masterdata.url +application-default.properties,mosip.kernel.keymanager.url +application-default.properties,mosip.kernel.auditmanager.url +application-default.properties,mosip.kernel.notification.url +application-default.properties,mosip.kernel.idgenerator.url +application-default.properties,mosip.kernel.otpmanager.url +application-default.properties,mosip.kernel.syncdata.url +application-default.properties,mosip.kernel.pridgenerator.url +application-default.properties,mosip.kernel.ridgenerator.url +application-default.properties,mosip.idrepo.identity.url +application-default.properties,mosip.idrepo.vid.url +application-default.properties,mosip.admin.hotlist.url +application-default.properties,mosip.admin.service.url +application-default.properties,mosip.admin.ui.url +application-default.properties,mosip.pms.policymanager.url +application-default.properties,mosip.pms.partnermanager.url +application-default.properties,mosip.pms.ui.url +application-default.properties,mosip.idrepo.credrequest.generator.url +application-default.properties,mosip.idrepo.credential.service.url +application-default.properties,mosip.datashare.url +application-default.properties,mosip.mock.biosdk.url +application-default.properties,mosip.regproc.biosdk.url +application-default.properties,mosip.idrepo.biosdk.url +application-default.properties,mosip.regproc.workflow.url +application-default.properties,mosip.regproc.status.service.url +application-default.properties,mosip.regproc.transaction.service.url +application-default.properties,mosip.packet.receiver.url +application-default.properties,mosip.websub.url +application-default.properties,mosip.consolidator.url +application-default.properties,mosip.file.server.url +application-default.properties,mosip.ida.internal.url +application-default.properties,mosip.ida.auth.url +application-default.properties,mosip.ida.otp.url +application-default.properties,mosip.resident.url +application-default.properties,mosip.artifactory.url +application-default.properties,config.server.file.storage.uri +application-default.properties,mosip.idobjectvalidator.masterdata.rest.uri +application-default.properties,mosip.kernel.idobjectvalidator.identity.id-schema-version-path +application-default.properties,mosip.kernel.idobjectvalidator.identity.dob-path +>>>>>>> [DSD-2904] added property migrator application-default.properties,mosip.idobjectvalidator.refresh-cache-on-unknown-value application-default.properties,mosip.kernel.idobjectvalidator.mandatory-attributes.reg-processor.biometric_correction application-default.properties,mosip.kernel.idobjectvalidator.mandatory-attributes.reg-processor.opencrvs_new @@ -430,16 +520,32 @@ application-default.properties,auth.server.admin.issuer.uri application-default.properties,mosip.kernel.auth.appids.realm.map application-default.properties,mosip.kernel.keymanager-service-CsSign-url application-default.properties,mosip.kernel.transliteration.english-language-code +<<<<<<< HEAD +======= +application-default.properties,mosip.kernel.transliteration.french-language-code +>>>>>>> [DSD-2904] added property migrator application-default.properties,mosip.kernel.syncdata-service-get-tpm-publicKey-url application-default.properties,mosip.kernel.keymanager-service-csverifysign-url application-default.properties,packetmanager.packet.signature.disable-verification application-default.properties,provider.packetreader.opencrvs application-default.properties,provider.packetwriter.opencrvs +<<<<<<< HEAD +======= +application-default.properties,logging.level.io.mosip.registration.processor.status +>>>>>>> [DSD-2904] added property migrator application-default.properties,mosip.mandatory-languages application-default.properties,mosip.optional-languages application-default.properties,mosip.min-languages.count application-default.properties,mosip.max-languages.count +<<<<<<< HEAD application-default.properties,mosip.identity.mapping-file +======= +application-default.properties,mosip.default.template-languages +application-default.properties,mosip.default.user-preferred-language-attribute +application-default.properties,mosip.identity.mapping-file +application-default.properties,mosip.notification.timezone +application-default.properties,mosip.centertypecode.validate.regex +>>>>>>> [DSD-2904] added property migrator application-default.properties,openapi.service.servers[0].url application-default.properties,openapi.service.servers[0].description application-default.properties,mosip.auth.filter_disable @@ -546,6 +652,14 @@ id-authentication-default.properties,mosip.role.keymanager.postvalidate id-authentication-default.properties,mosip.role.keymanager.postpdfsign id-authentication-default.properties,mosip.role.keymanager.postjwtsign id-authentication-default.properties,mosip.role.keymanager.postjwtverify +<<<<<<< HEAD +id-authentication-default.properties,ida-topic-pmp-oidc-client-updated +id-authentication-default.properties,idp.amr-acr.mapping.json.filename +id-authentication-default.properties,ida.api.id.kycauth +id-authentication-default.properties,ida-topic-pmp-oidc-client-created +id-authentication-default.properties,ida-topic-pmp-ca-certificate-uploaded +======= +>>>>>>> [DSD-2904] added property migrator id-repository-default.properties,mosip.idrepo.auth.client-id id-repository-default.properties,mosip.idrepo.auth.secret-key id-repository-default.properties,mosip.idrepo.auth.app-id @@ -562,6 +676,10 @@ id-repository-default.properties,mosip.idrepo.credential.cancel-request.rest.htt id-repository-default.properties,mosip.idrepo.credential.cancel-request.rest.headers.mediaType id-repository-default.properties,mosip.idrepo.credential.cancel-request.rest.timeout id-repository-default.properties,mosip.idrepo.credential-status-update-job.fixed-delay-in-ms +<<<<<<< HEAD +======= +id-repository-default.properties,idrepo-dummy-online-verification-partner-id +>>>>>>> [DSD-2904] added property migrator id-repository-default.properties,mosip.idrepo.websub.vid-credential-update.callback-url id-repository-default.properties,mosip.idrepo.websub.vid-credential-update.topic id-repository-default.properties,mosip.idrepo.websub.vid-credential-update.secret @@ -626,7 +744,17 @@ id-repository-default.properties,mosip.role.idrepo.vid.postvidregenerate id-repository-default.properties,mosip.role.idrepo.vid.postviddeactivate id-repository-default.properties,mosip.role.idrepo.vid.postvidreactivate id-repository-default.properties,mosip.role.idrepo.vid.postdraftvid +<<<<<<< HEAD +id-repository-default.properties,credential.batch.status +id-repository-default.properties,mosip.role.idrepo.identity.getRidByIndividualId +mock-abis-default.properties,secret_url +======= mock-abis-default.properties,secret_url +mock-abis-default.properties,secret_url.clientnId +mock-abis-default.properties,secret_url.id +mock-abis-default.properties,secret_url.secretKey +mock-abis-default.properties,secret_url.appId +>>>>>>> [DSD-2904] added property migrator partner-management-default.properties,auth.allowed.urls partner-management-default.properties,pmp.partner.mobileNumbe.max.length partner-management-default.properties,mosip.iam.adapter.clientid @@ -660,8 +788,16 @@ partner-management-default.properties,pms.notifications-schedule.fixed-rate partner-management-default.properties,partner.register.as.user.in.iam.enable partner-management-default.properties,mosip.iam.post-logout-uri-param-key partner-management-default.properties,mosip.iam.end-session-endpoint-path +<<<<<<< HEAD pre-registration-default.properties,mosip.preregistration.sync.sign.appid pre-registration-default.properties,mosip.preregistration.sync.sign.refid +======= +pre-registration-default.properties,mosip.prereg.application.url +pre-registration-default.properties,mosip.prereg.booking.url +pre-registration-default.properties,mosip.preregistration.sync.sign.appid +pre-registration-default.properties,mosip.preregistration.sync.sign.refid +pre-registration-default.properties,preregistration.job.schedule.cron.purgeExpiredRegCenterSlots +>>>>>>> [DSD-2904] added property migrator pre-registration-default.properties,mosip.kernel.masterdata.day.codes.map pre-registration-default.properties,cancel.appointment.email.subject pre-registration-default.properties,auth.server.admin.allowed.audience @@ -679,7 +815,13 @@ pre-registration-default.properties,mosip.lang.traslate.adapter.impl.basepackage pre-registration-default.properties,mosip.id.validation.identity.email pre-registration-default.properties,mosip.id.validation.identity.phone pre-registration-default.properties,mosip.preregistration.captcha.sitekey +<<<<<<< HEAD pre-registration-default.properties,object.store.s3.use.account.as.bucketname +======= +pre-registration-default.properties,"mosip.security.origins:localhost:8080,localhost:4200,${mosip.api.internal.url}" +pre-registration-default.properties,object.store.s3.use.account.as.bucketname +pre-registration-default.properties,spring.cache.type +>>>>>>> [DSD-2904] added property migrator pre-registration-default.properties,mosip.preregistration.appointment.getavailablity.url pre-registration-default.properties,mosip.preregistration.appointment.book.url pre-registration-default.properties,mosip.preregistration.appointment.multi.book.url @@ -698,6 +840,10 @@ pre-registration-default.properties,mosip.security.authentication.provider.beans pre-registration-default.properties,mosip.security.authentication.provider.beans.list.pre-registration-booking-service pre-registration-default.properties,object.store.s3.accesskey pre-registration-default.properties,object.store.s3.secretkey +<<<<<<< HEAD +======= +pre-registration-default.properties,object.store.s3.url +>>>>>>> [DSD-2904] added property migrator pre-registration-default.properties,object.store.s3.region pre-registration-default.properties,object.store.s3.readlimit pre-registration-default.properties,mosip.role.prereg.postapplications @@ -742,6 +888,10 @@ pre-registration-default.properties,mosip.role.prereg.getappointmentpreregistrat pre-registration-default.properties,mosip.role.prereg.getappointmentregistrationcenterid print-default.properties,mosip.event.delay-millisecs print-default.properties,print-websub-resubscription-delay-millisecs +<<<<<<< HEAD +======= +print-default.properties,mosip.template-language +>>>>>>> [DSD-2904] added property migrator print-default.properties,mosip.optional-languages print-default.properties,mosip.mandatory-languages print-default.properties,mosip.iam.adapter.clientid @@ -759,6 +909,15 @@ registration-default.properties,mosip.registration.reviewer_authentication_confi registration-default.properties,mosip.registration.supervisor_approval_config_flag registration-default.properties,mosip.registration.idle_time registration-default.properties,mosip.kernel.transliteration.english-language-code +<<<<<<< HEAD +======= +registration-default.properties,mosip.registration.onboard_yourself_url +registration-default.properties,mosip.registration.registering_individual_url +registration-default.properties,mosip.registration.sync_data_url +registration-default.properties,mosip.registration.mapping_devices_url +registration-default.properties,mosip.registration.uploading_data_url +registration-default.properties,mosip.registration.updating_biometrics_url +>>>>>>> [DSD-2904] added property migrator registration-default.properties,mosip.registration.mdm.validate.trust registration-default.properties,mosip.registration.mdm.connection.timeout registration-default.properties,mosip.registration.mdm.RCAPTURE.connection.timeout @@ -814,6 +973,16 @@ registration-default.properties,mosip.kernel.rid.sequence-length registration-default.properties,mosip.kernel.virus-scanner.host registration-default.properties,mosip.kernel.virus-scanner.port registration-default.properties,mosip.kernel.otp.expiry-time +<<<<<<< HEAD +======= +registration-default.properties,mosip.primary-language +registration-default.properties,mosip.secondary-language +registration-default.properties,mosip.kernel.applicant.type.age.limit +registration-processor-default.properties,mosip.regproc.notification.url +registration-processor-default.properties,mosip.preferred-language.enabled +registration-processor-default.properties,registration.processor.main-processes +registration-processor-default.properties,registration.processor.sub-processes +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,IDAINTERNAL registration-processor-default.properties,LANGUAGE registration-processor-default.properties,IDENTITY @@ -824,6 +993,10 @@ registration-processor-default.properties,IDREPOUPDATEDRAFT registration-processor-default.properties,IDREPOPUBLISHDRAFT registration-processor-default.properties,IDREPOEXTRACTBIOMETRICS registration-processor-default.properties,KEYMANAGER +<<<<<<< HEAD +======= +registration-processor-default.properties,registration.processor.demodedupe.manual.adjudication.status +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,DEVICEHOTLIST registration-processor-default.properties,JWTVERIFY registration-processor-default.properties,NOTIFIER @@ -837,6 +1010,11 @@ registration-processor-default.properties,mosip.registration.processor.packet.st registration-processor-default.properties,mosip.registration.processor.packet.status.transactiontypecodes-time-based-resend-required registration-processor-default.properties,mosip.registration.processor.registration.status.external-statuses-to-consider-processed registration-processor-default.properties,mosip.registration.processor.postalcode.req.url +<<<<<<< HEAD +======= +registration-processor-default.properties,mosip.identity.auth.internal.env +registration-processor-default.properties,mosip.registration.processor.lostrid.registrationdate.pattern +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.packet.receiver.eventbus.kafka.commit.type registration-processor-default.properties,mosip.regproc.packet.receiver.eventbus.kafka.max.poll.records registration-processor-default.properties,mosip.regproc.packet.receiver.eventbus.kafka.poll.frequency @@ -845,13 +1023,25 @@ registration-processor-default.properties,mosip.regproc.packet.receiver.server.s registration-processor-default.properties,mosip.regproc.packet.receiver.server.port registration-processor-default.properties,mosip.regproc.packet.receiver.eventbus.port registration-processor-default.properties,mosip.regproc.packet.receiver.message.tag.loading.disable +<<<<<<< HEAD +registration-processor-default.properties,registration.processor.notification_service_subscriber_callback_url +======= +registration-processor-default.properties,mosip.regproc.virusscanner.provider +registration-processor-default.properties,registration.processor.notification_service_subscriber_secret registration-processor-default.properties,registration.processor.notification_service_subscriber_callback_url +registration-processor-default.properties,registration.processor.notification_service_pausedforadditonalinfo_subscriber_secret +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.workflow.pausedforadditionalinfo.topic registration-processor-default.properties,registration.processor.notification_service_pausedforadditonalinfo_subscriber_callback_url registration-processor-default.properties,mosip.regproc.notification_service.biometric_correction.email registration-processor-default.properties,mosip.regproc.notification_service.biometric_correction.sms registration-processor-default.properties,mosip.regproc.notification_service.biometric_correction.subject registration-processor-default.properties,registration.processor.queue.connection.retry.count +<<<<<<< HEAD +======= +registration-processor-default.properties,registration.processor.queue.manualverification.request +registration-processor-default.properties,registration.processor.queue.manualverification.response +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,registration.processor.reprocess.limit registration-processor-default.properties,registration.processor.pause.packets.for.backpressure registration-processor-default.properties,mosip.regproc.verification.eventbus.kafka.commit.type @@ -860,8 +1050,16 @@ registration-processor-default.properties,mosip.regproc.verification.eventbus.ka registration-processor-default.properties,mosip.regproc.verification.eventbus.kafka.group.id registration-processor-default.properties,mosip.regproc.verification.message.expiry-time-limit registration-processor-default.properties,registration.processor.verification.queue.typeOfQueue +<<<<<<< HEAD registration-processor-default.properties,registration.processor.verification.policy.id registration-processor-default.properties,registration.processor.verification.subscriber.id +======= +registration-processor-default.properties,registration.processor.verification.queue.response +registration-processor-default.properties,registration.processor.queue.verification.request +registration-processor-default.properties,registration.processor.verification.policy.id +registration-processor-default.properties,registration.processor.verification.subscriber.id +registration-processor-default.properties,registration.processor.queue.verification.request.messageTTL +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.verification.eventbus.port registration-processor-default.properties,mosip.regproc.verification.server.port registration-processor-default.properties,mosip.regproc.verification.server.servlet.path @@ -879,6 +1077,12 @@ registration-processor-default.properties,mosip.registration.processor.manual.ad registration-processor-default.properties,mosip.registration.processor.manual.adjudication.biometric.id registration-processor-default.properties,mosip.registration.processor.manual.adjudication.demographic.id registration-processor-default.properties,mosip.registration.processor.manual.adjudication.packetinfo.id +<<<<<<< HEAD +======= +registration-processor-default.properties,registration.processor.manual.adjudication.queue.response +registration-processor-default.properties,registration.processor.queue.manual.adjudication.request.messageTTL +registration-processor-default.properties,registration.processor.manual.adjudication.reprocess.buffer.time +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.workflow.complete.topic registration-processor-default.properties,mosip.regproc.workflow.action.job.server.port registration-processor-default.properties,mosip.regproc.workflow.action.job.eventbus.port @@ -910,6 +1114,10 @@ registration-processor-default.properties,mosip.regproc.workflow.manager.message registration-processor-default.properties,PACKETMANAGER_DELETE_TAGS registration-processor-default.properties,PACKETMANAGER_GET_TAGS registration-processor-default.properties,mosip.regproc.data.share.internal.domain.name +<<<<<<< HEAD +======= +registration-processor-default.properties,mosip.regproc.data.share.protocol +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.biosdk.default.service.url registration-processor-default.properties,mosip.biometric.sdk.providers.finger.mosip-ref-impl-sdk-client.classname registration-processor-default.properties,mosip.biometric.sdk.providers.finger.mosip-ref-impl-sdk-client.version @@ -924,6 +1132,10 @@ registration-processor-default.properties,mosip.biometric.sdk.providers.face.mos registration-processor-default.properties,mosip.regproc.mosip-stage-executor.stage-beans-base-packages.default registration-processor-default.properties,mosip.anonymous.profile.eventbus.address registration-processor-default.properties,mosip.regproc.camelbridge.endpoint-prefix +<<<<<<< HEAD +======= +registration-processor-default.properties,mosip.regproc.camelbridge.pause-settings +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.securezone.notification.server.port registration-processor-default.properties,mosip.regproc.securezone.notification.server.servlet.path registration-processor-default.properties,mosip.regproc.securezone.notification.eventbus.port @@ -937,6 +1149,10 @@ registration-processor-default.properties,mosip.regproc.packet.validator.server. registration-processor-default.properties,mosip.regproc.packet.validator.eventbus.port registration-processor-default.properties,mosip.regproc.packet.validator.server.servlet.path registration-processor-default.properties,mosip.regproc.packet.validator.validate-applicant-document +<<<<<<< HEAD +======= +registration-processor-default.properties,mosip.regproc.packet.validator.validate-applicant-document.processes +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.operator-validator.eventbus.kafka.commit.type registration-processor-default.properties,mosip.regproc.operator-validator.eventbus.kafka.max.poll.records registration-processor-default.properties,mosip.regproc.operator-validator.eventbus.kafka.poll.frequency @@ -959,6 +1175,10 @@ registration-processor-default.properties,mosip.regproc.cmd-validator.device-val registration-processor-default.properties,mosip.regproc.cmd-validator.working-hour-validation-required registration-processor-default.properties,mosip.regproc.cmd-validator.device.disable-trust-validation registration-processor-default.properties,mosip.regproc.cmd-validator.device.allowed-digital-id-timestamp-variation +<<<<<<< HEAD +======= +registration-processor-default.properties,mosip.regproc.cmd-validator.device.digital-id-timestamp-format +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.packet.classifier.server.port registration-processor-default.properties,mosip.regproc.packet.classifier.eventbus.port registration-processor-default.properties,mosip.regproc.packet.classifier.server.servlet.path @@ -970,8 +1190,15 @@ registration-processor-default.properties,mosip.regproc.quality.classifier.messa registration-processor-default.properties,mosip.regproc.quality.classifier.server.port registration-processor-default.properties,mosip.regproc.quality.classifier.eventbus.port registration-processor-default.properties,mosip.regproc.quality.classifier.server.servlet.path +<<<<<<< HEAD +registration-processor-default.properties,mosip.regproc.quality.classifier.tagging.quality.prefix +registration-processor-default.properties,mosip.regproc.quality.classifier.tagging.quality.biometric-not-available-tag-value +======= +registration-processor-default.properties,mosip.regproc.quality.classifier.tagging.quality.ranges registration-processor-default.properties,mosip.regproc.quality.classifier.tagging.quality.prefix registration-processor-default.properties,mosip.regproc.quality.classifier.tagging.quality.biometric-not-available-tag-value +registration-processor-default.properties,mosip.regproc.quality.classifier.tagging.quality.modalities +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.introducer-validator.eventbus.kafka.commit.type registration-processor-default.properties,mosip.regproc.introducer-validator.eventbus.kafka.max.poll.records registration-processor-default.properties,mosip.regproc.introducer-validator.eventbus.kafka.poll.frequency @@ -986,6 +1213,13 @@ registration-processor-default.properties,mosip.regproc.demo.dedupe.server.servl registration-processor-default.properties,mosip.regproc.abis.handler.server.port registration-processor-default.properties,mosip.regproc.abis.handler.eventbus.port registration-processor-default.properties,mosip.regproc.abis.handler.server.servlet.path +<<<<<<< HEAD +======= +registration-processor-default.properties,mosip.regproc.abis.handler.biometric-modalities-segments-mapping.INFANT +registration-processor-default.properties,mosip.regproc.abis.handler.biometric-modalities-segments-mapping.MINOR +registration-processor-default.properties,mosip.regproc.abis.handler.biometric-modalities-segments-mapping.ADULT +registration-processor-default.properties,mosip.regproc.abis.handler.biometric-segments-exceptions-mapping +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,mosip.regproc.bio.dedupe.server.port registration-processor-default.properties,mosip.regproc.bio.dedupe.eventbus.port registration-processor-default.properties,mosip.regproc.bio.dedupe.server.servlet.path @@ -1120,6 +1354,10 @@ registration-processor-default.properties,mosip.iam.adapter.self-token-renewal-e registration-processor-default.properties,mosip.auth.filter_disable registration-processor-default.properties,object.store.s3.accesskey registration-processor-default.properties,object.store.s3.secretkey +<<<<<<< HEAD +======= +registration-processor-default.properties,object.store.s3.url +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,object.store.s3.region registration-processor-default.properties,object.store.s3.readlimit registration-processor-default.properties,mosip.role.registration.getGetsearchrid @@ -1132,6 +1370,10 @@ registration-processor-default.properties,mosip.role.registration.getPostlostrid registration-processor-default.properties,mosip.role.registration.getPostsync registration-processor-default.properties,mosip.role.registration.getPostsyncv2 registration-processor-default.properties,auth.server.admin.allowed.audience +<<<<<<< HEAD +======= +registration-processor-default.properties,mosip.regproc.cbeff-validation.mandatory.modalities +>>>>>>> [DSD-2904] added property migrator registration-processor-default.properties,registration.processor.lostrid.max.registrationid registration-processor-default.properties,mosip.registration.processor.lostrid.max-registration-date-filter-interval resident-default.properties,MACHINESEARCH @@ -1146,6 +1388,11 @@ resident-default.properties,auth.server.admin.issuer.uri resident-default.properties,mosip.service-context resident-default.properties,mosip.service.end-points resident-default.properties,mosip.service.exclude.auth.allowed.method +<<<<<<< HEAD +resident-default.properties,resident.update-uin.machine-spec-id +resident-default.properties,ida.online-verification-partner-id +======= +>>>>>>> [DSD-2904] added property migrator syncdata-default.properties,mosip.iam.role-based-user-url syncdata-default.properties,mosip.iam.adapter.clientid syncdata-default.properties,mosip.iam.adapter.clientsecret @@ -1274,13 +1521,21 @@ resident-default.properties,sequence-order resident-default.properties,resident.template.bell-icon.request-received.order-a-physical-card resident-default.properties,mosip.resident.sign.pdf.reference.id resident-default.properties,resident.template.ack.update-demographic-data +<<<<<<< HEAD resident-default.properties,resident.update-uin.machine-name-prefix +======= +resident-default.properties,resident.update-uin.machine-name-prefix +>>>>>>> [DSD-2904] added property migrator resident-default.properties,mosip.scope.resident.postAuthTypeStatus resident-default.properties,resident.template.tnc.share-cred-with-partner resident-default.properties,mosip.resident.ack.personalised_card.name.convention resident-default.properties,resident.template.bell-icon.success.update-demo-data resident-default.properties,resident.template.bell-icon.request-received.verify-my-phone-email resident-default.properties,resident.template.email.subject.success.vid-card-download +<<<<<<< HEAD +======= +resident-default.properties,otpChannel.mobile +>>>>>>> [DSD-2904] added property migrator resident-default.properties,resident-ui-schema-file-name-prefix resident-default.properties,resident.template.email.subject.success.get-my-uin-card resident-default.properties,mosip.scope.resident.postgeneratevid @@ -1354,7 +1609,11 @@ resident-default.properties,mosip.scope.resident.getAuthTransactions resident-default.properties,mosip.resident.phone.token.claim-phone resident-default.properties,mosip.resident.request.vid.card.version resident-default.properties,spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults +<<<<<<< HEAD resident-default.properties,hibernate.jdbc.lob.non_contextual_creation +======= +resident-default.properties,hibernate.jdbc.lob.non_contextual_creation +>>>>>>> [DSD-2904] added property migrator resident-default.properties,mosip.email.template.property resident-default.properties,mosip.full.name.template.property resident-default.properties,mosip.resident.download.service.history.file.name.convention @@ -1512,7 +1771,11 @@ resident-default.properties,resident.template.purpose.failure.get-my-uin-card resident-default.properties,resident.template.purpose.failure.order-a-physical-card resident-default.properties,resident.service-history.download.max.count resident-default.properties,resident.template.sms.request-received.verify-my-phone-email +<<<<<<< HEAD resident-default.properties,resident.download.card.eventid.id +======= +resident-default.properties,resident.download.card.eventid.id +>>>>>>> [DSD-2904] added property migrator resident-default.properties,mosip.iam.module.login_flow.response_type resident-default.properties,resident.template.email.content.success.verify-my-phone-email resident-default.properties,resident.grievance-redressal.alt-email.chars.limit @@ -1623,3 +1886,28 @@ resident-default.properties,mosip.scope.resident.postRequestShareCredWithPartner resident-default.properties,resident.template.support-docs-list resident-default.properties,resident.identity.info.version resident-default.properties,resident.template.email.content.failure.cust-and-down-my-card +<<<<<<< HEAD +packet-manager-default.properties,auth.server.admin.allowed.audience +packet-manager-default.properties,packetmanager.additional.fields.search.from.metainfo +packet-manager-default.properties,mosip.role.commons-packet.putcreatepacket +packet-manager-default.properties,mosip.role.commons-packet.postaddtag +packet-manager-default.properties,mosip.role.commons-packet.postaddorupdatetag +packet-manager-default.properties,mosip.role.commons-packet.postdeletetag +packet-manager-default.properties,mosip.role.commons-packet.postinfo +packet-manager-default.properties,mosip.role.commons-packet.postgettags +packet-manager-default.properties,mosip.role.commons-packet.postvalidatepacket +packet-manager-default.properties,mosip.role.commons-packet.postaudits +packet-manager-default.properties,mosip.role.commons-packet.postmetainfo +packet-manager-default.properties,mosip.role.commons-packet.postbiometrics +packet-manager-default.properties,mosip.role.commons-packet.postdocument +packet-manager-default.properties,mosip.role.commons-packet.postsearchfields +packet-manager-default.properties,object.store.s3.accesskey +packet-manager-default.properties,object.store.s3.secretkey +packet-manager-default.properties,object.store.s3.region +packet-manager-default.properties,object.store.s3.readlimit +packet-manager-default.properties,mosip.iam.adapter.appid +packet-manager-default.properties,mosip.iam.adapter.clientid +packet-manager-default.properties,mosip.iam.adapter.clientsecret +credential-service-default.properties,credentialType.formatter.VERCRED +======= +>>>>>>> [DSD-2904] added property migrator diff --git a/deployment/v3/utils/prop_migrator/knowledge/old-value-takes-priority.csv b/deployment/v3/utils/prop_migrator/knowledge/old-value-takes-priority.csv index f8cbdc3fe..9b5eecc1b 100644 --- a/deployment/v3/utils/prop_migrator/knowledge/old-value-takes-priority.csv +++ b/deployment/v3/utils/prop_migrator/knowledge/old-value-takes-priority.csv @@ -48,8 +48,13 @@ registration-processor-default.properties,packetmanager.provider.uingenerator.pa registration-processor-default.properties,packetmanager.provider.uingenerator.parentOrGuardianRID registration-processor-default.properties,registration.processor.reprocess.elapse.time registration-processor-default.properties,registration.processor.reprocess.hours +registration-processor-default.properties,mosip.registration.processor.database.port registration-processor-default.properties,registration.processor.LANDING_ZONE registration-processor-default.properties,mosip.regproc.packet.classifier.tagging.agegroup.ranges +registration-processor-default.properties,mosip.kernel.virus-scanner.host +registration-processor-default.properties,registration.processor.reprocess.minutes: +registration-processor-default.properties,mosip.kernel.virus-scanner.port: +registration-processor-default.properties,registration.processor.queue.username: registration-default.properties,mosip.registration.num_of_fingerprint_retries registration-default.properties,mosip.registration.num_of_iris_retries registration-default.properties,mosip.registration.num_of_face_retries @@ -117,6 +122,8 @@ application-default.properties,mosip.kernel.machineid.length application-default.properties,mosip.kernel.rid.length application-default.properties,mosip.kernel.rid.timestamp-length application-default.properties,mosip.kernel.rid.sequence-length +application-default.properties,mosip.kernel.virus-scanner.host +application-default.properties,mosip.kernel.virus-scanner.port application-default.properties,mosip.kernel.otp.expiry-time application-default.properties,mosip.primary-language application-default.properties,mosip.secondary-language diff --git a/deployment/v3/utils/readuser-util/README.md b/deployment/v3/utils/readuser-util/README.md new file mode 100644 index 000000000..99c617859 --- /dev/null +++ b/deployment/v3/utils/readuser-util/README.md @@ -0,0 +1,39 @@ +# ReadUser Creation Utility: + +This Utility is used for the creation of user with readonly privilages for postgres, minio and keycloak server. + +- This utility is designed to initialize MinIO with user management and policy attachment based on the specified action (create or delete). +- Also runs a script that creates a read-only user in a PostgreSQL database. +- To Initialize keycloak with user with readonly privilages. + +## Prerequisites +Ensure the following prerequisites are met before deploying the utility: + +- Kubernetes Cluster: A running Kubernetes cluster. +- MinIO Deployment: MinIO server should be deployed and running. +- Postgres Deployment: Postgres server should be deployed and running. +- Keycloak Deployment: Keycloak server should be deployed and running. +- Kubernetes ConfigMap and Secrets: + * Secret containing the "postgres-password" + * Secret containing the MinIO access and secret keys. +- Configuration for the username, password, policy name, and action should be managed via a values file (typically used with Helm charts) for s3-readuser-util chart. +- Configuration for the username, password, dbhost, dbport and action should be managed via a values file (typically used with Helm charts) for postgres-readuser-util chart. +- readuser-init-values.yaml file with user configurations to initialize keycloak. + +### Notes: + +* The action (create or delete), username, password, and policy name should be set in the values.yaml file, which will be referenced in the Job manifest. +* The utility uses mc client to create readuser in minio server. +* The utility uses sql script which is passed in configmaps to create readuser in postgres server. +* If you want to create readuser then the "action" key value from values.yaml needs to be "create". +* If you want to delete readuser then the "action" key value from values.yaml needs to be "delete". +* Once after exicuting this utility please confirm from the minio, postgres and keycloak server whether the user created has the necessary privilages or not. +* And in case of deleteion of user crosscheck from the minio, postgres and keycloak server if the user is deleted or not. + +### Install + +* `install.sh` + +### Delete + +* `delete.sh` \ No newline at end of file diff --git a/deployment/v3/utils/readuser-util/copy_cm.sh b/deployment/v3/utils/readuser-util/copy_cm.sh new file mode 100755 index 000000000..0e9f30dd3 --- /dev/null +++ b/deployment/v3/utils/readuser-util/copy_cm.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Copy configmaps from other namespaces + +function copying_cm() { + COPY_UTIL=../copy_cm_func.sh + DST_NS=util # DST_NS: Destination namespace + + $COPY_UTIL configmap keycloak-host keycloak $DST_NS + $COPY_UTIL configmap keycloak-env-vars keycloak $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +copying_cm # calling function diff --git a/deployment/v3/utils/readuser-util/copy_secrets.sh b/deployment/v3/utils/readuser-util/copy_secrets.sh new file mode 100755 index 000000000..0ce3be107 --- /dev/null +++ b/deployment/v3/utils/readuser-util/copy_secrets.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Copy secrets from other namespaces + +function copying_secrets() { + COPY_UTIL=../copy_cm_func.sh + DST_NS=util # DST_NS: Destination namespace + $COPY_UTIL secret minio minio $DST_NS + $COPY_UTIL secret postgres-postgresql postgres $DST_NS + $COPY_UTIL secret keycloak keycloak $DST_NS + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +copying_secrets # calling function diff --git a/deployment/v3/utils/readuser-util/delete.sh b/deployment/v3/utils/readuser-util/delete.sh new file mode 100755 index 000000000..1920da5af --- /dev/null +++ b/deployment/v3/utils/readuser-util/delete.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Uninstalls readuser-util +## Usage: ./delete.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +function deleting_readuser-util() { + NS=util + while true; do + read -p "Are you sure you want to delete readuser-util helm charts?(Y/n) " yn + if [ $yn = "Y" ] + then + helm -n $NS delete readuser-util + helm -n $NS delete readuser-iam-init + break + else + break + fi + done + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +deleting_readuser-util # calling function \ No newline at end of file diff --git a/deployment/v3/utils/readuser-util/install.sh b/deployment/v3/utils/readuser-util/install.sh new file mode 100755 index 000000000..6a115dac0 --- /dev/null +++ b/deployment/v3/utils/readuser-util/install.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Installs readuser-util +## Usage: ./install.sh [kubeconfig] + +if [ $# -ge 1 ] ; then + export KUBECONFIG=$1 +fi + +NS=util +CHART_VERSION=0.0.1-develop + +echo Create $NS namespace +kubectl create ns $NS + +function installing_readuser-util() { + + echo Copy secrets + sed -i 's/\r$//' copy_secrets.sh + ./copy_secrets.sh + + echo Copy configmaps + sed -i 's/\r$//' copy_cm.sh + ./copy_cm.sh + + echo Installing readuser-util + helm -n $NS install readuser-util mosip/readuser-util --version $CHART_VERSION -f values.yaml --wait + helm -n $NS install readuser-iam-init mosip/keycloak-init --version $CHART_VERSION -f readuser-init-values.yaml --wait + + echo Installed readuser-util + return 0 +} + +# set commands for error handling. +set -e +set -o errexit ## set -e : exit the script if any statement returns a non-true return value +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable +set -o errtrace # trace ERR through 'time command' and other functions +set -o pipefail # trace ERR through pipes +installing_readuser-util # calling function diff --git a/deployment/v3/utils/readuser-util/readuser-init-values.yaml b/deployment/v3/utils/readuser-util/readuser-init-values.yaml new file mode 100644 index 000000000..7a99a9881 --- /dev/null +++ b/deployment/v3/utils/readuser-util/readuser-init-values.yaml @@ -0,0 +1,25 @@ +## YAML to create a users +keycloak: + realms: + mosip: # realm + roles: [] + clients: [] + users: + - username: readuser + email: read_user15@xyz.com + firstName: read + lastName: user + password: mosip123 + temporary: False + attributes: {} + realmRoles: + - offline_access + - uma_authorization + client: "realm-management" + clientRoles: + - "view-users" + - "view-authorization" + - "view-clients" + - "view-events" + - "view-realm" + - "view-identity-providers" diff --git a/deployment/v3/utils/readuser-util/values.yaml b/deployment/v3/utils/readuser-util/values.yaml new file mode 100644 index 000000000..4dee20a27 --- /dev/null +++ b/deployment/v3/utils/readuser-util/values.yaml @@ -0,0 +1,32 @@ +# Default values for readuser. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +postgres-readuser-util: + enabled: true + # Values for readuser creation. + # "action" key specifies whether you want to "create" or "delete" readuser. + # "username" key specifies the username of readuser creating. + # "password" key specifies the password for readuser. + # "dbport" key specifies the DB port number. + # "dbhost" key specifies the DB host. + user: + action: "create" + username: "readuser" + password: "mosip123" + dbport: 5432 + dbhost: api-internal.xyz.mosip.net + +s3-readuser-util: + enabled: true + # Values for readuser creation. + # "action" key specifies whether you want to "create" or "delete" readuser. + # "username" key specifies the username of readuser creating. + # "password" key specifies the password for readuser. + # "policyName" key specifies the policyname creating. + s3user: + action: "create" + username: "readuser" + password: "mosip123" + policyName: "dataread" +