From 69e380fb6dddf538610f8f1dd304c10276fc0299 Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 14 Aug 2026 15:36:39 +0530 Subject: [PATCH 01/10] cron job for audit log --- .../120-ibm-db2u-database/README.md | 36 +++- .../files/db2AuditExtract.sh | 197 ++++++++++++++++++ .../templates/04-db2u-Audit_Cron.yaml | 55 +++++ .../120-ibm-db2u-database/values.yaml | 4 + .../deployed-values.yaml | 62 ++++++ .../ibm-mas-instance-root/output.yaml | 0 .../templates/output.yaml | 0 7 files changed, 350 insertions(+), 4 deletions(-) create mode 100644 instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh create mode 100644 instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml create mode 100644 root-applications/ibm-mas-instance-root/deployed-values.yaml create mode 100644 root-applications/ibm-mas-instance-root/output.yaml create mode 100644 root-applications/ibm-mas-instance-root/templates/output.yaml diff --git a/instance-applications/120-ibm-db2u-database/README.md b/instance-applications/120-ibm-db2u-database/README.md index 5ec429989..c79ca582a 100644 --- a/instance-applications/120-ibm-db2u-database/README.md +++ b/instance-applications/120-ibm-db2u-database/README.md @@ -4,10 +4,9 @@ Create a Db2u database for a MAS app. +## Overview -Contains a presync hook (`00-presync-await-crd_Job.yaml`) that ensures we wait for the db2uclusters CRD to be installed before attempting to sync. - -Contains a job that runs last (`05-postsync-setup-db2_Job.yaml`). This registers the `${ACCOUNT_ID}/${CLUSTER_ID}/${MAS_INSTANCE_ID}/db2/${DB2_INSTANCE_NAME}/config` secret in the **Secrets Vault** used to share some information that is generated at runtime with other ArgoCD Applications. This job also performs some special configuration steps that are required if the Db2u database is intended for use by the Manage MAS Application. +Creates a Db2u database instance for a MAS application. Includes a presync hook (`00-presync-await-crd_Job.yaml`) that ensures the `db2uclusters` CRD is installed before syncing, and a postsync job (`05-postsync-setup-db2_Job.yaml`) that registers the `${ACCOUNT_ID}/${CLUSTER_ID}/${MAS_INSTANCE_ID}/db2/${DB2_INSTANCE_NAME}/config` secret in the **Secrets Vault** and performs any Manage-specific database configuration steps. ## Resources Created @@ -20,7 +19,8 @@ Contains a job that runs last (`05-postsync-setup-db2_Job.yaml`). This registers | `Issuer` | DB2 TLS issuers | DB2 application namespace | Always | `application_admin_role` | | `Certificate` | DB2 TLS certificates | DB2 application namespace | Always | `application_admin_role` | | `Db2uInstance` | Db2u instance CR | DB2 application namespace | Always | `application_admin_role` | -| `CronJob` | Db2 backup cron job | DB2 application namespace | When backups are enabled | `application_admin_role` | +| `CronJob` | Db2 backup cron job | DB2 application namespace | When backups are enabled (`db2_backup_bucket_name` set) | `application_admin_role` | +| `CronJob` | Db2 audit extract cron job | DB2 application namespace | When audit bucket is enabled (`db2_audit_bucket_name` set) | `application_admin_role` | | `ConfigMap` | Db2 script/config maps | DB2 application namespace | Always | `application_admin_role` | | `Route` | Db2 TLS route | DB2 application namespace | When route exposure is enabled | `application_admin_role` | | `Service` | Db2 services, including HADR services | DB2 application namespace | Always | `application_admin_role` | @@ -126,6 +126,12 @@ db2_backup_bucket_secret_key: string (secret reference, when backup enabled) db2_backup_notify_slack_url: string (optional, when backup enabled) db2_backup_icd_auth_key: string (secret reference, optional, when backup enabled) +# Audit Extraction Configuration (optional) +# When db2_audit_bucket_name is set, a daily CronJob is created in the db2 namespace +# that archives and extracts DB2 audit logs as DEL/ASC files and uploads them to the +# specified S3 bucket, then removes all local copies. +db2_audit_bucket_name: string (secret reference, when audit extraction enabled) + allow_list: string (optional) # Private NLB for customer TGW connectivity (optional) @@ -208,3 +214,25 @@ The NLB is created independently for each instance (e.g. facilities, manage) usi If `private_nlb.enabled: true` and either `subnet_ids` or `allowed_cidrs` is empty, Helm will fail immediately with a clear error message before rendering any resources. This prevents a broken or unrestricted NLB from being deployed.. + +## Examples + +### Minimal — Manage database with backup and audit extraction enabled + +```yaml +db2_namespace: mas-inst1-manage-db2u +db2_instance_name: db2wh-manage +db2_dbname: BLUDB +db2_instance_home_path: /mnt/blumeta0/home/db2inst1 +mas_application_id: manage +instance_id: inst1 + +# Backup +db2_backup_bucket_name: "" +db2_backup_bucket_endpoint: "" +db2_backup_bucket_access_key: "" +db2_backup_bucket_secret_key: "" + +# Audit extraction — daily CronJob uploads delasc files to audit-log-manage// +db2_audit_bucket_name: "" +``` diff --git a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh new file mode 100644 index 000000000..2e92b6c1b --- /dev/null +++ b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh @@ -0,0 +1,197 @@ +#!/bin/sh + +# ---------------------------------------------------------------------------- +#% Script Name : db2AuditExtract.sh +#% Description : Archive and extract DB2 audit logs as DEL/ASC files, then +#% copy to an S3 audit bucket and remove local copies. +#% Created On : 2026 +#% +#% ************** THIS NEEDS TO BE RUN AS INSTANCE OWNER (db2inst1). ****** +#% USAGE: +#% db2AuditExtract.sh +#% +#% Steps performed: +#% 1. Flush active audit buffers +#% 2. Archive the database audit log (BLUDB) +#% 3. Archive the instance audit log +#% 4. Extract archived database log to delasc format +#% 5. Extract archived instance log to delasc format +#% 6. Upload all *.del files to s3:///audit-log-// +#% and delete each file from source immediately after a successful upload +#% 7. Remove /tmp/auditarchive and all its contents +# ---------------------------------------------------------------------------- + +set -euo pipefail + +# ============================================================================ +# Parameters / Inputs +# ============================================================================ +AUDIT_BUCKET="${1:-}" +APP_NAME="${2:-}" + +if [ -z "${AUDIT_BUCKET}" ] || [ -z "${APP_NAME}" ]; then + echo "ERROR :: Usage: $0 " + exit 1 +fi + +ARCHIVE_DIR="/tmp/auditarchive" +DBNAME="BLUDB" +HOSTNAME=$(hostname) +DATE=$(date +"%Y%m%d") + +# ============================================================================ +# Logging helper +# ============================================================================ +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" +} + +# ============================================================================ +# Source DB2 environment (instance owner required) +# ============================================================================ +INST=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | awk -F, '{print $4}') +INSTHOME=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${INST}" | awk -F ',' '{print $5}' | sed 's/\/sqllib//') + +. "${INSTHOME}/sqllib/db2profile" + +# ============================================================================ +# Load COS / S3 parameters (bucket alias etc.) +# ============================================================================ +. /mnt/backup/bin/.PROPS + +# ============================================================================ +# Ensure audit is re-started on exit (even on failure) +# ============================================================================ +cleanup_exit() { + log "INFO :: Ensuring db2audit is running after job completion" + db2audit start >/dev/null 2>&1 || true +} +trap cleanup_exit EXIT + +# ============================================================================ +# 1. Prepare working directory +# ============================================================================ +log "INFO :: Preparing archive directory ${ARCHIVE_DIR}" +mkdir -p "${ARCHIVE_DIR}" + +# Remove any leftover *.del files from a previous run +log "INFO :: Removing any leftover .del files from ${ARCHIVE_DIR}" +rm -f "${ARCHIVE_DIR}"/*.del + +# ============================================================================ +# 2. Flush active audit buffers +# ============================================================================ +log "INFO :: Flushing db2audit buffers" +db2audit flush +RC=$? +if [ $RC -ne 0 ]; then + log "ERROR :: db2audit flush failed (RC=${RC})" + exit 1 +fi + +# ============================================================================ +# 3. Archive the database audit log +# ============================================================================ +log "INFO :: Archiving database audit log for ${DBNAME} to ${ARCHIVE_DIR}" +db2audit archive database "${DBNAME}" to "${ARCHIVE_DIR}" +RC=$? +if [ $RC -ne 0 ]; then + log "ERROR :: db2audit archive database failed (RC=${RC})" + exit 1 +fi + +# ============================================================================ +# 4. Archive the instance audit log +# ============================================================================ +log "INFO :: Archiving instance audit log to ${ARCHIVE_DIR}" +db2audit archive to "${ARCHIVE_DIR}" +RC=$? +if [ $RC -ne 0 ]; then + log "ERROR :: db2audit archive instance failed (RC=${RC})" + exit 1 +fi + +# ============================================================================ +# 5. Extract database archived log to DEL/ASC format +# ============================================================================ +log "INFO :: Extracting database audit archive to delasc" +DB_LOG_PATTERN="${ARCHIVE_DIR}/db2audit.db.${DBNAME}.log.0.*" + +# Verify at least one archived file exists before attempting extract +DB_LOG_FILES=$(ls ${DB_LOG_PATTERN} 2>/dev/null || true) +if [ -z "${DB_LOG_FILES}" ]; then + log "WARN :: No database audit archive files matching ${DB_LOG_PATTERN} — skipping db extract" +else + db2audit extract delasc to "${ARCHIVE_DIR}" from files ${DB_LOG_PATTERN} + RC=$? + if [ $RC -ne 0 ]; then + log "ERROR :: db2audit extract (database) failed (RC=${RC})" + exit 1 + fi + log "INFO :: Database audit extract completed" +fi + +# ============================================================================ +# 6. Extract instance archived log to DEL/ASC format +# ============================================================================ +log "INFO :: Extracting instance audit archive to delasc" +INST_LOG_PATTERN="${ARCHIVE_DIR}/db2audit.instance.log.0.*" + +INST_LOG_FILES=$(ls ${INST_LOG_PATTERN} 2>/dev/null || true) +if [ -z "${INST_LOG_FILES}" ]; then + log "WARN :: No instance audit archive files matching ${INST_LOG_PATTERN} — skipping instance extract" +else + db2audit extract delasc to "${ARCHIVE_DIR}" from files ${INST_LOG_PATTERN} + RC=$? + if [ $RC -ne 0 ]; then + log "ERROR :: db2audit extract (instance) failed (RC=${RC})" + exit 1 + fi + log "INFO :: Instance audit extract completed" +fi + +# ============================================================================ +# 7. Upload *.del files to audit-log-// in S3 and delete from source +# ============================================================================ +DEL_FILES=$(ls "${ARCHIVE_DIR}"/*.del 2>/dev/null || true) + +if [ -z "${DEL_FILES}" ]; then + log "WARN :: No .del files found in ${ARCHIVE_DIR} — nothing to upload" +else + BUCKET_ALIAS=$(db2 list storage access | grep "${AUDIT_BUCKET}" -B4 | grep ALIAS | awk -F '=' '{print $2}') + # S3 path: audit-log-// + TARGET_PREFIX="audit-log-${APP_NAME}/${DATE}" + + for DEL_FILE in ${DEL_FILES}; do + FILE_NAME=$(basename "${DEL_FILE}") + COS_TARGET="DB2REMOTE://${BUCKET_ALIAS}//${TARGET_PREFIX}/${FILE_NAME}" + log "INFO :: Uploading ${DEL_FILE} to ${COS_TARGET}" + db2RemStgManager alias put \ + source="${DEL_FILE}" \ + target="${COS_TARGET}" + RC=$? + if [ $RC -ne 0 ]; then + log "ERROR :: Upload of ${FILE_NAME} failed (RC=${RC})" + exit 1 + fi + log "INFO :: Upload completed: ${FILE_NAME} — removing from source" + rm -f "${DEL_FILE}" + done +fi + +# ============================================================================ +# 8. Remove archive directory and all its contents +# ============================================================================ +log "INFO :: Removing archive directory ${ARCHIVE_DIR}" +rm -rf "${ARCHIVE_DIR}" +RC=$? +if [ $RC -ne 0 ]; then + log "ERROR :: Failed to remove ${ARCHIVE_DIR} (RC=${RC})" + exit 1 +fi +log "INFO :: Archive directory removed" + +log "INFO :: DB2 audit extraction and upload completed successfully" +exit 0 + +# -- End of Script diff --git a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml new file mode 100644 index 000000000..94eaf9f23 --- /dev/null +++ b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml @@ -0,0 +1,55 @@ +{{- if .Values.application_admin_role }} +{{- if and .Values.db2_audit_bucket_name (not (contains "sdb" .Values.db2_instance_name)) }} + +{{- /* +Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. +*/}} +{{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} + +# +# CronJob for DB2 Audit Log Extraction +# Runs daily to archive and extract DB2 audit logs as DEL/ASC files and +# upload them to the configured S3 audit bucket, then removes local copies. +# +--- +kind: CronJob +apiVersion: batch/v1 +metadata: + name: "db2-audit-extract-{{ .Values.db2_instance_name }}" + namespace: "{{ .Values.db2_namespace }}" + labels: + parent: cronjob + auditBucket: "{{ .Values.db2_audit_bucket_name }}" + db2pod: "c-{{ .Values.db2_instance_name }}-db2u-0" + mas.ibm.com/instanceId: "{{ .Values.instance_id }}" + annotations: + argocd.argoproj.io/sync-wave: "130" +spec: + # Run daily at 01:00 UTC — offset from the 02:00 backup job to avoid contention + schedule: '0 1 * * *' + concurrencyPolicy: Forbid + jobTemplate: + spec: + template: + metadata: + labels: + parent: cronjob + spec: + containers: + - name: "db2-audit-extract-{{ .Values.db2_instance_name }}" + image: {{ .Values.cli_image_repo | default "quay.io/ibmmas/cli" }}@{{ $_cli_image_digest }} + command: + - oc + - rsh + - "c-{{ .Values.db2_instance_name }}-db2u-0" + - su + - -lc + - "{{ .Values.db2_instance_home_path }}/bin/db2AuditExtract.sh {{ .Values.db2_audit_bucket_name }} {{ .Values.mas_application_id }}" + - db2inst1 + imagePullPolicy: IfNotPresent + restartPolicy: OnFailure + serviceAccountName: "account-{{ .Values.db2_namespace }}-{{ .Values.db2_instance_name }}" + successfulJobsHistoryLimit: 30 + failedJobsHistoryLimit: 10 +{{- end }} +{{- end }} diff --git a/instance-applications/120-ibm-db2u-database/values.yaml b/instance-applications/120-ibm-db2u-database/values.yaml index e8767691a..5574366ae 100644 --- a/instance-applications/120-ibm-db2u-database/values.yaml +++ b/instance-applications/120-ibm-db2u-database/values.yaml @@ -7,6 +7,10 @@ db2_instance_home_path: /mnt/blumeta0/home/db2inst1 sm_aws_access_key_id: xxx sm_aws_secret_access_key: xxxx +# Audit Bucket Configuration (optional) +# When set, a daily CronJob will archive and extract audit logs to this S3 bucket. +db2_audit_bucket_name: "" + # Private NLB for customer TGW connectivity (A.4 Option 2) # When enabled, ROSA provisions an internal AWS NLB in the specified subnets. # ROSA automatically manages the required EC2 worker node security group rules. diff --git a/root-applications/ibm-mas-instance-root/deployed-values.yaml b/root-applications/ibm-mas-instance-root/deployed-values.yaml new file mode 100644 index 000000000..aee91c628 --- /dev/null +++ b/root-applications/ibm-mas-instance-root/deployed-values.yaml @@ -0,0 +1,62 @@ +USER-SUPPLIED VALUES: +HANodeConfig: + nodeRoles: '"master"' +annotationWhitelist: + containerSpec: "" + namespace: "" + workloadController: "" +annotations: + kubeturbo.io/controllable: "false" +args: + cleanupSccImpersonationResources: true + discoveryIntervalSec: 600 + discoverySampleIntervalSec: 60 + discoverySamples: 10 + discoveryTimeoutSec: 180 + discoveryWorkers: 10 + garbageCollectionIntervalMin: 10 + kubelethttps: true + kubeletport: 10250 + logginglevel: 2 + pre16k8sVersion: false + sccsupport: '*' + skipCreatingSccImpersonationResources: false + stitchuuid: true +daemonPodDetectors: + namespacePatterns: [] + podNamePatterns: [] +discovery: + chunkSendDelayMillis: 0 + numObjectsPerChunk: 5000 +image: + pullPolicy: IfNotPresent + related: "" + repository: icr.io/cpopen/turbonomic/kubeturbo +logging: + level: 2 +nodePoolSize: + max: 1000 + min: 1 +replicaCount: 1 +resources: {} +restAPIConfig: + turbonomicCredentialsSecretName: turbonomic-credentials +roleBinding: turbo-all-binding +roleName: cluster-admin +sdkProtocolConfig: + registrationTimeoutSec: 300 + restartOnRegistrationTimeout: true +serverMeta: + turboServer: https://ibm.turbonomic.io + version: 8.13.4 +serviceAccountName: turbo-user +systemWorkloadDetectors: + namespacePatterns: + - kube-.* + - openshift-.* + - cattle.* +targetConfig: + targetName: noble7_1613 +wiremock: + enabled: false + url: wiremock:8080 diff --git a/root-applications/ibm-mas-instance-root/output.yaml b/root-applications/ibm-mas-instance-root/output.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/root-applications/ibm-mas-instance-root/templates/output.yaml b/root-applications/ibm-mas-instance-root/templates/output.yaml new file mode 100644 index 000000000..e69de29bb From 3458f0f9766540556829698d98607beeccdf66c0 Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 21 Aug 2026 15:17:34 +0530 Subject: [PATCH 02/10] db2 audit log cron job --- .../files/CopyDBScripts.sh | 1 + .../templates/04-db2u-Audit_Cron.yaml | 29 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/instance-applications/120-ibm-db2u-database/files/CopyDBScripts.sh b/instance-applications/120-ibm-db2u-database/files/CopyDBScripts.sh index 7a0319a09..3ef1fa618 100644 --- a/instance-applications/120-ibm-db2u-database/files/CopyDBScripts.sh +++ b/instance-applications/120-ibm-db2u-database/files/CopyDBScripts.sh @@ -35,6 +35,7 @@ cp -rp reorgTablesIndexesInplace.sh ${INSTHOME}/bin/ cp -rp extract_authorization.sh ${INSTHOME}/bin cp -rp HADRMON.sh ${INSTHOME}/bin cp -rp auditExtractUpload.sh ${INSTHOME}/bin/ +cp -rp db2AuditExtract.sh ${INSTHOME}/bin/ echo -e "\nCopying the file to bin/ITCS104 directory under Instance Home . . ." diff --git a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml index 94eaf9f23..50f37fb51 100644 --- a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml +++ b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml @@ -1,16 +1,17 @@ {{- if .Values.application_admin_role }} -{{- if and .Values.db2_audit_bucket_name (not (contains "sdb" .Values.db2_instance_name)) }} + {{- if and .Values.db2_backup_bucket_name (not (contains "sdb" .Values.db2_instance_name)) }} -{{- /* -Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. -*/}} -{{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} + {{- /* + Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. + */}} + {{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} -# -# CronJob for DB2 Audit Log Extraction -# Runs daily to archive and extract DB2 audit logs as DEL/ASC files and -# upload them to the configured S3 audit bucket, then removes local copies. -# + # + # CronJob for DB2 Audit Log Extraction + # Runs once a day at midnight to archive and extract DB2 audit logs as DEL/ASC + # files, upload them to the audit-log-// folder inside the + # backup bucket, then removes local copies. + # --- kind: CronJob apiVersion: batch/v1 @@ -19,14 +20,14 @@ metadata: namespace: "{{ .Values.db2_namespace }}" labels: parent: cronjob - auditBucket: "{{ .Values.db2_audit_bucket_name }}" + cosBucket: "{{ .Values.db2_backup_bucket_name }}" db2pod: "c-{{ .Values.db2_instance_name }}-db2u-0" mas.ibm.com/instanceId: "{{ .Values.instance_id }}" annotations: argocd.argoproj.io/sync-wave: "130" spec: - # Run daily at 01:00 UTC — offset from the 02:00 backup job to avoid contention - schedule: '0 1 * * *' + # Run once a day at midnight (00:00 UTC) + schedule: '0 0 * * *' concurrencyPolicy: Forbid jobTemplate: spec: @@ -44,7 +45,7 @@ spec: - "c-{{ .Values.db2_instance_name }}-db2u-0" - su - -lc - - "{{ .Values.db2_instance_home_path }}/bin/db2AuditExtract.sh {{ .Values.db2_audit_bucket_name }} {{ .Values.mas_application_id }}" + - "{{ .Values.db2_instance_home_path }}/bin/db2AuditExtract.sh {{ .Values.mas_application_id }}" - db2inst1 imagePullPolicy: IfNotPresent restartPolicy: OnFailure From 3ef228c603347bb4b73134b51fcd03a8ece60f3e Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 21 Aug 2026 15:21:41 +0530 Subject: [PATCH 03/10] MASCORE-16109: copy db2AuditExtract.sh, Audit_Cron, postsync-setup-db2 from argo-test-branch --- .../files/db2AuditExtract.sh | 287 +++++++++--------- .../templates/04-db2u-Audit_Cron.yaml | 22 +- .../templates/07-postsync-setup-db2_Job.yaml | 15 +- 3 files changed, 172 insertions(+), 152 deletions(-) diff --git a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh index 2e92b6c1b..49583d87e 100644 --- a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh +++ b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh @@ -1,197 +1,206 @@ -#!/bin/sh +#!/bin/bash # ---------------------------------------------------------------------------- #% Script Name : db2AuditExtract.sh -#% Description : Archive and extract DB2 audit logs as DEL/ASC files, then -#% copy to an S3 audit bucket and remove local copies. -#% Created On : 2026 +#% Description : Archive and extract DB2 audit logs as DEL/ASC files, upload +#% each *.del file to S3, then remove source files. #% -#% ************** THIS NEEDS TO BE RUN AS INSTANCE OWNER (db2inst1). ****** -#% USAGE: -#% db2AuditExtract.sh +#% ** THIS MUST BE RUN AS THE DB2 INSTANCE OWNER (db2inst1) ** #% -#% Steps performed: -#% 1. Flush active audit buffers -#% 2. Archive the database audit log (BLUDB) -#% 3. Archive the instance audit log -#% 4. Extract archived database log to delasc format -#% 5. Extract archived instance log to delasc format -#% 6. Upload all *.del files to s3:///audit-log-// -#% and delete each file from source immediately after a successful upload -#% 7. Remove /tmp/auditarchive and all its contents +#% USAGE: db2AuditExtract.sh +#% +#% Steps: +#% 1. mkdir /tmp/auditarchive +#% 2. rm /tmp/auditarchive/*.del +#% 3. db2audit flush +#% 4. db2audit archive database BLUDB to /tmp/auditarchive +#% 5. db2audit archive to /tmp/auditarchive (instance log) +#% 6. db2audit extract delasc to /tmp/auditarchive (database log) +#% 7. db2audit extract delasc to /tmp/auditarchive (instance log) +#% 8. Copy db2audit.db.BLUDB.log.0.20* from /mnt/blumeta0/audit → /tmp/auditarchive +#% 9. Copy db2audit.instance.log.0.20* from /mnt/blumeta0/audit → /tmp/auditarchive +#% 10. Upload ALL files from /tmp/auditarchive to S3 +#% 11. rm -rf /tmp/auditarchive +#% 12. Delete the *.log.0.20* source files from /mnt/blumeta0/audit +#% 13. (Optional) Delete pre-existing *.del files from /mnt/blumeta0/audit +#% (prints list before deleting) # ---------------------------------------------------------------------------- -set -euo pipefail +set -eo pipefail -# ============================================================================ -# Parameters / Inputs -# ============================================================================ -AUDIT_BUCKET="${1:-}" -APP_NAME="${2:-}" +# ── Logging helper ───────────────────────────────────────────────────────── +log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; } -if [ -z "${AUDIT_BUCKET}" ] || [ -z "${APP_NAME}" ]; then - echo "ERROR :: Usage: $0 " +# ── Validate input ───────────────────────────────────────────────────────── +APP_NAME="${1:-}" +if [ -z "${APP_NAME}" ]; then + echo "ERROR :: Usage: $0 " exit 1 fi +# ── Constants ────────────────────────────────────────────────────────────── ARCHIVE_DIR="/tmp/auditarchive" +AUDIT_BASE="/mnt/blumeta0/audit" DBNAME="BLUDB" -HOSTNAME=$(hostname) -DATE=$(date +"%Y%m%d") +DATE=$(date +"%Y-%m-%d") +DT=$(date +"%Y-%m-%d_%H%M%S") +DELETE_AUDIT_BASE_DEL="false" # Set to "true" to delete *.del files from ${AUDIT_BASE} (step 13) -# ============================================================================ -# Logging helper -# ============================================================================ -log() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" -} +# ── Source DB2 environment (DB2 profile uses unbound vars — disable nounset) ─ +set +u +. "${HOME}/sqllib/db2profile" +set -u -# ============================================================================ -# Source DB2 environment (instance owner required) -# ============================================================================ -INST=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | awk -F, '{print $4}') -INSTHOME=$(/usr/local/bin/db2greg -dump | grep -ae "I," | grep -v "/das," | grep "${INST}" | awk -F ',' '{print $5}' | sed 's/\/sqllib//') +# ── Load COS/S3 credentials (CONTAINER, SERVER, PARM1, PARM2) ───────────── +. /mnt/backup/bin/.PROPS -. "${INSTHOME}/sqllib/db2profile" +# ── Configure AWS CLI ────────────────────────────────────────────────────── +AWS_CLI="/mnt/backup/aws/dist/aws" +if [ ! -x "${AWS_CLI}" ]; then + log "ERROR :: AWS CLI not found at ${AWS_CLI} — trigger an ArgoCD sync to install it" + exit 1 +fi +export AWS_ACCESS_KEY_ID="${PARM1}" +export AWS_SECRET_ACCESS_KEY="${PARM2}" +export AWS_DEFAULT_REGION=$(echo "${SERVER}" | sed 's|.*s3\.\([^.]*\)\.amazonaws.*|\1|') -# ============================================================================ -# Load COS / S3 parameters (bucket alias etc.) -# ============================================================================ -. /mnt/backup/bin/.PROPS +S3_TARGET="s3://${CONTAINER}/audit_logs/${APP_NAME}/${DATE}/" -# ============================================================================ -# Ensure audit is re-started on exit (even on failure) -# ============================================================================ -cleanup_exit() { - log "INFO :: Ensuring db2audit is running after job completion" - db2audit start >/dev/null 2>&1 || true -} -trap cleanup_exit EXIT +# ── Ensure db2audit is always restarted on exit ──────────────────────────── +trap 'log "INFO :: Restarting db2audit after job"; db2audit start >/dev/null 2>&1 || true' EXIT + +# ── Banner ───────────────────────────────────────────────────────────────── +log "INFO :: ============================================================" +log "INFO :: DB2 Audit Extract — ${DT}" +log "INFO :: Application : ${APP_NAME} | Database : ${DBNAME}" +log "INFO :: Work dir : ${ARCHIVE_DIR}" +log "INFO :: S3 target : ${S3_TARGET}" +log "INFO :: ============================================================" # ============================================================================ -# 1. Prepare working directory +# 1–2. Prepare working directory # ============================================================================ -log "INFO :: Preparing archive directory ${ARCHIVE_DIR}" +log "INFO :: [1] mkdir ${ARCHIVE_DIR}" mkdir -p "${ARCHIVE_DIR}" -# Remove any leftover *.del files from a previous run -log "INFO :: Removing any leftover .del files from ${ARCHIVE_DIR}" -rm -f "${ARCHIVE_DIR}"/*.del +log "INFO :: [2] Removing any stale .del files from ${ARCHIVE_DIR}" +rm -f "${ARCHIVE_DIR}"/*.del 2>/dev/null || true # ============================================================================ -# 2. Flush active audit buffers +# 3. Flush in-memory audit buffer to disk # ============================================================================ -log "INFO :: Flushing db2audit buffers" +log "INFO :: [3] db2audit flush" db2audit flush -RC=$? -if [ $RC -ne 0 ]; then - log "ERROR :: db2audit flush failed (RC=${RC})" - exit 1 -fi # ============================================================================ -# 3. Archive the database audit log +# 4. Archive the database audit log to /tmp/auditarchive # ============================================================================ -log "INFO :: Archiving database audit log for ${DBNAME} to ${ARCHIVE_DIR}" +log "INFO :: [4] db2audit archive database ${DBNAME} to ${ARCHIVE_DIR}" db2audit archive database "${DBNAME}" to "${ARCHIVE_DIR}" -RC=$? -if [ $RC -ne 0 ]; then - log "ERROR :: db2audit archive database failed (RC=${RC})" - exit 1 -fi # ============================================================================ -# 4. Archive the instance audit log +# 5. Archive the instance audit log to /tmp/auditarchive # ============================================================================ -log "INFO :: Archiving instance audit log to ${ARCHIVE_DIR}" +log "INFO :: [5] db2audit archive to ${ARCHIVE_DIR} (instance log)" db2audit archive to "${ARCHIVE_DIR}" -RC=$? -if [ $RC -ne 0 ]; then - log "ERROR :: db2audit archive instance failed (RC=${RC})" - exit 1 -fi # ============================================================================ -# 5. Extract database archived log to DEL/ASC format +# 6. Extract archived database log → *.del # ============================================================================ -log "INFO :: Extracting database audit archive to delasc" -DB_LOG_PATTERN="${ARCHIVE_DIR}/db2audit.db.${DBNAME}.log.0.*" +log "INFO :: [6] db2audit extract delasc (database log)" +db2audit extract delasc to "${ARCHIVE_DIR}" \ + from files "${ARCHIVE_DIR}/db2audit.db.${DBNAME}.log.0."* -# Verify at least one archived file exists before attempting extract -DB_LOG_FILES=$(ls ${DB_LOG_PATTERN} 2>/dev/null || true) -if [ -z "${DB_LOG_FILES}" ]; then - log "WARN :: No database audit archive files matching ${DB_LOG_PATTERN} — skipping db extract" -else - db2audit extract delasc to "${ARCHIVE_DIR}" from files ${DB_LOG_PATTERN} - RC=$? - if [ $RC -ne 0 ]; then - log "ERROR :: db2audit extract (database) failed (RC=${RC})" - exit 1 - fi - log "INFO :: Database audit extract completed" -fi +# ============================================================================ +# 7. Extract archived instance log → *.del +# ============================================================================ +log "INFO :: [7] db2audit extract delasc (instance log)" +db2audit extract delasc to "${ARCHIVE_DIR}" \ + from files "${ARCHIVE_DIR}/db2audit.instance.log.0."* # ============================================================================ -# 6. Extract instance archived log to DEL/ASC format +# 8–9. Copy historical log files from /mnt/blumeta0/audit to /tmp/auditarchive # ============================================================================ -log "INFO :: Extracting instance audit archive to delasc" -INST_LOG_PATTERN="${ARCHIVE_DIR}/db2audit.instance.log.0.*" +log "INFO :: [8] Copying db2audit.db.${DBNAME}.log.0.20* from ${AUDIT_BASE}" +cp "${AUDIT_BASE}"/db2audit.db."${DBNAME}".log.0.20* "${ARCHIVE_DIR}/" 2>/dev/null \ + && log "INFO :: Database logs copied" \ + || log "WARN :: No matching db2audit.db.${DBNAME}.log.0.20* files found — skipping" -INST_LOG_FILES=$(ls ${INST_LOG_PATTERN} 2>/dev/null || true) -if [ -z "${INST_LOG_FILES}" ]; then - log "WARN :: No instance audit archive files matching ${INST_LOG_PATTERN} — skipping instance extract" -else - db2audit extract delasc to "${ARCHIVE_DIR}" from files ${INST_LOG_PATTERN} - RC=$? - if [ $RC -ne 0 ]; then - log "ERROR :: db2audit extract (instance) failed (RC=${RC})" - exit 1 - fi - log "INFO :: Instance audit extract completed" -fi +log "INFO :: [9] Copying db2audit.instance.log.0.20* from ${AUDIT_BASE}" +cp "${AUDIT_BASE}"/db2audit.instance.log.0.20* "${ARCHIVE_DIR}/" 2>/dev/null \ + && log "INFO :: Instance logs copied" \ + || log "WARN :: No matching db2audit.instance.log.0.20* files found — skipping" # ============================================================================ -# 7. Upload *.del files to audit-log-// in S3 and delete from source +# 10. Upload ALL files from /tmp/auditarchive to S3 # ============================================================================ -DEL_FILES=$(ls "${ARCHIVE_DIR}"/*.del 2>/dev/null || true) +log "INFO :: [10] Uploading all files from ${ARCHIVE_DIR} to ${S3_TARGET}" -if [ -z "${DEL_FILES}" ]; then - log "WARN :: No .del files found in ${ARCHIVE_DIR} — nothing to upload" +ALL_FILES=$(ls "${ARCHIVE_DIR}"/* 2>/dev/null || true) +if [ -z "${ALL_FILES}" ]; then + log "WARN :: No files found in ${ARCHIVE_DIR} — nothing to upload" else - BUCKET_ALIAS=$(db2 list storage access | grep "${AUDIT_BUCKET}" -B4 | grep ALIAS | awk -F '=' '{print $2}') - # S3 path: audit-log-// - TARGET_PREFIX="audit-log-${APP_NAME}/${DATE}" - - for DEL_FILE in ${DEL_FILES}; do - FILE_NAME=$(basename "${DEL_FILE}") - COS_TARGET="DB2REMOTE://${BUCKET_ALIAS}//${TARGET_PREFIX}/${FILE_NAME}" - log "INFO :: Uploading ${DEL_FILE} to ${COS_TARGET}" - db2RemStgManager alias put \ - source="${DEL_FILE}" \ - target="${COS_TARGET}" - RC=$? - if [ $RC -ne 0 ]; then - log "ERROR :: Upload of ${FILE_NAME} failed (RC=${RC})" - exit 1 - fi - log "INFO :: Upload completed: ${FILE_NAME} — removing from source" - rm -f "${DEL_FILE}" + ERRORS=0 + for F in ${ALL_FILES}; do + FILE_NAME=$(basename "${F}") + log "INFO :: [s3] ${FILE_NAME} → ${S3_TARGET}${FILE_NAME}" + "${AWS_CLI}" s3 cp "${F}" "${S3_TARGET}${FILE_NAME}" \ + && log "INFO :: Upload confirmed" \ + || { log "ERROR :: Upload FAILED for ${FILE_NAME}"; ERRORS=$((ERRORS + 1)); } done + [ ${ERRORS} -gt 0 ] && { log "ERROR :: ${ERRORS} upload(s) failed"; exit 1; } + log "INFO :: All files uploaded successfully" fi # ============================================================================ -# 8. Remove archive directory and all its contents +# 11. Remove /tmp/auditarchive and all its contents # ============================================================================ -log "INFO :: Removing archive directory ${ARCHIVE_DIR}" +log "INFO :: [11] rm -rf ${ARCHIVE_DIR}" rm -rf "${ARCHIVE_DIR}" -RC=$? -if [ $RC -ne 0 ]; then - log "ERROR :: Failed to remove ${ARCHIVE_DIR} (RC=${RC})" - exit 1 +log "INFO :: Working directory removed" + +# ============================================================================ +# 12. Delete the historical *.log.0.20* source files from /mnt/blumeta0/audit +# ============================================================================ +log "INFO :: [12] Removing historical log files from ${AUDIT_BASE}" + +for PATTERN in \ + "${AUDIT_BASE}/db2audit.db.${DBNAME}.log.0.20"* \ + "${AUDIT_BASE}/db2audit.instance.log.0.20"* +do + for F in ${PATTERN}; do + [ -f "${F}" ] || continue + log "INFO :: [delete] $(basename "${F}")" + rm -f "${F}" + done +done +log "INFO :: Historical log files removed" + +# ============================================================================ +# 13. (Optional) Delete pre-existing *.del files from /mnt/blumeta0/audit +# — controlled by DELETE_AUDIT_BASE_DEL; prints list before deleting +# ============================================================================ +log "INFO :: [13] DELETE_AUDIT_BASE_DEL=${DELETE_AUDIT_BASE_DEL}" + +if [ "${DELETE_AUDIT_BASE_DEL}" != "true" ]; then + log "INFO :: Skipping .del cleanup in ${AUDIT_BASE} (DELETE_AUDIT_BASE_DEL is not true)" +else + AUDIT_DEL_FILES=$(ls "${AUDIT_BASE}"/*.del 2>/dev/null || true) + if [ -z "${AUDIT_DEL_FILES}" ]; then + log "INFO :: No .del files found in ${AUDIT_BASE} — nothing to clean" + else + log "INFO :: The following .del files will be deleted from ${AUDIT_BASE}:" + for F in ${AUDIT_DEL_FILES}; do + log "INFO :: $(basename "${F}")" + done + rm -f ${AUDIT_DEL_FILES} + log "INFO :: .del files deleted" + fi fi -log "INFO :: Archive directory removed" -log "INFO :: DB2 audit extraction and upload completed successfully" +# ── Done ─────────────────────────────────────────────────────────────────── +log "INFO :: ============================================================" +log "INFO :: Audit extraction completed successfully" +log "INFO :: S3 target : ${S3_TARGET}" +log "INFO :: ============================================================" exit 0 - -# -- End of Script diff --git a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml index 50f37fb51..64b7cfc65 100644 --- a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml +++ b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml @@ -1,17 +1,17 @@ {{- if .Values.application_admin_role }} - {{- if and .Values.db2_backup_bucket_name (not (contains "sdb" .Values.db2_instance_name)) }} +{{- if and .Values.db2_backup_bucket_name (not (contains "sdb" .Values.db2_instance_name)) }} - {{- /* - Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. - */}} - {{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} +{{- /* +Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. +*/}} +{{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} - # - # CronJob for DB2 Audit Log Extraction - # Runs once a day at midnight to archive and extract DB2 audit logs as DEL/ASC - # files, upload them to the audit-log-// folder inside the - # backup bucket, then removes local copies. - # +# +# CronJob for DB2 Audit Log Extraction +# Runs once a day at midnight to archive and extract DB2 audit logs as DEL/ASC +# files, upload them to the audit-log-// folder inside the +# backup bucket, then removes local copies. +# --- kind: CronJob apiVersion: batch/v1 diff --git a/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml b/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml index 05476c2cb..47c51c27e 100644 --- a/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml +++ b/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml @@ -18,7 +18,7 @@ Meaningful prefix for the job resource name. Must be under 52 chars in length to Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. Included in $_job_hash (see below). */}} -{{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} +{{- $_cli_image_digest := "sha256:db6dba0d58592a1bbed459bbe8285316c36d0d8c0bf8b39e1d0f910b3400f441" }} {{- /* A dict of values that influence the behaviour of the job in some way. @@ -35,7 +35,7 @@ Increment this value whenever you make a change to an immutable field of the Job E.g. passing in a new environment variable. Included in $_job_hash (see below). */}} -{{- $_job_version := "v22" }} +{{- $_job_version := "v37" }} {{- /* 10 char hash appended to the job name taking into account $_job_config_values, $_job_version and $_cli_image_digest This is to ensure ArgoCD will create a new job resource intead of attempting (and failing) to update an @@ -889,6 +889,17 @@ spec: echo "--------------------------------------------------------------------------------" oc exec -n ${DB2_NAMESPACE} c-${DB2_INSTANCE_NAME}-db2u-0 -- su -lc "${SET_COS_STORAGE_SH_PATH} | tee /tmp/setcosstorage.log" db2inst1 || exit $? + echo "" + echo "Installing AWS CLI on c-${DB2_INSTANCE_NAME}-db2u-0 if not already present" + echo "--------------------------------------------------------------------------------" + aws_is_installed=`oc exec -n ${DB2_NAMESPACE} c-${DB2_INSTANCE_NAME}-db2u-0 -- su -lc "/mnt/backup/aws/dist/aws --version 2>&1 || true" db2inst1` + if [[ $aws_is_installed =~ 'not found' ]] || [[ -z $aws_is_installed ]]; then + oc exec -n ${DB2_NAMESPACE} c-${DB2_INSTANCE_NAME}-db2u-0 -- su -lc "cd /mnt/backup; curl 'https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip' -o 'awscliv2.zip'; unzip awscliv2.zip -d /mnt/backup/;" db2inst1 || exit $? + echo "AWS CLI installed at /mnt/backup/aws/dist/aws" + else + echo "AWS CLI already present: ${aws_is_installed}" + fi + CHECK_COS_STORAGE_SH_PATH="CheckCOS.sh" echo "" echo "Executing ${INSTHOME}/bin/CheckCOS.sh file on ${DB2_NAMESPACE}/c-${DB2_INSTANCE_NAME}-db2u-0" From 71d648b567a35e71f996f6139745b9f1d08f78fc Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 21 Aug 2026 15:35:02 +0530 Subject: [PATCH 04/10] MASCORE-16109: move AWS CLI install from postsync Job into db2AuditExtract.sh --- .../files/db2AuditExtract.sh | 16 +++++++++++----- .../templates/07-postsync-setup-db2_Job.yaml | 13 +------------ 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh index 49583d87e..f7ad4ffab 100644 --- a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh +++ b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh @@ -22,7 +22,7 @@ #% 10. Upload ALL files from /tmp/auditarchive to S3 #% 11. rm -rf /tmp/auditarchive #% 12. Delete the *.log.0.20* source files from /mnt/blumeta0/audit -#% 13. (Optional) Delete pre-existing *.del files from /mnt/blumeta0/audit +#% 13. (Conditional) Delete pre-existing *.del files from /mnt/blumeta0/audit #% (prints list before deleting) # ---------------------------------------------------------------------------- @@ -54,11 +54,17 @@ set -u # ── Load COS/S3 credentials (CONTAINER, SERVER, PARM1, PARM2) ───────────── . /mnt/backup/bin/.PROPS -# ── Configure AWS CLI ────────────────────────────────────────────────────── +# ── Install AWS CLI if not already present ──────────────────────────────── AWS_CLI="/mnt/backup/aws/dist/aws" -if [ ! -x "${AWS_CLI}" ]; then - log "ERROR :: AWS CLI not found at ${AWS_CLI} — trigger an ArgoCD sync to install it" - exit 1 +log "INFO :: Checking AWS CLI at ${AWS_CLI}" +if ! "${AWS_CLI}" --version >/dev/null 2>&1; then + log "INFO :: Not found — installing AWS CLI to /mnt/backup/" + cd /mnt/backup + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip -d /mnt/backup/ + log "INFO :: AWS CLI installed at ${AWS_CLI}" +else + log "INFO :: AWS CLI already present: $(${AWS_CLI} --version 2>&1)" fi export AWS_ACCESS_KEY_ID="${PARM1}" export AWS_SECRET_ACCESS_KEY="${PARM2}" diff --git a/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml b/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml index 47c51c27e..6288662a9 100644 --- a/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml +++ b/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml @@ -35,7 +35,7 @@ Increment this value whenever you make a change to an immutable field of the Job E.g. passing in a new environment variable. Included in $_job_hash (see below). */}} -{{- $_job_version := "v37" }} +{{- $_job_version := "v24" }} {{- /* 10 char hash appended to the job name taking into account $_job_config_values, $_job_version and $_cli_image_digest This is to ensure ArgoCD will create a new job resource intead of attempting (and failing) to update an @@ -889,17 +889,6 @@ spec: echo "--------------------------------------------------------------------------------" oc exec -n ${DB2_NAMESPACE} c-${DB2_INSTANCE_NAME}-db2u-0 -- su -lc "${SET_COS_STORAGE_SH_PATH} | tee /tmp/setcosstorage.log" db2inst1 || exit $? - echo "" - echo "Installing AWS CLI on c-${DB2_INSTANCE_NAME}-db2u-0 if not already present" - echo "--------------------------------------------------------------------------------" - aws_is_installed=`oc exec -n ${DB2_NAMESPACE} c-${DB2_INSTANCE_NAME}-db2u-0 -- su -lc "/mnt/backup/aws/dist/aws --version 2>&1 || true" db2inst1` - if [[ $aws_is_installed =~ 'not found' ]] || [[ -z $aws_is_installed ]]; then - oc exec -n ${DB2_NAMESPACE} c-${DB2_INSTANCE_NAME}-db2u-0 -- su -lc "cd /mnt/backup; curl 'https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip' -o 'awscliv2.zip'; unzip awscliv2.zip -d /mnt/backup/;" db2inst1 || exit $? - echo "AWS CLI installed at /mnt/backup/aws/dist/aws" - else - echo "AWS CLI already present: ${aws_is_installed}" - fi - CHECK_COS_STORAGE_SH_PATH="CheckCOS.sh" echo "" echo "Executing ${INSTHOME}/bin/CheckCOS.sh file on ${DB2_NAMESPACE}/c-${DB2_INSTANCE_NAME}-db2u-0" From c8e554e5ea4fa6f47d3ead7d990f267178347a7e Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 21 Aug 2026 16:22:39 +0530 Subject: [PATCH 05/10] MASCORE-16109: add missing README sections to pass verify-readme-structure hook --- .../120-ibm-db2u-database/README.md | 100 +++++++++++------- .../templates/07-postsync-setup-db2_Job.yaml | 4 +- .../120-ibm-db2u-database/values.yaml | 4 - .../deployed-values.yaml | 62 ----------- .../templates/output.yaml | 0 5 files changed, 64 insertions(+), 106 deletions(-) delete mode 100644 root-applications/ibm-mas-instance-root/deployed-values.yaml delete mode 100644 root-applications/ibm-mas-instance-root/templates/output.yaml diff --git a/instance-applications/120-ibm-db2u-database/README.md b/instance-applications/120-ibm-db2u-database/README.md index c79ca582a..0ba19cb18 100644 --- a/instance-applications/120-ibm-db2u-database/README.md +++ b/instance-applications/120-ibm-db2u-database/README.md @@ -6,28 +6,32 @@ Create a Db2u database for a MAS app. ## Overview -Creates a Db2u database instance for a MAS application. Includes a presync hook (`00-presync-await-crd_Job.yaml`) that ensures the `db2uclusters` CRD is installed before syncing, and a postsync job (`05-postsync-setup-db2_Job.yaml`) that registers the `${ACCOUNT_ID}/${CLUSTER_ID}/${MAS_INSTANCE_ID}/db2/${DB2_INSTANCE_NAME}/config` secret in the **Secrets Vault** and performs any Manage-specific database configuration steps. +This chart deploys and configures a Db2u database instance for use by a MAS application. It manages the full lifecycle of the database including TLS certificates, storage, backup, audit log extraction, and HADR services. + +Contains a presync hook (`00-presync-await-crd_Job.yaml`) that ensures we wait for the `db2uclusters` CRD to be installed before attempting to sync. + +Contains a job that runs last (`05-postsync-setup-db2_Job.yaml`). This registers the `${ACCOUNT_ID}/${CLUSTER_ID}/${MAS_INSTANCE_ID}/db2/${DB2_INSTANCE_NAME}/config` secret in the **Secrets Vault** used to share some information that is generated at runtime with other ArgoCD Applications. This job also performs some special configuration steps that are required if the Db2u database is intended for use by the Manage MAS Application. ## Resources Created -| Resource Type | Resource Name | Namespace | Condition | Installed By | -|--------------|---------------|-----------|-----------|--------------| -| `StorageClass` | Db2 storage class definitions | DB2 application namespace / cluster | When storage classes are managed by this chart | `application_admin_role` | -| `ServiceAccount` | Pre/post-sync DB2 job service accounts | DB2 application namespace | Always | `application_admin_role` | -| `Role` | Pre/post-sync DB2 job roles | DB2 application namespace and related namespaces | Always | `application_admin_role` | -| `RoleBinding` | Pre/post-sync DB2 job role bindings | DB2 application namespace and related namespaces | Always | `application_admin_role` | -| `Issuer` | DB2 TLS issuers | DB2 application namespace | Always | `application_admin_role` | -| `Certificate` | DB2 TLS certificates | DB2 application namespace | Always | `application_admin_role` | -| `Db2uInstance` | Db2u instance CR | DB2 application namespace | Always | `application_admin_role` | -| `CronJob` | Db2 backup cron job | DB2 application namespace | When backups are enabled (`db2_backup_bucket_name` set) | `application_admin_role` | -| `CronJob` | Db2 audit extract cron job | DB2 application namespace | When audit bucket is enabled (`db2_audit_bucket_name` set) | `application_admin_role` | -| `ConfigMap` | Db2 script/config maps | DB2 application namespace | Always | `application_admin_role` | -| `Route` | Db2 TLS route | DB2 application namespace | When route exposure is enabled | `application_admin_role` | -| `Service` | Db2 services, including HADR services | DB2 application namespace | Always | `application_admin_role` | -| `Service` | Private NLB service | DB2 application namespace | When `private_nlb.enabled` is true | `application_admin_role` | -| `Secret` | Post-sync DB2 generated secret | DB2 application namespace | Always | `application_admin_role` | -| `NetworkPolicy` | HADR network policy | DB2 application namespace | When HADR is enabled | `application_admin_role` | -| `Job` | Pre/post-sync DB2 setup jobs | DB2 application namespace | Always | `application_admin_role` | +| Resource Type | Resource Name | Namespace | Condition | Installed By | +|--------------|---------------|-----------|-------------------------------------------------------------|--------------| +| `StorageClass` | Db2 storage class definitions | DB2 application namespace / cluster | When storage classes are managed by this chart | `application_admin_role` | +| `ServiceAccount` | Pre/post-sync DB2 job service accounts | DB2 application namespace | Always | `application_admin_role` | +| `Role` | Pre/post-sync DB2 job roles | DB2 application namespace and related namespaces | Always | `application_admin_role` | +| `RoleBinding` | Pre/post-sync DB2 job role bindings | DB2 application namespace and related namespaces | Always | `application_admin_role` | +| `Issuer` | DB2 TLS issuers | DB2 application namespace | Always | `application_admin_role` | +| `Certificate` | DB2 TLS certificates | DB2 application namespace | Always | `application_admin_role` | +| `Db2uInstance` | Db2u instance CR | DB2 application namespace | Always | `application_admin_role` | +| `CronJob` | Db2 backup cron job | DB2 application namespace | When backups are enabled (`db2_backup_bucket_name` set) | `application_admin_role` | +| `CronJob` | Db2 audit extract cron job | DB2 application namespace | When backup bucket is enabled (`db2_audit_bucket_name` set) | `application_admin_role` | +| `ConfigMap` | Db2 script/config maps | DB2 application namespace | Always | `application_admin_role` | +| `Route` | Db2 TLS route | DB2 application namespace | When route exposure is enabled | `application_admin_role` | +| `Service` | Db2 services, including HADR services | DB2 application namespace | Always | `application_admin_role` | +| `Service` | Private NLB service | DB2 application namespace | When `private_nlb.enabled` is true | `application_admin_role` | +| `Secret` | Post-sync DB2 generated secret | DB2 application namespace | Always | `application_admin_role` | +| `NetworkPolicy` | HADR network policy | DB2 application namespace | When HADR is enabled | `application_admin_role` | +| `Job` | Pre/post-sync DB2 setup jobs | DB2 application namespace | Always | `application_admin_role` | ## Configuration @@ -126,12 +130,6 @@ db2_backup_bucket_secret_key: string (secret reference, when backup enabled) db2_backup_notify_slack_url: string (optional, when backup enabled) db2_backup_icd_auth_key: string (secret reference, optional, when backup enabled) -# Audit Extraction Configuration (optional) -# When db2_audit_bucket_name is set, a daily CronJob is created in the db2 namespace -# that archives and extracts DB2 audit logs as DEL/ASC files and uploads them to the -# specified S3 bucket, then removes all local copies. -db2_audit_bucket_name: string (secret reference, when audit extraction enabled) - allow_list: string (optional) # Private NLB for customer TGW connectivity (optional) @@ -213,26 +211,52 @@ The NLB is created independently for each instance (e.g. facilities, manage) usi If `private_nlb.enabled: true` and either `subnet_ids` or `allowed_cidrs` is empty, Helm will fail immediately with a clear error message before rendering -any resources. This prevents a broken or unrestricted NLB from being deployed.. +any resources. This prevents a broken or unrestricted NLB from being deployed. + +## Prerequisites + +- The `db2uclusters` CRD must be available on the cluster (ensured by the presync hook). +- An S3-compatible backup bucket must be provisioned when backup or audit log upload is enabled. +- Secrets for S3 credentials, cluster domain, and Secrets Manager access must be pre-populated in the Secrets Vault before sync. ## Examples -### Minimal — Manage database with backup and audit extraction enabled +### Minimal deployment ```yaml -db2_namespace: mas-inst1-manage-db2u -db2_instance_name: db2wh-manage +db2_namespace: db2u-manage +db2_instance_name: db2u-manage db2_dbname: BLUDB -db2_instance_home_path: /mnt/blumeta0/home/db2inst1 +db2_version: "11.5.9.0" +db2_tls_version: "1.2" +db2_table_org: ROW mas_application_id: manage -instance_id: inst1 +cluster_domain: "" +``` -# Backup -db2_backup_bucket_name: "" -db2_backup_bucket_endpoint: "" -db2_backup_bucket_access_key: "" -db2_backup_bucket_secret_key: "" +### With backup and audit log upload enabled -# Audit extraction — daily CronJob uploads delasc files to audit-log-manage// -db2_audit_bucket_name: "" +```yaml +db2_namespace: db2u-manage +db2_instance_name: db2u-manage +db2_dbname: BLUDB +db2_backup_bucket_name: "" +db2_backup_bucket_endpoint: "" +db2_backup_bucket_access_key: "" +db2_backup_bucket_secret_key: "" +auto_backup: true +mas_application_id: manage +cluster_domain: "" ``` + +## Troubleshooting + +- **Presync job stuck** — verify the `db2uclusters` CRD is installed by the DB2U operator before the ArgoCD sync wave reaches this chart. +- **Postsync job failing** — check the job logs in the DB2 namespace; common causes are missing S3 credentials or an unreachable backup bucket. +- **Audit CronJob not running** — confirm `db2_backup_bucket_name` is set and the instance name does not contain `sdb` (audit cron is disabled for SDB instances). +- **AWS CLI missing** — `db2AuditExtract.sh` will install the AWS CLI automatically on first run via `curl`/`unzip` into `/mnt/backup/`. + +## Related Documentation + +- [Instance Base Values Reference](../../docs/reference/instance-base-values.md) +- [IBM Db2u Operator Documentation](https://www.ibm.com/docs/en/db2/11.5) diff --git a/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml b/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml index 6288662a9..efaef34ff 100644 --- a/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml +++ b/instance-applications/120-ibm-db2u-database/templates/07-postsync-setup-db2_Job.yaml @@ -18,7 +18,7 @@ Meaningful prefix for the job resource name. Must be under 52 chars in length to Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. Included in $_job_hash (see below). */}} -{{- $_cli_image_digest := "sha256:db6dba0d58592a1bbed459bbe8285316c36d0d8c0bf8b39e1d0f910b3400f441" }} +{{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} {{- /* A dict of values that influence the behaviour of the job in some way. @@ -35,7 +35,7 @@ Increment this value whenever you make a change to an immutable field of the Job E.g. passing in a new environment variable. Included in $_job_hash (see below). */}} -{{- $_job_version := "v24" }} +{{- $_job_version := "v23" }} {{- /* 10 char hash appended to the job name taking into account $_job_config_values, $_job_version and $_cli_image_digest This is to ensure ArgoCD will create a new job resource intead of attempting (and failing) to update an diff --git a/instance-applications/120-ibm-db2u-database/values.yaml b/instance-applications/120-ibm-db2u-database/values.yaml index 5574366ae..e8767691a 100644 --- a/instance-applications/120-ibm-db2u-database/values.yaml +++ b/instance-applications/120-ibm-db2u-database/values.yaml @@ -7,10 +7,6 @@ db2_instance_home_path: /mnt/blumeta0/home/db2inst1 sm_aws_access_key_id: xxx sm_aws_secret_access_key: xxxx -# Audit Bucket Configuration (optional) -# When set, a daily CronJob will archive and extract audit logs to this S3 bucket. -db2_audit_bucket_name: "" - # Private NLB for customer TGW connectivity (A.4 Option 2) # When enabled, ROSA provisions an internal AWS NLB in the specified subnets. # ROSA automatically manages the required EC2 worker node security group rules. diff --git a/root-applications/ibm-mas-instance-root/deployed-values.yaml b/root-applications/ibm-mas-instance-root/deployed-values.yaml deleted file mode 100644 index aee91c628..000000000 --- a/root-applications/ibm-mas-instance-root/deployed-values.yaml +++ /dev/null @@ -1,62 +0,0 @@ -USER-SUPPLIED VALUES: -HANodeConfig: - nodeRoles: '"master"' -annotationWhitelist: - containerSpec: "" - namespace: "" - workloadController: "" -annotations: - kubeturbo.io/controllable: "false" -args: - cleanupSccImpersonationResources: true - discoveryIntervalSec: 600 - discoverySampleIntervalSec: 60 - discoverySamples: 10 - discoveryTimeoutSec: 180 - discoveryWorkers: 10 - garbageCollectionIntervalMin: 10 - kubelethttps: true - kubeletport: 10250 - logginglevel: 2 - pre16k8sVersion: false - sccsupport: '*' - skipCreatingSccImpersonationResources: false - stitchuuid: true -daemonPodDetectors: - namespacePatterns: [] - podNamePatterns: [] -discovery: - chunkSendDelayMillis: 0 - numObjectsPerChunk: 5000 -image: - pullPolicy: IfNotPresent - related: "" - repository: icr.io/cpopen/turbonomic/kubeturbo -logging: - level: 2 -nodePoolSize: - max: 1000 - min: 1 -replicaCount: 1 -resources: {} -restAPIConfig: - turbonomicCredentialsSecretName: turbonomic-credentials -roleBinding: turbo-all-binding -roleName: cluster-admin -sdkProtocolConfig: - registrationTimeoutSec: 300 - restartOnRegistrationTimeout: true -serverMeta: - turboServer: https://ibm.turbonomic.io - version: 8.13.4 -serviceAccountName: turbo-user -systemWorkloadDetectors: - namespacePatterns: - - kube-.* - - openshift-.* - - cattle.* -targetConfig: - targetName: noble7_1613 -wiremock: - enabled: false - url: wiremock:8080 diff --git a/root-applications/ibm-mas-instance-root/templates/output.yaml b/root-applications/ibm-mas-instance-root/templates/output.yaml deleted file mode 100644 index e69de29bb..000000000 From 52c4d6a553e36ffe60119ac983a7a9101dc4ecaf Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 21 Aug 2026 17:01:38 +0530 Subject: [PATCH 06/10] updated CLI version --- .../120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml index 64b7cfc65..7ed3339f2 100644 --- a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml +++ b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml @@ -4,7 +4,7 @@ {{- /* Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. */}} -{{- $_cli_image_digest := "sha256:887cc3059a04601241687711df0c03d662931e6719121eec0eb0490001b2c8b9" }} +{{- $_cli_image_digest := "sha256:db6dba0d58592a1bbed459bbe8285316c36d0d8c0bf8b39e1d0f910b3400f441" }} # # CronJob for DB2 Audit Log Extraction From c287b1ef277ecc466c34dbae24990b7e3cf44487 Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 21 Aug 2026 17:28:11 +0530 Subject: [PATCH 07/10] DID DBName dynamic --- .../120-ibm-db2u-database/files/db2AuditExtract.sh | 4 ++-- .../120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh index f7ad4ffab..b69e794e4 100644 --- a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh +++ b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh @@ -7,7 +7,7 @@ #% #% ** THIS MUST BE RUN AS THE DB2 INSTANCE OWNER (db2inst1) ** #% -#% USAGE: db2AuditExtract.sh +#% USAGE: db2AuditExtract.sh [dbname] #% #% Steps: #% 1. mkdir /tmp/auditarchive @@ -41,7 +41,7 @@ fi # ── Constants ────────────────────────────────────────────────────────────── ARCHIVE_DIR="/tmp/auditarchive" AUDIT_BASE="/mnt/blumeta0/audit" -DBNAME="BLUDB" +DBNAME="${2:-BLUDB}" # Passed as 2nd arg from CronJob; falls back to BLUDB DATE=$(date +"%Y-%m-%d") DT=$(date +"%Y-%m-%d_%H%M%S") DELETE_AUDIT_BASE_DEL="false" # Set to "true" to delete *.del files from ${AUDIT_BASE} (step 13) diff --git a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml index 7ed3339f2..35799ca02 100644 --- a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml +++ b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml @@ -45,7 +45,7 @@ spec: - "c-{{ .Values.db2_instance_name }}-db2u-0" - su - -lc - - "{{ .Values.db2_instance_home_path }}/bin/db2AuditExtract.sh {{ .Values.mas_application_id }}" + - "{{ .Values.db2_instance_home_path }}/bin/db2AuditExtract.sh {{ .Values.mas_application_id }} {{ .Values.db2_dbname }}" - db2inst1 imagePullPolicy: IfNotPresent restartPolicy: OnFailure From 25e282ad26b124fd646dcac08223a63e89e7a1b3 Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 21 Aug 2026 17:28:59 +0530 Subject: [PATCH 08/10] updated SYNC_wave to 132 after audit policy --- .../120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml index 35799ca02..91957df46 100644 --- a/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml +++ b/instance-applications/120-ibm-db2u-database/templates/04-db2u-Audit_Cron.yaml @@ -24,7 +24,7 @@ metadata: db2pod: "c-{{ .Values.db2_instance_name }}-db2u-0" mas.ibm.com/instanceId: "{{ .Values.instance_id }}" annotations: - argocd.argoproj.io/sync-wave: "130" + argocd.argoproj.io/sync-wave: "132" spec: # Run once a day at midnight (00:00 UTC) schedule: '0 0 * * *' From 5d3d8eb7f3ef08bb4bcd9d59dd52dcfdaf28a64e Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Fri, 21 Aug 2026 17:44:55 +0530 Subject: [PATCH 09/10] sync with main --- root-applications/ibm-mas-instance-root/output.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 root-applications/ibm-mas-instance-root/output.yaml diff --git a/root-applications/ibm-mas-instance-root/output.yaml b/root-applications/ibm-mas-instance-root/output.yaml deleted file mode 100644 index e69de29bb..000000000 From 7c6b3b47a8572efca4b689abf96c508f3c37215b Mon Sep 17 00:00:00 2001 From: "sumit.jain6" Date: Mon, 24 Aug 2026 11:53:44 +0530 Subject: [PATCH 10/10] updated script - added more checks to check files before processing --- .../files/db2AuditExtract.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh index b69e794e4..4f9f985d7 100644 --- a/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh +++ b/instance-applications/120-ibm-db2u-database/files/db2AuditExtract.sh @@ -114,15 +114,23 @@ db2audit archive to "${ARCHIVE_DIR}" # 6. Extract archived database log → *.del # ============================================================================ log "INFO :: [6] db2audit extract delasc (database log)" -db2audit extract delasc to "${ARCHIVE_DIR}" \ - from files "${ARCHIVE_DIR}/db2audit.db.${DBNAME}.log.0."* +DB_LOGS=$(ls "${ARCHIVE_DIR}"/db2audit.db."${DBNAME}".log.0.* 2>/dev/null || true) +if [ -z "${DB_LOGS}" ]; then + log "WARN :: No database archive log found in ${ARCHIVE_DIR} — skipping extract" +else + db2audit extract delasc to "${ARCHIVE_DIR}" from files ${DB_LOGS} +fi # ============================================================================ # 7. Extract archived instance log → *.del # ============================================================================ log "INFO :: [7] db2audit extract delasc (instance log)" -db2audit extract delasc to "${ARCHIVE_DIR}" \ - from files "${ARCHIVE_DIR}/db2audit.instance.log.0."* +INST_LOGS=$(ls "${ARCHIVE_DIR}"/db2audit.instance.log.0.* 2>/dev/null || true) +if [ -z "${INST_LOGS}" ]; then + log "WARN :: No instance archive log found in ${ARCHIVE_DIR} — skipping extract" +else + db2audit extract delasc to "${ARCHIVE_DIR}" from files ${INST_LOGS} +fi # ============================================================================ # 8–9. Copy historical log files from /mnt/blumeta0/audit to /tmp/auditarchive @@ -209,4 +217,4 @@ log "INFO :: ============================================================" log "INFO :: Audit extraction completed successfully" log "INFO :: S3 target : ${S3_TARGET}" log "INFO :: ============================================================" -exit 0 +exit 0 \ No newline at end of file