diff --git a/Chart.yaml b/Chart.yaml index 775b536..48cb8c0 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: pgdog-control description: PgDog Control type: application -version: 0.2.7 +version: 0.2.8 appVersion: "438ab3d1" diff --git a/README.md b/README.md index 5ef8ead..e681cd9 100644 --- a/README.md +++ b/README.md @@ -522,6 +522,8 @@ control: config: rds: refresh_interval_secs: 60 + # Experimental: do not enable in production yet. + autodiscovery: false kube: refresh_interval_secs: 15 dns: @@ -535,6 +537,7 @@ control: | Option | Description | |-|-| | `rds.refresh_interval_secs` | How often to poll AWS RDS for cluster and instance topology (int, default `60`). | +| `rds.autodiscovery` | **Experimental. Do not enable in production yet.** Automatically reconcile Helm-managed PgDog database entries from discovered RDS topology (bool, default `false`). | | `kube.refresh_interval_secs` | How often to poll Kubernetes for PgDog workloads. Independent of the `watch` streams, which fire on events (int, default `15`). | | `dns.refresh_interval_secs` | How often to re-resolve every known RDS hostname (int, default `30`). | | `cloudwatch.refresh_interval_secs` | How often to poll CloudWatch for per-instance metrics (int, default `60`). | @@ -581,6 +584,7 @@ control: evict_after_secs: 60 metrics_retention_secs: 300 query_history_limit: 1000 + autoreload: false ``` | Option | Description | @@ -590,6 +594,24 @@ control: | `evict_after_secs` | Instance is dropped from the store entirely if its newest metric is older than this (int, default `60`). | | `metrics_retention_secs` | How much per-instance metric history is kept in memory. Older points are dropped as new ones arrive (int, default `300`). | | `query_history_limit` | Per-token historical query store capacity. Oldest deduped query entries are evicted first once the limit is reached (int, default `1000`). | +| `autoreload` | Automatically enqueue `reload_configuration` for instances that report config drift (bool, default `false`). | + +### Slack Notifications + +`control.config.slack` enables Slack status updates for long-running deployment and maintenance work. Leave either field empty to disable Slack. If the section is omitted, the control plane falls back to the `SLACK_BOT_TOKEN` and `SLACK_CHANNEL` environment variables. + +```yaml +control: + config: + slack: + bot_token: xoxb-... + channel: C0123456789 +``` + +| Option | Description | +|-|-| +| `bot_token` | Slack bot token with `chat:write` permission (string, optional). | +| `channel` | Slack channel ID or name for status updates (string, optional). | ### Redis persistence diff --git a/templates/configmap.yaml b/templates/configmap.yaml index 2566b4f..69cb9c5 100644 --- a/templates/configmap.yaml +++ b/templates/configmap.yaml @@ -23,6 +23,9 @@ data: {{- with .refresh_interval_secs }} refresh_interval_secs = {{ . }} {{- end }} + {{- if hasKey . "autodiscovery" }} + autodiscovery = {{ .autodiscovery }} + {{- end }} {{- end }} {{- with $config.kube }} @@ -73,6 +76,9 @@ data: {{- if hasKey . "query_history_limit" }} query_history_limit = {{ .query_history_limit }} {{- end }} + {{- if hasKey . "autoreload" }} + autoreload = {{ .autoreload }} + {{- end }} {{- end }} {{- with $config.helm }} @@ -166,6 +172,17 @@ data: {{- end }} {{- end }} + {{- with $config.slack }} + + [slack] + {{- if hasKey . "bot_token" }} + bot_token = {{ .bot_token | quote }} + {{- end }} + {{- if hasKey . "channel" }} + channel = {{ .channel | quote }} + {{- end }} + {{- end }} + {{- $redis := $config.redis | default dict }} {{- $redisUrl := $redis.url | default (printf "redis://%s.%s.svc.cluster.local:6379" (include "pgdog-control.redis.fullname" .) .Release.Namespace) }} diff --git a/templates/deployment.yaml b/templates/deployment.yaml index 9b828c5..9ae1479 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -81,7 +81,7 @@ spec: value: /var/lib/pgdog-control/helm/config - name: HELM_DATA_HOME value: /var/lib/pgdog-control/helm/data - # control2's whoami uses these to look up the Service that fronts + # The control plane uses these to look up the Service that fronts # this pod (src/models/deployment/kube/whoami.rs); without them # endpoint() falls back to the host.minikube.internal dev URL. - name: POD_NAME diff --git a/templates/rbac.yaml b/templates/rbac.yaml index 82341da..443f0b4 100644 --- a/templates/rbac.yaml +++ b/templates/rbac.yaml @@ -11,7 +11,7 @@ metadata: eks.amazonaws.com/role-arn: {{ . | quote }} {{- end }} --- -# Cluster-scoped because control2 lists namespaces and reads workloads +# Cluster-scoped because the control plane lists namespaces and reads workloads # across all namespaces (Api::all in src/models/deployment/kube/client.rs). apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -20,7 +20,7 @@ metadata: labels: {{- include "pgdog-control.labels" . | nindent 4 }} rules: - # control2 lists/reads these cluster-wide (Api::all) to render the + # The control plane lists/reads these cluster-wide (Api::all) to render the # workload, services, and pod views across every namespace. - apiGroups: [""] resources: ["namespaces", "configmaps", "secrets", "services"] @@ -56,7 +56,7 @@ subjects: namespace: {{ .Release.Namespace }} {{- range $ns := .Values.control.rbac.writeNamespaces }} --- -# Namespace-scoped write access for workloads control2 manages. +# Namespace-scoped write access for workloads the control plane manages. apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: diff --git a/values.yaml b/values.yaml index c58cb93..2648ccc 100644 --- a/values.yaml +++ b/values.yaml @@ -37,7 +37,7 @@ control: # Override the ServiceAccount name. When empty, falls back to # `-control`. serviceAccountName: "" - # Namespaces where control2 is allowed to create/update/patch/delete + # Namespaces where the control plane is allowed to create/update/patch/delete # workloads (deployments, statefulsets, configmaps, secrets, services). # A Role + RoleBinding is generated in each listed namespace. Empty # means no write access anywhere — list the release namespace @@ -67,12 +67,14 @@ control: capabilities: drop: ["ALL"] # Runtime configuration written to /etc/pgdog-control/control.toml. - # Mirrors control2/src/config.rs. Every field is optional — anything left + # Mirrors the control plane runtime config. Every field is optional — anything left # unset falls back to the Rust-side default. Field names match the TOML # keys (snake_case) so values are passed through verbatim. config: rds: {} # refresh_interval_secs: 60 + # Experimental: do not enable in production yet. + # autodiscovery: false kube: {} # refresh_interval_secs: 15 dns: {} @@ -87,6 +89,7 @@ control: # evict_after_secs: 60 # metrics_retention_secs: 300 # query_history_limit: 1000 + # autoreload: false helm: {} # chart: pgdog # repo: pgdogdev @@ -114,6 +117,9 @@ control: # server_connections: 100 # incident_io: # api_key: "" + slack: {} + # bot_token: "" # optional; defaults to SLACK_BOT_TOKEN env when absent + # channel: "" # optional; defaults to SLACK_CHANNEL env when absent redis: {} # url: "" # optional; defaults to in-cluster redis # save_interval_secs: 60 @@ -163,7 +169,7 @@ ingress: # annotations, ingressClassName, and tls block via the # top-level keys below. mode: nginx - # host is the external hostname routed to control2. Required when + # host is the external hostname routed to the control plane. Required when # mode is "nginx" or "aws"; optional in "default" mode (omit to leave # the rule unbound to a host). # host: control.example.com