From 92d0caa1d66a788d1f4257d4af2aa8ea501313e0 Mon Sep 17 00:00:00 2001 From: gsmith-sas <65406958+gsmith-sas@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:29:42 -0400 Subject: [PATCH 1/6] Adjust indentation in autogenerate-include.sh --- bin/autogenerate-include.sh | 208 ++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 105 deletions(-) diff --git a/bin/autogenerate-include.sh b/bin/autogenerate-include.sh index 6349f046..d294cc1c 100644 --- a/bin/autogenerate-include.sh +++ b/bin/autogenerate-include.sh @@ -6,40 +6,40 @@ function checkYqVersion { - # confirm yq installed and correct version - local goodver yq_version - goodver="yq \(.+mikefarah.+\) version (v)?(4\.(3[2-9]|[4-9][0-9])\..+)" - yq_version=$(yq --version) - if [ "$?" == "1" ]; then - log_error "Required component [yq] not available." - return 1 - elif [[ ! $yq_version =~ $goodver ]]; then - log_error "Incorrect version [$yq_version] found; version 4.32.2+ required." - return 1 - else - log_debug "A valid version [$yq_version] of yq detected" - return 0 - fi + # confirm yq installed and correct version + local goodver yq_version + goodver="yq \(.+mikefarah.+\) version (v)?(4\.(3[2-9]|[4-9][0-9])\..+)" + yq_version=$(yq --version) + if [ "$?" == "1" ]; then + log_error "Required component [yq] not available." + return 1 + elif [[ ! $yq_version =~ $goodver ]]; then + log_error "Incorrect version [$yq_version] found; version 4.32.2+ required." + return 1 + else + log_debug "A valid version [$yq_version] of yq detected" + return 0 + fi } export -f checkYqVersion function create_ingress_certs { - local certFile keyFile namespace secretName - - namespace="$1" - secretName="$2" - certFile="${3:-$INGRESS_CERT}" - keyFile="${4:-$INGRESS_KEY}" - - if [ -f "$certFile" ] && [ -f "$keyFile" ]; then - kubectl delete secret "$secretName" --namespace "$namespace" --ignore-not-found - kubectl create secret tls "$secretName" --namespace "$namespace" --key="$keyFile" --cert="$certFile" - kubectl -n $namespace label secret $secretName managed-by="v4m-es-script" - elif [ ! -z "$certFile$keyFile" ]; then - log_warn "Missing Ingress certificate file; specified Ingress cert [$certFile] and/or key [$keyFile] file is missing." - log_warn "Create the missing Kubernetes secrets after deployment; use command: kubectl -create secret tls $secretName --namespace $namespace --key=cert_key_file --cert=cert_file" - fi + local certFile keyFile namespace secretName + + namespace="$1" + secretName="$2" + certFile="${3:-$INGRESS_CERT}" + keyFile="${4:-$INGRESS_KEY}" + + if [ -f "$certFile" ] && [ -f "$keyFile" ]; then + kubectl delete secret "$secretName" --namespace "$namespace" --ignore-not-found + kubectl create secret tls "$secretName" --namespace "$namespace" --key="$keyFile" --cert="$certFile" + kubectl -n $namespace label secret $secretName managed-by="v4m-es-script" + elif [ ! -z "$certFile$keyFile" ]; then + log_warn "Missing Ingress certificate file; specified Ingress cert [$certFile] and/or key [$keyFile] file is missing." + log_warn "Create the missing Kubernetes secrets after deployment; use command: kubectl -create secret tls $secretName --namespace $namespace --key=cert_key_file --cert=cert_file" + fi } export -f create_ingress_certs @@ -48,76 +48,76 @@ AUTOGENERATE_INGRESS="${AUTOGENERATE_INGRESS:-false}" AUTOGENERATE_STORAGECLASS="${AUTOGENERATE_STORAGECLASS:-false}" if [ "$AUTOGENERATE_INGRESS" != "true" ] && [ "$AUTOGENERATE_STORAGECLASS" != "true" ]; then - log_debug "No autogeneration of YAML enabled" - export AUTOGENERATE_SOURCED="NotNeeded" + log_debug "No autogeneration of YAML enabled" + export AUTOGENERATE_SOURCED="NotNeeded" fi if [ -z "$AUTOGENERATE_SOURCED" ]; then - if ! checkYqVersion; then - exit 1 - fi - - if [ "$AUTOGENERATE_INGRESS" == "true" ]; then - - # Confirm NOT on OpenShift - if [ "$OPENSHIFT_CLUSTER" == "true" ]; then - log_error "Setting AUTOGENERATE_INGRESS to 'true' is not valid on OpenShift clusters." - log_error "Web applications will be made accessible via OpenShift routes instead (if enabled)." - - export AUTOGENERATE_INGRESS="false" - exit 1 - fi - - - #validate required inputs - BASE_DOMAIN="${BASE_DOMAIN}" - if [ -z "$BASE_DOMAIN" ]; then - log_error "Required parameter [BASE_DOMAIN] not provided" - exit 1 - fi - - ROUTING="${ROUTING:-host}" - - if [ "$ROUTING" == "path" ]; then - export MON_TLS_PATH_INGRESS="true" - log_debug "Path ingress requested, setting MON_TLS_PATH_INGRESS to 'true'" - elif [ "$ROUTING" != "host" ] && [ "$ROUTING" != "path" ]; then - log_error "Invalid ROUTING value, valid values are 'host' or 'path'" - exit 1 - fi - - INGRESS_CERT="${INGRESS_CERT}" - INGRESS_KEY="${INGRESS_KEY}" - if [ "$INGRESS_CERT/$INGRESS_KEY" != "/" ]; then - if [ ! -f "$INGRESS_CERT" ] || [ ! -f "$INGRESS_KEY" ]; then - # Only WARN b/c missing cert doesn't prevent deployment and it can be created afterwards - log_warn "Missing Ingress certificate file; specified Ingress cert [$INGRESS_CERT] and/or key [$INGRESS_KEY] file is missing." - log_warn "You can create the missing Kubernetes secrets after deployment. See Enable TLS for Ingress topic in Help Center documentation." - #unset variable values to prevent further attempted use - unset INGRESS_CERT - unset INGRESS_KEY - else - log_debug "Ingress cert [$INGRESS_CERT] and key [$INGRESS_KEY] files exist." - fi - fi - - log_info "Autogeneration of Ingress definitions has been enabled" - - fi - - if [ "$AUTOGENERATE_STORAGECLASS" == "true" ]; then - - log_info "Autogeneration of StorageClass specfication has been enabled" - - fi - - export AUTOGENERATE_SOURCED="true" - -elif [ "$AUTOGENERATE_SOURCED" == "NotNeeded" ]; then - log_debug "autogenerate-include.sh not needed" -else - log_debug "autogenerate-include.sh was already sourced [$AUTOGENERATE_SOURCED]" + if ! checkYqVersion; then + exit 1 + fi + + if [ "$AUTOGENERATE_INGRESS" == "true" ]; then + + # Confirm NOT on OpenShift + if [ "$OPENSHIFT_CLUSTER" == "true" ]; then + log_error "Setting AUTOGENERATE_INGRESS to 'true' is not valid on OpenShift clusters." + log_error "Web applications will be made accessible via OpenShift routes instead (if enabled)." + + export AUTOGENERATE_INGRESS="false" + exit 1 + fi + + + #validate required inputs + BASE_DOMAIN="${BASE_DOMAIN}" + if [ -z "$BASE_DOMAIN" ]; then + log_error "Required parameter [BASE_DOMAIN] not provided" + exit 1 + fi + + ROUTING="${ROUTING:-host}" + + if [ "$ROUTING" == "path" ]; then + export MON_TLS_PATH_INGRESS="true" + log_debug "Path ingress requested, setting MON_TLS_PATH_INGRESS to 'true'" + elif [ "$ROUTING" != "host" ] && [ "$ROUTING" != "path" ]; then + log_error "Invalid ROUTING value, valid values are 'host' or 'path'" + exit 1 + fi + + INGRESS_CERT="${INGRESS_CERT}" + INGRESS_KEY="${INGRESS_KEY}" + if [ "$INGRESS_CERT/$INGRESS_KEY" != "/" ]; then + if [ ! -f "$INGRESS_CERT" ] || [ ! -f "$INGRESS_KEY" ]; then + # Only WARN b/c missing cert doesn't prevent deployment and it can be created afterwards + log_warn "Missing Ingress certificate file; specified Ingress cert [$INGRESS_CERT] and/or key [$INGRESS_KEY] file is missing." + log_warn "You can create the missing Kubernetes secrets after deployment. See Enable TLS for Ingress topic in Help Center documentation." + #unset variable values to prevent further attempted use + unset INGRESS_CERT + unset INGRESS_KEY + else + log_debug "Ingress cert [$INGRESS_CERT] and key [$INGRESS_KEY] files exist." + fi + fi + + log_info "Autogeneration of Ingress definitions has been enabled" + + fi + + if [ "$AUTOGENERATE_STORAGECLASS" == "true" ]; then + + log_info "Autogeneration of StorageClass specfication has been enabled" + + fi + + export AUTOGENERATE_SOURCED="true" + + elif [ "$AUTOGENERATE_SOURCED" == "NotNeeded" ]; then + log_debug "autogenerate-include.sh not needed" + else + log_debug "autogenerate-include.sh was already sourced [$AUTOGENERATE_SOURCED]" fi @@ -131,19 +131,17 @@ function checkStorageClass { storageClass="${2:-$STORAGECLASS}" if [ -z "$storageClass" ]; then - log_error "Required parameter not provided. Either [$storageClassEnvVar] or [STORAGECLASS] MUST be provided." - exit 1 + log_error "Required parameter not provided. Either [$storageClassEnvVar] or [STORAGECLASS] MUST be provided." + exit 1 else - if $(kubectl get storageClass "$storageClass" -o name &>/dev/null); then - log_debug "The specified StorageClass [$storageClass] exists" - else - log_error "The specified StorageClass [$storageClass] does NOT exist" - exit 1 - fi + if $(kubectl get storageClass "$storageClass" -o name &>/dev/null); then + log_debug "The specified StorageClass [$storageClass] exists" + else + log_error "The specified StorageClass [$storageClass] does NOT exist" + exit 1 + fi fi } - - export -f checkStorageClass From bb390168b686ecb3fe0129bd1b2a0ed4e0ef95a1 Mon Sep 17 00:00:00 2001 From: gsmith-sas <65406958+gsmith-sas@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:22:38 -0400 Subject: [PATCH 2/6] [FEATURE] Autogenerate SMTP configuration for Grafana --- CHANGELOG.md | 6 ++ bin/autogenerate-include.sh | 64 ++++++++++++++++++++- monitoring/bin/deploy_monitoring_cluster.sh | 49 ++++++++++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e4fa24b..80f45761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ * [UPGRADE] Fluent Bit Helm chart upgraded from 0.49.0 to 0.52.0 * [UPGRADE] Elasticsearch Exporer Helm chart upgraded from 6.7.2 to 7.0.0 * [UPGRADE] OpenSearch Data Source Plugin to Grafana upgraded from 2.28.0 to 2.29.1 +* **Metrics** + * [FEATURE] Automatically define the SMTP server configuration to permit Grafana to send e-mails. +If enabled (by setting AUTOGENERATE_SMTP to 'true'), this optional feature allows admins to define +email-based contact points for alerts. Users need to provide connection information via the environment +variables: SMTP_SERVER, SMTP_PORT, SMTP_FROM_ADDRESS and SMTP_FROM_NAME. See Autogenerate SMTP Configuration +for more information. ## Version 1.2.41 (19AUG2025) diff --git a/bin/autogenerate-include.sh b/bin/autogenerate-include.sh index d294cc1c..ddde64cf 100644 --- a/bin/autogenerate-include.sh +++ b/bin/autogenerate-include.sh @@ -46,8 +46,9 @@ export -f create_ingress_certs AUTOGENERATE_INGRESS="${AUTOGENERATE_INGRESS:-false}" AUTOGENERATE_STORAGECLASS="${AUTOGENERATE_STORAGECLASS:-false}" +AUTOGENERATE_SMTP="${AUTOGENERATE_SMTP:-false}" -if [ "$AUTOGENERATE_INGRESS" != "true" ] && [ "$AUTOGENERATE_STORAGECLASS" != "true" ]; then +if [ "$AUTOGENERATE_INGRESS" != "true" ] && [ "$AUTOGENERATE_STORAGECLASS" != "true" ] && [ "$AUTOGENERATE_SMTP" != "true" ]; then log_debug "No autogeneration of YAML enabled" export AUTOGENERATE_SOURCED="NotNeeded" fi @@ -69,7 +70,6 @@ if [ -z "$AUTOGENERATE_SOURCED" ]; then exit 1 fi - #validate required inputs BASE_DOMAIN="${BASE_DOMAIN}" if [ -z "$BASE_DOMAIN" ]; then @@ -107,8 +107,66 @@ if [ -z "$AUTOGENERATE_SOURCED" ]; then fi if [ "$AUTOGENERATE_STORAGECLASS" == "true" ]; then - log_info "Autogeneration of StorageClass specfication has been enabled" + fi + + if [ "$AUTOGENERATE_SMTP" == "true" ]; then + + #required + # shellcheck disable=SC2269 + SMTP_HOST="${SMTP_HOST}" + # shellcheck disable=SC2269 + SMTP_PORT="${SMTP_PORT}" + # shellcheck disable=SC2269 + SMTP_FROM_ADDRESS="${SMTP_FROM_ADDRESS}" + # shellcheck disable=SC2269 + SMTP_FROM_NAME="${SMTP_FROM_NAME}" + + #optional + # shellcheck disable=SC2269 + SMTP_USER="${SMTP_USER}" + # shellcheck disable=SC2269 + SMTP_PASSWORD="${SMTP_PASSWORD}" + SMTP_USER_SECRET="${SMTP_USER_SECRET:-grafana-smtp-user}" + SMTP_SKIP_VERIFY="${SMTP_SKIP_VERIFY:-false}" + SMTP_TLS_CERT_FILE="${SMTP_TLS_CERT_FILE:-/cert/tls.crt}" + SMTP_TLS_KEY_FILE="${SMTP_TLS_KEY_FILE:-/cert/tls.key}" + + log_info "Autogeneration of SMTP Configuration has been enabled" + + if [ -z "$SMTP_HOST" ]; then + log_error "Required parameter [SMTP_HOST] not provided" + exit 1 + fi + + if [ -z "$SMTP_PORT" ]; then + log_error "Required parameter [SMTP_PORT] not provided" + exit 1 + fi + + if [ -z "$SMTP_FROM_ADDRESS" ]; then + log_error "Required parameter [SMTP_FROM_ADDRESS] not provided" + exit 1 + fi + + if [ -z "$SMTP_FROM_NAME" ]; then + log_error "Required parameter [SMTP_FROM_NAME] not provided" + exit 1 + fi + + # Handle SMTP user credentials + if [ -n "$(kubectl get secret -n "$MON_NS" "$SMTP_USER_SECRET" --ignore-not-found -o name 2> /dev/null)" ]; then + log_debug "Secret [$SMTP_USER_SECRET] exists; will use it for SMTP user credentials" + elif [ -z "$SMTP_USER" ] && [ -z "$SMTP_PASSWORD" ]; then + log_debug "Neither SMTP_USER nor SMTP_PASSWORD are set; skipping creation of secret [$SMTP_USER_SECRET]" + elif [ -z "$SMTP_USER" ] || [ -z "$SMTP_PASSWORD" ]; then + log_error "Complete SMTP Credentials NOT provided; MUST provide BOTH [SMTP_USER] and [SMTP_PASSWORD]" + log_info "SMTP_USER is set to [$SMTP_USER] and SMTP_PASSWORD is set to [$SMTP_PASSWORD]" + exit 1 + else + log_debug "Creating secret [$MON_NS/$SMTP_USER_SECRET] from supplied user [$SMTP_USER] and password." + kubectl create secret generic "$SMTP_USER_SECRET" -n "$MON_NS" --from-literal=user="$SMTP_USER" --from-literal=password="$SMTP_PASSWORD" + fi fi diff --git a/monitoring/bin/deploy_monitoring_cluster.sh b/monitoring/bin/deploy_monitoring_cluster.sh index be1e11d7..c1834406 100755 --- a/monitoring/bin/deploy_monitoring_cluster.sh +++ b/monitoring/bin/deploy_monitoring_cluster.sh @@ -59,6 +59,55 @@ else log_debug "Autogeneration of storageClassReferences NOT enabled" fi +AUTOGENERATE_SMTP="${AUTOGENERATE_SMTP:-false}" + +if [ "$AUTOGENERATE_SMTP" == "true" ]; then + + if [ ! -f "$autogeneratedYAMLFile" ]; then + log_debug "Creating file [$autogeneratedYAMLFile]" + touch "$autogeneratedYAMLFile" + else + log_debug "File [$autogeneratedYAMLFile] already exists" + fi + + smtpHost="${SMTP_HOST}" + smtpPort="${SMTP_PORT}" + smtpFromAddress="${SMTP_FROM_ADDRESS}" + smtpFromName="${SMTP_FROM_NAME}" + smtpUserSecret="${SMTP_USER_SECRET}" + smtpSkipVerify="${SMTP_SKIP_VERIFY:-false}" + smtpTLSCertFile="${SMTP_TLS_CERT_FILE:-/cert/tls.crt}" + smtpTLSKeyFile="${SMTP_TLS_KEY_FILE:-/cert/tls.key}" + ###smtpTLSSecret="${SMTP_TLS_REQUIRED}" + + yq -i '.grafana."grafana.ini".smtp.enabled=true' "$autogeneratedYAMLFile" + + value="$smtpHost:$smtpPort" yq -i '.grafana."grafana.ini".smtp.host=env(value)' "$autogeneratedYAMLFile" + + value="$smtpFromAddress" yq -i '.grafana."grafana.ini".smtp.from_address=env(value)' "$autogeneratedYAMLFile" + value="$smtpFromName" yq -i '.grafana."grafana.ini".smtp.from_name=env(value)' "$autogeneratedYAMLFile" + + if [ -n "$smtpUserSecret" ]; then + value="$smtpUserSecret" yq -i '.grafana.smtp.existingSecret=env(value)' "$autogeneratedYAMLFile" + fi + + value="$smtpSkipVerify" yq -i '.grafana."grafana.ini".smtp.skip_verify=env(value)' "$autogeneratedYAMLFile" + + value="$smtpTLSCertFile" yq -i '.grafana."grafana.ini".smtp.cert_file=env(value)' "$autogeneratedYAMLFile" + value="$smtpTLSKeyFile" yq -i '.grafana."grafana.ini".smtp.key_file=env(value)' "$autogeneratedYAMLFile" + +# if [ -n "$smtpUser" ]; then +# value="$smtpUser" yq -i '.grafana."grafana.ini".smtp.user=env(value)' "$autogeneratedYAMLFile" +# fi +# if [ -n "$smtpPassword" ]; then +# value="$smtpPassword" yq -i '.grafana."grafana.ini".smtp.password=env(value)' "$autogeneratedYAMLFile" +# fi + +else + log_debug "Auto-generation of SMTP not enabled; skipping Grafana SMTP server configuration" +fi + + PROM_OPER_USER_YAML="${PROM_OPER_USER_YAML:-$USER_DIR/monitoring/user-values-prom-operator.yaml}" if [ ! -f "$PROM_OPER_USER_YAML" ]; then log_debug "[$PROM_OPER_USER_YAML] not found. Using $TMP_DIR/empty.yaml" From c28f0a824666bec6f467220691b80c90da3e2db7 Mon Sep 17 00:00:00 2001 From: gsmith-sas <65406958+gsmith-sas@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:45:24 -0400 Subject: [PATCH 3/6] tweaked CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80f45761..9b80cae5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,9 +12,9 @@ * [UPGRADE] OpenSearch Data Source Plugin to Grafana upgraded from 2.28.0 to 2.29.1 * **Metrics** * [FEATURE] Automatically define the SMTP server configuration to permit Grafana to send e-mails. -If enabled (by setting AUTOGENERATE_SMTP to 'true'), this optional feature allows admins to define +If enabled (by setting `AUTOGENERATE_SMTP` to 'true'), this optional feature allows admins to define email-based contact points for alerts. Users need to provide connection information via the environment -variables: SMTP_SERVER, SMTP_PORT, SMTP_FROM_ADDRESS and SMTP_FROM_NAME. See Autogenerate SMTP Configuration +variables: `SMTP_SERVER, SMTP_PORT`, `SMTP_FROM_ADDRESS` and `SMTP_FROM_NAME`. See Autogenerate SMTP Configuration for more information. From 041914c911d393ba0609db044b883d24cc878f6a Mon Sep 17 00:00:00 2001 From: gsmith-sas <65406958+gsmith-sas@users.noreply.github.com> Date: Thu, 11 Sep 2025 11:07:40 -0400 Subject: [PATCH 4/6] Move SMTP Autogen logic after namespace creation --- bin/autogenerate-include.sh | 5 +- monitoring/bin/deploy_monitoring_cluster.sh | 85 ++++++++++----------- 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/bin/autogenerate-include.sh b/bin/autogenerate-include.sh index ddde64cf..e3e7b0bf 100644 --- a/bin/autogenerate-include.sh +++ b/bin/autogenerate-include.sh @@ -164,8 +164,9 @@ if [ -z "$AUTOGENERATE_SOURCED" ]; then log_info "SMTP_USER is set to [$SMTP_USER] and SMTP_PASSWORD is set to [$SMTP_PASSWORD]" exit 1 else - log_debug "Creating secret [$MON_NS/$SMTP_USER_SECRET] from supplied user [$SMTP_USER] and password." - kubectl create secret generic "$SMTP_USER_SECRET" -n "$MON_NS" --from-literal=user="$SMTP_USER" --from-literal=password="$SMTP_PASSWORD" + log_debug "Secret [$MON_NS/$SMTP_USER_SECRET] will need to be created later." + # shellcheck disable=SC2034 + smtpCreateUserSecret="true" fi fi diff --git a/monitoring/bin/deploy_monitoring_cluster.sh b/monitoring/bin/deploy_monitoring_cluster.sh index c1834406..381fe0b4 100755 --- a/monitoring/bin/deploy_monitoring_cluster.sh +++ b/monitoring/bin/deploy_monitoring_cluster.sh @@ -59,6 +59,23 @@ else log_debug "Autogeneration of storageClassReferences NOT enabled" fi +PROM_OPER_USER_YAML="${PROM_OPER_USER_YAML:-$USER_DIR/monitoring/user-values-prom-operator.yaml}" +if [ ! -f "$PROM_OPER_USER_YAML" ]; then + log_debug "[$PROM_OPER_USER_YAML] not found. Using $TMP_DIR/empty.yaml" + PROM_OPER_USER_YAML=$TMP_DIR/empty.yaml +fi + +if [ "$HELM_DEBUG" == "true" ]; then + helmDebug="--debug" +fi + +if [ -z "$(kubectl get ns "$MON_NS" -o name 2> /dev/null)" ]; then + kubectl create ns "$MON_NS" + + #Container Security: Disable serviceAccount Token Automounting + disable_sa_token_automount "$MON_NS" default +fi + AUTOGENERATE_SMTP="${AUTOGENERATE_SMTP:-false}" if [ "$AUTOGENERATE_SMTP" == "true" ]; then @@ -70,61 +87,41 @@ if [ "$AUTOGENERATE_SMTP" == "true" ]; then log_debug "File [$autogeneratedYAMLFile] already exists" fi - smtpHost="${SMTP_HOST}" - smtpPort="${SMTP_PORT}" - smtpFromAddress="${SMTP_FROM_ADDRESS}" - smtpFromName="${SMTP_FROM_NAME}" - smtpUserSecret="${SMTP_USER_SECRET}" - smtpSkipVerify="${SMTP_SKIP_VERIFY:-false}" - smtpTLSCertFile="${SMTP_TLS_CERT_FILE:-/cert/tls.crt}" - smtpTLSKeyFile="${SMTP_TLS_KEY_FILE:-/cert/tls.key}" - ###smtpTLSSecret="${SMTP_TLS_REQUIRED}" - - yq -i '.grafana."grafana.ini".smtp.enabled=true' "$autogeneratedYAMLFile" + smtpHost="${SMTP_HOST}" + smtpPort="${SMTP_PORT}" + smtpFromAddress="${SMTP_FROM_ADDRESS}" + smtpFromName="${SMTP_FROM_NAME}" + smtpUserSecret="${SMTP_USER_SECRET}" + smtpSkipVerify="${SMTP_SKIP_VERIFY:-false}" + smtpTLSCertFile="${SMTP_TLS_CERT_FILE:-/cert/tls.crt}" + smtpTLSKeyFile="${SMTP_TLS_KEY_FILE:-/cert/tls.key}" + + # Create secret to hold SMTP user credentials + if [ "$smtpCreateUserSecret" == "true" ]; then + log_debug "Creating secret [$MON_NS/$SMTP_USER_SECRET] from supplied user [$SMTP_USER] and password." + kubectl create secret generic "$SMTP_USER_SECRET" -n "$MON_NS" --from-literal=user="$SMTP_USER" --from-literal=password="$SMTP_PASSWORD" + fi - value="$smtpHost:$smtpPort" yq -i '.grafana."grafana.ini".smtp.host=env(value)' "$autogeneratedYAMLFile" + yq -i '.grafana."grafana.ini".smtp.enabled=true' "$autogeneratedYAMLFile" - value="$smtpFromAddress" yq -i '.grafana."grafana.ini".smtp.from_address=env(value)' "$autogeneratedYAMLFile" - value="$smtpFromName" yq -i '.grafana."grafana.ini".smtp.from_name=env(value)' "$autogeneratedYAMLFile" + value="$smtpHost:$smtpPort" yq -i '.grafana."grafana.ini".smtp.host=env(value)' "$autogeneratedYAMLFile" - if [ -n "$smtpUserSecret" ]; then - value="$smtpUserSecret" yq -i '.grafana.smtp.existingSecret=env(value)' "$autogeneratedYAMLFile" - fi + value="$smtpFromAddress" yq -i '.grafana."grafana.ini".smtp.from_address=env(value)' "$autogeneratedYAMLFile" + value="$smtpFromName" yq -i '.grafana."grafana.ini".smtp.from_name=env(value)' "$autogeneratedYAMLFile" - value="$smtpSkipVerify" yq -i '.grafana."grafana.ini".smtp.skip_verify=env(value)' "$autogeneratedYAMLFile" + if [ -n "$smtpUserSecret" ]; then + value="$smtpUserSecret" yq -i '.grafana.smtp.existingSecret=env(value)' "$autogeneratedYAMLFile" + fi - value="$smtpTLSCertFile" yq -i '.grafana."grafana.ini".smtp.cert_file=env(value)' "$autogeneratedYAMLFile" - value="$smtpTLSKeyFile" yq -i '.grafana."grafana.ini".smtp.key_file=env(value)' "$autogeneratedYAMLFile" + value="$smtpSkipVerify" yq -i '.grafana."grafana.ini".smtp.skip_verify=env(value)' "$autogeneratedYAMLFile" -# if [ -n "$smtpUser" ]; then -# value="$smtpUser" yq -i '.grafana."grafana.ini".smtp.user=env(value)' "$autogeneratedYAMLFile" -# fi -# if [ -n "$smtpPassword" ]; then -# value="$smtpPassword" yq -i '.grafana."grafana.ini".smtp.password=env(value)' "$autogeneratedYAMLFile" -# fi + value="$smtpTLSCertFile" yq -i '.grafana."grafana.ini".smtp.cert_file=env(value)' "$autogeneratedYAMLFile" + value="$smtpTLSKeyFile" yq -i '.grafana."grafana.ini".smtp.key_file=env(value)' "$autogeneratedYAMLFile" else log_debug "Auto-generation of SMTP not enabled; skipping Grafana SMTP server configuration" fi - -PROM_OPER_USER_YAML="${PROM_OPER_USER_YAML:-$USER_DIR/monitoring/user-values-prom-operator.yaml}" -if [ ! -f "$PROM_OPER_USER_YAML" ]; then - log_debug "[$PROM_OPER_USER_YAML] not found. Using $TMP_DIR/empty.yaml" - PROM_OPER_USER_YAML=$TMP_DIR/empty.yaml -fi - -if [ "$HELM_DEBUG" == "true" ]; then - helmDebug="--debug" -fi - -if [ -z "$(kubectl get ns "$MON_NS" -o name 2> /dev/null)" ]; then - kubectl create ns "$MON_NS" - - #Container Security: Disable serviceAccount Token Automounting - disable_sa_token_automount "$MON_NS" default -fi - #Generate yaml file with all container-related keys generateImageKeysFile "$PROMOP_FULL_IMAGE" "monitoring/prom-operator_container_image.template" generateImageKeysFile "$ALERTMANAGER_FULL_IMAGE" "$imageKeysFile" "ALERTMANAGER_" From 084d28c9132a8bc4addb08ee36855d803857c7b6 Mon Sep 17 00:00:00 2001 From: gsmith-sas <65406958+gsmith-sas@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:54:30 -0400 Subject: [PATCH 5/6] Updated CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b80cae5..60ed5d89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,12 @@ * [UPGRADE] Fluent Bit Helm chart upgraded from 0.49.0 to 0.52.0 * [UPGRADE] Elasticsearch Exporer Helm chart upgraded from 6.7.2 to 7.0.0 * [UPGRADE] OpenSearch Data Source Plugin to Grafana upgraded from 2.28.0 to 2.29.1 + * **Metrics** * [FEATURE] Automatically define the SMTP server configuration to permit Grafana to send e-mails. If enabled (by setting `AUTOGENERATE_SMTP` to 'true'), this optional feature allows admins to define email-based contact points for alerts. Users need to provide connection information via the environment -variables: `SMTP_SERVER, SMTP_PORT`, `SMTP_FROM_ADDRESS` and `SMTP_FROM_NAME`. See Autogenerate SMTP Configuration +variables: `SMTP_SERVER, SMTP_PORT`, `SMTP_FROM_ADDRESS` and `SMTP_FROM_NAME`. See [Configure Email Settings for Grafana Alerts](documentation.sas.com/doc/en/obsrvcdc/v_003/obsrvdply/n0auhd4hutsf7xn169hfvriysz4e.htm#p1fql9ekyxckamn1jtlujeauhy72) for more information. From 9a529bcb68f3ad4442a876ef64b7eaecd14204f4 Mon Sep 17 00:00:00 2001 From: gsmith-sas <65406958+gsmith-sas@users.noreply.github.com> Date: Tue, 16 Sep 2025 13:31:03 -0400 Subject: [PATCH 6/6] Fix doc url --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dabd4f1..4f6ccfda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ * [FEATURE] Automatically define the SMTP server configuration to permit Grafana to send e-mails. If enabled (by setting `AUTOGENERATE_SMTP` to 'true'), this optional feature allows admins to define email-based contact points for alerts. Users need to provide connection information via the environment -variables: `SMTP_SERVER, SMTP_PORT`, `SMTP_FROM_ADDRESS` and `SMTP_FROM_NAME`. See [Configure Email Settings for Grafana Alerts](documentation.sas.com/doc/en/obsrvcdc/v_003/obsrvdply/n0auhd4hutsf7xn169hfvriysz4e.htm#p1fql9ekyxckamn1jtlujeauhy72) +variables: `SMTP_SERVER, SMTP_PORT`, `SMTP_FROM_ADDRESS` and `SMTP_FROM_NAME`. See [Configure Email Settings for Grafana Alerts](https://documentation.sas.com/doc/en/obsrvcdc/v_003/obsrvdply/n0auhd4hutsf7xn169hfvriysz4e.htm#p1fql9ekyxckamn1jtlujeauhy72) for more information. * [CHANGE] The Grafana alerts targeting SAS Viya that previously were provided by default have been moved to the samples directory. Given the variability of SAS Viya environments, these alerts are now optional.