diff --git a/instance-applications/120-ibm-dbs-rds-database/templates/00-presync-create-database.yaml b/instance-applications/120-ibm-dbs-rds-database/templates/00-presync-create-database.yaml new file mode 100644 index 000000000..6fd682004 --- /dev/null +++ b/instance-applications/120-ibm-dbs-rds-database/templates/00-presync-create-database.yaml @@ -0,0 +1,270 @@ +{{- if .Values.application_admin_role }} +{{- $_job_name_prefix := "dbs-rds-presync-create-db" }} +{{- $_cli_image_digest := "sha256:100bcfef43b0ab0e266c1a316637e23640d2c57509d643bcf4d7f256c0b6ba4a" }} +{{- $_job_config_values := omit .Values "junitreporter" }} +{{- $_job_version := "v1" }} +{{- $_job_hash := print ($_job_config_values | toYaml) $_cli_image_digest $_job_version | adler32sum }} +{{- $_job_name := join "-" (list $_job_name_prefix $_job_hash ) }} +{{- $_job_cleanup_group := cat $_job_name_prefix .Values.db2_rds_instance_name | sha1sum }} + +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ .Values.db2_rds_instance_name }}-create-db-secret + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/hook-delete-policy: HookSucceeded,HookFailed,BeforeHookCreation + {{- if .Values.custom_labels }} +labels: + {{ .Values.custom_labels | toYaml | indent 4 }} + {{- end }} +data: + username: {{ .Values.user | b64enc }} + password: {{ .Values.password | b64enc }} + +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ .Values.db2_rds_instance_name }}-aws-creds + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/hook-delete-policy: HookSucceeded,HookFailed,BeforeHookCreation + {{- if .Values.custom_labels }} + labels: + {{ .Values.custom_labels | toYaml | indent 4 }} + {{- end }} +data: + aws_access_key_id: {{ .Values.sm_aws_access_key_id | b64enc }} + aws_secret_access_key: {{ .Values.sm_aws_secret_access_key | b64enc }} + +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ $_job_name }} + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/hook-delete-policy: HookSucceeded,BeforeHookCreation + labels: + mas.ibm.com/job-cleanup-group: {{ $_job_cleanup_group }} + {{- if .Values.custom_labels }} + {{ .Values.custom_labels | toYaml | indent 4 }} + {{- end }} +spec: + backoffLimit: 4 + template: + {{- if .Values.custom_labels }} + metadata: + labels: + {{ .Values.custom_labels | toYaml | indent 8 }} + {{- end }} + spec: + restartPolicy: Never + containers: + - name: create-database + image: quay.io/ibmmas/cli@{{ $_cli_image_digest }} + resources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 10m + memory: 64Mi + command: ["/bin/sh", "-c"] + args: + - | + set -eo pipefail + + source /mascli/functions/gitops_utils + + echo "==== DB2 RDS Idempotent Provisioning ====" + echo "" + echo "📋 Input Parameters:" + echo " AWS Account: ${ACCOUNT_ID}" + echo " Cluster ID: ${CLUSTER_ID}" + echo " Instance ID: ${INSTANCE_ID}" + echo " MAS App ID: ${MAS_APP_ID}" + echo " DB Name (env): ${DB_NAME}" + echo " DB Host: ${DB_HOST}" + echo " DB Port: ${DB_PORT}" + echo " RDS Admin DB: ${RDS_ADMIN_DB}" + echo "" + + # ----------------------------- + # Determine DB_NAME (if not provided, generate it) + # ----------------------------- + if [ -z "${DB_NAME:-}" ]; then + echo "â„šī¸ No DB_NAME provided, generating deterministic DB name" + + # Normalize INSTANCE_ID: + # - uppercase + # - remove non-alphanumeric + INST_CLEAN=$(echo "${INSTANCE_ID:-}" \ + | tr '[:lower:]' '[:upper:]' \ + | tr -cd 'A-Z0-9') + + # Normalize MAS_APP_ID: + # - remove vowels + # - uppercase + # - remove non-alphanumeric + APP_CLEAN=$(echo "${MAS_APP_ID:-}" \ + | tr -d 'aeiouAEIOU' \ + | tr '[:lower:]' '[:upper:]' \ + | tr -cd 'A-Z0-9') + + # Safety: if app name becomes empty after vowel removal, use default + if [ -z "${APP_CLEAN}" ]; then + APP_CLEAN="APP" + fi + + # Build fixed-width parts + INST_PART=$(printf "%-5s" "${INST_CLEAN}" | tr ' ' 'X' | cut -c1-5) + APP_PART=$(printf "%-3s" "${APP_CLEAN}" | tr ' ' 'X' | cut -c1-3) + + DB_NAME="${INST_PART}${APP_PART}" + + # Ensure DB name starts with a letter (DB2-safe) + case "${DB_NAME}" in + [A-Z]*) + ;; + *) + DB_NAME="D${DB_NAME:1}" + ;; + esac + else + echo "â„šī¸ Using provided DB_NAME: ${DB_NAME}" + fi + + export DB_NAME + + # ----------------------------- + # Verify pre-installed dependencies + # ----------------------------- + echo "Verifying ibm_db package..." + python3 -c "import ibm_db; print('✅ ibm_db version:', ibm_db.__version__)" + + mkdir -p /etc/mas/rds-ssl + curl -sSL https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem \ + -o /etc/mas/rds-ssl/global-bundle.pem + + export SSL_CERT_PATH=/etc/mas/rds-ssl/global-bundle.pem + + # ----------------------------- + # Database Existence Check & Creation + # ----------------------------- + echo "Checking if database '${DB_NAME}' exists..." + + echo "Running database creation script..." + python3 -u /etc/mas/scripts/db2_create_database.py 2>&1 | tee /tmp/db_output.log + RC=${PIPESTATUS[0]} + + echo "Script execution completed with rc=${RC}" + + case "${RC}" in + 10) + DB_WAS_CREATED=true + echo "✅ Database '${DB_NAME}' was created" + ;; + 0) + DB_WAS_CREATED=false + echo "â„šī¸ Database '${DB_NAME}' already exists" + ;; + *) + echo "❌ Database operation failed with exit code ${RC}" + cat /tmp/db_output.log + exit 1 + ;; + esac + + # ----------------------------- + # Update Secrets Manager (using sm_* functions like create user Job) + # ----------------------------- + echo "Checking if Secrets Manager needs updating..." + + export SM_AWS_ACCESS_KEY_ID=$(cat /etc/mas/creds/aws/aws_access_key_id) + export SM_AWS_SECRET_ACCESS_KEY=$(cat /etc/mas/creds/aws/aws_secret_access_key) + export SM_AWS_REGION=${SM_AWS_SECRET_REGION} + + sm_login + + SECRET_PATH="${ACCOUNT_ID}/${CLUSTER_ID}/${INSTANCE_ID}/jdbc/{{ .Values.db2_rds_instance_name }}/config" + + EXISTING_SECRET=$(sm_get_secret_value "${SECRET_PATH}" 2>/dev/null || echo "{}") + + # Validate JSON + if ! echo "${EXISTING_SECRET}" | jq empty >/dev/null 2>&1; then + echo "âš ī¸ Invalid JSON from Secrets Manager, using empty object" + EXISTING_SECRET="{}" + fi + + # Check if db2_name is already set correctly + EXISTING_DB_NAME=$(echo "${EXISTING_SECRET}" | jq -r '.db2_name // empty') + + if [ "$DB_WAS_CREATED" = "true" ] || [ -z "${EXISTING_DB_NAME}" ] || [ "${EXISTING_DB_NAME}" != "${DB_NAME}" ]; then + echo "Updating Secrets Manager..." + echo " Reason: DB_WAS_CREATED=${DB_WAS_CREATED}, EXISTING_DB_NAME='${EXISTING_DB_NAME}', DB_NAME='${DB_NAME}'" + + NEW_SECRET=$(echo "${EXISTING_SECRET}" | jq --arg db "${DB_NAME}" '. + {db2_name: $db}') + + if [ -n "${JDBC_CONNECTION_URL:-}" ]; then + NEW_URL=$(printf '%s\n' "${JDBC_CONNECTION_URL:-}" | sed -E "s|(jdbc:db2://[^/]+/)([^:]*)(:.*)?$|\\1${DB_NAME}\\3|") + NEW_SECRET=$(echo "${NEW_SECRET}" | jq --arg url "${NEW_URL}" '. + {jdbc_connection_url: $url}') + fi + + # Tags for Secrets Manager + TAGS="[{\"Key\": \"source\", \"Value\": \"presync-create-database\"}, {\"Key\": \"account\", \"Value\": \"${ACCOUNT_ID}\"}, {\"Key\": \"cluster\", \"Value\": \"${CLUSTER_ID}\"}, {\"Key\": \"instance\", \"Value\": \"${INSTANCE_ID}\"}, {\"Key\": \"app\", \"Value\": \"${MAS_APP_ID}\"}, {\"Key\": \"db_name\", \"Value\": \"${DB_NAME}\"}]" + + sm_update_secret "${SECRET_PATH}" "${NEW_SECRET}" "${TAGS}" + echo "✓ Secrets Manager updated with db2_name: ${DB_NAME}" + else + echo "â„šī¸ Secrets Manager already has correct db2_name: ${EXISTING_DB_NAME}" + fi + + echo "==== COMPLETED ====" + env: + - name: DB_NAME + value: {{ .Values.dbname | default "" | quote }} + - name: DB_HOST + value: {{ .Values.host | quote }} + - name: DB_PORT + value: {{ .Values.port | default "50000" | quote }} + - name: RDS_ADMIN_DB + value: {{ .Values.rds_admin_db_name | default "rdsadmin" | quote }} + - name: JDBC_CONNECTION_URL + value: {{ .Values.jdbc_connection_url | default "" | quote }} + - name: ACCOUNT_ID + value: {{ .Values.account_id | quote }} + - name: CLUSTER_ID + value: {{ .Values.cluster_id | quote }} + - name: INSTANCE_ID + value: {{ .Values.instance_id | quote }} + - name: MAS_APP_ID + value: {{ .Values.mas_application_id | default "" | quote }} + - name: SM_AWS_SECRET_REGION + value: {{ .Values.sm_aws_secret_region | default "us-east-1" | quote }} + - name: AWS_DEFAULT_REGION + value: {{ .Values.sm_aws_secret_region | default "us-east-1" | quote }} + volumeMounts: + - name: dbs-rds-create-db-secret + mountPath: /etc/mas/dbs-rds-creds/ + - name: aws + mountPath: /etc/mas/creds/aws + - name: create-db-script + mountPath: /etc/mas/scripts/ + volumes: + - name: dbs-rds-create-db-secret + secret: + secretName: {{ .Values.db2_rds_instance_name }}-create-db-secret + - name: aws + secret: + secretName: {{ .Values.db2_rds_instance_name }}-aws-creds + - name: create-db-script + configMap: + name: {{ .Values.db2_rds_instance_name }}-create-db-script + defaultMode: 0755 + +{{- end }} diff --git a/instance-applications/120-ibm-dbs-rds-database/templates/00-presync-script-create-database-job.yaml b/instance-applications/120-ibm-dbs-rds-database/templates/00-presync-script-create-database-job.yaml new file mode 100644 index 000000000..c0f0de271 --- /dev/null +++ b/instance-applications/120-ibm-dbs-rds-database/templates/00-presync-script-create-database-job.yaml @@ -0,0 +1,182 @@ +{{- if .Values.application_admin_role }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.db2_rds_instance_name }}-create-db-script + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/hook-delete-policy: HookSucceeded,BeforeHookCreation + {{- if .Values.custom_labels }} + labels: + {{ .Values.custom_labels | toYaml | indent 4 }} + {{- end }} +data: + db2_create_database.py: | + #!/usr/bin/env python3 + import ibm_db as db2 + import os, sys, re, time, json + + def log(msg): + print(json.dumps(msg)) + + def validate_db_name(db_name): + """Validate database name to prevent SQL injection.""" + if not re.fullmatch(r"[A-Za-z0-9_]+", db_name): + raise ValueError(f"Invalid DB name: {db_name}") + + def database_exists(db_name, db_host, db_port, username, password, ssl_cert_path, ssl_version): + try: + conn_str = ( + f"DATABASE={db_name};" + f"HOSTNAME={db_host};" + f"PORT={db_port};" + f"PROTOCOL=TCPIP;" + f"UID={username};" + f"PWD={password};" + f"Security=SSL;" + f"SSLServerCertificate={ssl_cert_path};" + f"SSLVersion={ssl_version};" + ) + conn = db2.connect(conn_str, "", "") + db2.close(conn) + return True + + except Exception as e: + msg = str(e) + + if any(code in msg for code in ["SQL1013N","SQLSTATE=42705","SQL30061N","SQLSTATE=08004"]): + return False + + # Auth failure - may indicate DB exists but credentials changed + # Only assume exists if explicitly enabled via env var + if "SQL30082N" in msg: + assume_exists = os.getenv("ASSUME_EXISTS_ON_AUTH_FAILURE", "false").lower() == "true" + log({"event":"auth_failure","db":db_name,"assume_exists":assume_exists}) + return assume_exists + + raise RuntimeError(f"Unknown error determining DB existence: {msg}") + + def wait_for_db(db_name, timeout, interval, *args): + # Ensure at least one retry even if timeout < interval + retries = max(1, timeout // interval) + + for i in range(retries): + time.sleep(interval) + try: + if database_exists(db_name, *args): + return True + except RuntimeError as e: + msg = str(e) + + if any(x in msg for x in ["SQLSTATE=57019","SQL1035N","SQL30081N"]): + log({"event":"retry","attempt":i+1}) + continue + raise + + return False + + def main(): + conn = None + try: + # Read credentials + username = open("/etc/mas/dbs-rds-creds/username").read().strip() + password = open("/etc/mas/dbs-rds-creds/password").read().strip() + + # Get environment variables + db_name = os.getenv("DB_NAME") + db_host = os.getenv("DB_HOST") + db_port = os.getenv("DB_PORT","50000") + rds_admin_db = os.getenv("RDS_ADMIN_DB","rdsadmin") + jdbc_url = os.getenv("JDBC_CONNECTION_URL","") + ssl_cert_path = os.getenv("SSL_CERT_PATH","/etc/mas/rds-ssl/global-bundle.pem") + + # Validate required environment variables + required = { + "DB_NAME": db_name, + "DB_HOST": db_host, + } + missing = [k for k, v in required.items() if not v] + if missing: + log({"event":"missing_env","vars":missing}) + sys.exit(1) + + # Validate database name (SQL injection prevention) + validate_db_name(db_name) + + timeout = int(os.getenv("DB_CREATE_TIMEOUT_SECONDS","600")) + interval = int(os.getenv("DB_POLL_INTERVAL_SECONDS","10")) + + ssl_version = "TLSv1.2" + if jdbc_url: + m = re.search(r'sslVersion=([^;]+)', jdbc_url, re.IGNORECASE) + if m: + ssl_version = m.group(1) + + log({"event":"start","db":db_name}) + + admin_conn_str = ( + f"DATABASE={rds_admin_db};" + f"HOSTNAME={db_host};" + f"PORT={db_port};" + f"PROTOCOL=TCPIP;" + f"UID={username};" + f"PWD={password};" + f"Security=SSL;" + f"SSLServerCertificate={ssl_cert_path};" + f"SSLVersion={ssl_version};" + ) + + try: + conn = db2.connect(admin_conn_str,"","") + except Exception as e: + log({"event":"connect_failed","error":str(e)}) + sys.exit(1) + + # 🔁 ALWAYS check real state + exists = database_exists(db_name, db_host, db_port, username, password, ssl_cert_path, ssl_version) + + if exists: + log({"event":"db_exists","db":db_name}) + log({"event":"complete","db":db_name,"action":"none"}) + sys.exit(0) # Exit code 0: database already exists + else: + log({"event":"create_start","db":db_name}) + + try: + # Safe: db_name validated with regex above + db2.exec_immediate(conn, f"CALL rdsadmin.create_database('{db_name}')") + except Exception as e: + msg = str(e) + # Handle race condition (another job created it) + # SQLSTATE=42710: Duplicate object (semantic duplicate-object condition) + # SQLCODE=-601: Commonly paired with duplicate object creation + if any(x in msg for x in ["SQLSTATE=42710", "SQLCODE=-601"]): + log({"event":"race_condition_detected","db":db_name}) + log({"event":"complete","db":db_name,"action":"none"}) + sys.exit(0) # Exit code 0: database exists (race condition) + + log({"event":"create_failed","error":msg}) + sys.exit(1) # Exit code 1: error + + if not wait_for_db(db_name, timeout, interval, db_host, db_port, username, password, ssl_cert_path, ssl_version): + log({"event":"timeout","db":db_name}) + sys.exit(1) # Exit code 1: timeout + + log({"event":"create_complete","db":db_name}) + log({"event":"complete","db":db_name,"action":"created"}) + sys.exit(10) # Exit code 10: database was created + + finally: + # Always close connection on exit + if conn: + try: + db2.close(conn) + except: + pass + + if __name__ == "__main__": + main() + + +{{- end }} diff --git a/instance-applications/120-ibm-dbs-rds-database/templates/01-dbs-rds-postsync-setup.yaml b/instance-applications/120-ibm-dbs-rds-database/templates/01-dbs-rds-postsync-setup.yaml index aa3d2638c..15bc0b58e 100644 --- a/instance-applications/120-ibm-dbs-rds-database/templates/01-dbs-rds-postsync-setup.yaml +++ b/instance-applications/120-ibm-dbs-rds-database/templates/01-dbs-rds-postsync-setup.yaml @@ -8,7 +8,7 @@ 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:4636b74525a46ebd88cd540794e8e23143f0112ea85149f9dfc78d02704ad5a6" }} +{{- $_cli_image_digest := "sha256:100bcfef43b0ab0e266c1a316637e23640d2c57509d643bcf4d7f256c0b6ba4a" }} {{- /* A dict of values that influence the behaviour of the job in some way. @@ -111,7 +111,9 @@ spec: echo "✅ Certificate downloaded to /etc/mas/rds-ssl/global-bundle.pem" - pip install ibm_db && \ + echo "Verifying ibm_db package..." + python3 -c "import ibm_db; print('✅ ibm_db version:', ibm_db.__version__)" + export SSL_CERT_PATH=/etc/mas/rds-ssl/global-bundle.pem && \ python /etc/mas/dbs-rds-init-script/dbs-rds-init.py env: diff --git a/instance-applications/120-ibm-dbs-rds-database/templates/03-backup-cronjobs.yaml b/instance-applications/120-ibm-dbs-rds-database/templates/03-backup-cronjobs.yaml index 85fd83ac1..907ec02d7 100644 --- a/instance-applications/120-ibm-dbs-rds-database/templates/03-backup-cronjobs.yaml +++ b/instance-applications/120-ibm-dbs-rds-database/templates/03-backup-cronjobs.yaml @@ -2,7 +2,7 @@ {{- /* Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. */}} -{{- $_cli_image_digest := "sha256:4636b74525a46ebd88cd540794e8e23143f0112ea85149f9dfc78d02704ad5a6" }} +{{- $_cli_image_digest := "sha256:100bcfef43b0ab0e266c1a316637e23640d2c57509d643bcf4d7f256c0b6ba4a" }} --- # Full Backup CronJob (Sundays at 2 AM) diff --git a/instance-applications/120-ibm-dbs-rds-database/values.yaml b/instance-applications/120-ibm-dbs-rds-database/values.yaml index ce99a4970..20014ed82 100644 --- a/instance-applications/120-ibm-dbs-rds-database/values.yaml +++ b/instance-applications/120-ibm-dbs-rds-database/values.yaml @@ -1,3 +1,13 @@ +# Account/Cluster/Instance identifiers (for Secrets Manager) +account_id: "xxx" +cluster_id: "xxx" +instance_id: "xxx" + +# AWS Secrets Manager configuration +sm_aws_access_key_id: "xxx" +sm_aws_secret_access_key: "xxx" +sm_aws_secret_region: "us-east-1" + # Basic connection configuration rds_admin_db_name: "rdsadmin" host: "xyz.db" @@ -8,7 +18,7 @@ password: "dummy" # Additional basic values db2_namespace: "" -mas_application_id: "" # manage, facilities, or iot +mas_application_id: "" jdbc_connection_url: "" replica_db: false diff --git a/instance-applications/130-ibm-jdbc-config/templates/00-presync-create-db2-rds-user-Job.yaml b/instance-applications/130-ibm-jdbc-config/templates/00-presync-create-db2-rds-user-Job.yaml index d7afb9691..6678736fc 100644 --- a/instance-applications/130-ibm-jdbc-config/templates/00-presync-create-db2-rds-user-Job.yaml +++ b/instance-applications/130-ibm-jdbc-config/templates/00-presync-create-db2-rds-user-Job.yaml @@ -3,7 +3,7 @@ {{- /* Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. */}} - {{- $_cli_image_digest := "sha256:4636b74525a46ebd88cd540794e8e23143f0112ea85149f9dfc78d02704ad5a6" }} + {{- $_cli_image_digest := "sha256:100bcfef43b0ab0e266c1a316637e23640d2c57509d643bcf4d7f256c0b6ba4a" }} {{ $ns := printf "mas-%s-core" .Values.instance_id }} {{ $prefix := printf "pre-jdbc-create-user-%s" .Values.mas_config_name }} @@ -133,7 +133,7 @@ spec: echo "" echo "================================================================================" - echo "Settings" + echo "Settings (2026-05-11-v8-final)" echo "================================================================================" echo "ACCOUNT_ID .......................... ${ACCOUNT_ID}" echo "REGION_ID ........................... ${REGION_ID}" @@ -148,10 +148,11 @@ spec: export SM_AWS_SECRET_ACCESS_KEY=$(cat /etc/mas/creds/aws/aws_secret_access_key) export SM_AWS_REGION=${REGION_ID} - echo "" - echo "Installing required Python packages..." - echo "--------------------------------------------------------------------------------" - pip install ibm_db + # ----------------------------- + # Verify pre-installed dependencies + # ----------------------------- + echo "Verifying ibm_db package..." + python3 -c "import ibm_db; print('✅ ibm_db version:', ibm_db.__version__)" echo "" echo "Downloading RDS SSL certificate..." @@ -273,7 +274,7 @@ spec: # 1. Admin users: We CREATE these with DBADM (for schema management) # Validate MAS_APP_ID - valid_apps = ['manage', 'facilities', 'iot'] + valid_apps = ['manage', 'facilities', 'iot', 'monitor'] if mas_app_id not in valid_apps: print(f"Unknown MAS_APP_ID: {mas_app_id}") sys.exit(1) diff --git a/instance-applications/510-550-ibm-mas-suite-app-config/templates/703-postsync-rds-app-roles.yaml b/instance-applications/510-550-ibm-mas-suite-app-config/templates/703-postsync-rds-app-roles.yaml index e667c5f2a..8570a06fc 100644 --- a/instance-applications/510-550-ibm-mas-suite-app-config/templates/703-postsync-rds-app-roles.yaml +++ b/instance-applications/510-550-ibm-mas-suite-app-config/templates/703-postsync-rds-app-roles.yaml @@ -3,7 +3,7 @@ {{- /* Use the build/bin/set-cli-image-digest.sh script to update this value across all charts. */}} -{{- $_cli_image_digest := "sha256:4636b74525a46ebd88cd540794e8e23143f0112ea85149f9dfc78d02704ad5a6" }} +{{- $_cli_image_digest := "sha256:100bcfef43b0ab0e266c1a316637e23640d2c57509d643bcf4d7f256c0b6ba4a" }} {{ $app_ns := .Values.mas_app_namespace }} {{ $np_name := "postsync-app-rds-roles-np" }} @@ -205,10 +205,13 @@ spec: echo "RDS_PORT ............................ ${RDS_PORT}" echo "OPERATIONAL_MODE .................... ${OPERATIONAL_MODE}" + # ----------------------------- + # Verify pre-installed dependencies + # ----------------------------- echo "" - echo "Installing required Python packages..." + echo "Verifying ibm_db package..." echo "--------------------------------------------------------------------------------" - pip install ibm_db + python3 -c "import ibm_db; print('✅ ibm_db version:', ibm_db.__version__)" echo "" echo "Downloading RDS SSL certificate..." diff --git a/root-applications/ibm-mas-instance-root/templates/120-dbs-rds-databases-app.yaml b/root-applications/ibm-mas-instance-root/templates/120-dbs-rds-databases-app.yaml index fb7dfbfc5..2dad05684 100644 --- a/root-applications/ibm-mas-instance-root/templates/120-dbs-rds-databases-app.yaml +++ b/root-applications/ibm-mas-instance-root/templates/120-dbs-rds-databases-app.yaml @@ -39,6 +39,16 @@ spec: env: - name: {{ $.Values.avp.values_varname }} value: | + # Account/Cluster/Instance identifiers (for Secrets Manager) + account_id: "{{ $.Values.account.id }}" + cluster_id: "{{ $.Values.cluster.id }}" + instance_id: "{{ $.Values.instance.id }}" + + # AWS Secrets Manager configuration + sm_aws_access_key_id: "{{ $.Values.sm.aws_access_key_id }}" + sm_aws_secret_access_key: "{{ $.Values.sm.aws_secret_access_key }}" + sm_aws_secret_region: "{{ $.Values.region.id }}" + # Basic connection configuration jdbc_connection_url: "{{ $value.jdbc_connection_url }}" rds_admin_db_name: "{{ $value.rds_admin_db_name }}"