From 152c286448db608fc64c19789fcab419d443f18f Mon Sep 17 00:00:00 2001 From: Markus Pesch Date: Mon, 25 Nov 2024 11:53:09 +0100 Subject: [PATCH] Initial Commit --- .editorconfig | 12 + .gitignore | 6 + .helmignore | 49 + .markdownlint.yaml | 154 +++ .markdownlintignore | 4 + .npmrc | 1 + .prettierignore | 1 + .vscode/extensions.json | 8 + .vscode/settings.json | 8 + .yamllint.yaml | 20 + CODEOWNERS | 1 + CONTRIBUTING.md | 1 + Chart.yaml | 18 + Makefile | 108 ++ README.md | 263 +++++ package-lock.json | 919 ++++++++++++++++++ package.json | 19 + .../prometheus-postgres-exporter/_common.tpl | 58 ++ .../_deployment.tpl | 70 ++ .../prometheus-postgres-exporter/_ingress.tpl | 19 + .../prometheus-postgres-exporter/_pod.tpl | 17 + .../_podMonitors.tpl | 19 + .../_prometheusRules.tpl | 13 + .../prometheus-postgres-exporter/_secrets.tpl | 48 + .../_serviceAccount.tpl | 17 + .../_serviceMonitors.tpl | 25 + .../_services.tpl | 29 + .../deployment.yaml | 119 +++ .../prometheus-postgres-exporter/ingress.yaml | 45 + .../podMonitor.yaml | 40 + .../prometheusRules.yaml | 23 + .../secretDatabase.yaml | 20 + .../secretExporterConfig.yaml | 19 + .../secretWebConfig.yaml | 19 + .../serviceAccount.yaml | 26 + .../serviceHTTP.yaml | 57 ++ .../serviceMonitorHTTP.yaml | 40 + unittests/deployment/deployment.yaml | 45 + unittests/ingress/ingress.yaml | 140 +++ unittests/podMonitors/podMonitorHTTP.yaml | 172 ++++ unittests/secrets/database.yaml | 104 ++ unittests/secrets/exporterConfig.yaml | 86 ++ unittests/secrets/webconfig.yaml | 81 ++ unittests/serviceAccounts/serviceAccount.yaml | 79 ++ .../serviceMonitors/serviceMonitorHTTP.yaml | 172 ++++ unittests/services/http.yaml | 177 ++++ values.yaml | 521 ++++++++++ 47 files changed, 3892 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .helmignore create mode 100644 .markdownlint.yaml create mode 100644 .markdownlintignore create mode 100644 .npmrc create mode 100644 .prettierignore create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 .yamllint.yaml create mode 100644 CODEOWNERS create mode 100644 CONTRIBUTING.md create mode 100644 Chart.yaml create mode 100644 Makefile create mode 100644 README.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 templates/prometheus-postgres-exporter/_common.tpl create mode 100644 templates/prometheus-postgres-exporter/_deployment.tpl create mode 100644 templates/prometheus-postgres-exporter/_ingress.tpl create mode 100644 templates/prometheus-postgres-exporter/_pod.tpl create mode 100644 templates/prometheus-postgres-exporter/_podMonitors.tpl create mode 100644 templates/prometheus-postgres-exporter/_prometheusRules.tpl create mode 100644 templates/prometheus-postgres-exporter/_secrets.tpl create mode 100644 templates/prometheus-postgres-exporter/_serviceAccount.tpl create mode 100644 templates/prometheus-postgres-exporter/_serviceMonitors.tpl create mode 100644 templates/prometheus-postgres-exporter/_services.tpl create mode 100644 templates/prometheus-postgres-exporter/deployment.yaml create mode 100644 templates/prometheus-postgres-exporter/ingress.yaml create mode 100644 templates/prometheus-postgres-exporter/podMonitor.yaml create mode 100644 templates/prometheus-postgres-exporter/prometheusRules.yaml create mode 100644 templates/prometheus-postgres-exporter/secretDatabase.yaml create mode 100644 templates/prometheus-postgres-exporter/secretExporterConfig.yaml create mode 100644 templates/prometheus-postgres-exporter/secretWebConfig.yaml create mode 100644 templates/prometheus-postgres-exporter/serviceAccount.yaml create mode 100644 templates/prometheus-postgres-exporter/serviceHTTP.yaml create mode 100644 templates/prometheus-postgres-exporter/serviceMonitorHTTP.yaml create mode 100644 unittests/deployment/deployment.yaml create mode 100644 unittests/ingress/ingress.yaml create mode 100644 unittests/podMonitors/podMonitorHTTP.yaml create mode 100644 unittests/secrets/database.yaml create mode 100644 unittests/secrets/exporterConfig.yaml create mode 100644 unittests/secrets/webconfig.yaml create mode 100644 unittests/serviceAccounts/serviceAccount.yaml create mode 100644 unittests/serviceMonitors/serviceMonitorHTTP.yaml create mode 100644 unittests/services/http.yaml create mode 100644 values.yaml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b53e68c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false + +[Makefile] +indent_style = tab \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba69fff --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +charts +node_modules +target +values2.yml +values2.yaml +*.tgz diff --git a/.helmignore b/.helmignore new file mode 100644 index 0000000..e4d5f3e --- /dev/null +++ b/.helmignore @@ -0,0 +1,49 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store + +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ + +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ + +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +# drone +.drone.ya?ml + +# editorconfig +.editorconfig + +# customized values +values2.yml +values2.yaml + +# helm packages +*.tgz + +# markdownlint +.markdownlint.yml +.markdownlint.yaml + +# maven +target + +# serviceDescriptor (uctl-cluster) +serviceDescriptor.yaml \ No newline at end of file diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..d898196 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,154 @@ +# markdownlint YAML configuration +# https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.yaml + +# Default state for all rules +default: true + +# Path to configuration file to extend +extends: null + +# MD003/heading-style/header-style - Heading style +MD003: + # Heading style + style: "atx" + +# MD004/ul-style - Unordered list style +MD004: + style: "dash" + +# MD007/ul-indent - Unordered list indentation +MD007: + # Spaces for indent + indent: 2 + # Whether to indent the first level of the list + start_indented: false + +# MD009/no-trailing-spaces - Trailing spaces +MD009: + # Spaces for line break + br_spaces: 2 + # Allow spaces for empty lines in list items + list_item_empty_lines: false + # Include unnecessary breaks + strict: false + +# MD010/no-hard-tabs - Hard tabs +MD010: + # Include code blocks + code_blocks: true + +# MD012/no-multiple-blanks - Multiple consecutive blank lines +MD012: + # Consecutive blank lines + maximum: 1 + +# MD013/line-length - Line length +MD013: + # Number of characters + line_length: 120 + # Number of characters for headings + heading_line_length: 120 + # Number of characters for code blocks + code_block_line_length: 80 + # Include code blocks + code_blocks: false + # Include tables + tables: false + # Include headings + headings: true + # Strict length checking + strict: false + # Stern length checking + stern: false + +# MD022/blanks-around-headings/blanks-around-headers - Headings should be surrounded by blank lines +MD022: + # Blank lines above heading + lines_above: 1 + # Blank lines below heading + lines_below: 1 + +# MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content +MD024: + # Only check sibling headings + siblings_only: true + +# MD025/single-title/single-h1 - Multiple top-level headings in the same document +MD025: + # Heading level + level: 1 + # RegExp for matching title in front matter + front_matter_title: "^\\s*title\\s*[:=]" + +# MD026/no-trailing-punctuation - Trailing punctuation in heading +MD026: + # Punctuation characters + punctuation: ".,;:!。,;:!" + +# MD029/ol-prefix - Ordered list item prefix +MD029: + # List style + style: "one_or_ordered" + +# MD030/list-marker-space - Spaces after list markers +MD030: + # Spaces for single-line unordered list items + ul_single: 1 + # Spaces for single-line ordered list items + ol_single: 1 + # Spaces for multi-line unordered list items + ul_multi: 1 + # Spaces for multi-line ordered list items + ol_multi: 1 + +# MD033/no-inline-html - Inline HTML +MD033: + # Allowed elements + allowed_elements: [] + +# MD035/hr-style - Horizontal rule style +MD035: + # Horizontal rule style + style: "---" + +# MD036/no-emphasis-as-heading/no-emphasis-as-header - Emphasis used instead of a heading +MD036: + # Punctuation characters + punctuation: ".,;:!?。,;:!?" + +# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading +MD041: + # Heading level + level: 1 + # RegExp for matching title in front matter + front_matter_title: "^\\s*title\\s*[:=]" + +# MD044/proper-names - Proper names should have the correct capitalization +MD044: + # List of proper names + names: + - Git + - Gitea + - GitDevOps + - GitHub + - GitLab + - GitOps + - Memcached + - Oracle + - ORBIS U + - PostgreSQL + - Prometheus + - SSL + - TLS + # Include code blocks + code_blocks: false + +# MD046/code-block-style - Code block style +MD046: + # Block style + style: "fenced" + +# MD048/code-fence-style - Code fence style +MD048: + # Code fence syle + style: "backtick" diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 0000000..9fe4803 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,4 @@ +.github/ +Chart.lock +charts/ +node_modules/ \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..fafeafa --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +Chart.lock \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..08a5b51 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "DavidAnson.vscode-markdownlint", + "esbenp.prettier-vscode", + "Tim-Koehler.helm-intellisense", + "yzhang.markdown-all-in-one" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7ed7716 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "yaml.schemas": { + "https://raw.githubusercontent.com/helm-unittest/helm-unittest/v0.5.2/schema/helm-testsuite.json": [ + "/unittests/**/*.yaml" + ] + }, + "yaml.schemaStore.enable": true +} \ No newline at end of file diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 0000000..90128be --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,20 @@ +--- +extends: default + +ignore: | + .yamllint + node_modules + templates + + +rules: + truthy: + allowed-values: ['true', 'false'] + check-keys: False + level: error + line-length: disable + document-start: disable + comments: + min-spaces-from-content: 1 + braces: + max-spaces-inside: 2 \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..af45fc8 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @volker.raschek diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8a1b9f1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1 @@ +# Contribution Guidelines diff --git a/Chart.yaml b/Chart.yaml new file mode 100644 index 0000000..31c314f --- /dev/null +++ b/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: prometheus-postgres-exporter +description: Prometheus metric exporter for PostgreSQL +type: application +kubeVersion: ">=1.20.0" +version: "0.1.0" +appVersion: "0.15.0" + +# icon: https://annotations.example.com/icon.png + +keywords: +- prometheus +- prometheus exporter +- postgres + +sources: +- https://github.com/prometheus-community/postgres_exporter +- https://git.cryptic.systems/volker.raschek/prometheus-postgres-exporter \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d4e5db8 --- /dev/null +++ b/Makefile @@ -0,0 +1,108 @@ +# CONTAINER_RUNTIME +CONTAINER_RUNTIME?=$(shell which podman) + +# HELM_IMAGE +HELM_IMAGE_REGISTRY_HOST?=docker.io +HELM_IMAGE_REPOSITORY=volkerraschek/helm +HELM_IMAGE_VERSION?=3.16.1 # renovate: datasource=docker registryUrl=https://docker.io depName=volkerraschek/helm +HELM_IMAGE_FULLY_QUALIFIED=${HELM_IMAGE_REGISTRY_HOST}/${HELM_IMAGE_REPOSITORY}:${HELM_IMAGE_VERSION} + +# MARKDOWNLINKCHECKER_IMAGE +MARKDOWNLINKCHECK_IMAGE_REGISTRY_HOST?=ghcr.io +MARKDOWNLINKCHECK_IMAGE_REPOSITORY=tcort/markdown-link-check +MARKDOWNLINKCHECK_IMAGE_VERSION?=3.12.2 # renovate: datasource=docker registryUrl=https://ghcr.io depName=tcort/markdown-link-check +MARKDOWNLINKCHECK_IMAGE_FULLY_QUALIFIED=${MARKDOWNLINT_IMAGE_REGISTRY_HOST}/${MARKDOWNLINT_IMAGE_REPOSITORY}:${MARKDOWNLINT_IMAGE_VERSION} + +# NODE_IMAGE +NODE_IMAGE_REGISTRY_HOST?=docker.io +NODE_IMAGE_REPOSITORY=library/node +NODE_IMAGE_VERSION?=22.9.0-alpine # renovate: datasource=docker registryUrl=https://docker.io depName=library/node +NODE_IMAGE_FULLY_QUALIFIED=${NODE_IMAGE_REGISTRY_HOST}/${NODE_IMAGE_REPOSITORY}:${NODE_IMAGE_VERSION} + +# CHART_SERVER +CHART_SERVER_HOST?=charts.u.orbis-healthcare.com +CHART_SERVER_NAMESPACE?=orbis-u +CHART_SERVER_REPOSITORY?=qu-seed +CHART_VERSION?=0.1.0 + +# MISSING DOT +# ============================================================================== +missing-dot: + grep --perl-regexp '## @(param|skip).*[^.]$$' values.yaml + +# CONTAINER RUN - PREPARE ENVIRONMENT +# ============================================================================== +PHONY+=container-run/readme +container-run/readme: + ${CONTAINER_RUNTIME} run \ + --rm \ + --volume $(shell pwd):$(shell pwd) \ + --workdir $(shell pwd) \ + ${NODE_IMAGE_FULLY_QUALIFIED} \ + npm install && npm run readme:parameters && npm run readme:lint + +# CONTAINER RUN - HELM UNITTESTS +# ============================================================================== +PHONY+=container-run/helm-unittests +container-run/helm-unittests: + ${CONTAINER_RUNTIME} run \ + --env HELM_REPO_PASSWORD=${CHART_SERVER_PASSWORD} \ + --env HELM_REPO_USERNAME=${CHART_SERVER_USERNAME} \ + --rm \ + --volume $(shell pwd):$(shell pwd) \ + --workdir $(shell pwd) \ + ${HELM_IMAGE_FULLY_QUALIFIED} \ + unittest --strict --file 'unittests/**/*.yaml' ./ + +# CONTAINER RUN - HELM UPDATE DEPENDENCIES +# ============================================================================== +PHONY+=container-run/helm-update-dependencies +container-run/helm-update-dependencies: + ${CONTAINER_RUNTIME} run \ + --env HELM_REPO_PASSWORD=${CHART_SERVER_PASSWORD} \ + --env HELM_REPO_USERNAME=${CHART_SERVER_USERNAME} \ + --rm \ + --volume $(shell pwd):$(shell pwd) \ + --workdir $(shell pwd) \ + ${HELM_IMAGE_FULLY_QUALIFIED} \ + dependency update + +# CONTAINER RUN - DEPLOY2CHART-REPO +# ============================================================================== +container-run/deploy2chart-repo: + ${CONTAINER_RUNTIME} run \ + --env HELM_REPO_PASSWORD=${CHART_SERVER_PASSWORD} \ + --env HELM_REPO_USERNAME=${CHART_SERVER_USERNAME} \ + --entrypoint /bin/bash \ + --rm \ + --volume $(shell pwd):$(shell pwd) \ + --workdir $(shell pwd) \ + ${HELM_IMAGE_FULLY_QUALIFIED} \ + -c "helm repo add ${CHART_SERVER_NAMESPACE} http://${CHART_SERVER_HOST}/${CHART_SERVER_NAMESPACE} && helm package --version ${CHART_VERSION} . && helm cm-push ./${CHART_SERVER_REPOSITORY}-${CHART_VERSION}.tgz ${CHART_SERVER_NAMESPACE}" + +# CONTAINER RUN - MARKDOWN-LINT +# ============================================================================== +PHONY+=container-run/helm-lint +container-run/helm-lint: + ${CONTAINER_RUNTIME} run \ + --rm \ + --volume $(shell pwd):$(shell pwd) \ + --workdir $(shell pwd) \ + ${HELM_IMAGE_FULLY_QUALIFIED} \ + lint --values values.yaml . + +# CONTAINER RUN - MARKDOWN-LINK-CHECK +# ============================================================================== +PHONY+=container-run/markdown-link-check +container-run/markdown-link-check: + ${CONTAINER_RUNTIME} run \ + --rm \ + --volume $(shell pwd):/work \ + ${MARKDOWNLINKCHECK_IMAGE_FULLY_QUALIFIED} \ + *.md + +# PHONY +# ============================================================================== +# Declare the contents of the PHONY variable as phony. We keep that information +# in a variable so we can use it in if_changed. +.PHONY: ${PHONY} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a33ef1e --- /dev/null +++ b/README.md @@ -0,0 +1,263 @@ +# Prometheus PostgreSQL exporter + +This helm chart enables the deployment of a Prometheus metrics exporter for PostgreSQL databases and allows the +individual configuration of additional containers/initContainers, mounting of volumes, defining additional environment +variables, apply a user-defined web-config.yaml and much more. + +Chapter [configuration and installation](#helm-configuration-and-installation) describes the basics how to configure helm +and use it to deploy the exporter. It also contains further configuration examples. + +Furthermore, this helm chart unit tests to detect regressions and stabilize the deployment. Additionally, this helm +chart is tested for deployment scenarios with ArgoCD. + +> ![NOTE] +> This is not the official *community* helm chart of the Prometheus metric exporter for PostgreSQL databases. You can +> find the official community chart [here](https://github.com/prometheus-community/helm-charts). + +## Helm: configuration and installation + +1. A helm chart repository must be configured, to pull the helm charts from. +2. All available parameters are [here](#parameters). The parameters can be defined via the helm `--set` flag or directly + as part of a `values.yaml` file. The following example defines the `prometheus-exporter` repository and use the + `--set` flag for a basic deployment. + +```bash +helm repo add prometheus-exporter https://charts.cryptic.systems/prometheus-exporter +helm repo update +helm install prometheus-exporter/prometheus-postgres-exporter prometheus-postgres-exporter \ + --set 'config.database.secret.databaseUsername=postgres' \ + --set 'config.database.secret.databasePassword=postgres' \ + --set 'config.database.secret.databaseConnectionUrl="postgres.example.local:5432/postgres?ssl=disable"' +``` + +Instead of passing all parameters via the *set* flag, it is also possible to define them as part of the `values.yaml`. +The following command downloads the `values.yaml` for a specific version of this chart. Please keep in mind, that the +version of the chart must be in sync with the `values.yaml`. Newer *minor* versions can have new features. New *major* +versions can break something! + +```bash +helm show values prometheus-exporter/prometheus-postgres-exporter --version 0.1.0 > values.yaml +``` + +A complete list of available helm chart versions can be displayed via the following command: + +```bash +helm search repo prometheus-postgres-exporter --versions +``` + +### Examples + +The following examples serve as individual configurations and as inspiration for how deployment problems can be solved. + +### TLS authentication and encryption + +The first example shows how to deploy the metric exporter with TLS encryption. The verification of the custom TLS +certification will be skipped by Prometheus. + +> [!WARN] +> A TLS secret with the name `prometheus-postgresql-exporter-http` containing a `ca.crt`, `tls.key` and `tls.crt` is +> already present. + +```bash +helm install prometheus-exporter/prometheus-postgres-exporter prometheus-postgres-exporter \ + --set 'config.database.secret.databaseUsername=postgres' \ + --set 'config.database.secret.databasePassword=postgres' \ + --set 'config.database.secret.databaseConnectionUrl="postgres.example.local:5432/postgres?ssl=disable"' \ + --set 'config.webConfig.secret.webConfig.cert_file=/etc/prometheus-postgres-exporter/tls/tls.crt' \ + --set 'config.webConfig.secret.webConfig.client_ca_file=/etc/prometheus-postgres-exporter/tls/ca.crt' \ + --set 'config.webConfig.secret.webConfig.key_file=/etc/prometheus-postgres-exporter/tls/tls.key' + --set 'deployment.volumes[0].name=tls' \ + --set 'deployment.volumes[0].secret.secretName=prometheus-postgresql-exporter-http' \ + --set 'deployment.postgresExporter.volumeMounts[0].name=tls' \ + --set 'deployment.postgresExporter.volumeMounts[0].mountPath=/etc/prometheus-postgres-exporter/tls' \ + --set 'deployment.postgresExporter.volumeMounts[0].readOnly=true' \ + --set 'prometheus.serviceMonitor.enabled=true' \ + --set 'prometheus.serviceMonitor.scheme=https' \ + --set 'prometheus.serviceMonitor.tlsConfig.insecureSkipVerify=true' +``` + +If the Prometheus pod has a TLS certificate mounted and is also signed by the private key of the CA which issued the TLS +certificate for the metrics exporter - TLS certificate verification can be enabled. The following flags must be +replaced: + +```diff + helm install prometheus-exporter/prometheus-postgres-exporter prometheus-postgres-exporter \ + --set 'config.database.secret.databaseUsername=postgres' \ + --set 'config.database.secret.databasePassword=postgres' \ + --set 'config.database.secret.databaseConnectionUrl="postgres.example.local:5432/postgres?ssl=disable"' \ + --set 'config.webConfig.secret.webConfig.cert_file=/etc/prometheus-postgres-exporter/tls/tls.crt' \ + --set 'config.webConfig.secret.webConfig.client_ca_file=/etc/prometheus-postgres-exporter/tls/ca.crt' \ + --set 'config.webConfig.secret.webConfig.key_file=/etc/prometheus-postgres-exporter/tls/tls.key' + --set 'deployment.volumes[0].name=tls' \ + --set 'deployment.volumes[0].secret.secretName=prometheus-postgresql-exporter-http' \ + --set 'deployment.postgresExporter.volumeMounts[0].name=tls' \ + --set 'deployment.postgresExporter.volumeMounts[0].mountPath=/etc/prometheus-postgres-exporter/tls' \ + --set 'deployment.postgresExporter.volumeMounts[0].readOnly=true' \ + --set 'prometheus.serviceMonitor.enabled=true' \ + --set 'prometheus.serviceMonitor.scheme=https' \ +- --set 'prometheus.serviceMonitor.tlsConfig.insecureSkipVerify=true' \ ++ --set 'prometheus.serviceMonitor.tlsConfig.caFile=/etc/prometheus/tls/ca.crt' \ ++ --set 'prometheus.serviceMonitor.tlsConfig.certFile=/etc/prometheus/tls/tls.crt' \ ++ --set 'prometheus.serviceMonitor.tlsConfig.keyFile=/etc/prometheus/tls/tls.key' +``` + +## Parameters + +### Global + +| Name | Description | Value | +| ------------------ | ----------------------------------------- | ----- | +| `nameOverride` | Individual release name suffix. | `""` | +| `fullnameOverride` | Override the complete release name logic. | `""` | + +### Configuration + +| Name | Description | Value | +| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `config.database.existingSecret.enabled` | Mount an existing secret containing the application specific `DATA_SOURCE_` prefixed environment variables. | `false` | +| `config.database.existingSecret.secretName` | Name of the existing secret containing the application specific `DATA_SOURCE_` prefixed environment variables. | `""` | +| `config.database.secret.annotations` | Additional annotations of the secret containing the database credentials. | `{}` | +| `config.database.secret.labels` | Additional labels of the secret containing the database credentials. | `{}` | +| `config.database.secret.databaseUsername` | Database username. Will be defined as env `DATA_SOURCE_USER` as part of a secret. | `""` | +| `config.database.secret.databasePassword` | Database password. Will be defined as env `DATA_SOURCE_PASS` as part of a secret. | `""` | +| `config.database.secret.databaseConnectionUrl` | Complex database connection URL. Will be defined as env `DATA_SOURCE_URI` as part of a secret. | `""` | +| `config.exporterConfig.existingSecret.enabled` | Mount an existing secret containing the key `exporter_config.yaml`. | `false` | +| `config.exporterConfig.existingSecret.secretName` | Name of the existing secret containing the key `exporter_config.yaml`. | `""` | +| `config.exporterConfig.secret.annotations` | Additional annotations of the secret containing the `exporterConfig.yaml`. | `{}` | +| `config.exporterConfig.secret.labels` | Additional labels of the secret containing the `exporterConfig.yaml`. | `{}` | +| `config.exporterConfig.secret.exporterConfig` | Content of the `exporterConfig.yaml`. Further information can be found [here](https://prometheus.io/docs/prometheus/latest/configuration/https/). | `{}` | +| `config.webConfig.existingSecret.enabled` | Mount an existing secret containing the key `webConfig.yaml`. | `false` | +| `config.webConfig.existingSecret.secretName` | Name of the existing secret containing the key `webConfig.yaml`. | `""` | +| `config.webConfig.secret.annotations` | Additional annotations of the secret containing the `webConfig.yaml`. | `{}` | +| `config.webConfig.secret.labels` | Additional labels of the secret containing the `webConfig.yaml`. | `{}` | +| `config.webConfig.secret.webConfig` | Content of the `webConfig.yaml`. Further information can be found [here](https://prometheus.io/docs/prometheus/latest/configuration/https/). | `{}` | + +### Deployment + +| Name | Description | Value | +| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| `deployment.annotations` | Additional deployment annotations. | `{}` | +| `deployment.labels` | Additional ingress labels. | `{}` | +| `deployment.additionalContainers` | List of additional containers. | `[]` | +| `deployment.affinity` | Affinity for the postgres-exporter deployment. | `{}` | +| `deployment.initContainers` | List of additional init containers. | `[]` | +| `deployment.dnsConfig` | dnsConfig of the postgres-exporter deployment. | `{}` | +| `deployment.dnsPolicy` | dnsPolicy of the postgres-exporter deployment. | `""` | +| `deployment.hostname` | Individual hostname of the pod. | `""` | +| `deployment.subdomain` | Individual domain of the pod. | `""` | +| `deployment.hostNetwork` | Use the kernel network namespace of the host system. | `false` | +| `deployment.imagePullSecrets` | Secret to use for pulling the image. | `[]` | +| `deployment.postgresExporter.args` | Arguments passed to the postgres-exporter container. | `[]` | +| `deployment.postgresExporter.env` | List of environment variables for the postgres-exporter container. | `[]` | +| `deployment.postgresExporter.envFrom` | List of environment variables mounted from configMaps or secrets for the postgres-exporter container. | `[]` | +| `deployment.postgresExporter.image.registry` | Image registry, eg. `docker.io`. | `quay.io` | +| `deployment.postgresExporter.image.repository` | Image repository, eg. `library/busybox`. | `prometheuscommunity/postgres-exporter` | +| `deployment.postgresExporter.image.tag` | Custom image tag, eg. `0.1.0`. Defaults to `appVersion`. | `""` | +| `deployment.postgresExporter.image.pullPolicy` | Image pull policy. | `IfNotPresent` | +| `deployment.postgresExporter.resources` | CPU and memory resources of the pod. | `{}` | +| `deployment.postgresExporter.securityContext` | Security context of the container of the deployment. | `{}` | +| `deployment.postgresExporter.volumeMounts` | Additional volume mounts. | `{}` | +| `deployment.nodeSelector` | NodeSelector of the postgres-exporter deployment. | `{}` | +| `deployment.priorityClassName` | PriorityClassName of the postgres-exporter deployment. | `""` | +| `deployment.replicaCount` | Number of replicas for the postgres-exporter deployment. | `1` | +| `deployment.securityContext` | Security context of the postgres-exporter deployment. | `{}` | +| `deployment.strategy.type` | Strategy type - `Recreate` or `Rollingupdate`. | `Recreate` | +| `deployment.strategy.rollingUpdate.maxSurge` | The maximum number of pods that can be scheduled above the desired number of pods during a rolling update. | `1` | +| `deployment.strategy.rollingUpdate.maxUnavailable` | The maximum number of pods that can be unavailable during a rolling update. | `1` | +| `deployment.terminationGracePeriodSeconds` | How long to wait until forcefully kill the pod. | `60` | +| `deployment.tolerations` | Tolerations of the postgres-exporter deployment. | `[]` | +| `deployment.topologySpreadConstraints` | TopologySpreadConstraints of the postgres-exporter deployment. | `[]` | +| `deployment.volumes` | Additional volumes to mount into the pods of the Prometheus-exporter deployment. | `[]` | + +### Grafana + +| Name | Description | Value | +| ------------------------------------ | --------------------------------------------------------- | ------- | +| `grafana.enabled` | Enable integration into Grafana. | `false` | +| `grafana.dashboards.businessMetrics` | Enable deployment of Grafana dashboard `businessMetrics`. | `true` | + +### Ingress + +| Name | Description | Value | +| --------------------- | -------------------------------------------------------------------------------------------------------------------- | ------- | +| `ingress.enabled` | Enable creation of an ingress resource. Requires, that the http service is also enabled. | `false` | +| `ingress.className` | Ingress class. | `nginx` | +| `ingress.annotations` | Additional ingress annotations. | `{}` | +| `ingress.labels` | Additional ingress labels. | `{}` | +| `ingress.hosts` | Ingress specific configuration. Specification only required when another ingress controller is used instead of `t1k. | `[]` | +| `ingress.tls` | Ingress TLS settings. Specification only required when another ingress controller is used instead of `t1k``. | `[]` | + +### Pod disruption + +| Name | Description | Value | +| --------------------- | ---------------------- | ----- | +| `podDisruptionBudget` | Pod disruption budget. | `{}` | + +### Network + +| Name | Description | Value | +| ----------------- | ------------------------------------------------------------------------------------------------------------------ | ----- | +| `networkPolicies` | Deploy network policies based on the used container network interface (CNI) implementation - like calico or weave. | `{}` | + +### Prometheus + +| Name | Description | Value | +| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `prometheus.metrics.enabled` | Enable of scraping metrics by Prometheus. | `true` | +| `prometheus.metrics.podMonitor.enabled` | Enable creation of a podMonitor. Excludes the existence of a serviceMonitor resource. | `false` | +| `prometheus.metrics.podMonitor.annotations` | Additional podMonitor annotations. | `{}` | +| `prometheus.metrics.podMonitor.enableHttp2` | Enable HTTP2. | `false` | +| `prometheus.metrics.podMonitor.followRedirects` | FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. | `false` | +| `prometheus.metrics.podMonitor.honorLabels` | Honor labels. | `false` | +| `prometheus.metrics.podMonitor.labels` | Additional podMonitor labels. | `{}` | +| `prometheus.metrics.podMonitor.interval` | Interval at which metrics should be scraped. If not specified Prometheus' global scrape interval is used. | `60s` | +| `prometheus.metrics.podMonitor.path` | HTTP path for scraping Prometheus metrics. | `/metrics` | +| `prometheus.metrics.podMonitor.relabelings` | RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds relabelings for a few standard Kubernetes fields. | `[]` | +| `prometheus.metrics.podMonitor.scrapeTimeout` | Timeout after which the scrape is ended. If not specified, global Prometheus scrape timeout is used. | `30s` | +| `prometheus.metrics.podMonitor.scheme` | HTTP scheme to use for scraping. For example `http` or `https`. | `http` | +| `prometheus.metrics.podMonitor.tlsConfig` | TLS configuration to use when scraping the metric endpoint by Prometheus. | `{}` | +| `prometheus.metrics.serviceMonitor.enabled` | Enable creation of a serviceMonitor. Excludes the existence of a podMonitor resource. | `false` | +| `prometheus.metrics.serviceMonitor.annotations` | Additional serviceMonitor annotations. | `{}` | +| `prometheus.metrics.serviceMonitor.labels` | Additional serviceMonitor labels. | `{}` | +| `prometheus.metrics.serviceMonitor.enableHttp2` | Enable HTTP2. | `false` | +| `prometheus.metrics.serviceMonitor.followRedirects` | FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. | `false` | +| `prometheus.metrics.serviceMonitor.honorLabels` | Honor labels. | `false` | +| `prometheus.metrics.serviceMonitor.interval` | Interval at which metrics should be scraped. If not specified Prometheus' global scrape interval is used. | `60s` | +| `prometheus.metrics.serviceMonitor.path` | HTTP path for scraping Prometheus metrics. | `/metrics` | +| `prometheus.metrics.serviceMonitor.port` | HTTP port for scraping Prometheus metrics. | `9187` | +| `prometheus.metrics.serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds relabelings for a few standard Kubernetes fields. | `[]` | +| `prometheus.metrics.serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended. If not specified, global Prometheus scrape timeout is used. | `30s` | +| `prometheus.metrics.serviceMonitor.scheme` | HTTP scheme to use for scraping. For example `http` or `https`. | `http` | +| `prometheus.metrics.serviceMonitor.tlsConfig` | TLS configuration to use when scraping the metric endpoint by Prometheus. | `{}` | +| `prometheus.rules` | Array of Prometheus rules for monitoring the application and triggering alerts. | `[]` | + +### Service + +| Name | Description | Value | +| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `services.http.enabled` | Enable the service. | `true` | +| `services.http.annotations` | Additional service annotations. | `{}` | +| `services.http.externalIPs` | External IPs for the service. | `[]` | +| `services.http.externalTrafficPolicy` | If `service.type` is `NodePort` or `LoadBalancer`, set this to `Local` to tell kube-proxy to only use node local endpoints for cluster external traffic. Furthermore, this enables source IP preservation. | `Cluster` | +| `services.http.internalTrafficPolicy` | If `service.type` is `NodePort` or `LoadBalancer`, set this to `Local` to tell kube-proxy to only use node local endpoints for cluster internal traffic. | `Cluster` | +| `services.http.ipFamilies` | IPFamilies is list of IP families (e.g. `IPv4`, `IPv6`) assigned to this service. This field is usually assigned automatically based on cluster configuration and only required for customization. | `[]` | +| `services.http.labels` | Additional service labels. | `{}` | +| `services.http.loadBalancerClass` | LoadBalancerClass is the class of the load balancer implementation this Service belongs to. Requires service from type `LoadBalancer`. | `""` | +| `services.http.loadBalancerIP` | LoadBalancer will get created with the IP specified in this field. Requires service from type `LoadBalancer`. | `""` | +| `services.http.loadBalancerSourceRanges` | Source range filter for LoadBalancer. Requires service from type `LoadBalancer`. | `[]` | +| `services.http.port` | Port to forward the traffic to. | `9187` | +| `services.http.sessionAffinity` | Supports `ClientIP` and `None`. Enable client IP based session affinity via `ClientIP`. | `None` | +| `services.http.sessionAffinityConfig` | Contains the configuration of the session affinity. | `{}` | +| `services.http.type` | Kubernetes service type for the traffic. | `ClusterIP` | + +### ServiceAccount + +| Name | Description | Value | +| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `serviceAccount.existing.enabled` | Use an existing service account instead of creating a new one. Assumes that the user has all the necessary kubernetes API authorizations. | `false` | +| `serviceAccount.existing.serviceAccountName` | Name of the existing service account. | `""` | +| `serviceAccount.new.annotations` | Additional service account annotations. | `{}` | +| `serviceAccount.new.labels` | Additional service account labels. | `{}` | +| `serviceAccount.new.automountServiceAccountToken` | Enable/disable auto mounting of the service account token. | `true` | +| `serviceAccount.new.imagePullSecrets` | ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this serviceAccount. | `[]` | +| `serviceAccount.new.secrets` | Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. | `[]` | diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..455c3b6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,919 @@ +{ + "name": "qu-seed-chart", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "qu-seed-chart", + "license": "MIT", + "devDependencies": { + "@bitnami/readme-generator-for-helm": "^2.5.0", + "markdownlint-cli": "^0.41.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + } + }, + "node_modules/@bitnami/readme-generator-for-helm": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@bitnami/readme-generator-for-helm/-/readme-generator-for-helm-2.6.1.tgz", + "integrity": "sha512-rN0m0sfbOuaNdCmQWBfSj9o4kgzz+Dw67Dl1ssDVqghv/UpLkrDmNuTxhD1CWu+sesGL66UYJ2VplGz9KxlAdg==", + "dev": true, + "dependencies": { + "commander": "^7.1.0", + "dot-object": "^2.1.4", + "lodash": "^4.17.21", + "markdown-table": "^2.0.0", + "yaml": "^2.0.0-3" + }, + "bin": { + "readme-generator": "bin/index.js" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/dot-object": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/dot-object/-/dot-object-2.1.4.tgz", + "integrity": "sha512-7FXnyyCLFawNYJ+NhkqyP9Wd2yzuo+7n9pGiYpkmXCTYa8Ci2U0eUNDVg5OuO5Pm6aFXI2SWN8/N/w7SJWu1WA==", + "dev": true, + "dependencies": { + "commander": "^4.0.0", + "glob": "^7.1.5" + }, + "bin": { + "dot-object": "bin/dot-object" + } + }, + "node_modules/dot-object/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz", + "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/markdownlint": { + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz", + "integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==", + "dev": true, + "dependencies": { + "markdown-it": "14.1.0", + "markdownlint-micromark": "0.1.9" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.41.0.tgz", + "integrity": "sha512-kp29tKrMKdn+xonfefjp3a/MsNzAd9c5ke0ydMEI9PR98bOjzglYN4nfMSaIs69msUf1DNkgevAIAPtK2SeX0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "~12.1.0", + "get-stdin": "~9.0.0", + "glob": "~10.4.1", + "ignore": "~5.3.1", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.2.1", + "jsonpointer": "5.0.1", + "markdownlint": "~0.34.0", + "minimatch": "~9.0.4", + "run-con": "~1.3.2", + "smol-toml": "~1.2.0" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/markdownlint-cli/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/markdownlint-cli/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/markdownlint-cli/node_modules/glob": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", + "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/markdownlint-cli/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/markdownlint-micromark": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz", + "integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/run-con": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", + "integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~4.1.0", + "minimist": "^1.2.8", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.1.tgz", + "integrity": "sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/smol-toml": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.2.0.tgz", + "integrity": "sha512-KObxdQANC/xje3OoatMbSwQf2XAvJ0RbK+4nmQRszFNZptbNRnMWqbLF/zb4sMi9xJ6HNyhWXeuZ9zC/I/XY7w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18", + "pnpm": ">= 9" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yaml": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz", + "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==", + "dev": true, + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..361cd38 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "qu-seed-chart", + "homepage": "https://github.com/dedalus-cis4u/qu-seed-chart.git", + "license": "MIT", + "private": true, + "engineStrict": true, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "scripts": { + "readme:lint": "markdownlint *.md -f", + "readme:parameters": "readme-generator -v values.yaml -r README.md" + }, + "devDependencies": { + "@bitnami/readme-generator-for-helm": "^2.5.0", + "markdownlint-cli": "^0.41.0" + } +} diff --git a/templates/prometheus-postgres-exporter/_common.tpl b/templates/prometheus-postgres-exporter/_common.tpl new file mode 100644 index 0000000..e8c23c4 --- /dev/null +++ b/templates/prometheus-postgres-exporter/_common.tpl @@ -0,0 +1,58 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "prometheus-postgres-exporter.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "prometheus-postgres-exporter.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "prometheus-postgres-exporter.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common annotations +*/}} +{{- define "prometheus-postgres-exporter.annotations" -}} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "prometheus-postgres-exporter.labels" -}} +{{ include "prometheus-postgres-exporter.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +helm.sh/chart: {{ include "prometheus-postgres-exporter.chart" . }} +{{- end }} + +{{/* +Common selector labels +*/}} +{{- define "prometheus-postgres-exporter.selectorLabels" -}} +app.kubernetes.io/name: {{ include "prometheus-postgres-exporter.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/_deployment.tpl b/templates/prometheus-postgres-exporter/_deployment.tpl new file mode 100644 index 0000000..55da6a2 --- /dev/null +++ b/templates/prometheus-postgres-exporter/_deployment.tpl @@ -0,0 +1,70 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.deployment.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- if .Values.deployment.annotations }} +{{ toYaml .Values.deployment.annotations }} +{{- end }} +{{- end }} + +{{/* envFrom */}} + +{{- define "prometheus-postgres-exporter.deployment.envFrom" -}} +{{- $envFrom := dict "envFrom" (.Values.deployment.postgresExporter.envFrom | default (list) ) }} +{{- $secretName := .Values.config.database.existingSecret.secretName -}} +{{- if not .Values.config.database.existingSecret.enabled }} +{{- $secretName = printf "%s-database-env" (include "prometheus-postgres-exporter.fullname" . ) }} +{{- end }} +{{- $envFrom = merge $envFrom (dict "envFrom" (list (dict "secretRef" (dict "name" $secretName)))) }} +{{ toYaml $envFrom }} +{{- end -}} + +{{/* image */}} + +{{- define "prometheus-postgres-exporter.deployment.images.postgres-exporter.fqin" -}} +{{- $registry := .Values.deployment.postgresExporter.image.registry -}} +{{- $repository := .Values.deployment.postgresExporter.image.repository -}} +{{- $tag := default .Chart.AppVersion .Values.deployment.postgresExporter.image.tag -}} +{{- printf "%s/%s:v%s" $registry $repository $tag -}} +{{- end -}} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.deployment.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- if .Values.deployment.labels }} +{{ toYaml .Values.deployment.labels }} +{{- end }} +{{- end }} + +{{/* serviceAccount */}} + +{{- define "prometheus-postgres-exporter.deployment.serviceAccount" -}} +{{- if .Values.serviceAccount.existing.enabled -}} +{{- printf "%s" .Values.serviceAccount.existing.serviceAccountName -}} +{{- else -}} +{{- include "prometheus-postgres-exporter.fullname" . -}} +{{- end -}} +{{- end }} + +{{/* volumeMounts */}} + +{{- define "prometheus-postgres-exporter.deployment.volumeMounts" -}} +{{- $volumeMounts := dict "volumeMounts" (.Values.deployment.postgresExporter.volumeMounts | default (list) ) }} +{{- $volumeMounts = merge $volumeMounts (dict "volumeMounts" (list (dict "name" "exporter-config" "mountPath" "/etc/prometheus-postgres-exporter/config.d" ))) }} +{{ toYaml $volumeMounts }} +{{- end -}} + +{{/* volumes */}} + +{{- define "prometheus-postgres-exporter.deployment.volumes" -}} +{{- $volumes := dict "volumes" (.Values.deployment.volumes | default (list) ) }} +{{- $secretName := .Values.config.exporterConfig.existingSecret.secretName -}} +{{- if not .Values.config.exporterConfig.existingSecret.enabled }} +{{- $secretName = printf "%s-exporter-config" (include "prometheus-postgres-exporter.fullname" . ) }} +{{- end }} +{{- $volumes = merge $volumes (dict "volumes" (list (dict "name" "exporter-config" "secret" (dict "secretName" $secretName)))) }} +{{ toYaml $volumes }} +{{- end -}} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/_ingress.tpl b/templates/prometheus-postgres-exporter/_ingress.tpl new file mode 100644 index 0000000..bb2dfff --- /dev/null +++ b/templates/prometheus-postgres-exporter/_ingress.tpl @@ -0,0 +1,19 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.ingress.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- if .Values.ingress.annotations }} +{{ toYaml .Values.ingress.annotations }} +{{- end }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.ingress.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- if .Values.ingress.labels }} +{{ toYaml .Values.ingress.labels }} +{{- end }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/_pod.tpl b/templates/prometheus-postgres-exporter/_pod.tpl new file mode 100644 index 0000000..c728c7f --- /dev/null +++ b/templates/prometheus-postgres-exporter/_pod.tpl @@ -0,0 +1,17 @@ +--- + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.pod.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.pod.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- end }} + +{{- define "prometheus-postgres-exporter.pod.selectorLabels" -}} +{{ include "prometheus-postgres-exporter.pod.labels" . }} +{{- end }} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/_podMonitors.tpl b/templates/prometheus-postgres-exporter/_podMonitors.tpl new file mode 100644 index 0000000..e1cc7f3 --- /dev/null +++ b/templates/prometheus-postgres-exporter/_podMonitors.tpl @@ -0,0 +1,19 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.podMonitors.http.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- if .Values.prometheus.metrics.podMonitor.annotations }} +{{ toYaml .Values.prometheus.metrics.podMonitor.annotations }} +{{- end }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.podMonitors.http.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- if .Values.prometheus.metrics.podMonitor.labels }} +{{ toYaml .Values.prometheus.metrics.podMonitor.labels }} +{{- end }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/_prometheusRules.tpl b/templates/prometheus-postgres-exporter/_prometheusRules.tpl new file mode 100644 index 0000000..3043c09 --- /dev/null +++ b/templates/prometheus-postgres-exporter/_prometheusRules.tpl @@ -0,0 +1,13 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.prometheusRules.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.prometheusRules.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/_secrets.tpl b/templates/prometheus-postgres-exporter/_secrets.tpl new file mode 100644 index 0000000..99354f9 --- /dev/null +++ b/templates/prometheus-postgres-exporter/_secrets.tpl @@ -0,0 +1,48 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.secrets.database.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- if .Values.config.database.secret.annotations }} +{{ toYaml .Values.config.database.secret.annotations }} +{{- end }} +{{- end }} + +{{- define "prometheus-postgres-exporter.secrets.exporterConfig.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- if .Values.config.exporterConfig.secret.annotations }} +{{ toYaml .Values.config.exporterConfig.secret.annotations }} +{{- end }} +{{- end }} + +{{- define "prometheus-postgres-exporter.secrets.webConfig.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- if .Values.config.webConfig.secret.annotations }} +{{ toYaml .Values.config.webConfig.secret.annotations }} +{{- end }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.secrets.database.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- if .Values.config.database.secret.labels }} +{{ toYaml .Values.config.database.secret.labels }} +{{- end }} +{{- end }} + +{{- define "prometheus-postgres-exporter.secrets.exporterConfig.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- if .Values.config.exporterConfig.secret.labels }} +{{ toYaml .Values.config.exporterConfig.secret.labels }} +{{- end }} +{{- end }} + + +{{- define "prometheus-postgres-exporter.secrets.webConfig.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- if .Values.config.webConfig.secret.labels }} +{{ toYaml .Values.config.webConfig.secret.labels }} +{{- end }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/_serviceAccount.tpl b/templates/prometheus-postgres-exporter/_serviceAccount.tpl new file mode 100644 index 0000000..66f09fd --- /dev/null +++ b/templates/prometheus-postgres-exporter/_serviceAccount.tpl @@ -0,0 +1,17 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.serviceAccount.annotations" -}} +{{- if .Values.serviceAccount.new.annotations }} +{{ toYaml .Values.serviceAccount.new.annotations }} +{{- end }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.serviceAccount.labels" -}} +{{- if .Values.serviceAccount.new.labels }} +{{ toYaml .Values.serviceAccount.new.labels }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/_serviceMonitors.tpl b/templates/prometheus-postgres-exporter/_serviceMonitors.tpl new file mode 100644 index 0000000..24c0344 --- /dev/null +++ b/templates/prometheus-postgres-exporter/_serviceMonitors.tpl @@ -0,0 +1,25 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.serviceMonitors.http.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- if .Values.prometheus.metrics.serviceMonitor.annotations }} +{{ toYaml .Values.prometheus.metrics.serviceMonitor.annotations }} +{{- end }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.serviceMonitors.http.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{- if .Values.prometheus.metrics.serviceMonitor.labels }} +{{ toYaml .Values.prometheus.metrics.serviceMonitor.labels }} +{{- end }} +{{- end }} + +{{- define "prometheus-postgres-exporter.serviceMonitors.http.selectorLabels" -}} +{{ include "prometheus-postgres-exporter.selectorLabels" . }} +{{/* Add label to select the correct service via `selector.matchLabels` of the serviceMonitor resource. */}} +app.kubernetes.io/service-name: http +{{- end }} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/_services.tpl b/templates/prometheus-postgres-exporter/_services.tpl new file mode 100644 index 0000000..54128cc --- /dev/null +++ b/templates/prometheus-postgres-exporter/_services.tpl @@ -0,0 +1,29 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.services.http.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" . }} +{{- if .Values.services.http.annotations }} +{{ toYaml .Values.services.http.annotations }} +{{- end }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.services.http.labels" -}} +{{ include "prometheus-postgres-exporter.labels" . }} +{{/* Add label to select the correct service via `selector.matchLabels` of the serviceMonitor resource. */}} +app.kubernetes.io/service-name: http +{{- if .Values.services.http.labels }} +{{ toYaml .Values.services.http.labels }} +{{- end }} +{{- end }} + +{{/* names */}} + +{{- define "prometheus-postgres-exporter.services.http.name" -}} +{{- if .Values.services.http.enabled -}} +{{ include "prometheus-postgres-exporter.fullname" . }}-http +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/deployment.yaml b/templates/prometheus-postgres-exporter/deployment.yaml new file mode 100644 index 0000000..60b3390 --- /dev/null +++ b/templates/prometheus-postgres-exporter/deployment.yaml @@ -0,0 +1,119 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with (include "prometheus-postgres-exporter.deployment.annotations" . | fromYaml) }} + annotations: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.deployment.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + {{- include "prometheus-postgres-exporter.pod.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "prometheus-postgres-exporter.pod.labels" . | nindent 8 }} + spec: + containers: + - name: postgres-exporter + args: + - "--config.file=/etc/prometheus-postgres-exporter/config.d/exporterConfig.yaml" + - "--web.listen-address=:9187" + {{- range .Values.deployment.postgresExporter.args }} + - {{ . | quote }} + {{- end }} + {{- with .Values.deployment.postgresExporter.env }} + env: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- $envFrom := (include "prometheus-postgres-exporter.deployment.envFrom" . | fromYaml) }} + {{- if hasKey $envFrom "envFrom" }} + envFrom: + {{- toYaml $envFrom.envFrom | nindent 8 }} + {{- end }} + image: {{ include "prometheus-postgres-exporter.deployment.images.postgres-exporter.fqin" . | quote }} + imagePullPolicy: {{ .Values.deployment.postgresExporter.image.pullPolicy }} + livenessProbe: + tcpSocket: + port: 9187 + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 60 + successThreshold: 1 + timeoutSeconds: 3 + readinessProbe: + tcpSocket: + port: 9187 + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 3 + ports: + - name: http + containerPort: 9187 + protocol: TCP + {{- with .Values.deployment.containerResources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.deployment.postgresExporter.securityContext }} + securityContext: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- $volumeMounts := (include "prometheus-postgres-exporter.deployment.volumeMounts" . | fromYaml) }} + {{- if hasKey $volumeMounts "volumeMounts" }} + volumeMounts: + {{- toYaml $volumeMounts.volumeMounts | nindent 8 }} + {{- end }} + {{- with .Values.deployment.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.deployment.dnsPolicy }} + dnsPolicy: {{ .Values.deployment.dnsPolicy }} + {{- end }} + {{- if .Values.deployment.hostname }} + hostname: {{ .Values.batch.dbUpdate.hostname }} + {{- end }} + hostNetwork: {{ .Values.deployment.hostNetwork }} + {{- with .Values.deployment.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.deployment.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.deployment.priorityClassName }} + priorityClassName: {{ .Values.deployment.priorityClassName }} + {{- end }} + restartPolicy: {{ .Values.deployment.restartPolicy }} + {{- with .Values.deployment.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccount: {{ include "prometheus-postgres-exporter.deployment.serviceAccount" . }} + {{- if .Values.deployment.subdomain }} + subdomain: {{ .Values.deployment.subdomain }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds }} + {{- with .Values.deployment.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.deployment.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- $volumes := (include "prometheus-postgres-exporter.deployment.volumes" . | fromYaml) }} + {{- if hasKey $volumes "volumes" }} + volumes: + {{- toYaml $volumes.volumes | nindent 6 }} + {{- end }} diff --git a/templates/prometheus-postgres-exporter/ingress.yaml b/templates/prometheus-postgres-exporter/ingress.yaml new file mode 100644 index 0000000..d36bda4 --- /dev/null +++ b/templates/prometheus-postgres-exporter/ingress.yaml @@ -0,0 +1,45 @@ +{{- if and .Values.services.http.enabled .Values.ingress.enabled }} +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + {{- with (include "prometheus-postgres-exporter.ingress.annotations" . | fromYaml) }} + annotations: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.ingress.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + ingressClassName: {{ .Values.ingress.className }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ tpl .host $ | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if .pathType }} + pathType: {{ .pathType }} + {{- end }} + backend: + service: + name: {{ include "prometheus-postgres-exporter.fullname" $ }} + port: + number: {{ $.Values.services.http.port }} + {{- end }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ tpl . $ | quote }} + {{- end }} + secretName: {{ .secretName | quote }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/podMonitor.yaml b/templates/prometheus-postgres-exporter/podMonitor.yaml new file mode 100644 index 0000000..6140828 --- /dev/null +++ b/templates/prometheus-postgres-exporter/podMonitor.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.prometheus.metrics.enabled .Values.prometheus.metrics.podMonitor.enabled (not .Values.prometheus.metrics.serviceMonitor.enabled) }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + {{- with (include "prometheus-postgres-exporter.podMonitors.http.annotations" . | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.podMonitors.http.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }}-http + namespace: {{ .Release.Namespace }} +spec: + podMetricsEndpoints: + - enableHttp2: {{ required "The enableHttp2 option of the podMonitor is not defined!" .Values.prometheus.metrics.podMonitor.enableHttp2 }} + followRedirects: {{ required "The followRedirects option of the podMonitor is not defined!" .Values.prometheus.metrics.podMonitor.followRedirects }} + honorLabels: {{ required "The honorLabels option of the podMonitor is not defined!" .Values.prometheus.metrics.podMonitor.honorLabels }} + interval: {{ required "The scrape interval of the podMonitor is not defined!" .Values.prometheus.metrics.podMonitor.interval }} + path: {{ required "The metric path of the podMonitor is not defined!" .Values.prometheus.metrics.podMonitor.path }} + port: "http" + {{- with .Values.prometheus.metrics.podMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + scrapeTimeout: {{ required "The scrape timeout of the podMonitor is not defined!" .Values.prometheus.metrics.podMonitor.scrapeTimeout }} + scheme: {{ required "The scheme of the podMonitor is not defined!" .Values.prometheus.metrics.podMonitor.scheme}} + {{- with .Values.prometheus.metrics.podMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "prometheus-postgres-exporter.pod.selectorLabels" . | nindent 6 }} +{{- end }} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/prometheusRules.yaml b/templates/prometheus-postgres-exporter/prometheusRules.yaml new file mode 100644 index 0000000..0ef225a --- /dev/null +++ b/templates/prometheus-postgres-exporter/prometheusRules.yaml @@ -0,0 +1,23 @@ +{{- if gt (len .Values.prometheus.rules) 0 }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + {{- with (include "prometheus-postgres-exporter.prometheusRules.annotations" . | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.prometheusRules.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: +{{- with .Values.prometheus.rules }} + groups: + - name: {{ template "prometheus-postgres-exporter.name" $ }} + rules: + {{ toYaml . | nindent 4 }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/secretDatabase.yaml b/templates/prometheus-postgres-exporter/secretDatabase.yaml new file mode 100644 index 0000000..a1483c0 --- /dev/null +++ b/templates/prometheus-postgres-exporter/secretDatabase.yaml @@ -0,0 +1,20 @@ +{{- if not (.Values.config.database.existingSecret.enabled) }} +--- +apiVersion: v1 +kind: Secret +metadata: + {{- with (include "prometheus-postgres-exporter.secrets.database.annotations" . | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.secrets.database.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }}-database-env + namespace: {{ .Release.Namespace }} +stringData: + DATA_SOURCE_URI: {{ required "No `databaseConnectionUrl` defined!" .Values.config.database.secret.databaseConnectionUrl }} + DATA_SOURCE_USER: {{ required "No `databaseUsername` defined!" .Values.config.database.secret.databaseUsername }} + DATA_SOURCE_PASS: {{ required "No `databasePassword` defined!" .Values.config.database.secret.databasePassword }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/secretExporterConfig.yaml b/templates/prometheus-postgres-exporter/secretExporterConfig.yaml new file mode 100644 index 0000000..7c9e30d --- /dev/null +++ b/templates/prometheus-postgres-exporter/secretExporterConfig.yaml @@ -0,0 +1,19 @@ +{{- if not .Values.config.exporterConfig.existingSecret.enabled }} +--- +apiVersion: v1 +kind: Secret +metadata: + {{- with (include "prometheus-postgres-exporter.secrets.exporterConfig.annotations" . | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.secrets.exporterConfig.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }}-exporter-config + namespace: {{ .Release.Namespace }} +stringData: + exporterConfig.yaml: | + {{- toYaml .Values.config.exporterConfig.secret.exporterConfig | nindent 4 }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/secretWebConfig.yaml b/templates/prometheus-postgres-exporter/secretWebConfig.yaml new file mode 100644 index 0000000..dfe9f87 --- /dev/null +++ b/templates/prometheus-postgres-exporter/secretWebConfig.yaml @@ -0,0 +1,19 @@ +{{- if and (not (.Values.config.webConfig.existingSecret.enabled)) .Values.config.webConfig.secret.webConfig }} +--- +apiVersion: v1 +kind: Secret +metadata: + {{- with (include "prometheus-postgres-exporter.secrets.webConfig.annotations" . | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.secrets.webConfig.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }}-webconfig + namespace: {{ .Release.Namespace }} +stringData: + webConfig.yaml: | + {{- toYaml .Values.config.webConfig.secret.webConfig | nindent 4 }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/serviceAccount.yaml b/templates/prometheus-postgres-exporter/serviceAccount.yaml new file mode 100644 index 0000000..a395fea --- /dev/null +++ b/templates/prometheus-postgres-exporter/serviceAccount.yaml @@ -0,0 +1,26 @@ +{{- if not .Values.serviceAccount.existing.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + {{- with (include "prometheus-postgres-exporter.serviceAccount.annotations" . | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.serviceAccount.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + automountServiceAccountToken: {{ .Values.serviceAccount.new.automountServiceAccountToken }} + {{- with .Values.serviceAccount.new.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.new.secrets }} + secrets: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/serviceHTTP.yaml b/templates/prometheus-postgres-exporter/serviceHTTP.yaml new file mode 100644 index 0000000..ba4614e --- /dev/null +++ b/templates/prometheus-postgres-exporter/serviceHTTP.yaml @@ -0,0 +1,57 @@ +{{- if .Values.services.http.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + {{- with (include "prometheus-postgres-exporter.services.http.annotations" . | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.services.http.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.services.http.name" . }} + namespace: {{ .Release.Namespace }} +spec: + {{- if not (empty .Values.services.http.externalIPs) }} + externalIPs: + {{- range .Values.services.http.externalIPs }} + - {{ . }} + {{- end }} + {{- end }} + {{- if and (or (eq .Values.services.http.type "LoadBalancer") (eq .Values.services.http.type "NodePort") ) .Values.services.http.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.services.http.externalTrafficPolicy }} + {{- end }} + internalTrafficPolicy: {{ required "No internal traffic policy defined!" .Values.services.http.internalTrafficPolicy }} + {{- if .Values.services.http.ipFamilies }} + ipFamilies: + {{- range .Values.services.http.ipFamilies }} + - {{ . }} + {{- end }} + {{- end }} + {{- if and (eq .Values.services.http.type "LoadBalancer") .Values.services.http.loadBalancerClass }} + loadBalancerClass: {{ .Values.services.http.loadBalancerClass }} + {{- end }} + {{- if and (eq .Values.services.http.type "LoadBalancer") .Values.services.http.loadBalancerIP }} + loadBalancerIP: {{ .Values.services.http.loadBalancerIP }} + {{- end }} + {{- if eq .Values.services.http.type "LoadBalancer" }} + loadBalancerSourceRanges: + {{- range .Values.services.http.loadBalancerSourceRanges }} + - {{ . }} + {{- end }} + {{- end }} + ports: + - name: http + protocol: TCP + port: {{ required "No service port defined!" .Values.services.http.port }} + selector: + {{- include "prometheus-postgres-exporter.pod.selectorLabels" . | nindent 4 }} + sessionAffinity: {{ required "No session affinity defined!" .Values.services.http.sessionAffinity }} + {{- with .Values.services.http.sessionAffinityConfig }} + sessionAffinityConfig: + {{- toYaml . | nindent 4}} + {{- end }} + type: {{ required "No service type defined!" .Values.services.http.type }} +{{- end }} \ No newline at end of file diff --git a/templates/prometheus-postgres-exporter/serviceMonitorHTTP.yaml b/templates/prometheus-postgres-exporter/serviceMonitorHTTP.yaml new file mode 100644 index 0000000..82c09b5 --- /dev/null +++ b/templates/prometheus-postgres-exporter/serviceMonitorHTTP.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.services.http.enabled .Values.prometheus.metrics.enabled .Values.prometheus.metrics.serviceMonitor.enabled (not .Values.prometheus.metrics.podMonitor.enabled)}} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + {{- with (include "prometheus-postgres-exporter.serviceMonitors.http.annotations" . | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.serviceMonitors.http.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "prometheus-postgres-exporter.fullname" . }}-http + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - enableHttp2: {{ required "The enableHttp2 option of the serviceMonitor is not defined!" .Values.prometheus.metrics.serviceMonitor.enableHttp2 }} + followRedirects: {{ required "The followRedirects option of the serviceMonitor is not defined!" .Values.prometheus.metrics.serviceMonitor.followRedirects }} + honorLabels: {{ required "The honorLabels option of the serviceMonitor is not defined!" .Values.prometheus.metrics.serviceMonitor.honorLabels }} + interval: {{ required "The scrape interval of the serviceMonitor is not defined!" .Values.prometheus.metrics.serviceMonitor.interval }} + path: {{ required "The metric path of the serviceMonitor is not defined!" .Values.prometheus.metrics.serviceMonitor.path }} + {{- with .Values.prometheus.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + scrapeTimeout: {{ required "The scrape timeout of the serviceMonitor is not defined!" .Values.prometheus.metrics.serviceMonitor.scrapeTimeout }} + scheme: {{ required "The scheme of the serviceMonitor is not defined!" .Values.prometheus.metrics.serviceMonitor.scheme}} + targetPort: {{ required "The port of the serviceMonitor is not defined!" .Values.prometheus.metrics.serviceMonitor.port }} + {{- with .Values.prometheus.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "prometheus-postgres-exporter.serviceMonitors.http.selectorLabels" . | nindent 6 }} +{{- end }} \ No newline at end of file diff --git a/unittests/deployment/deployment.yaml b/unittests/deployment/deployment.yaml new file mode 100644 index 0000000..8872f5f --- /dev/null +++ b/unittests/deployment/deployment.yaml @@ -0,0 +1,45 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: Deployment template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/deployment.yaml +tests: +- it: Rendering default + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: apps/v1 + kind: Deployment + name: prometheus-postgres-exporter-unittest + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - contains: + path: spec.template.spec.containers[0].envFrom + content: + secretRef: + name: prometheus-postgres-exporter-unittest-database-env + +- it: Test custom database secret + set: + config.database.existingSecret.enabled: true + config.database.existingSecret.secretName: custom-database-secret + asserts: + - contains: + path: spec.template.spec.containers[0].envFrom + content: + secretRef: + name: custom-database-secret diff --git a/unittests/ingress/ingress.yaml b/unittests/ingress/ingress.yaml new file mode 100644 index 0000000..5f63bcf --- /dev/null +++ b/unittests/ingress/ingress.yaml @@ -0,0 +1,140 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: Ingress template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/ingress.yaml +tests: +- it: Skip ingress by default. + asserts: + - hasDocuments: + count: 0 + +- it: Skip ingress, when service is disabled. + set: + services.http.enabled: false + ingress.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Render ingress with default values. + set: + ingress.enabled: true + ingress.hosts: + - host: postgres-exporter.example.local + paths: + - path: / + pathType: Prefix + ingress.tls: + - secretName: postgres-exporter-http-tls + hosts: + - postgres-exporter.example.local + + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: networking.k8s.io/v1 + kind: Ingress + name: prometheus-postgres-exporter-unittest + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - equal: + path: spec.ingressClassName + value: nginx + - contains: + path: spec.rules + content: + host: postgres-exporter.example.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: prometheus-postgres-exporter-unittest + port: + number: 9187 + - contains: + path: spec.tls + content: + hosts: + - postgres-exporter.example.local + secretName: postgres-exporter-http-tls + +- it: Render ingress with custom values. + set: + ingress.enabled: true + ingress.annotations: + foo: bar + ingress.className: nginx + ingress.labels: + bar: foo + ingress.hosts: + - host: postgres-exporter.example.local + paths: + - path: / + pathType: Prefix + ingress.tls: + - secretName: postgres-exporter-http-tls + hosts: + - postgres-exporter.example.local + + services.http.port: 8080 + + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: networking.k8s.io/v1 + kind: Ingress + name: prometheus-postgres-exporter-unittest + namespace: testing + - equal: + path: metadata.annotations + value: + foo: bar + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + bar: foo + - equal: + path: spec.ingressClassName + value: nginx + - contains: + path: spec.rules + content: + host: postgres-exporter.example.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: prometheus-postgres-exporter-unittest + port: + number: 8080 + - contains: + path: spec.tls + content: + hosts: + - postgres-exporter.example.local + secretName: postgres-exporter-http-tls diff --git a/unittests/podMonitors/podMonitorHTTP.yaml b/unittests/podMonitors/podMonitorHTTP.yaml new file mode 100644 index 0000000..b634455 --- /dev/null +++ b/unittests/podMonitors/podMonitorHTTP.yaml @@ -0,0 +1,172 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: PodMonitor http template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/podMonitor.yaml +tests: +- it: Skip podMonitor when metrics are disabled. + set: + prometheus.metrics.enabled: false + prometheus.metrics.podMonitor.enabled: true + prometheus.metrics.serviceMonitor.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Skip podMonitor when podMonitor is disabled. + set: + prometheus.metrics.enabled: true + prometheus.metrics.podMonitor.enabled: false + asserts: + - hasDocuments: + count: 0 + +- it: Skip podMonitor when both monitor types are enabled. + set: + prometheus.metrics.enabled: true + prometheus.metrics.podMonitor.enabled: true + prometheus.metrics.serviceMonitor.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Rendering podMonitor with default values - enabled manually. + set: + prometheus.metrics.enabled: true + prometheus.metrics.podMonitor.enabled: true + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: monitoring.coreos.com/v1 + kind: PodMonitor + name: prometheus-postgres-exporter-unittest-http + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - equal: + path: spec.podMetricsEndpoints[0].enableHttp2 + value: false + - equal: + path: spec.podMetricsEndpoints[0].followRedirects + value: false + - equal: + path: spec.podMetricsEndpoints[0].honorLabels + value: false + - equal: + path: spec.podMetricsEndpoints[0].interval + value: 60s + - equal: + path: spec.podMetricsEndpoints[0].path + value: /metrics + - equal: + path: spec.podMetricsEndpoints[0].port + value: http + - notExists: + path: spec.podMetricsEndpoints[0].relabelings + - equal: + path: spec.podMetricsEndpoints[0].scrapeTimeout + value: 30s + - equal: + path: spec.podMetricsEndpoints[0].scheme + value: http + - contains: + path: spec.namespaceSelector.matchNames + content: + testing + - equal: + path: spec.selector.matchLabels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + +- it: Render podMonitor with custom annotations and labels. + set: + prometheus.metrics.enabled: true + prometheus.metrics.podMonitor.enabled: true + prometheus.metrics.podMonitor.annotations: + foo: bar + prometheus.metrics.podMonitor.labels: + bar: foo + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + bar: foo + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + +- it: Change defaults + set: + prometheus.metrics.enabled: true + prometheus.metrics.podMonitor.enabled: true + prometheus.metrics.podMonitor.enableHttp2: true + prometheus.metrics.podMonitor.followRedirects: true + prometheus.metrics.podMonitor.honorLabels: true + prometheus.metrics.podMonitor.interval: "180s" + prometheus.metrics.podMonitor.path: "/my-metrics" + prometheus.metrics.podMonitor.relabelings: + - sourceLabels: [ container ] + separator: ";" + regex: "app" + replacement: "$1" + action: "drop" + prometheus.metrics.podMonitor.scrapeTimeout: "5s" + prometheus.metrics.podMonitor.scheme: "http" + asserts: + - hasDocuments: + count: 1 + - equal: + path: spec.podMetricsEndpoints[0].enableHttp2 + value: true + - equal: + path: spec.podMetricsEndpoints[0].followRedirects + value: true + - equal: + path: spec.podMetricsEndpoints[0].honorLabels + value: true + - equal: + path: spec.podMetricsEndpoints[0].interval + value: 180s + - equal: + path: spec.podMetricsEndpoints[0].path + value: /my-metrics + - equal: + path: spec.podMetricsEndpoints[0].port + value: http + - contains: + path: spec.podMetricsEndpoints[0].relabelings + content: + sourceLabels: [ container ] + separator: ";" + regex: "app" + replacement: "$1" + action: "drop" + - equal: + path: spec.podMetricsEndpoints[0].scrapeTimeout + value: 5s + - equal: + path: spec.podMetricsEndpoints[0].scheme + value: http \ No newline at end of file diff --git a/unittests/secrets/database.yaml b/unittests/secrets/database.yaml new file mode 100644 index 0000000..e288fee --- /dev/null +++ b/unittests/secrets/database.yaml @@ -0,0 +1,104 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: Secret database template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/secretDatabase.yaml +tests: +- it: Skip rendering by using existing secret. + set: + config.database.existingSecret.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Expect error when no variable is defined. + asserts: + - failedTemplate: + errorMessage: No `databaseConnectionUrl` defined! + +- it: Expect error when variable `databaseUsername` is not defined. + set: + # config.database.secret.databaseUsername: "" + config.database.secret.databasePassword: "postgres" + config.database.secret.databaseConnectionUrl: "localhost:5432/postgres?sslmode=disable" + asserts: + - failedTemplate: + errorMessage: No `databaseUsername` defined! + +- it: Expect error when variable `databasePassword` is not defined. + set: + config.database.secret.databaseUsername: "postgres" + # config.database.secret.databasePassword: "postgres" + config.database.secret.databaseConnectionUrl: "localhost:5432/postgres?sslmode=disable" + asserts: + - failedTemplate: + errorMessage: No `databasePassword` defined! + +- it: Expect error when variable `databaseConnectionUrl` is not defined. + set: + config.database.secret.databaseUsername: "postgres" + config.database.secret.databasePassword: "postgres" + # config.database.secret.databaseConnectionUrl: "localhost:5432/postgres?sslmode=disable" + asserts: + - failedTemplate: + errorMessage: No `databaseConnectionUrl` defined! + +- it: Rendering database secret. + set: + config.database.secret.databaseUsername: "postgres" + config.database.secret.databasePassword: "postgres" + config.database.secret.databaseConnectionUrl: "localhost:5432/postgres?sslmode=disable" + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: v1 + kind: Secret + name: prometheus-postgres-exporter-unittest-database-env + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - equal: + path: stringData.DATA_SOURCE_URI + value: "localhost:5432/postgres?sslmode=disable" + - equal: + path: stringData.DATA_SOURCE_USER + value: "postgres" + - equal: + path: stringData.DATA_SOURCE_PASS + value: "postgres" + +- it: Rendering custom annotations and labels. + set: + config.database.secret.annotations: + foo: bar + bar: foo + config.database.secret.databaseUsername: "postgres" + config.database.secret.databasePassword: "postgres" + config.database.secret.databaseConnectionUrl: "localhost:5432/postgres?sslmode=disable" + config.database.secret.labels: + foo: bar + bar: foo + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + bar: foo + - isSubset: + path: metadata.labels + content: + foo: bar + bar: foo \ No newline at end of file diff --git a/unittests/secrets/exporterConfig.yaml b/unittests/secrets/exporterConfig.yaml new file mode 100644 index 0000000..f82fb93 --- /dev/null +++ b/unittests/secrets/exporterConfig.yaml @@ -0,0 +1,86 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: Secret database template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/secretExporterConfig.yaml +tests: +- it: Skip rendering by using existing secret. + set: + config.exporterConfig.existingSecret.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Render secret, but with no value. + asserts: + - hasDocuments: + count: 1 + - equal: + path: stringData["exporterConfig.yaml"] + value: | + {} + +- it: Rendering exporter config secret. + set: + config.exporterConfig.secret.exporterConfig: + auth_modules: + first: + type: userpass + userpass: + username: first_username + password: first_password + options: + sslmode: disable + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: v1 + kind: Secret + name: prometheus-postgres-exporter-unittest-exporter-config + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - equal: + path: stringData["exporterConfig.yaml"] + value: | + auth_modules: + first: + options: + sslmode: disable + type: userpass + userpass: + password: first_password + username: first_username + +- it: Rendering custom annotations and labels. + set: + config.exporterConfig.secret.annotations: + foo: bar + bar: foo + config.exporterConfig.secret.labels: + foo: bar + bar: foo + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + bar: foo + - isSubset: + path: metadata.labels + content: + foo: bar + bar: foo \ No newline at end of file diff --git a/unittests/secrets/webconfig.yaml b/unittests/secrets/webconfig.yaml new file mode 100644 index 0000000..f70cf57 --- /dev/null +++ b/unittests/secrets/webconfig.yaml @@ -0,0 +1,81 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: Secret database template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/secretWebConfig.yaml +tests: +- it: Skip rendering by using existing secret. + set: + config.webConfig.existingSecret.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Skip rendering when no webConfig.yaml is defined. + set: + config.webConfig.existingSecret.enabled: false + asserts: + - hasDocuments: + count: 0 + +- it: Rendering database secret. + set: + config.webConfig.secret.webConfig: + tls_server_config: + cert_file: /path/to/cert.pem + client_ca_file: /path/to/ca.pem + key_file: /path/to/key.pem + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: v1 + kind: Secret + name: prometheus-postgres-exporter-unittest-webconfig + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - equal: + path: stringData["webConfig.yaml"] + value: | + tls_server_config: + cert_file: /path/to/cert.pem + client_ca_file: /path/to/ca.pem + key_file: /path/to/key.pem + +- it: Rendering custom annotations and labels. + set: + config.webConfig.secret.annotations: + foo: bar + bar: foo + config.webConfig.secret.labels: + foo: bar + bar: foo + config.webConfig.secret.webConfig: + tls_server_config: + cert_file: /path/to/cert.pem + key_file: /path/to/key.pem + client_ca_file: /path/to/ca.pem + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + bar: foo + - isSubset: + path: metadata.labels + content: + foo: bar + bar: foo \ No newline at end of file diff --git a/unittests/serviceAccounts/serviceAccount.yaml b/unittests/serviceAccounts/serviceAccount.yaml new file mode 100644 index 0000000..5f1d4cf --- /dev/null +++ b/unittests/serviceAccounts/serviceAccount.yaml @@ -0,0 +1,79 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: ServiceAccount prometheus-postgres-exporter template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/serviceAccount.yaml +tests: +- it: Skip rendering. + set: + serviceAccount.existing.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Rendering serviceAccount with default values. + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: v1 + kind: ServiceAccount + name: prometheus-postgres-exporter-unittest + namespace: testing + - notExists: + path: metadata.annotations + - notExists: + path: metadata.labels + - equal: + path: spec.automountServiceAccountToken + value: true + - notExists: + path: spec.imagePullSecrets + - notExists: + path: spec.secrets + + +- it: Rendering serviceAccount with custom values. + set: + serviceAccount.new.annotations: + foo: bar + serviceAccount.new.labels: + bar: foo + serviceAccount.new.automountServiceAccountToken: false + serviceAccount.new.imagePullSecrets: + - name: "my-pull-secret" + serviceAccount.new.secrets: + - name: "my-secret" + namespace: "my-namespace" + fieldPath: "my-path" + asserts: + - hasDocuments: + count: 1 + - exists: + path: metadata.annotations + value: + foo: bar + - exists: + path: metadata.labels + value: + bar: foo + - equal: + path: metadata.name + value: prometheus-postgres-exporter-unittest + - equal: + path: spec.automountServiceAccountToken + value: false + - equal: + path: spec.imagePullSecrets + value: + - name: "my-pull-secret" + - equal: + path: spec.secrets + value: + - name: "my-secret" + namespace: "my-namespace" + fieldPath: "my-path" diff --git a/unittests/serviceMonitors/serviceMonitorHTTP.yaml b/unittests/serviceMonitors/serviceMonitorHTTP.yaml new file mode 100644 index 0000000..3f481b7 --- /dev/null +++ b/unittests/serviceMonitors/serviceMonitorHTTP.yaml @@ -0,0 +1,172 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: ServiceMonitor http template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/serviceMonitorHTTP.yaml +tests: +- it: Skip serviceMonitor when service is disabled. + set: + prometheus.metrics.enabled: true + prometheus.metrics.serviceMonitor.enabled: true + services.http.enabled: false + asserts: + - hasDocuments: + count: 0 + +- it: Skip serviceMonitor when metrics are disabled. + set: + prometheus.metrics.enabled: false + prometheus.metrics.serviceMonitor.enabled: true + services.http.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Skip serviceMonitor when serviceMonitor is disabled. + set: + prometheus.metrics.enabled: true + prometheus.metrics.serviceMonitor.enabled: false + services.http.enabled: true + asserts: + - hasDocuments: + count: 0 + +- it: Rendering serviceMonitor with default values - enabled manually. + set: + prometheus.metrics.enabled: true + prometheus.metrics.serviceMonitor.enabled: true + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: monitoring.coreos.com/v1 + kind: ServiceMonitor + name: prometheus-postgres-exporter-unittest-http + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - equal: + path: spec.endpoints[0].enableHttp2 + value: false + - equal: + path: spec.endpoints[0].followRedirects + value: false + - equal: + path: spec.endpoints[0].honorLabels + value: false + - equal: + path: spec.endpoints[0].interval + value: 60s + - equal: + path: spec.endpoints[0].path + value: /metrics + - notExists: + path: spec.endpoints[0].relabelings + - equal: + path: spec.endpoints[0].scrapeTimeout + value: 30s + - equal: + path: spec.endpoints[0].scheme + value: http + - equal: + path: spec.endpoints[0].targetPort + value: 9187 + - contains: + path: spec.namespaceSelector.matchNames + content: + testing + - equal: + path: spec.selector.matchLabels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/service-name: http + +- it: Render serviceMonitor with custom annotations and labels. + set: + prometheus.metrics.enabled: true + prometheus.metrics.serviceMonitor.enabled: true + prometheus.metrics.serviceMonitor.annotations: + foo: bar + prometheus.metrics.serviceMonitor.labels: + bar: foo + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + bar: foo + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + +- it: Change defaults + set: + prometheus.metrics.enabled: true + prometheus.metrics.serviceMonitor.enabled: true + prometheus.metrics.serviceMonitor.enableHttp2: true + prometheus.metrics.serviceMonitor.followRedirects: true + prometheus.metrics.serviceMonitor.honorLabels: true + prometheus.metrics.serviceMonitor.interval: "180s" + prometheus.metrics.serviceMonitor.path: "/my-metrics" + prometheus.metrics.serviceMonitor.relabelings: + - sourceLabels: [ container ] + separator: ";" + regex: "app" + replacement: "$1" + action: "drop" + prometheus.metrics.serviceMonitor.scrapeTimeout: "5s" + prometheus.metrics.serviceMonitor.scheme: "http" + prometheus.metrics.serviceMonitor.port: 10443 + asserts: + - hasDocuments: + count: 1 + - equal: + path: spec.endpoints[0].enableHttp2 + value: true + - equal: + path: spec.endpoints[0].followRedirects + value: true + - equal: + path: spec.endpoints[0].honorLabels + value: true + - equal: + path: spec.endpoints[0].interval + value: 180s + - equal: + path: spec.endpoints[0].path + value: /my-metrics + - contains: + path: spec.endpoints[0].relabelings + content: + sourceLabels: [ container ] + separator: ";" + regex: "app" + replacement: "$1" + action: "drop" + - equal: + path: spec.endpoints[0].scrapeTimeout + value: 5s + - equal: + path: spec.endpoints[0].scheme + value: http + - equal: + path: spec.endpoints[0].targetPort + value: 10443 \ No newline at end of file diff --git a/unittests/services/http.yaml b/unittests/services/http.yaml new file mode 100644 index 0000000..dc9b251 --- /dev/null +++ b/unittests/services/http.yaml @@ -0,0 +1,177 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: Service http template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/serviceHTTP.yaml +tests: +- it: Skip service when disabled. + set: + services.http.enabled: false + asserts: + - hasDocuments: + count: 0 + +- it: Rendering service with default values. + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: v1 + kind: Service + name: prometheus-postgres-exporter-unittest-http + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/service-name: http + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - notExists: + path: spec.externalIPs + - notExists: + path: spec.externalTrafficPolicy + - equal: + path: spec.internalTrafficPolicy + value: Cluster + - notExists: + path: spec.ipFamilies + - notExists: + path: spec.loadBalancerClass + - notExists: + path: spec.loadBalancerIP + - notExists: + path: spec.loadBalancerSourceRanges + - equal: + path: spec.ports[0].name + value: http + - equal: + path: spec.ports[0].protocol + value: TCP + - equal: + path: spec.ports[0].port + value: 9187 + - equal: + path: spec.selector + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - equal: + path: spec.sessionAffinity + value: None + - notExists: + path: spec.sessionAffinityConfig + - equal: + path: spec.type + value: ClusterIP + +- it: Require internalTrafficPolicy. + set: + services.http.internalTrafficPolicy: "" + asserts: + - failedTemplate: + errorMessage: No internal traffic policy defined! + +- it: Require port. + set: + services.http.port: "" + asserts: + - failedTemplate: + errorMessage: No service port defined! + +- it: Require sessionAffinity. + set: + services.http.sessionAffinity: "" + asserts: + - failedTemplate: + errorMessage: No session affinity defined! + +- it: Require service type. + set: + services.http.type: "" + asserts: + - failedTemplate: + errorMessage: No service type defined! + +- it: Render service with custom annotations and labels. + set: + services.http.annotations: + foo: bar + services.http.labels: + bar: foo + asserts: + - equal: + path: metadata.annotations + value: + foo: bar + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/service-name: http + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + bar: foo + +- it: Change defaults + set: + services.http.externalIPs: + - "10.11.12.13/32" + services.http.externalTrafficPolicy: Local + services.http.internalTrafficPolicy: Local + services.http.ipFamilies: + - IPv4 + services.http.loadBalancerClass: aws + services.http.loadBalancerIP: "11.12.13.14" + services.http.loadBalancerSourceRanges: + - "11.12.0.0/17" + services.http.port: 10443 + services.http.sessionAffinity: ClientIP + services.http.type: LoadBalancer + asserts: + - equal: + path: spec.externalIPs + value: + - 10.11.12.13/32 + - equal: + path: spec.externalTrafficPolicy + value: Local + - equal: + path: spec.internalTrafficPolicy + value: Local + - equal: + path: spec.ipFamilies + value: + - IPv4 + - equal: + path: spec.loadBalancerClass + value: aws + - equal: + path: spec.loadBalancerIP + value: "11.12.13.14" + - equal: + path: spec.loadBalancerSourceRanges + value: + - "11.12.0.0/17" + - equal: + path: spec.ports[0].port + value: 10443 + - equal: + path: spec.sessionAffinity + value: ClientIP + - equal: + path: spec.type + value: LoadBalancer \ No newline at end of file diff --git a/values.yaml b/values.yaml new file mode 100644 index 0000000..96aa82d --- /dev/null +++ b/values.yaml @@ -0,0 +1,521 @@ +# Default values for qu-seed. +# This is a YAML-formatted file. + +# Declare variables to be passed into your templates. +## @section Global +## @param nameOverride Individual release name suffix. +## @param fullnameOverride Override the complete release name logic. +nameOverride: "" +fullnameOverride: "" + +## @section Configuration +config: + database: + ## @param config.database.existingSecret.enabled Mount an existing secret containing the application specific `DATA_SOURCE_` prefixed environment variables. + ## @param config.database.existingSecret.secretName Name of the existing secret containing the application specific `DATA_SOURCE_` prefixed environment variables. + existingSecret: + enabled: false + secretName: "" + + ## @param config.database.secret.annotations Additional annotations of the secret containing the database credentials. + ## @param config.database.secret.labels Additional labels of the secret containing the database credentials. + ## @param config.database.secret.databaseUsername Database username. Will be defined as env `DATA_SOURCE_USER` as part of a secret. + ## @param config.database.secret.databasePassword Database password. Will be defined as env `DATA_SOURCE_PASS` as part of a secret. + ## @param config.database.secret.databaseConnectionUrl Complex database connection URL. Will be defined as env `DATA_SOURCE_URI` as part of a secret. + secret: + annotations: {} + labels: {} + databaseUsername: "" + databasePassword: "" + databaseConnectionUrl: "" + + exporterConfig: + ## @param config.exporterConfig.existingSecret.enabled Mount an existing secret containing the key `exporter_config.yaml`. + ## @param config.exporterConfig.existingSecret.secretName Name of the existing secret containing the key `exporter_config.yaml`. + existingSecret: + enabled: false + secretName: "" + + ## @param config.exporterConfig.secret.annotations Additional annotations of the secret containing the `exporterConfig.yaml`. + ## @param config.exporterConfig.secret.labels Additional labels of the secret containing the `exporterConfig.yaml`. + ## @param config.exporterConfig.secret.exporterConfig Content of the `exporterConfig.yaml`. Further information can be found [here](https://prometheus.io/docs/prometheus/latest/configuration/https/). + ## @skip config.exporterConfig.secret.exporterConfig Skip individual postgres exporter configuration. + secret: + annotations: {} + labels: {} + exporterConfig: {} + # auth_modules: + # first: + # options: + # sslmode: disable + # type: userpass + # userpass: + # password: first_password + # username: first_username + + webConfig: + ## @param config.webConfig.existingSecret.enabled Mount an existing secret containing the key `webConfig.yaml`. + ## @param config.webConfig.existingSecret.secretName Name of the existing secret containing the key `webConfig.yaml`. + existingSecret: + enabled: false + secretName: "" + + ## @param config.webConfig.secret.annotations Additional annotations of the secret containing the `webConfig.yaml`. + ## @param config.webConfig.secret.labels Additional labels of the secret containing the `webConfig.yaml`. + ## @param config.webConfig.secret.webConfig Content of the `webConfig.yaml`. Further information can be found [here](https://prometheus.io/docs/prometheus/latest/configuration/https/). + ## @skip config.webConfig.secret.webConfig Skip individual web configuration. + secret: + annotations: {} + labels: {} + webConfig: {} + # basic_auth_users: + # prom: + # http_server_config: + # http2: true + # tls_server_config: + # cert_file: /path/to/cert.pem + # client_allowed_sans: + # - postgres.example.local + # client_ca_file: /path/to/ca.pem + # key_file: /path/to/key.pem + # max_version: TLS13 + # min_version: TLS12 + +## @section Deployment +deployment: + ## @param deployment.annotations Additional deployment annotations. + ## @param deployment.labels Additional ingress labels. + annotations: {} + labels: {} + + ## @param deployment.additionalContainers List of additional containers. + additionalContainers: [] + # - command: [ "sh", "-c", "echo hello world" ] + # image: "docker.io/library/busybox:latest" + # name: side-car + + ## @param deployment.affinity Affinity for the postgres-exporter deployment. + affinity: {} + + ## @param deployment.initContainers List of additional init containers. + initContainers: [] + # - command: [ "sh", "-c", "echo hello world" ] + # image: "docker.io/library/busybox:latest" + # name: init + + ## @param deployment.dnsConfig dnsConfig of the postgres-exporter deployment. + dnsConfig: {} + # nameservers: + # - 192.0.2.1 # this is an example + # searches: + # - ns1.svc.cluster-domain.example + # - my.dns.search.suffix + # options: + # - name: ndots + # value: "2" + # - name: edns0 + + ## @param deployment.dnsPolicy dnsPolicy of the postgres-exporter deployment. + dnsPolicy: "" + + ## @param deployment.hostname Individual hostname of the pod. + ## @param deployment.subdomain Individual domain of the pod. + hostname: "" + subdomain: "" + + ## @param deployment.hostNetwork Use the kernel network namespace of the host system. + hostNetwork: false + + ## @param deployment.imagePullSecrets Secret to use for pulling the image. + imagePullSecrets: [] + # - name: "my-custom-secret" + + postgresExporter: + ## @param deployment.postgresExporter.args Arguments passed to the postgres-exporter container. + args: [] + + ## @param deployment.postgresExporter.env List of environment variables for the postgres-exporter container. + env: [] + # - name: SPECIAL_ENV_A + # value: special-key + # - name: SPECIAL_ENV + # valueFrom: + # configMapKeyRef: + # name: special-config + # key: special-key + # - name: SPECIAL_ENV + # valueFrom: + # secretKeyRef: + # name: special-secret + # key: special-key + + ## @param deployment.postgresExporter.envFrom List of environment variables mounted from configMaps or secrets for the postgres-exporter container. + envFrom: [] + # - configMapRef: + # name: special-config + # - secretRef: + # name: special-secret + + ## @param deployment.postgresExporter.image.registry Image registry, eg. `docker.io`. + ## @param deployment.postgresExporter.image.repository Image repository, eg. `library/busybox`. + ## @param deployment.postgresExporter.image.tag Custom image tag, eg. `0.1.0`. Defaults to `appVersion`. + ## @param deployment.postgresExporter.image.pullPolicy Image pull policy. + image: + registry: quay.io + repository: prometheuscommunity/postgres-exporter + tag: "" + pullPolicy: IfNotPresent + + ## @param deployment.postgresExporter.resources CPU and memory resources of the pod. + resources: {} + # limits: + # cpu: + # ephemeral-storage: + # memory: + # requests: + # cpu: + # ephemeral-storage: + # memory: + + ## @param deployment.postgresExporter.securityContext Security context of the container of the deployment. + securityContext: {} + # capabilities: + # add: + # - NET_RAW + # drop: + # - ALL + # privileged: false + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + + ## @param deployment.postgresExporter.volumeMounts Additional volume mounts. + volumeMounts: {} + # - name: my-configmap-volume + # mountPath: /configmap + # readOnly: true + + ## @param deployment.nodeSelector NodeSelector of the postgres-exporter deployment. + nodeSelector: {} + + ## @param deployment.priorityClassName PriorityClassName of the postgres-exporter deployment. + priorityClassName: "" + + ## @param deployment.replicaCount Number of replicas for the postgres-exporter deployment. + replicaCount: 1 + + ## @param deployment.securityContext Security context of the postgres-exporter deployment. + securityContext: {} + # fsGroup: 2000 + + ## @param deployment.strategy.type Strategy type - `Recreate` or `Rollingupdate`. + ## @param deployment.strategy.rollingUpdate.maxSurge The maximum number of pods that can be scheduled above the desired number of pods during a rolling update. + ## @param deployment.strategy.rollingUpdate.maxUnavailable The maximum number of pods that can be unavailable during a rolling update. + strategy: + type: "Recreate" + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + + ## @param deployment.terminationGracePeriodSeconds How long to wait until forcefully kill the pod. + terminationGracePeriodSeconds: 60 + + ## @param deployment.tolerations Tolerations of the postgres-exporter deployment. + tolerations: [] + + ## @param deployment.topologySpreadConstraints TopologySpreadConstraints of the postgres-exporter deployment. + topologySpreadConstraints: [] + # - topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app.kubernetes.io/instance: prometheus-postgres-exporter + + ## @param deployment.volumes Additional volumes to mount into the pods of the prometheus-exporter deployment. + volumes: [] + # - name: my-configmap-volume + # config: + # name: my-configmap + # - name: my-secret-volume + # secret: + # secretName: my-secret + +## @section Grafana +## @param grafana.enabled Enable integration into Grafana. +## @param grafana.dashboards.businessMetrics Enable deployment of Grafana dashboard `businessMetrics`. +grafana: + enabled: false + dashboards: + businessMetrics: true + +## @section Ingress +ingress: + ## @param ingress.enabled Enable creation of an ingress resource. Requires, that the http service is also enabled. + ## @param ingress.className Ingress class. + ## @param ingress.annotations Additional ingress annotations. + ## @param ingress.labels Additional ingress labels. + enabled: false + className: "nginx" + annotations: {} + labels: {} + + ## @param ingress.hosts Ingress specific configuration. Specification only required when another ingress controller is used instead of `t1k. + ## @skip ingress.hosts Skip individual host configuration. + hosts: [] + # - host: postgres-exporter.example.local + # paths: + # - path: / + # pathType: Prefix + + ## @param ingress.tls Ingress TLS settings. Specification only required when another ingress controller is used instead of `t1k``. + ## @skip ingress.tls Skip individual TLS configuration. + tls: [] + # - secretName: postgres-exporter-http-tls + # hosts: + # - postgres-exporter.example.local + +## @section Pod disruption +## @param podDisruptionBudget Pod disruption budget. +podDisruptionBudget: {} +# maxUnavailable: 1 +# minAvailable: 1 + +## @section Network +## @param networkPolicies Deploy network policies based on the used container network interface (CNI) implementation - like calico or weave. +networkPolicies: {} + +## @section Prometheus +prometheus: + ## @param prometheus.metrics.enabled Enable of scraping metrics by Prometheus. + metrics: + enabled: true + + ## @param prometheus.metrics.podMonitor.enabled Enable creation of a podMonitor. Excludes the existence of a serviceMonitor resource. + ## @param prometheus.metrics.podMonitor.annotations Additional podMonitor annotations. + ## @param prometheus.metrics.podMonitor.enableHttp2 Enable HTTP2. + ## @param prometheus.metrics.podMonitor.followRedirects FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. + ## @param prometheus.metrics.podMonitor.honorLabels Honor labels. + ## @param prometheus.metrics.podMonitor.labels Additional podMonitor labels. + ## @param prometheus.metrics.podMonitor.interval Interval at which metrics should be scraped. If not specified Prometheus' global scrape interval is used. + ## @param prometheus.metrics.podMonitor.path HTTP path for scraping prometheus metrics. + ## @param prometheus.metrics.podMonitor.relabelings RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds relabelings for a few standard Kubernetes fields. + ## @param prometheus.metrics.podMonitor.scrapeTimeout Timeout after which the scrape is ended. If not specified, global Prometheus scrape timeout is used. + ## @param prometheus.metrics.podMonitor.scheme HTTP scheme to use for scraping. For example `http` or `https`. + ## @param prometheus.metrics.podMonitor.tlsConfig TLS configuration to use when scraping the metric endpoint by Prometheus. + ## @skip prometheus.metrics.podMonitor.tlsConfig Skip individual TLS configuration. + podMonitor: + enabled: false + annotations: {} + enableHttp2: false + followRedirects: false + honorLabels: false + labels: {} + interval: "60s" + path: "/metrics" + relabelings: [] + scrapeTimeout: "30s" + scheme: "http" + tlsConfig: {} + + ## @param prometheus.metrics.serviceMonitor.enabled Enable creation of a serviceMonitor. Excludes the existence of a podMonitor resource. + ## @param prometheus.metrics.serviceMonitor.annotations Additional serviceMonitor annotations. + ## @param prometheus.metrics.serviceMonitor.labels Additional serviceMonitor labels. + ## @param prometheus.metrics.serviceMonitor.enableHttp2 Enable HTTP2. + ## @param prometheus.metrics.serviceMonitor.followRedirects FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. + ## @param prometheus.metrics.serviceMonitor.honorLabels Honor labels. + ## @param prometheus.metrics.serviceMonitor.interval Interval at which metrics should be scraped. If not specified Prometheus' global scrape interval is used. + ## @param prometheus.metrics.serviceMonitor.path HTTP path for scraping prometheus metrics. + ## @param prometheus.metrics.serviceMonitor.port HTTP port for scraping prometheus metrics. + ## @param prometheus.metrics.serviceMonitor.relabelings RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds relabelings for a few standard Kubernetes fields. + ## @param prometheus.metrics.serviceMonitor.scrapeTimeout Timeout after which the scrape is ended. If not specified, global Prometheus scrape timeout is used. + ## @param prometheus.metrics.serviceMonitor.scheme HTTP scheme to use for scraping. For example `http` or `https`. + ## @param prometheus.metrics.serviceMonitor.tlsConfig TLS configuration to use when scraping the metric endpoint by Prometheus. + ## @skip prometheus.metrics.serviceMonitor.tlsConfig Skip individual TLS configuration. + serviceMonitor: + enabled: false + annotations: {} + labels: {} + enableHttp2: false + followRedirects: false + honorLabels: false + interval: "60s" + path: "/metrics" + port: 9187 + relabelings: [] + scrapeTimeout: "30s" + scheme: "http" + tlsConfig: {} + + ## @param prometheus.rules Array of prometheus rules for monitoring the application and triggering alerts. + ## @skip prometheus.rules Skip individual prometheus rules. + rules: [] + # - alert: ExporterErrors + # expr: pg_exporter_last_scrape_error == 1 + # for: 10m + # labels: + # service: PostgreSQL + # severity: critical + # annotations: + # description: The Postgres Exporter is not running or it is showing errors {{ $labels.instance }} + # summary: Postgres Exporter is down or is showing errors + # - alert: InstanceDown + # expr: pg_up == 0 + # for: 1m + # labels: + # service: PostgreSQL + # severity: critical + # annotations: + # description: Postgres server has not been responding for the past 1 minutes on {{ $labels.instance }} + # summary: Postgres server instance is down + # title: Postgres server instance {{ $labels.instance}} is down + # - alert: InactiveReplicationSlots + # expr: pg_replication_slots_active == 0 + # for: 30m + # labels: + # severity: warning + # service: PostgreSQL + # annotations: + # summary: There are inactive replications slots + # description: The are some inactive replication slots on {{$labels.instance}} in cluster {{$labels.cluster_name}} + # - alert: NotEnoughConnections + # expr: sum by (datname) (pg_stat_activity_count{datname!~"template.*|postgres"}) < 5 + # for: 5m + # labels: + # severity: warning + # annotations: + # summary: Postgresql not enough connections (instance {{ $labels.instance }} in cluster {{$labels.cluster_name}}) + # description: "PostgreSQL instance should have more connections (> 5)\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" + # - alert: PromotedNode + # expr: pg_replication_is_replica and changes(pg_replication_is_replica[1m]) > 0 + # for: 5m + # labels: + # severity: warning + # annotations: + # summary: Postgresql promoted node (instance {{ $labels.instance }}, cluster {{ $labels.cluster_name }}) + # description: "Postgresql standby server has been promoted as primary node\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" + # - alert: ReplicationLagSizeTooLarge + # expr: pg_replication_status_lag_size > 1e+09 + # for: 5m + # labels: + # service: PostgreSQL + # severity: critical + # annotations: + # summary: Postgres replication lag size is to large + # description: Replication lag size on server {{ $labels.instance }} ({{ $labels.application_name }}) is currently {{ $value }} behind the leader in cluster {{ $labels.cluster_name }} + # - alert: TooManyDeadTuples + # expr: ((pg_stat_user_tables_n_dead_tup > 1e+06) / (pg_stat_user_tables_n_live_tup + pg_stat_user_tables_n_dead_tup)) >= 0.05 + # for: 30m + # labels: + # service: PostgreSQL + # severity: warning + # annotations: + # description: The dead tuple ratio of {{ $labels.relname }} on database {{ $labels.datname }} is greater than 5% in cluster {{ $labels.cluster_name }} + # summary: PostgreSQL dead tuples is too large + # - alert: TooManyConnections + # expr: sum by (datname) (pg_stat_activity_count{datname!~"template.*|postgres"}) > pg_settings_max_connections * 0.9 + # for: 5m + # labels: + # severity: warning + # annotations: + # summary: Postgresql too many connections (instance {{ $labels.instance }} in cluster {{$labels.cluster_name}}) + # description: "PostgreSQL instance has too many connections\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" + + ## Connection Pooling alerts + #### + + # - alert: BouncerAvgWaitTimeTooHigh + # expr: pgbouncer_show_stats_avg_wait_time > 1e+6 + # for: 5m + # labels: + # severity: warning + # annotations: + # description: "PgBouncer wait for a server connections is too high = {{ $value }}" + # summary: PgBouncer time spent by clients waiting for a connections is too high on {{ $labels.instance }} in cluster {{$labels.cluster_name}}) + # - alert: BouncerNotEnoughConnections + # expr: (sum by (database,instance) (pgbouncer_show_pools_cl_active{database!~"template.*|postgres|pgbouncer"}) + sum by (database, instance) (pgbouncer_show_pools_cl_waiting{database!~"template.*|postgres|pgbouncer"})) - on (database,instance) (pgbouncer_show_databases_pool_size{database!~"template.*|postgres|pgbouncer"}) > 0 + # for: 10m + # labels: + # severity: critical + # annotations: + # description: "PgBouncer is getting more connections than the pool size, extra connections = {{ $value }}" + # summary: PgBouncer pool size is not enough for the current connections on {{ $labels.instance }} in cluster {{$labels.cluster_name}}) + # - alert: BouncerPoolFillingUp + # expr: (sum by (database,instance) (pgbouncer_show_databases_pool_size{database!~"template.*|postgres|pgbouncer"}) - on (database,instance) pgbouncer_show_databases_current_connections) <= 15 + # for: 5m + # labels: + # severity: warning + # annotations: + # description: "PgBouncer pool is filling up, remaining connections = {{ $value }}" + # summary: PgBouncer pool is filling up on {{ $labels.instance }} in cluster {{$labels.cluster_name}}) + # - alert: BouncerQueryTimeTooHigh + # expr: pgbouncer_show_stats_avg_query_time > 5e+6 + # for: 5m + # labels: + # severity: warning + # annotations: + # description: "PgBouncer average query duration more than 5 seconds = {{ $value }}" + # summary: PgBouncer average query duration more than 5 seconds on {{ $labels.instance }} in cluster {{$labels.cluster_name}}) + # - alert: BouncerWaitingClients + # expr: pgbouncer_show_pools_cl_waiting > 0 + # for: 5m + # labels: + # severity: warning + # annotations: + # description: "PgBouncer instance has waiting clients\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" + # summary: PgBouncer has waiting clients on instance {{ $labels.instance }} in cluster {{$labels.cluster_name}}) + +## @section Service +## @param services.http.enabled Enable the service. +## @param services.http.annotations Additional service annotations. +## @param services.http.externalIPs External IPs for the service. +## @param services.http.externalTrafficPolicy If `service.type` is `NodePort` or `LoadBalancer`, set this to `Local` to tell kube-proxy to only use node local endpoints for cluster external traffic. Furthermore, this enables source IP preservation. +## @param services.http.internalTrafficPolicy If `service.type` is `NodePort` or `LoadBalancer`, set this to `Local` to tell kube-proxy to only use node local endpoints for cluster internal traffic. +## @param services.http.ipFamilies IPFamilies is list of IP families (e.g. `IPv4`, `IPv6`) assigned to this service. This field is usually assigned automatically based on cluster configuration and only required for customization. +## @param services.http.labels Additional service labels. +## @param services.http.loadBalancerClass LoadBalancerClass is the class of the load balancer implementation this Service belongs to. Requires service from type `LoadBalancer`. +## @param services.http.loadBalancerIP LoadBalancer will get created with the IP specified in this field. Requires service from type `LoadBalancer`. +## @param services.http.loadBalancerSourceRanges Source range filter for LoadBalancer. Requires service from type `LoadBalancer`. +## @param services.http.port Port to forward the traffic to. +## @param services.http.sessionAffinity Supports `ClientIP` and `None`. Enable client IP based session affinity via `ClientIP`. +## @param services.http.sessionAffinityConfig Contains the configuration of the session affinity. +## @param services.http.type Kubernetes service type for the traffic. +services: + http: + enabled: true + annotations: {} + externalIPs: [] + externalTrafficPolicy: "Cluster" + internalTrafficPolicy: "Cluster" + ipFamilies: [] + labels: {} + loadBalancerClass: "" + loadBalancerIP: "" + loadBalancerSourceRanges: [] + port: 9187 + sessionAffinity: "None" + sessionAffinityConfig: {} + type: "ClusterIP" + +## @section ServiceAccount +serviceAccount: + ## @param serviceAccount.existing.enabled Use an existing service account instead of creating a new one. Assumes that the user has all the necessary kubernetes API authorizations. + ## @param serviceAccount.existing.serviceAccountName Name of the existing service account. + existing: + enabled: false + serviceAccountName: "" + + ## @param serviceAccount.new.annotations Additional service account annotations. + ## @param serviceAccount.new.labels Additional service account labels. + ## @param serviceAccount.new.automountServiceAccountToken Enable/disable auto mounting of the service account token. + ## @param serviceAccount.new.imagePullSecrets ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this serviceAccount. + ## @param serviceAccount.new.secrets Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. + new: + annotations: {} + labels: {} + automountServiceAccountToken: true + imagePullSecrets: [] + # - name: "my-image-pull-secret" + secrets: [] + # - name: "my-secret" + # namespace: "my-namespace" + # fieldPath: "my-field"