diff --git a/.github/workflows/auto-pr-to-release.yml b/.github/workflows/auto-pr-to-release.yml
index 0be40b8fb..4b2132549 100644
--- a/.github/workflows/auto-pr-to-release.yml
+++ b/.github/workflows/auto-pr-to-release.yml
@@ -33,19 +33,17 @@ jobs:
id: get_pr_details_dispatch
run: |
PR_NUMBER=${{ github.event.inputs.pr_number }}
- PR_DATA=$(gh pr view $PR_NUMBER --json number,headRefName,baseRefName,mergedBy,mergeCommit,author,milestone,title --jq '{number: .number, headRefName: .headRefName, baseRefName: .baseRefName, merger: .mergedBy.login, author: .author.login, milestone: .milestone.title, title: .title}')
- echo "PR_ID=$(echo $PR_DATA | jq -r '.number')" >> $GITHUB_ENV
- echo "PR_AUTHOR=$(echo $PR_DATA | jq -r '.author')" >> $GITHUB_ENV
- echo "PR_MERGER=$(echo $PR_DATA | jq -r '.merger')" >> $GITHUB_ENV
- echo "MILESTONE=$(echo $PR_DATA | jq -r '.milestone')" >> $GITHUB_ENV
- echo "BASE_BRANCH=$(echo $PR_DATA | jq -r '.baseRefName')" >> $GITHUB_ENV
- echo "HEAD_BRANCH=$(echo $PR_DATA | jq -r '.headRefName')" >> $GITHUB_ENV
- echo "PR_TITLE=$(echo $PR_DATA | jq -r '.title')" >> $GITHUB_ENV
-
- LATEST_COMMIT_SHA=$(gh pr view $PR_NUMBER --json commits --jq '.commits[-1].oid')
- FIRST_COMMIT_SHA=$(gh pr view $PR_NUMBER --json commits --jq '.commits[0].oid')
- echo "LATEST_COMMIT_SHA=${LATEST_COMMIT_SHA}" >> $GITHUB_ENV
- echo "FIRST_COMMIT_SHA=${FIRST_COMMIT_SHA}" >> $GITHUB_ENV
+ PR_DATA=$(curl -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/opencrvs/opencrvs-countryconfig/pulls/$PR_NUMBER)
+ # printf escapes the newlines in the JSON, so we can use jq to parse output such as:
+ # "body": "![image](https://github.com/user-attachments/assets/8eee5bcf-7692-490f-a19f-576623e09961)\r\n",
+ echo "PR_ID=$(printf '%s' $PR_DATA | jq -r '.number')" >> $GITHUB_ENV
+ echo "PR_AUTHOR=$(printf '%s' $PR_DATA | jq -r '.user.login')" >> $GITHUB_ENV
+ echo "PR_MERGER=$(printf '%s' $PR_DATA | jq -r '.merged_by.login')" >> $GITHUB_ENV
+ echo "MILESTONE=$(printf '%s' $PR_DATA | jq -r '.milestone.title')" >> $GITHUB_ENV
+ echo "BASE_BRANCH=$(printf '%s' $PR_DATA | jq -r '.base.ref')" >> $GITHUB_ENV
+ echo "HEAD_BRANCH=$(printf '%s' $PR_DATA | jq -r '.head.ref')" >> $GITHUB_ENV
+ echo "PR_TITLE=$(printf '%s' $PR_DATA | jq -r '.title')" >> $GITHUB_ENV
+ echo "BASE_SHA=$(printf '%s' $PR_DATA | jq -r '.base.sha')" >> $GITHUB_ENV
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -60,11 +58,7 @@ jobs:
echo "BASE_BRANCH=${{ github.event.pull_request.base.ref }}" >> $GITHUB_ENV
echo "HEAD_BRANCH=${{ github.event.pull_request.head.ref }}" >> $GITHUB_ENV
echo "PR_TITLE=${{ github.event.pull_request.title }}" >> $GITHUB_ENV
-
- LATEST_COMMIT_SHA=$(gh pr view $PR_NUMBER --json commits --jq '.commits[-1].oid')
- FIRST_COMMIT_SHA=$(gh pr view $PR_NUMBER --json commits --jq '.commits[0].oid')
- echo "LATEST_COMMIT_SHA=${LATEST_COMMIT_SHA}" >> $GITHUB_ENV
- echo "FIRST_COMMIT_SHA=${FIRST_COMMIT_SHA}" >> $GITHUB_ENV
+ echo "BASE_SHA=${{ github.event.pull_request.base.sha }}" >> $GITHUB_ENV
PR_DETAILS=$(gh pr view $PR_NUMBER --json mergedBy)
MERGED_BY_LOGIN=$(echo "$PR_DETAILS" | jq -r '.mergedBy.login')
@@ -111,28 +105,30 @@ jobs:
git config advice.mergeConflict false
# Fetch and checkout the release branch
- git fetch --all
+ git fetch --all --unshallow
git checkout ${{ env.RELEASE_BRANCH }}
# Create a new branch for the PR
NEW_BRANCH="auto-pr-${{ env.RELEASE_BRANCH }}-${{ env.PR_ID }}-$RANDOM"
git checkout -b $NEW_BRANCH
- echo "First commit: ${{ env.FIRST_COMMIT_SHA }}"
- echo "Latest commit: ${{ env.LATEST_COMMIT_SHA }}"
- COMMIT_RANGE="${{ env.FIRST_COMMIT_SHA }}..${{ env.LATEST_COMMIT_SHA }}"
+ echo "HEAD_BRANCH: ${{ env.HEAD_BRANCH }}"
+ echo "BASE_SHA: ${{ env.BASE_SHA }}"
- if [ "${{ env.FIRST_COMMIT_SHA }}" == "${{ env.LATEST_COMMIT_SHA }}" ]; then
- COMMIT_RANGE=${{ env.FIRST_COMMIT_SHA }}
- fi
+ COMMIT_RANGE="${{ env.BASE_SHA }}..origin/${{ env.HEAD_BRANCH }}"
+
+ echo "Commit range: ${COMMIT_RANGE}"
- echo "Commit range: $COMMIT_RANGE"
+ NON_MERGE_COMMITS=$(git log ${COMMIT_RANGE} --reverse --no-merges --pretty=format:"%h" -- | xargs)
+
+ echo "Ordered non-merge commits: $NON_MERGE_COMMITS"
# Attempt to cherry-pick the commits from the original PR
- CHERRY_PICK_OUTPUT=$(git cherry-pick $COMMIT_RANGE 2>&1) || {
+ CHERRY_PICK_OUTPUT=$(git cherry-pick ${NON_MERGE_COMMITS} 2>&1) || {
git cherry-pick --abort || true
# If cherry-pick fails, create a placeholder commit
echo "Cherry-pick failed. Creating placeholder commit."
+
git reset --hard
git commit --allow-empty -m "Placeholder commit for PR #${{ env.PR_ID }}"
@@ -152,8 +148,9 @@ jobs:
git checkout $NEW_BRANCH
git reset --hard HEAD~1 # Remove placeholder commit
- git cherry-pick $COMMIT_RANGE
+ git cherry-pick $NON_MERGE_COMMITS
\`\`\`
+
"
}
diff --git a/.github/workflows/check-changelog.yml b/.github/workflows/check-changelog.yml
new file mode 100644
index 000000000..2cb663718
--- /dev/null
+++ b/.github/workflows/check-changelog.yml
@@ -0,0 +1,19 @@
+name: Verify CHANGELOG.md is updated
+
+on: [pull_request]
+
+jobs:
+ check:
+ runs-on: ubuntu-22.04
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - uses: mskelton/changelog-reminder-action@v3
+ with:
+ message: >
+ Oops! Looks like you forgot to update the changelog.
+ When updating CHANGELOG.md, please consider the following:
+ - Changelog is read by country implementors who might not always be familiar with all technical details of OpenCRVS. Keep language high-level, user friendly and avoid technical references to internals.
+ - Answer "What's new?", "Why was the change made?" and "Why should I care?" for each change.
+ - If it's a breaking change, include a migration guide answering "What do I need to do to upgrade?".
diff --git a/.github/workflows/clear-environment.yml b/.github/workflows/clear-environment.yml
index 25f360477..fea82bf7a 100644
--- a/.github/workflows/clear-environment.yml
+++ b/.github/workflows/clear-environment.yml
@@ -22,6 +22,8 @@ jobs:
name: 'Reset data'
environment: ${{ github.event.inputs.environment }}
runs-on: ubuntu-22.04
+ outputs:
+ outcome: ${{ steps.reset-data.outcome }}
timeout-minutes: 60
steps:
- name: Clone country config resource package
@@ -45,6 +47,7 @@ jobs:
known_hosts: ${{ env.KNOWN_HOSTS }}
- name: Reset data
+ id: reset-data
env:
HOST: ${{ vars.DOMAIN }}
ENV: ${{ vars.ENVIRONMENT_TYPE }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04bfe37d6..aaead0ec5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,12 @@
# Changelog
+
## 1.7.0 Release candidate
+### Bug fixes
+
+- Kibana disk space alerts now work regardless of your disk device names. Alerts listen devices mounted both to `/` and `/data` (encrypted data partition)
+
### Breaking changes
- **Title** Description
@@ -58,11 +63,15 @@ INSERT CSV ROWS IN ENGLISH ONLY
- Remove `splitView` option from DOCUMENT_UPLOADER_WITH_OPTION field
- New required sections preview & review added. Signature field definitions are now part of these two sections same as normal form fields.
- Remove `inputFieldWidth` from Number type form field
-- **Title** Description
-
-### Infrastructure breaking changes
-
-- **Title** Description
+- Application config file is renamed to `application-config.ts`
+- Allow configuring the default search criteria for record search which can be done by adding or modifying a property named `SEARCH_DEFAULT_CRITERIA` in `application-config.ts`
+ Value of `SEARCH_DEFAULT_CRITERIA` can be one of the following
+ 1. 'TRACKING_ID',
+ 2. 'REGISTRATION_NUMBER',
+ 3. 'NATIONAL_ID',
+ 4. 'NAME',
+ 5. 'PHONE_NUMBER',
+ 6. 'EMAIL'
### New features
diff --git a/infrastructure/deployment/deploy.sh b/infrastructure/deployment/deploy.sh
index 5d8725915..ba3eda77d 100755
--- a/infrastructure/deployment/deploy.sh
+++ b/infrastructure/deployment/deploy.sh
@@ -386,6 +386,15 @@ echo
echo "Waiting 2 mins for mongo to deploy before working with data. Please note it can take up to 10 minutes for the entire stack to deploy in some scenarios."
echo
+echo 'Setting up elastalert indices'
+
+while true; do
+ if configured_ssh "/opt/opencrvs/infrastructure/elasticsearch/setup-elastalert-indices.sh"; then
+ break
+ fi
+ sleep 5
+done
+
echo "Setting up Kibana config & alerts"
while true; do
diff --git a/infrastructure/docker-compose.deploy.yml b/infrastructure/docker-compose.deploy.yml
index 4d8a8473f..3af57d9e6 100644
--- a/infrastructure/docker-compose.deploy.yml
+++ b/infrastructure/docker-compose.deploy.yml
@@ -60,7 +60,7 @@ services:
- overlay_net
filebeat:
- image: docker.elastic.co/beats/filebeat:7.17.0
+ image: docker.elastic.co/beats/filebeat:8.14.3
user: root
networks:
- overlay_net
@@ -85,7 +85,7 @@ services:
- 'traefik.enable=false'
metricbeat:
- image: docker.elastic.co/beats/metricbeat:7.17.13
+ image: docker.elastic.co/beats/metricbeat:8.14.3
user: root
cap_add:
- SYS_PTRACE
@@ -128,7 +128,7 @@ services:
[
'curl',
'-u',
- 'elastic:${ELASTICSEARCH_SUPERUSER_PASSWORD}',
+ 'kibana_system:${KIBANA_SYSTEM_PASSWORD}',
'-X',
'POST',
'http://kibana:5601/api/saved_objects/_import?overwrite=true',
@@ -156,7 +156,7 @@ services:
gelf-address: 'udp://127.0.0.1:12201'
tag: 'setup-kibana-config'
kibana:
- image: docker.elastic.co/kibana/kibana:7.17.0
+ image: docker.elastic.co/kibana/kibana:8.14.3
restart: always
deploy:
labels:
@@ -173,8 +173,8 @@ services:
networks:
- overlay_net
environment:
- - ELASTICSEARCH_USERNAME=elastic
- - ELASTICSEARCH_PASSWORD=${ELASTICSEARCH_SUPERUSER_PASSWORD}
+ - ELASTICSEARCH_USERNAME=kibana_system
+ - ELASTICSEARCH_PASSWORD=${KIBANA_SYSTEM_PASSWORD}
configs:
- source: kibana.{{ts}}
target: /usr/share/kibana/config/kibana.yml
@@ -282,7 +282,6 @@ services:
- path.repo=/data/backups/elasticsearch
- cluster.name=docker-cluster
- network.host=0.0.0.0
- - discovery.zen.minimum_master_nodes=1
- discovery.type=single-node
- xpack.security.enabled=true
- xpack.security.authc.api_key.enabled=true
@@ -365,6 +364,7 @@ services:
- APM_ELASTIC_PASSWORD=${ROTATING_APM_ELASTIC_PASSWORD}
- SEARCH_ELASTIC_USERNAME=search-user
- SEARCH_ELASTIC_PASSWORD=${ROTATING_SEARCH_ELASTIC_PASSWORD}
+ - KIBANA_SYSTEM_PASSWORD=${KIBANA_SYSTEM_PASSWORD}
- KIBANA_USERNAME=${KIBANA_USERNAME}
- KIBANA_PASSWORD=${KIBANA_PASSWORD}
volumes:
@@ -384,7 +384,7 @@ services:
gelf-address: 'udp://127.0.0.1:12201'
tag: 'setup-elasticsearch-users'
elastalert:
- image: jertel/elastalert2:2.3.0
+ image: jertel/elastalert2:2.19.0
restart: unless-stopped
environment:
- ES_USERNAME=elastic
@@ -408,7 +408,7 @@ services:
tag: 'elastalert'
logstash:
- image: logstash:7.17.0
+ image: logstash:8.14.3
command: logstash -f /etc/logstash/logstash.conf --verbose
ports:
- '12201:12201'
@@ -431,7 +431,7 @@ services:
- 'traefik.enable=false'
replicas: 1
apm-server:
- image: docker.elastic.co/apm/apm-server:7.15.2
+ image: docker.elastic.co/apm/apm-server:7.17.22
cap_add: ['CHOWN', 'DAC_OVERRIDE', 'SETGID', 'SETUID']
cap_drop: ['ALL']
restart: always
diff --git a/infrastructure/elasticsearch/roles/search_user.json b/infrastructure/elasticsearch/roles/search_user.json
index b7be198b5..da60cdeb8 100644
--- a/infrastructure/elasticsearch/roles/search_user.json
+++ b/infrastructure/elasticsearch/roles/search_user.json
@@ -1,8 +1,17 @@
{
+ "cluster": ["manage"],
"indices": [
{
- "names": ["ocrvs"],
- "privileges": ["write", "create", "create_index", "delete", "delete_index", "read"]
+ "names": ["ocrvs", "ocrvs-*"],
+ "privileges": [
+ "write",
+ "create",
+ "create_index",
+ "delete",
+ "delete_index",
+ "read",
+ "manage"
+ ]
}
]
}
diff --git a/infrastructure/elasticsearch/setup-elastalert-indices.sh b/infrastructure/elasticsearch/setup-elastalert-indices.sh
new file mode 100755
index 000000000..d36fd8d10
--- /dev/null
+++ b/infrastructure/elasticsearch/setup-elastalert-indices.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# OpenCRVS is also distributed under the terms of the Civil Registration
+# & Healthcare Disclaimer located at http://opencrvs.org/license.
+#
+# Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
+
+# Upgrading from 7 to 8 requires deleting elastalert indices. https://elastalert2.readthedocs.io/en/latest/recipes/faq.html#does-elastalert-2-support-elasticsearch-8
+
+set -e
+
+docker_command="docker run --rm --network=opencrvs_overlay_net curlimages/curl"
+
+echo 'Waiting for availability of Elasticsearch'
+ping_status_code=$($docker_command --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD -o /dev/null -w '%{http_code}' "http://elasticsearch:9200")
+
+if [ "$ping_status_code" -ne 200 ]; then
+ echo "Elasticsearch is not ready. API returned status code: $ping_status_code"
+ exit 1
+fi
+
+
+
+echo 'Scaling down Elastalert'
+
+docker service scale opencrvs_elastalert=0
+
+echo 'Deleting Elastalert indices'
+indices='elastalert_status,elastalert_status_error,elastalert_status_past,elastalert_status_silence,elastalert_status_status'
+
+delete_status_code=$($docker_command --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD -o /dev/null -w '%{http_code}' "http://elasticsearch:9200/${indices}?ignore_unavailable=true" -X DELETE)
+
+if [ "$delete_status_code" -ne 200 ]; then
+ echo "Could not delete indices. API returned status code: $delete_status_code"
+ exit 1
+fi
+
+echo 'Scaling up Elastalert'
+docker service scale opencrvs_elastalert=1
+
diff --git a/infrastructure/elasticsearch/setup-helpers.sh b/infrastructure/elasticsearch/setup-helpers.sh
index c6a25e874..1b3380f0f 100755
--- a/infrastructure/elasticsearch/setup-helpers.sh
+++ b/infrastructure/elasticsearch/setup-helpers.sh
@@ -230,36 +230,3 @@ function ensure_settings {
return $result
}
-
-
-function create_elastic_index {
- local index_name=$1
- local elasticsearch_host="${ELASTICSEARCH_HOST:-elasticsearch}"
-
- local -a args=( '-s' '-D-' '-m15' '-w' '%{http_code}'
- "http://${elasticsearch_host}:9200/${index_name}"
- '-X' 'PUT'
- '-H' 'Content-Type: application/json'
- )
-
- if [[ -n "${ELASTIC_PASSWORD:-}" ]]; then
- args+=( '-u' "elastic:${ELASTIC_PASSWORD}" )
- fi
-
- local -i result=1
- local output
-
- output="$(curl "${args[@]}")"
-
- echo "${output}"
-
- if [[ "${output: -3}" -eq 200 || $output == *"resource_already_exists"* ]]; then
- result=0
- fi
-
- if ((result)); then
- echo -e "\n${output::-3}\n"
- fi
-
- return $result
-}
diff --git a/infrastructure/elasticsearch/setup-settings.sh b/infrastructure/elasticsearch/setup-settings.sh
index eea61f90a..260e13a31 100644
--- a/infrastructure/elasticsearch/setup-settings.sh
+++ b/infrastructure/elasticsearch/setup-settings.sh
@@ -19,8 +19,5 @@ echo "-------- $(date) --------"
log 'Waiting for availability of Elasticsearch'
wait_for_elasticsearch
-log "Creating index for Elasticsearch. Index: ocrvs"
-create_elastic_index "ocrvs"
-
log "Updating replicas for Elasticsearch"
ensure_settings "{\"index\":{\"number_of_replicas\":0}}"
diff --git a/infrastructure/elasticsearch/setup-users.sh b/infrastructure/elasticsearch/setup-users.sh
index 366090da1..30d2f5923 100755
--- a/infrastructure/elasticsearch/setup-users.sh
+++ b/infrastructure/elasticsearch/setup-users.sh
@@ -24,6 +24,7 @@ users_passwords=(
[$SEARCH_ELASTIC_USERNAME]="${SEARCH_ELASTIC_PASSWORD:-}"
[beats_system]="${METRICBEAT_ELASTIC_PASSWORD:-}"
[apm_system]="${APM_ELASTIC_PASSWORD:-}"
+ [kibana_system]="${KIBANA_SYSTEM_PASSWORD:-}"
[$KIBANA_USERNAME]="${KIBANA_PASSWORD:-}"
)
diff --git a/infrastructure/environments/github.ts b/infrastructure/environments/github.ts
index d95184430..6782f0473 100644
--- a/infrastructure/environments/github.ts
+++ b/infrastructure/environments/github.ts
@@ -244,9 +244,11 @@ export async function listEnvironmentSecrets(
{
owner: owner,
repository_id: repositoryId,
- environment_name: environmentName
+ environment_name: environmentName,
+ per_page: 100
}
)
+
return response.data.secrets.map((secret) => ({
...secret,
type: 'SECRET',
@@ -263,7 +265,8 @@ export async function listRepositorySecrets(
'GET /repos/{owner}/{repo}/actions/secrets',
{
owner: owner,
- repo: repositoryName
+ repo: repositoryName,
+ per_page: 100
}
)
return response.data.secrets.map((secret) => ({
@@ -281,9 +284,9 @@ export async function listEnvironmentVariables(
const response = await octokit.request(
'GET /repositories/{repository_id}/environments/{environment_name}/variables',
{
- per_page: 30,
repository_id: repositoryId,
environment_name: environmentName,
+ per_page: 100,
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
diff --git a/infrastructure/environments/setup-environment.ts b/infrastructure/environments/setup-environment.ts
index 83a0642bf..aa5d3dd41 100644
--- a/infrastructure/environments/setup-environment.ts
+++ b/infrastructure/environments/setup-environment.ts
@@ -653,6 +653,13 @@ const derivedVariables = [
type: 'disabled',
scope: 'ENVIRONMENT'
},
+ {
+ name: 'KIBANA_SYSTEM_PASSWORD',
+ valueLabel: 'KIBANA_SYSTEM_PASSWORD',
+ valueType: 'SECRET',
+ type: 'disabled',
+ scope: 'ENVIRONMENT'
+ },
{
name: 'MINIO_ROOT_USER',
valueLabel: 'MINIO_ROOT_USER',
@@ -1103,6 +1110,23 @@ const SPECIAL_NON_APPLICATION_ENVIRONMENTS = ['jump', 'backup']
),
scope: 'ENVIRONMENT' as const
},
+ {
+ name: 'KIBANA_SYSTEM_PASSWORD',
+ type: 'SECRET' as const,
+ didExist: findExistingValue(
+ 'KIBANA_SYSTEM_PASSWORD',
+ 'SECRET',
+ 'ENVIRONMENT',
+ existingValues
+ ),
+ value: findExistingOrDefine(
+ 'KIBANA_SYSTEM_PASSWORD',
+ 'SECRET',
+ 'ENVIRONMENT',
+ generateLongPassword()
+ ),
+ scope: 'ENVIRONMENT' as const
+ },
{
name: 'MINIO_ROOT_USER',
type: 'SECRET' as const,
diff --git a/infrastructure/monitoring/beats/metricbeat.yml b/infrastructure/monitoring/beats/metricbeat.yml
index cb4875457..78bd940a7 100644
--- a/infrastructure/monitoring/beats/metricbeat.yml
+++ b/infrastructure/monitoring/beats/metricbeat.yml
@@ -85,7 +85,7 @@ setup.kibana:
password: ${KIBANA_PASSWORD}
#============================== Xpack Monitoring ===============================
-xpack.monitoring:
+monitoring:
enabled: true
elasticsearch:
username: ${BEATS_USERNAME}
diff --git a/infrastructure/monitoring/filebeat/filebeat.yml b/infrastructure/monitoring/filebeat/filebeat.yml
index d2ac41bcb..8f75ec4b9 100644
--- a/infrastructure/monitoring/filebeat/filebeat.yml
+++ b/infrastructure/monitoring/filebeat/filebeat.yml
@@ -60,7 +60,7 @@ setup.kibana:
password: ${ELASTICSEARCH_PASSWORD}
#============================== Xpack Monitoring ===============================
-xpack.monitoring:
+monitoring:
enabled: true
elasticsearch:
diff --git a/infrastructure/monitoring/kibana/config.ndjson b/infrastructure/monitoring/kibana/config.ndjson
index a8f47219d..d8ff821ed 100644
--- a/infrastructure/monitoring/kibana/config.ndjson
+++ b/infrastructure/monitoring/kibana/config.ndjson
@@ -1,10 +1,10 @@
-{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"metrics.inventory_threshold.fired","params":{"documents":["{\"@timestamp\":\"2023-11-17T13:17:52.791Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"]}}],"alertTypeId":"metrics.alert.inventory.threshold","apiKey":null,"apiKeyOwner":null,"consumer":"alerts","createdAt":"2023-11-17T12:01:46.420Z","createdBy":"elastic","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-02-07T08:28:08.400Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.0"},"muteAll":false,"mutedInstanceIds":[],"name":"Available disk space in data partition","notifyWhen":"onActionGroupChange","params":{"criteria":[{"comparator":"<","customMetric":{"aggregation":"min","field":"system.filesystem.available","id":"alert-custom-metric","type":"custom"},"metric":"custom","threshold":[170000000000],"timeSize":1,"timeUnit":"h","warningComparator":"<","warningThreshold":[220000000000]}],"filterQuery":"{\"bool\":{\"should\":[{\"match_phrase\":{\"system.filesystem.device_name\":\"/dev/vda\"}}],\"minimum_should_match\":1}}","filterQueryText":"system.filesystem.device_name : \"/dev/vda\"","nodeType":"host","sourceId":"default"},"schedule":{"interval":"1h"},"scheduledTaskId":null,"tags":["infra","opencrvs-builtin"],"throttle":null,"updatedAt":"2024-02-07T02:27:29.567Z","updatedBy":"elastic"},"coreMigrationVersion":"7.17.0","id":"14778650-8541-11ee-9002-2f37fdc4e5d5","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1707294424438,232754],"type":"alert","updated_at":"2024-02-07T08:27:04.438Z","version":"WzQ5NTQzMSwxOV0="}
+{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"metrics.inventory_threshold.fired","params":{"documents":["{\"@timestamp\":\"2024-08-06T07:57:35.644Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"]}}],"alertTypeId":"metrics.alert.inventory.threshold","apiKey":null,"apiKeyOwner":null,"consumer":"alerts","createdAt":"2023-11-17T12:01:46.420Z","createdBy":"elastic","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-08-06T08:02:44.568Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.18"},"muteAll":false,"mutedInstanceIds":[],"name":"Available disk space in root file system","notifyWhen":"onActionGroupChange","params":{"alertOnNoData":true,"criteria":[{"comparator":">=","customMetric":{"aggregation":"max","field":"system.filesystem.used.pct","id":"alert-custom-metric","type":"custom"},"metric":"custom","threshold":[0.7],"timeSize":1,"timeUnit":"h","warningComparator":">=","warningThreshold":[0.5]}],"filterQuery":"{\"bool\":{\"should\":[{\"match_phrase\":{\"system.filesystem.mount_point\":\"/hostfs\"}}],\"minimum_should_match\":1}}","filterQueryText":"system.filesystem.mount_point : \"/hostfs\"","nodeType":"host","sourceId":"default"},"schedule":{"interval":"1h"},"scheduledTaskId":null,"tags":["infra","opencrvs-builtin"],"throttle":null,"updatedAt":"2024-08-06T08:01:56.542Z","updatedBy":"elastic"},"coreMigrationVersion":"7.17.18","id":"14778650-8541-11ee-9002-2f37fdc4e5d5","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1722931316554,643],"type":"alert","updated_at":"2024-08-06T08:01:56.554Z","version":"WzM5MywxXQ=="}
{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"threshold_met","params":{"documents":["{\"@timestamp\":\"2022-04-18T07:05:33.819Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"]}}],"alertTypeId":"apm.error_rate","apiKey":null,"apiKeyOwner":null,"consumer":"alerts","createdAt":"2022-06-01T11:30:27.033Z","createdBy":"opencrvs-admin","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-02-07T08:28:08.400Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.0"},"muteAll":false,"mutedInstanceIds":[],"name":"Error in service","notifyWhen":"onActionGroupChange","params":{"environment":"ENVIRONMENT_ALL","threshold":1,"windowSize":1,"windowUnit":"m"},"schedule":{"interval":"1m"},"scheduledTaskId":null,"tags":[],"throttle":null,"updatedAt":"2024-02-05T03:00:20.633Z","updatedBy":"opencrvs-admin"},"coreMigrationVersion":"7.17.0","id":"3b6722e0-e19e-11ec-ba8e-51649755648d","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1707273006619,214975],"type":"alert","updated_at":"2024-02-07T02:30:06.619Z","version":"WzQ5MjAzNCwxOV0="}
{"attributes":{"buildNum":46534,"defaultIndex":"metricbeat-*"},"coreMigrationVersion":"7.17.0","id":"7.17.0","migrationVersion":{"config":"7.13.0"},"references":[],"sort":[1707273006619,216009],"type":"config","updated_at":"2024-02-07T02:30:06.619Z","version":"WzQ5MjQyOCwxOV0="}
{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"logs.threshold.fired","params":{"documents":["{\"@timestamp\":\"2023-11-22T08:25:47.329Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"]}}],"alertTypeId":"logs.alert.document.count","apiKey":null,"apiKeyOwner":null,"consumer":"alerts","createdAt":"2023-11-22T08:32:38.272Z","createdBy":"elastic","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-02-07T08:28:08.400Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.0"},"muteAll":false,"mutedInstanceIds":[],"name":"Error in backup logs","notifyWhen":"onActionGroupChange","params":{"count":{"comparator":"more than or equals","value":1},"criteria":[{"comparator":"matches","field":"message","value":"error"},{"comparator":"equals","field":"log.file.path","value":"/var/log/opencrvs-backup.log"}],"timeSize":1,"timeUnit":"h"},"schedule":{"interval":"1h"},"scheduledTaskId":null,"tags":[],"throttle":null,"updatedAt":"2024-02-07T02:27:22.558Z","updatedBy":"elastic"},"coreMigrationVersion":"7.17.0","id":"b166fcb0-8911-11ee-8111-2f3be9e93efc","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1707294436464,232766],"type":"alert","updated_at":"2024-02-07T08:27:16.464Z","version":"WzQ5NTQzNCwxOV0="}
{"attributes":{"anomalyThreshold":50,"description":"","fields":{"container":"container.id","host":"host.name","message":["message","@message"],"pod":"kubernetes.pod.uid","tiebreaker":"_doc","timestamp":"@timestamp"},"inventoryDefaultView":"0","logColumns":[{"timestampColumn":{"id":"5e7f964a-be8a-40d8-88d2-fbcfbdca0e2f"}},{"fieldColumn":{"field":"event.dataset","id":" eb9777a8-fcd3-420e-ba7d-172fff6da7a2"}},{"messageColumn":{"id":"b645d6da-824b-4723-9a2a-e8cece1645c0"}}],"logIndices":{"indexName":"logs-*,filebeat-*,kibana_sample_data_logs*,logstash*","type":"index_name"},"metricAlias":"metrics-*,metricbeat-*","metricsExplorerDefaultView":"0","name":"Default"},"coreMigrationVersion":"7.17.0","id":"default","migrationVersion":{"infrastructure-ui-source":"7.16.2"},"references":[],"sort":[1707273006619,217714],"type":"infrastructure-ui-source","updated_at":"2024-02-07T02:30:06.619Z","version":"WzQ5MzAyNywxOV0="}
{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"query matched","params":{"documents":["{\"@timestamp\":\"2023-11-20T10:19:30.521Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"]}}],"alertTypeId":".es-query","apiKey":null,"apiKeyOwner":null,"consumer":"alerts","createdAt":"2023-11-20T09:12:19.237Z","createdBy":"elastic","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-02-07T08:28:08.400Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.0"},"muteAll":false,"mutedInstanceIds":[],"name":"Successful SSH login","notifyWhen":"onActionGroupChange","params":{"esQuery":"{ \"query\": { \"bool\": { \"must\": [ \n { \"term\": { \"log.file.path\": \"/var/log/auth.log\" } },\n { \"term\": { \"event.outcome\": \"success\" }}\n ] } } }","index":["filebeat-*"],"size":100,"threshold":[1],"thresholdComparator":">=","timeField":"@timestamp","timeWindowSize":1,"timeWindowUnit":"m"},"schedule":{"interval":"1m"},"scheduledTaskId":null,"tags":[],"throttle":null,"updatedAt":"2024-02-07T02:27:19.537Z","updatedBy":"elastic"},"coreMigrationVersion":"7.17.0","id":"e79aaa90-8784-11ee-b9ba-89bbe73df7ff","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1707294457367,232778],"type":"alert","updated_at":"2024-02-07T08:27:37.367Z","version":"WzQ5NTQ0MCwxOV0="}
{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"metrics.inventory_threshold.fired","params":{"documents":["{\"@timestamp\":\"2022-06-20T06:16:33.414Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"]}}],"alertTypeId":"metrics.alert.inventory.threshold","apiKey":null,"apiKeyOwner":null,"consumer":"alerts","createdAt":"2022-05-31T10:10:47.084Z","createdBy":"opencrvs-admin","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-02-07T08:28:08.400Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.0"},"muteAll":false,"mutedInstanceIds":[],"name":"CPU under heavy load","notifyWhen":"onActionGroupChange","params":{"criteria":[{"comparator":">","customMetric":{"aggregation":"avg","field":"","id":"alert-custom-metric","type":"custom"},"metric":"cpu","threshold":[70],"timeSize":1,"timeUnit":"m"}],"nodeType":"host","sourceId":"default"},"schedule":{"interval":"1m"},"scheduledTaskId":null,"tags":["infra","opencrvs-builtin"],"throttle":null,"updatedAt":"2024-02-07T02:27:30.573Z","updatedBy":"elastic"},"coreMigrationVersion":"7.17.0","id":"f022bee0-e0c9-11ec-99b8-dbfd54551fda","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1707294457362,232774],"type":"alert","updated_at":"2024-02-07T08:27:37.362Z","version":"WzQ5NTQzOCwxOV0="}
-{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"metrics.inventory_threshold.fired","params":{"documents":["{\"@timestamp\":\"2023-11-17T13:17:52.791Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"]}}],"alertTypeId":"metrics.alert.inventory.threshold","apiKey":null,"apiKeyOwner":null,"consumer":"infrastructure","createdAt":"2022-05-31T10:10:47.080Z","createdBy":"opencrvs-admin","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-02-07T08:28:08.400Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.0"},"muteAll":false,"mutedInstanceIds":[],"name":"Low on available disk space","notifyWhen":"onActionGroupChange","params":{"alertOnNoData":true,"criteria":[{"comparator":">","customMetric":{"aggregation":"max","field":"system.filesystem.used.pct","id":"alert-custom-metric","label":"","type":"custom"},"metric":"custom","threshold":[0.7],"timeSize":1,"timeUnit":"h","warningComparator":">","warningThreshold":[0.5]}],"filterQuery":"{\"bool\":{\"should\":[{\"match_phrase\":{\"system.filesystem.device_name\":\"/dev/mapper/cryptfs\"}}],\"minimum_should_match\":1}}","filterQueryText":"system.filesystem.device_name : \"/dev/mapper/cryptfs\"","nodeType":"host","sourceId":"default"},"schedule":{"interval":"1h"},"scheduledTaskId":null,"tags":["infra","opencrvs-builtin"],"throttle":null,"updatedAt":"2024-02-07T02:27:20.542Z","updatedBy":"elastic"},"coreMigrationVersion":"7.17.0","id":"f023d050-e0c9-11ec-99b8-dbfd54551fda","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1707294448366,232768],"type":"alert","updated_at":"2024-02-07T08:27:28.366Z","version":"WzQ5NTQzNSwxOV0="}
+{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"metrics.inventory_threshold.fired","params":{"documents":["{\"@timestamp\":\"2023-11-17T13:17:52.791Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"]}}],"alertTypeId":"metrics.alert.inventory.threshold","apiKey":null,"apiKeyOwner":null,"consumer":"infrastructure","createdAt":"2022-05-31T10:10:47.080Z","createdBy":"opencrvs-admin","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-02-07T08:28:08.400Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.0"},"muteAll":false,"mutedInstanceIds":[],"name":"Low on available disk space in data partition","notifyWhen":"onActionGroupChange","params":{"alertOnNoData":true,"criteria":[{"comparator":">=","customMetric":{"aggregation":"max","field":"system.filesystem.used.pct","id":"alert-custom-metric","label":"","type":"custom"},"metric":"custom","threshold":[0.7],"timeSize":1,"timeUnit":"h","warningComparator":">=","warningThreshold":[0.5]}],"filterQuery":"{\"bool\":{\"should\":[{\"match_phrase\":{\"system.filesystem.mount_point\":\"/hostfs/data\"}}],\"minimum_should_match\":1}}","filterQueryText":"system.filesystem.mount_point : \"/hostfs/data\"","nodeType":"host","sourceId":"default"},"schedule":{"interval":"1h"},"scheduledTaskId":null,"tags":["infra","opencrvs-builtin"],"throttle":null,"updatedAt":"2024-02-07T02:27:20.542Z","updatedBy":"elastic"},"coreMigrationVersion":"7.17.0","id":"f023d050-e0c9-11ec-99b8-dbfd54551fda","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1707294448366,232768],"type":"alert","updated_at":"2024-02-07T08:27:28.366Z","version":"WzQ5NTQzNSwxOV0="}
{"attributes":{"actions":[{"actionRef":"preconfigured:preconfigured-alert-history-es-index","actionTypeId":".index","group":"threshold_met","params":{"documents":["{\"@timestamp\":\"2023-06-15T07:57:35.954Z\",\"tags\":\"{{rule.tags}}\",\"rule\":{\"id\":\"{{rule.id}}\",\"name\":\"{{rule.name}}\",\"params\":{\"{{rule__type}}\":\"{{params}}\"},\"space\":\"{{rule.spaceId}}\",\"type\":\"{{rule.type}}\"},\"kibana\":{\"alert\":{\"id\":\"{{alert.id}}\",\"context\":{\"{{rule__type}}\":\"{{context}}\"},\"actionGroup\":\"{{alert.actionGroup}}\",\"actionGroupName\":\"{{alert.actionGroupName}}\"}},\"event\":{\"kind\":\"alert\"}}"],"indexOverride":"kibana-alert-history-services"}}],"alertTypeId":"apm.error_rate","apiKey":null,"apiKeyOwner":null,"consumer":"alerts","createdAt":"2022-05-31T10:10:47.069Z","createdBy":"opencrvs-admin","enabled":false,"executionStatus":{"error":null,"lastExecutionDate":"2024-02-07T08:28:08.400Z","status":"pending"},"legacyId":null,"meta":{"versionApiKeyLastmodified":"7.17.0"},"muteAll":false,"mutedInstanceIds":[],"name":"Error in service","notifyWhen":"onActionGroupChange","params":{"environment":"ENVIRONMENT_ALL","threshold":1,"windowSize":1,"windowUnit":"m"},"schedule":{"interval":"1m"},"scheduledTaskId":null,"tags":[],"throttle":null,"updatedAt":"2024-02-07T02:27:21.551Z","updatedBy":"elastic"},"coreMigrationVersion":"7.17.0","id":"f02b4a60-e0c9-11ec-99b8-dbfd54551fda","migrationVersion":{"alert":"7.16.0"},"references":[],"sort":[1707294457374,232780],"type":"alert","updated_at":"2024-02-07T08:27:37.374Z","version":"WzQ5NTQ0MSwxOV0="}
{"excludedObjects":[],"excludedObjectsCount":0,"exportedCount":9,"missingRefCount":0,"missingReferences":[]}
\ No newline at end of file
diff --git a/infrastructure/monitoring/kibana/kibana.yml b/infrastructure/monitoring/kibana/kibana.yml
index 90404ecab..a97e87780 100644
--- a/infrastructure/monitoring/kibana/kibana.yml
+++ b/infrastructure/monitoring/kibana/kibana.yml
@@ -53,7 +53,6 @@ monitoring.ui.container.elasticsearch.enabled: true
xpack.encryptedSavedObjects.encryptionKey: '{{KIBANA_ENCRYPTION_KEY}}'
xpack.reporting.encryptionKey: '{{KIBANA_ENCRYPTION_KEY}}'
xpack.actions.preconfiguredAlertHistoryEsIndex: true
-xpack.infra.sources.default.logAlias: 'logs-*,filebeat-*,kibana_sample_data_logs*,logstash*'
# If your Elasticsearch is protected with basic authentication, these settings provide
# the username and password that the Kibana server uses to perform maintenance on the Kibana
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
diff --git a/infrastructure/monitoring/kibana/setup-config.sh b/infrastructure/monitoring/kibana/setup-config.sh
index a2f5cca78..68ea00223 100755
--- a/infrastructure/monitoring/kibana/setup-config.sh
+++ b/infrastructure/monitoring/kibana/setup-config.sh
@@ -9,29 +9,90 @@
#!/bin/bash
set -e
+set -o pipefail
# Define common variables
kibana_alerting_api_url="http://kibana:5601/api/alerting/rules/_find?page=1&per_page=100&default_search_operator=AND&sort_field=name&sort_order=asc"
-docker_command="docker run --rm -v /opt/opencrvs/infrastructure/monitoring/kibana/config.ndjson:/config.ndjson --network=opencrvs_overlay_net curlimages/curl"
+
+docker pull ghcr.io/jqlang/jq
+docker pull curlimages/curl
+
+http_status_from_curl_output() {
+ echo "$1" | tail -n1
+}
+
+response_text_from_curl_output() {
+ echo "$1" | head -n-1
+}
+
+curl_raw() {
+ docker run --rm -v /opt/opencrvs/infrastructure/monitoring/kibana/config.ndjson:/config.ndjson --network=opencrvs_overlay_net curlimages/curl -s -w "\n%{http_code}" "$@"
+}
+
+parse_url_from_string() {
+ local input_string="$1"
+
+ local url
+ url=$(echo "$input_string" | grep -oP '(http|https)://[^\s]+')
+
+ echo "$url"
+}
+
+parse_method_from_string() {
+ local input_string="$1"
+
+ local method
+ method=$(echo "$input_string" | grep -oP '(?<=-X\s)[A-Z]+' || echo "GET")
+
+ echo "$method"
+}
+
+
+curl() {
+ result=$(curl_raw "$@")
+ params="$@"
+ method=$(parse_method_from_string "$params")
+ request_url=$(parse_url_from_string "$params")
+
+ http_status=$(http_status_from_curl_output "$result")
+ response=$(response_text_from_curl_output "$result")
+
+ if [ "$http_status" -ge 200 ] && [ "$http_status" -lt 300 ]; then
+ if [ -z "$response" ]; then
+ echo "$method $request_url – $http_status"
+ else
+ echo $response
+ fi
+ else
+ echo "$method $request_url – $http_status" >&2
+ echo "Error: HTTP request failed with status code $http_status" >&2
+ exit 1
+ fi
+}
+
+jq() {
+ docker run --rm -i --network=opencrvs_overlay_net ghcr.io/jqlang/jq "$@"
+}
# Initial API status check to ensure Kibana is ready
-status_code=$($docker_command --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD -o /dev/null -w '%{http_code}' "$kibana_alerting_api_url")
+response=$(curl_raw --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD -o /dev/null -w '%{http_code}' "$kibana_alerting_api_url")
+status_code=$(http_status_from_curl_output $response)
if [ "$status_code" -ne 200 ]; then
- echo "Kibana is not ready. API returned status code: $status_code"
+ echo "Kibana is not ready yet! HTTP status $status_code"
exit 1
fi
# Delete all alerts
-$docker_command --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "$kibana_alerting_api_url" | docker run --rm -i --network=opencrvs_overlay_net ghcr.io/jqlang/jq -r '.data[].id' | while read -r id; do
- $docker_command --connect-timeout 60 -X DELETE -H 'kbn-xsrf: true' -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "http://kibana:5601/api/alerting/rule/$id"
+curl --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "$kibana_alerting_api_url" | jq -r '.data[].id' | while read -r id; do
+ curl --connect-timeout 60 -X DELETE -H 'kbn-xsrf: true' -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "http://kibana:5601/api/alerting/rule/$id"
done
# Import configuration
-$docker_command --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD -X POST "http://kibana:5601/api/saved_objects/_import?overwrite=true" -H 'kbn-xsrf: true' --form file=@/config.ndjson > /dev/null
+curl --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD -X POST "http://kibana:5601/api/saved_objects/_import?overwrite=true" -H 'kbn-xsrf: true' --form file=@/config.ndjson > /dev/null
# Re-enable all alerts
-$docker_command --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "$kibana_alerting_api_url" | docker run --rm -i --network=opencrvs_overlay_net ghcr.io/jqlang/jq -r '.data[].id' | while read -r id; do
- $docker_command --connect-timeout 60 -X POST -H 'kbn-xsrf: true' -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "http://kibana:5601/api/alerting/rule/$id/_disable"
- $docker_command --connect-timeout 60 -X POST -H 'kbn-xsrf: true' -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "http://kibana:5601/api/alerting/rule/$id/_enable"
-done
+curl --connect-timeout 60 -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "$kibana_alerting_api_url" | jq -r '.data[].id' | while read -r id; do
+ curl --connect-timeout 60 -X POST -H 'kbn-xsrf: true' -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "http://kibana:5601/api/alerting/rule/$id/_disable"
+ curl --connect-timeout 60 -X POST -H 'kbn-xsrf: true' -u elastic:$ELASTICSEARCH_SUPERUSER_PASSWORD "http://kibana:5601/api/alerting/rule/$id/_enable"
+done
\ No newline at end of file
diff --git a/infrastructure/run-migrations.sh b/infrastructure/run-migrations.sh
index d68ee546b..fbe00d8b0 100755
--- a/infrastructure/run-migrations.sh
+++ b/infrastructure/run-migrations.sh
@@ -25,13 +25,5 @@ elasticsearch_host() {
fi
}
-create_elastic_index () {
- local index_name=$1
- echo "Creating ElasticSearch Index: ${index_name}"
- docker run --rm --network=opencrvs_overlay_net appropriate/curl curl -XPUT "http://$(elasticsearch_host)/$index_name" -v
-}
-
-create_elastic_index "ocrvs"
-
# run migration by restarting migration service
docker service update --force --update-parallelism 1 --update-delay 30s opencrvs_migration
diff --git a/infrastructure/server-setup/inventory/qa.yml b/infrastructure/server-setup/inventory/qa.yml
index 840662637..d1247ebc0 100644
--- a/infrastructure/server-setup/inventory/qa.yml
+++ b/infrastructure/server-setup/inventory/qa.yml
@@ -21,6 +21,8 @@ docker-manager-first:
hosts:
qa: # @todo set this to be the hostname of your target server
ansible_host: '55.55.55.55' # @todo set this to be the IP address of your server
+ # ansible_port: '23' # @todo set this to be the SSH port if it's not 22
+ # internal_ssh_port: '22' # @todo if you are port-forwarding and server SSH port is not the same as ansible_port, set it here
data_label: data1 # for manager machines, this should always be "data1"
# QA and staging servers are not configured to use workers.
diff --git a/infrastructure/server-setup/tasks/ufw.yml b/infrastructure/server-setup/tasks/ufw.yml
index 2d67cc6d6..915f787e5 100644
--- a/infrastructure/server-setup/tasks/ufw.yml
+++ b/infrastructure/server-setup/tasks/ufw.yml
@@ -3,19 +3,19 @@
name: ufw
state: present
+- name: Set default SSH port
+ set_fact:
+ ssh_port: '{{ internal_ssh_port | default(ansible_port) | default(22) }}'
+
- name: Allow OpenSSH for IPv4 from specific addresses
ufw:
rule: allow
- port: 22
+ port: '{{ ssh_port }}'
proto: tcp
src: '{{ item }}'
loop: '{{ only_allow_access_from_addresses }}'
when: only_allow_access_from_addresses is defined and only_allow_access_from_addresses | length > 0
-- name: Set default SSH port
- set_fact:
- ssh_port: '{{ ansible_port | default(22) }}'
-
- name: Remove general OpenSSH allow rule
ufw:
rule: allow
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 000000000..0c150f3b2
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,25 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": ["config:recommended", "monorepo:lerna", ":semanticCommits"],
+ "lockFileMaintenance": {
+ "enabled": true
+ },
+ "pruneStaleBranches": false,
+ "timezone": "Europe/London",
+ "schedule": [
+ "after 5pm every weekday",
+ "before 3am every weekday",
+ "every weekend"
+ ],
+ "vulnerabilityAlerts": {
+ "enabled": true,
+ "labels": ["Security"]
+ },
+ "osvVulnerabilityAlerts": true,
+ "packageRules": [
+ {
+ "updateTypes": ["patch"],
+ "enabled": false
+ }
+ ]
+}
diff --git a/src/api/application/application-config-default.ts b/src/api/application/application-config.ts
similarity index 83%
rename from src/api/application/application-config-default.ts
rename to src/api/application/application-config.ts
index 9b2db665a..d5f38db73 100644
--- a/src/api/application/application-config-default.ts
+++ b/src/api/application/application-config.ts
@@ -1,6 +1,6 @@
import { countryLogo } from '@countryconfig/api/application/country-logo'
-export const defaultApplicationConfig = {
+export const applicationConfig = {
APPLICATION_NAME: 'Farajaland CRS',
BIRTH: {
REGISTRATION_TARGET: 30,
@@ -38,7 +38,6 @@ export const defaultApplicationConfig = {
},
PRINT_IN_ADVANCE: true
},
- // Following constants aren't configurable via UI
FIELD_AGENT_AUDIT_LOCATIONS: 'DISTRICT',
DECLARATION_AUDIT_LOCATIONS: 'DISTRICT',
FEATURES: {
@@ -52,7 +51,17 @@ export const defaultApplicationConfig = {
},
USER_NOTIFICATION_DELIVERY_METHOD: 'email', // or 'sms', or '' ... You can use 'sms' for WhatsApp
INFORMANT_NOTIFICATION_DELIVERY_METHOD: 'email', // or 'sms', or '' ... You can use 'sms' for WhatsApp
- SIGNATURE_REQUIRED_FOR_ROLES: ['LOCAL_REGISTRAR', 'NATIONAL_REGISTRAR']
+ SIGNATURE_REQUIRED_FOR_ROLES: ['LOCAL_REGISTRAR', 'NATIONAL_REGISTRAR'],
+ SEARCH_DEFAULT_CRITERIA: 'TRACKING_ID'
+ /*
+ * SEARCH_DEFAULT_CRITERIA's value can be one of the following
+ * | 'TRACKING_ID',
+ * | 'REGISTRATION_NUMBER',
+ * | 'NATIONAL_ID',
+ * | 'NAME',
+ * | 'PHONE_NUMBER',
+ * | 'EMAIL'
+ */
}
export const COUNTRY_WIDE_CRUDE_DEATH_RATE = 10
diff --git a/src/api/application/handler.ts b/src/api/application/handler.ts
index 68e655f47..a7b028d30 100644
--- a/src/api/application/handler.ts
+++ b/src/api/application/handler.ts
@@ -10,7 +10,7 @@
*/
import { Request, ResponseToolkit } from '@hapi/hapi'
-import { defaultApplicationConfig as applicationConfig } from './application-config-default'
+import { applicationConfig } from './application-config'
export async function applicationConfigHandler(_: Request, h: ResponseToolkit) {
const res = JSON.stringify(applicationConfig)
diff --git a/src/client-static/images/icons/icon-128x128.png b/src/client-static/images/icons/icon-128x128.png
new file mode 100644
index 000000000..fbf19dc54
Binary files /dev/null and b/src/client-static/images/icons/icon-128x128.png differ
diff --git a/src/client-static/images/icons/icon-144x144.png b/src/client-static/images/icons/icon-144x144.png
new file mode 100644
index 000000000..bc3d73139
Binary files /dev/null and b/src/client-static/images/icons/icon-144x144.png differ
diff --git a/src/client-static/images/icons/icon-152x152.png b/src/client-static/images/icons/icon-152x152.png
new file mode 100644
index 000000000..4f27e38bd
Binary files /dev/null and b/src/client-static/images/icons/icon-152x152.png differ
diff --git a/src/client-static/images/icons/icon-196x196.png b/src/client-static/images/icons/icon-196x196.png
new file mode 100644
index 000000000..a50401d70
Binary files /dev/null and b/src/client-static/images/icons/icon-196x196.png differ
diff --git a/src/client-static/images/icons/icon-256x256.png b/src/client-static/images/icons/icon-256x256.png
new file mode 100644
index 000000000..6282479ad
Binary files /dev/null and b/src/client-static/images/icons/icon-256x256.png differ
diff --git a/src/client-static/images/icons/icon-512x512.png b/src/client-static/images/icons/icon-512x512.png
new file mode 100644
index 000000000..4625da3fc
Binary files /dev/null and b/src/client-static/images/icons/icon-512x512.png differ
diff --git a/src/client-static/images/icons/icon-72x72.png b/src/client-static/images/icons/icon-72x72.png
new file mode 100644
index 000000000..4881f71e0
Binary files /dev/null and b/src/client-static/images/icons/icon-72x72.png differ
diff --git a/src/client-static/images/logo-90x90.svg b/src/client-static/images/logo-90x90.svg
new file mode 100644
index 000000000..7e24a831b
--- /dev/null
+++ b/src/client-static/images/logo-90x90.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/src/client-static/manifest.json b/src/client-static/manifest.json
new file mode 100644
index 000000000..195d48c73
--- /dev/null
+++ b/src/client-static/manifest.json
@@ -0,0 +1,47 @@
+{
+ "name": "OpenCRVS",
+ "short_name": "OpenCRVS",
+ "theme_color": "#4c68c1",
+ "background_color": "#4c68c1",
+ "display": "standalone",
+ "scope": "/",
+ "start_url": "/",
+ "icons": [
+ {
+ "src": "images/icons/icon-72x72.png",
+ "sizes": "72x72",
+ "type": "image/png"
+ },
+ {
+ "src": "images/icons/icon-128x128.png",
+ "sizes": "128x128",
+ "type": "image/png"
+ },
+ {
+ "src": "images/icons/icon-144x144.png",
+ "sizes": "144x144",
+ "type": "image/png"
+ },
+ {
+ "src": "images/icons/icon-152x152.png",
+ "sizes": "152x152",
+ "type": "image/png"
+ },
+ {
+ "src": "images/icons/icon-196x196.png",
+ "sizes": "196x196",
+ "type": "image/png"
+ },
+ {
+ "src": "images/icons/icon-256x256.png",
+ "sizes": "256x256",
+ "type": "image/png"
+ },
+ {
+ "src": "images/icons/icon-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ }
+ ],
+ "permissions": ["unlimitedStorage"]
+}
diff --git a/src/data-seeding/certificates/source/Farajaland-birth-certificate-v2.svg b/src/data-seeding/certificates/source/Farajaland-birth-certificate-v2.svg
index 6d66223f4..7aa67b024 100644
--- a/src/data-seeding/certificates/source/Farajaland-birth-certificate-v2.svg
+++ b/src/data-seeding/certificates/source/Farajaland-birth-certificate-v2.svg
@@ -47,7 +47,6 @@
REPUBLIC OF FARAJALAND / REPUBLIQUE DE FARAJALANDCERTIFICATE OF BIRTH / ACTE DE NAISSANCE
-1.Child’s full name / Nom complet de l'enfant
@@ -129,9 +128,6 @@
-
-
-
diff --git a/src/data-seeding/certificates/source/Farajaland-death-certificate-v2.svg b/src/data-seeding/certificates/source/Farajaland-death-certificate-v2.svg
index 5ed6a20cd..994b425a3 100644
--- a/src/data-seeding/certificates/source/Farajaland-death-certificate-v2.svg
+++ b/src/data-seeding/certificates/source/Farajaland-death-certificate-v2.svg
@@ -14,7 +14,6 @@
Registrar / L'Officier de l'État Civil{{registrar.name}}I certify that this certificate is a true copy of the civil registry and is issued by the mandated authority in pursuance of civil registration law / Je certifie que le présent certificat est une copie conforme du registre d'état civil et qu'il est délivré par l'autorité mandatée conformément à la loi sur l'état civil.
-1.Deceased full name / Nom complet du défunt
@@ -114,9 +113,6 @@
REPUBLIC OF FARAJALAND / REPUBLIQUE DE FARAJALANDCERTIFICATE OF DEATH / ACTE DE DEATH
-
-
-
diff --git a/src/data-seeding/certificates/source/Farajaland-marriage-certificate-v2.svg b/src/data-seeding/certificates/source/Farajaland-marriage-certificate-v2.svg
index 3c0dca946..e84fb604d 100644
--- a/src/data-seeding/certificates/source/Farajaland-marriage-certificate-v2.svg
+++ b/src/data-seeding/certificates/source/Farajaland-marriage-certificate-v2.svg
@@ -36,7 +36,6 @@
REPUBLIC OF FARAJALAND / REPUBLIQUE DE FARAJALANDCERTIFICATE OF MARRIAGE / ACTE DE MARRIAGE
-1.Groom’s full name / Nom complet du marié
@@ -115,9 +114,6 @@
-
-
-
@@ -167,6 +163,5 @@
{{#ifCond printInAdvance '!==' true}}{{/ifCond}}
-
diff --git a/src/form/types/types.ts b/src/form/types/types.ts
index 28a95b547..70e12b025 100644
--- a/src/form/types/types.ts
+++ b/src/form/types/types.ts
@@ -159,10 +159,6 @@ export enum IntegratingSystemType {
Other = 'OTHER'
}
-export declare enum THEME_MODE {
- DARK = 'dark'
-}
-
export interface IPreviewGroup {
id: string
label: MessageDescriptor
@@ -569,7 +565,6 @@ export interface IFormFieldBase {
mapping?: IFormFieldMapping
hideAsterisk?: boolean
hideHeader?: boolean
- mode?: THEME_MODE
hidden?: boolean
previewGroup?: string
nestedFields?: { [key: string]: IFormField[] }
@@ -593,7 +588,6 @@ export interface IFormFieldBase {
ignoreFieldLabelOnErrorMessage?: boolean
ignoreBottomMargin?: boolean
customQuestionMappingId?: string
- ignoreMediaQuery?: boolean
}
export interface Conditional {
diff --git a/src/index.ts b/src/index.ts
index c7ea2459b..029ee5ecf 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -12,6 +12,7 @@ require('app-module-path').addPath(require('path').join(__dirname))
require('dotenv').config()
import fetch from 'node-fetch'
+import path from 'path'
import * as Hapi from '@hapi/hapi'
import * as Pino from 'hapi-pino'
import * as JWT from 'hapi-auth-jwt2'
@@ -54,7 +55,7 @@ import { usersHandler } from './data-seeding/employees/handler'
import { applicationConfigHandler } from './api/application/handler'
import { validatorsHandler } from './form/common/custom-validation-conditionals/validators-handler'
import { conditionalsHandler } from './form/common/custom-validation-conditionals/conditionals-handler'
-import { COUNTRY_WIDE_CRUDE_DEATH_RATE } from './api/application/application-config-default'
+import { COUNTRY_WIDE_CRUDE_DEATH_RATE } from './api/application/application-config'
import { handlebarsHandler } from './form/common/certificate/handlebars/handler'
import { trackingIDHandler } from './api/tracking-id/handler'
import { dashboardQueriesHandler } from './api/dashboards/handler'
@@ -529,6 +530,23 @@ export async function createServer() {
}
})
+ server.route({
+ method: 'GET',
+ path: '/static/{param*}',
+ handler: {
+ directory: {
+ path: path.join(__dirname, 'client-static'),
+ redirectToSlash: true,
+ index: false
+ }
+ },
+ options: {
+ auth: false,
+ tags: ['api', 'static'],
+ description: 'Server static files for client'
+ }
+ })
+
server.ext({
type: 'onRequest',
method(request: Hapi.Request & { sentryScope?: any }, h) {
diff --git a/src/translations/client.csv b/src/translations/client.csv
index 525186ad2..9d8bc5b1e 100644
--- a/src/translations/client.csv
+++ b/src/translations/client.csv
@@ -18,8 +18,11 @@ advancedSearch.form.recordStatusInReview,Option for form field: status of record
advancedSearch.form.recordStatusInprogress,Option for form field: status of record,In progress,En cours
advancedSearch.form.recordStatusRegistered,Option for form field: status of record,Registered,Inscrit
advancedSearch.form.recordStatusRequireUpdate,Option for form field: status of record,Requires updates,Nécessite des mises à jour
+advancedSearch.form.recordStatusValidated,Option for form field: status of record,Validated,Validé
advancedSearch.form.registrationDetails,The title of Registration details accordion,Registration details,Détails d'inscription
advancedSearch.form.statusOfRecordLabel,Label for input Status of record,Status of record,Etat d'avancement du dossier
+advancedSearch.form.timePeriodHelperText,Helper text for input Time period,Period of time since the record status changed,Période écoulée depuis le changement de statut de l'enregistrement
+advancedSearch.form.timePeriodLabel,Label for input Time period,Time period,Période de temps
advancedSearchResult.pill.childDoB,The label for child d.o.b in active advancedSearchParams,Child d.o.b,Date de naissance enfant
advancedSearchResult.pill.childFirstName,The label for child firstname in active advancedSearchParams,Child firstname,Prénom de l'enfant
advancedSearchResult.pill.childLastName,The label for child lastname in active advancedSearchParams,Child lastname,Nom de l'enfant
@@ -43,6 +46,7 @@ advancedSearchResult.pill.regDate,The label for registration date in active adv
advancedSearchResult.pill.regLocation,The label for event location in active advancedSearchParams,Location,Emplacement
advancedSearchResult.pill.regNumber,The label for registration number in active advancedSearchParams,Registration number,Numéro d'enregistrement
advancedSearchResult.pill.registationStatus,The label for registration Status param in active advancedSearchParams,Registration status,Statut d'enregistrement
+advancedSearchResult.pill.timePeriod,The label for time period in active advancedSearchParams,Time period,Période de temps
advancedSearchResult.pill.trackingId,The label for tracking id in active advancedSearchParams,Tracking ID,Identifiant de suivi
advancedSearchResult.table.noResult,The label for no result in advancedSearchResult page,No result,Pas de résultat
advancedSearchResult.table.searchResult,The label for search result header in advancedSearchResult page,Search results,Résultat de la recherche
@@ -156,134 +160,23 @@ changeEmail.validation.msg,Phone number validation message,Must be a valid email
changePhone.validation.msg,Phone number validation message,Must be a valid 10 digit number that starts with 0,Doit être un numéro valide à {num} chiffres qui commence par {start}.
config.advanced.search,This is used for the advanced search,Advanced Search,Recherche avancée
config.advanced.search.instruction,This is used for the advanced search,Select the options to build an advanced search. A minimum of two search parameters is required.,Sélectionnez les options pour construire une recherche avancée. Un minimum de deux paramètres de recherche est requis.
-config.application.applicationNameChangeNotification,Message for application name change notification,Name of application updated,Nom de l'application mise à jour
-config.application.applicationNameLabel,Application name config label,Name of application,Nom de l'application
-config.application.backgroundImageChangeNotification,Message for background image change notification,Background image updated,Mise à jour de l'image de fond
-config.application.backgroundImageError,Error message for background image change,Unable to change image. Please try again.,Impossible de modifier l'image. Veuillez réessayer.
-config.application.backgroundImageFileLimitError,Error message for large Background file,Background image file must be less than 2mb,Le fichier de l'image d'arrière-plan doit être inférieur à 2 Mo
-config.application.birthDelayedDialogTitle,Delayed dialog title for brith,Delayed registration time period for birth registration,Délai d'enregistrement retardé pour l'enregistrement des naissances
-config.application.birthDelayedFeeChangeNotification,Message for application birth delayed fee change notification,Birth delayed fee updated,Mise à jour de la pénalité de déclaration tardive des naissances
-config.application.birthLateFeeChangeNotification,Message for application birth late fee change notification,Birth late fee updated,Mise à jour de la pénalité de déclaration tardive des naissances
-config.application.birthLateRegTargetChangeNotification,Message for application birth late registration target change notification,Birth late registration target days updated,Mise à jour des jours cibles d'enregistrement tardif des naissances
-config.application.birthLegallySpecifiedDialogTitle,Legally specified dialog title for brith,Legally specified time period for birth registration,Délai légal pour déclaration des naissances
-config.application.birthOnTimeFeeChangeNotification,Message for application birth on time fee change notification,Birth on time fee updated,Mise à jour des frais de naissance à temps
-config.application.birthRegTargetChangeNotification,Message for application birth registration target change notification,Birth registration target days updated,Mise à jour des jours cibles pour l'enregistrement des naissances
config.application.birthTabTitle,The title for birth tab,Birth,Naissance
config.application.birthTabTitleExport,The title for birth tab for VSExport,Births,Naissances
-config.application.colourTabText,The title for colour tab text,Hex code,Code hexadécimal
-config.application.colourTabTitle,The title for colour tab,Colour,Couleur
-config.application.configChangeError,Error message for application config change,Unable to make change. Please try again,Impossible d'effectuer la modification. Veuillez réessayer
-config.application.currencyChangeMessage,Message for application currency change modal,Select your currency for your CRVS system,Selectionnez la devise
-config.application.currencyChangeNotification,Message for application currency change notification,Currency updated,Devise mise à jour
-config.application.currencyLabel,Currency config label,Currency,Devise
-config.application.deathDelayedFeeChangeNotification,Message for application death delayed fee change notification,Death delayed fee updated,Mise à jour de la pénalité de retard déclaration du décès
-config.application.deathLegallySpecifiedDialogTitle,Legally specified dialog title for death,Legally specified time period for death registration,Délais légal de déclaration du décès
-config.application.deathOnTimeFeeChangeNotification,Message for application death on time fee change notification,Death on time fee updated,Mise à jour des frais de déclaration de décès dans le délais legal
-config.application.deathRegTargetChangeNotification,Message for application death registration target change notification,Death registration target days updated,Mise à jour des jours cibles de déclaration des décès
config.application.deathTabTitle,The title for death tab,Death,Décès
config.application.deathTabTitleExport,The title for death tab for VSExport,Deaths,Décès
-config.application.delayedFeeDialogTitle,Delayed fee dialog title,Registration fees for delayed registrations,Frais pour les declarations tardives
-config.application.delayedRegistrationLabel,Delayed registration config label,Delayed registration,Enregistrement retardé
-config.application.delayedRegistrationValue,Delayed registration config value,After {lateTime} days,Après {lateTime} jours
config.application.emptystate,Vital Statistics Export Empty State Text,The previous month's vital statistics data (based on vital event registrations occurring within that month) will become available for you to export as of the 1st of every month. Large CSV files cannot be opened in Excel and should therefore be opened in a statistical program such as {posit}.,Les données statistiques vitales du mois précédent (basées sur les enregistrements d'événements vitaux survenus au cours de ce mois) seront disponibles pour l'exportation à partir du 1er de chaque mois. Les grands fichiers CSV ne peuvent pas être ouverts dans Excel et doivent donc être ouverts dans un programme statistique tel que {posit}.
-config.application.eventTargetInputLabel,The label for event target label,days,jours
-config.application.example,Label for Example,Example,Exemple
config.application.export,Download Export CSV,Export,Export
-config.application.generalTabTitle,The title for general tab,General,Général
-config.application.govermentLogoLabel,Government logo config label,Goverment logo,Logo du gouvernement
-config.application.govtLogoChangeError,Error message for country logo change,Unable to change logo. Please try again.,Impossible de modifier le logo. Veuillez réessayer.
-config.application.govtLogoChangeMessage,Message for government logo change modal,Upload a logo to be used on the login and declaration review screens,Téléchargez le logo du gouvernement qui sera utilisé sur le login et la décalcomanie du formulaire. Notez que le logo du certificat est téléchargé dans le cadre du modèle de certificat.
-config.application.govtLogoChangeNotification,Message for government logo change notification,Government logo updated,Mise à jour du logo du gouvernement
-config.application.govtLogoFileLimitError,Error message for large country logo file,Logo image file must be less than 2mb,Le fichier image du logo doit être inférieur à 2 Mo
-config.application.imageTabTitle,The title for image tab,Image,Image
-config.application.invalidExample,Label for Invalid example,Invalid,Invalide
-config.application.lateFeeDialogTitle,Date fee dialog title,Registration fees for late registrations,Frais d'inscription pour les inscriptions tardives
-config.application.lateRegistrationLabel,Late registration config label,Late registration,Déclaration tardive
-config.application.lateRegistrationValue,Late registration config value,Between {onTime} days and {lateTime} days,Entre {onTime} jours et {lateTime} jours
-config.application.legallySpecifiedLabel,Legally specified config label,Legally specified,Mention légale
-config.application.legallySpecifiedValue,Legally specified config value,Within {onTime} days,Dans (ontime) jours
-config.application.loginBackgroundLabel,Login Background config label,Login Background,Historique de la connexion
-config.application.loginImageText,Login Image config label,Upload an image and set how you would like it to display in the background,Téléchargez une image et définissez comment vous souhaitez qu'elle s'affiche en arrière-plan.
-config.application.marriageDelayedFeeChangeNotification,Message for application marriage delayed fee change notification,Marriage delayed fee updated,Mise à jour de la pénalité de retard déclaration du marriage
-config.application.marriageLegallySpecifiedDialogTitle,Legally specified dialog title for marriage,Legally specified time period for marriage registration,Délais légal de déclaration du marriage
-config.application.marriageOnTimeFeeChangeNotification,Message for application marriage on time fee change notification,Marriage on time fee updated,Mise à jour des frais de déclaration de marriage dans le délais legal
-config.application.marriageRegTargetChangeNotification,Message for application marriage registration target change notification,Marriage registration target days updated,Mise à jour des jours cibles de déclaration des marriages
-config.application.marriageTabTitle,The title for marriage tab,Marriage,Mariage
-config.application.nameChangeMessage,Message for application name change modal,Choose a name for your CRVS system,Choisissez un nom pour votre système CRVS
-config.application.nidPatternChangeError,Error message for invalid regular expression for NID number,Invalid regular expression for a National ID,Expression régulière invalide pour un identifiant national
-config.application.nidPatternChangeMessage,Unique Identification Number (UIN) config message,Set the regex pattern for your national ID. For guidance please refer to www.regex101.com,Expression régulière invalide pour un identifiant national
-config.application.nidPatternChangeNotification,Message for NID Pattern change modal,Unique Identification Number (UIN) regex pattern updated,Mise à jour du modèle regex pour le numéro d'identification unique (UIN)
-config.application.nidPatternTitle,Unique Identification Number (UIN) config title,Unique Identification Number (UIN) e.g. National ID,"Numéro d'identification unique (UIN), par exemple la carte d'identité nationale."
-config.application.onTimeFeeDialogTitle,On time fee dialog title,Registration fees within legally specified time,Droits d'inscription dans le délai légal
-config.application.pattern,Label for Pattern,Pattern,Modèle
-config.application.phoneNumberChangeError,Error message for invalid regular expression for phone number number,Invalid regular expression for a phone number,Expression régulière invalide pour un numéro de téléphone
-config.application.phoneNumberChangeMessage,phone number config config message,Set the regex pattern for your country phone number. For guidance please refer to www.regex101.com,"Définissez le modèle regex pour le numéro de téléphone de votre pays. Pour obtenir des conseils, veuillez consulter le site www.regex101.com"
-config.application.phoneNumberChangeNotification,Message for phone number Pattern change modal,Phone regex pattern updated,Mise à jour du modèle de regex téléphonique
-config.application.phoneNumberExampleLabel,,example: {example},exemple: {example}
-config.application.phoneNumberLabel,Phone number config label,Phone number,Numéro de téléphone
-config.application.phoneNumberPatternLabel,,pattern: {pattern},motif: {pattern}
-config.application.phoneNumberPatternTitle,Phone number config title,Phone number regex,Regex du numéro de téléphone
-config.application.registrationFeesGroupTitle,The title for registration fee group,Registration fees,Droits d'inscription
-config.application.registrationTimePeriodsGroupTitle,The title for registration time periods group,Registration time periods,Périodes d'enregistrement
-config.application.settings,Link Text for Config Application Settings,Application,Application
-config.application.testNumber,Label for test number,Test number,Numéro de test
-config.application.updatingeMessage,Message for application config updated modal,Updating...,Mise à jour en cours
-config.application.validExample,Label for valid example,Valid,Valable
config.application.vitalStatistics,Vital Statistics Export,"Month-{month}-Farajaland-{event, select, birth{birth} death{death} other{birth}}-event-statistics.csv {fileSize}","Mois-{month}-Farajaland-{event, select, birth{birth} death{death} other{birth}}-événement-statistiques.csv {fileSize}"
config.application.vsExportDownloadFailed,Vital Statistics Export Empty State Text,Sorry! Something went wrong,Désolé ! Quelque chose s'est mal passé
config.application.vsexport,VS Export tab,Vital statistics,Statistiques vitales
-config.application.withinLegallySpecifiedTimeLabel,Within legally specified time config label,Within legally specified time,Dans les délais prévus par la loi
-config.birthDefaultTempDesc,Label for default birth certificate template,Default birth certificate template,Modèle d'acte de naissance par défaut
-config.birthTemplate,Label for birth certificate template,Birth certificate,Certificat de naissance
-config.birthUpdatedTempDesc,,Updated {birthLongDate},Mise à jour de {birthLongDate}
config.certTemplate,Label for certificate templates,Certificate Template,Modèle de certificat
-config.certificate.allowPrinting,To allow printing in advanced of issuance,Allow printing in advanced of issuance,Permettre l'impression à l'avance de l'émission
-config.certificate.allowPrintingNotification,Message for allowing printing notification,Allow printing in advance of issuance updated,Permettre l'impression avant la mise à jour de l'émission
-config.certificate.certificateUpdated,Certificate template change message on success,{eventName} certificate has been updated,Le certificat {eventName} a été mis à jour.
-config.certificate.certificateUploading,Certificate template message when uploading SVG,Uploading and validating {eventName} certificate.,Téléchargement et validation du certificat {eventName}.
-config.certificate.certificateValidationError,Certificate template error message on failed,Unable to read SVG. Please check,Impossible de lire le SVG. Veuillez vérifier
config.certificate.options,Show options,Options,Options
-config.certificate.printDescription,Allowing printing,Records printed off in advance of collections will be added to the ready to issue work-queue,Les documents imprimés avant les collectes seront ajoutés à la liste des documents prêts à être délivrés
-config.certificate.template,Template for certificates,Template,Gabarit
-config.certificate.uploadCertificateDialogCancel,Cancel new certificate template upload button,Cancel,Annuler
-config.certificate.uploadCertificateDialogConfirm,Confirm new certificate template upload button,Upload,Télécharger
-config.certificate.uploadCertificateDialogDescription,The description for the dialog when upload new certificate template,This will replace the current certificate template. We recommend downloading the existing certificate template as a reference.,Ceci remplacera le modèle de certificat actuel. Nous vous recommandons de télécharger le modèle de certificat existant comme référence.
-config.certificate.uploadCertificateDialogTitle,Upload certificate template modal title,Upload new certificate?,Télécharger un nouveau certificat ?
-config.certificateConfiguration,Link Text for Config Declaration Settings,Certificate configuration,Configuration du certificat
-config.deathDefaultTempDesc,Label for default death certificate template,Default death certificate template,Modèle de certificat de décès par défaut
-config.deathTemplate,Label for death certificate template,Death certificate,Acte de mariage
-config.deathUpdatedTempDesc,,Updated {deathLongDate},Mise à jour de {deathLongDate}
-config.downloadTemplate,Download action in certificate config action menu,Download,Télécharger
config.emailAllUsers.modal.supportingCopy,Label for send email all users confirmation supporting copy,User will receive emails over the next 24 hours,L'utilisateur recevra des courriels au cours des prochaines 24 heures
config.emailAllUsers.modal.title,Label for send email all users confirmation title,Send email to all users?,Envoyer un e-mail à tous les utilisateurs ?
config.emailAllUsers.subtitle,Subtitle for email all users,This email will be sent to all users you are active. Emails will be sent over the next 24 hours. Only one email can be sent per day,Cet e-mail sera envoyé à tous les utilisateurs que vous activez. Les courriels seront envoyés au cours des prochaines 24 heures. Un seul courriel peut être envoyé par jour
config.emailAllUsers.title,Title for email all users,Email all users,Envoyer un e-mail à tous les utilisateurs
-config.eventUpdatedTempDesc,Label for updated birth certificate template,"Updated {lastModified, date, ::dd MMMM yyyy}","Mis à jour {lastModified, date, ::dd MMMM yyyy}"
-config.form.settings.time,,Time input,Saisie de l'heure
-config.form.tools.input.customSelectWithDynamicOptions,,Custom select with dynamic options,Sélection personnalisée avec options dynamiques
-config.informantNotification.declarationSMS,Title for informant declarationSMS notification,Declaration sent for review,Déclaration envoyée pour examen
-config.informantNotification.inProgressSMS,Title for informant inProgressSMS notification,Notification sent to Office,Notification envoyée au bureau
-config.informantNotification.registrationSMS,Title for informant registrationSMS notification,Declaration registered,Déclaration enregistrée
-config.informantNotification.rejectionSMS,Title for informant rejectionSMS notification,Declaration rejected,Déclaration rejetée
-config.informantNotification.subtitle,Subtile for informant sms notification,Select the notifications to send to the informant to keep them informed of the progress to their declaration. Your system is configured to send {communicationType}.,Sélectionnez les notifications à envoyer à l'informateur pour le tenir informé de l'avancement de sa déclaration. Votre système est configuré pour envoyer {communicationType}
-config.informantNotification.success,Notification for informant update success,Informant notifications updated,Mise à jour des notifications des informateurs
-config.informantNotification.title,The title for Informant notifications,Informant notifications,Notifications d'informateurs
-config.integrations,,Integrations,Intégrations
-config.listDetails,Details for certificates templates list,To learn how to edit an SVG and upload a certificate to suite your country requirements please refer to this detailed guide. ,"Pour savoir comment modifier un SVG et télécharger un certificat en fonction des exigences de votre pays, veuillez consulter ce guide détaillé."
-config.listDetailsQsn,Details question for certificates templates list,How to configure a certificate?,Comment configurer un certificat ?
-config.listTitle,Title for certificates templates list,Certification,La certification
-config.marriageDefaultTempDesc,Label for default marriage certificate template,Default marriage certificate template,Modèle de certificat de mariage par défaut
-config.marriageTemplate,Label for marriage certificate template,Marriage certificate,Certificat de mariage
-config.previewTemplate,,Preview,Prévisualiser
-config.printTemplate,Print action in certificate config action menu,Print,Imprimer
-config.uploadTemplate,Upload action in certificate config action menu,Upload,Télécharger
config.userRoles.language,Language name,"{language, select, en {English} fr {French} other {{language}}}","{language, select, en {Anglais} fr {Français} other {{language}}}"
-config.userRoles.role,ListViewSimplified header for role,ROLE,RÔLE
config.userRoles.roleUpdateInstruction,Instruction for adding/updating role in role management modal,Add the roles to be assigned the system role of {systemRole},Ajoutez les rôles auxquels attribuer le rôle système de {systemRole}
-config.userRoles.subtitle,Subtile for informant sms notification,Map user roles to each system role so that specific permissions and privileges are correctly assigned. To learn more about the different system roles see ... {link},"Associez les rôles d'utilisateur à chaque rôle système afin que les autorisations et les privilèges spécifiques soient correctement attribués. Pour en savoir plus sur les différents rôles système, voir ... {link}"
-config.userRoles.systemRoleSuccessMsg,Label for System role updated success message,System role updated successfully,Rôle système mis à jour avec succès
-config.userRoles.systemRoles,ListViewSimplified header for system roles,SYSTEM ROLES,RÔLES SYSTÈME
-config.userRoles.title,The title for user roles,User roles,Rôles des utilisateurs
conflicts.modal.assign.description,Description for modal when assign,Please note you will have sole access to this record. Please make any updates promptly otherwise unassign the record.,"Veuillez noter que vous aurez un accès exclusif à cet enregistrement. Veuillez effectuer rapidement les mises à jour éventuelles, sinon vous désassignez l'enregistrement."
conflicts.modal.assign.title,Title for modal when assign,Assign record?,Attribuer un enregistrement ?
conflicts.modal.assigned.description,Description for modal when record already assigned,{name} at {officeName} has sole editable access to this record,{name} à {officeName} a un accès unique et modifiable à cet enregistrement.
@@ -1352,6 +1245,10 @@ form.section.information.death.bullet2,,As the legal Informant it is important t
form.section.information.death.bullet3,,Once the declaration is processed you will receive an email to tell you when to visit the office to collect the certificate - Take your ID with you.,"Une fois la déclaration traitée, vous recevrez un courriel vous indiquant quand vous rendre au bureau pour retirer le certificat - Munissez-vous d'une pièce d'identité."
form.section.information.death.bullet4,,Make sure you collect the certificate. A death certificate is critical to support with inheritance claims and to resolve the affairs of the deceased e.g. closing bank accounts and setting loans.,"Veillez à récupérer le certificat. Le certificat de décès est essentiel pour les demandes d'héritage et pour régler les affaires de la personne décédée, par exemple la fermeture des comptes bancaires et la mise en place des prêts."
form.section.information.name,,Information,Informations
+form.section.label.timePeriodLast30Days,Label for option of time period select: last 30 days,last 30 days,les 30 derniers jours
+form.section.label.timePeriodLast7Days,Label for option of time period select: last 7 days,last 7 days,les 7 derniers jours
+form.section.label.timePeriodLast90Days,Label for option of time period select: last 90 days,last 90 days,les 90 derniers jours
+form.section.label.timePeriodLastYear,Label for option of time period select: last year,last year,l'année dernière
form.section.marriageEvent.date,,Date of marriage,Date du mariage
form.section.marriageEvent.name,,Marriage event details,Détails de l'événement de mariage
form.section.marriageEvent.title,,Marriage details,Détails du mariage
@@ -1853,6 +1750,9 @@ register.selectVitalEvent.registerNewEventHeading,The section heading on the pag
register.selectVitalEvent.registerNewEventTitle,The title that appears on the select vital event page,New declaration,Nouvelle déclaration
register.selectinformant.legalGuardian,,Legal guardian,Tuteur légal
register.workQueue.declarations.banner,,Declarations to register in your area,Déclarations à enregistrer dans votre région
+reloadmodal.body,Body of reload modal,There’s a new version of {app_name} available. Please update to continue.,Une nouvelle version de {app_name} est disponible. Veuillez effectuer la mise à jour pour continuer.
+reloadmodal.button.update,Label of update button,Update,Mise à jour
+reloadmodal.title,Title when update is available,Update available,Mise à jour disponible
review.actions.desc.regConfComp,,"By clicking register, you confirm that the information entered is correct and the vital event can be registered.","En cliquant sur Enregistrer, vous confirmez que les informations sont correctes et ont été vérifiées par l'informateur. L'informateur comprend qu'elles seront utilisées pour enregistrer la naissance et à des fins de planification. En enregistrant cette naissance, un certificat de naissance sera généré avec votre signature pour être délivré."
review.actions.desc.regConfInComp,,Please add mandatory information before registering.,Des informations obligatoires sont manquantes. Veuillez ajouter ces informations afin de pouvoir terminer le processus d'enregistrement.
review.actions.description,,"By clicking register, you confirm that the information entered is correct and the vital event can be registered. ","En vous enregistrant, vous confirmez que vous avez examiné cette déclaration et que vous êtes convaincu qu'elle remplit les conditions requises pour l'enregistrement."