From 2b5d2e10ea4a21435b8f241ecb09e75dc9133700 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 27 May 2026 04:26:12 -0400 Subject: [PATCH] fix: expose remaining settable properties via :report Adds the missing raw/global/computed report keys for ten settable properties across the ps, builder, scheduler, proxy, openresty, nginx, and scheduler-k3s plugins so external tooling can verify drift through `:report --format json`. The scheduler-k3s `token` is masked as `*******` in default stdout output and only unmasked when the report is requested via `--format json` or when the flag is queried explicitly by name; the same explicit-query unmasking rule is extended to the existing traefik `dns-provider-` keys. --- docs/appendices/0.38.0-migration-guide.md | 1 + .../deployment/builders/builder-management.md | 2 +- docs/deployment/schedulers/k3s.md | 2 +- .../schedulers/scheduler-management.md | 2 +- docs/networking/proxies/nginx.md | 2 +- docs/networking/proxies/openresty.md | 2 +- docs/networking/proxies/traefik.md | 2 +- docs/networking/proxy-management.md | 6 +- docs/processes/process-management.md | 6 +- plugins/builder/report.go | 43 +++-- plugins/nginx-vhosts/command-functions | 3 + plugins/openresty-vhosts/command-functions | 4 + plugins/openresty-vhosts/internal-functions | 17 ++ plugins/proxy/functions.go | 47 ++++++ plugins/proxy/report.go | 56 ++++++- plugins/ps/report.go | 69 ++++++-- plugins/ps/triggers.go | 8 - plugins/scheduler-k3s/report.go | 22 +++ plugins/scheduler/report.go | 22 +++ plugins/traefik-vhosts/command-functions | 2 +- tests/unit/builder.bats | 50 ++++++ tests/unit/nginx-vhosts_properties.bats | 1 + tests/unit/openresty.bats | 61 +++++++ tests/unit/proxy.bats | 150 ++++++++++++++++++ tests/unit/ps-general-1.bats | 108 +++++++++++++ tests/unit/scheduler-k3s-report.bats | 38 ++++- tests/unit/scheduler.bats | 50 ++++++ tests/unit/traefik.bats | 8 +- 28 files changed, 734 insertions(+), 50 deletions(-) diff --git a/docs/appendices/0.38.0-migration-guide.md b/docs/appendices/0.38.0-migration-guide.md index f53c718a8..5f049d2bb 100644 --- a/docs/appendices/0.38.0-migration-guide.md +++ b/docs/appendices/0.38.0-migration-guide.md @@ -23,6 +23,7 @@ - All `:report` subcommands now accept the `--global` flag, which scopes the report to globally-configured properties. The flag composes with `--format json`, so a JSON report of global properties can be obtained via, for example, `dokku scheduler:report --global --format json`. Previously, combining `--global` with `--format json` was rejected with an "info flag" error, and `--global` on its own was treated as an unknown flag. - Every `:report` key of the form `-global-` now returns the raw stored global value (empty when the property has never been set) instead of the resolved value with the built-in default substituted in. A new `-computed-` key has been added wherever a default existed and returns the effective value (per-app value, falling back to the global value, then to the built-in default). This affects `app-json`, `builder-dockerfile`, `builder-herokuish`, `builder-lambda`, `builder-nixpacks`, `builder-pack`, `builder-railpack`, `caddy`, `checks`, `git`, `haproxy`, `logs`, `network`, `nginx`, `openresty`, `proxy`, `registry`, `scheduler`, `scheduler-k3s` and `traefik`. External tooling that read `-global-` and depended on the default value should switch to `-computed-`. The bare `-` keys for caddy/haproxy/traefik/openresty global-only properties (`caddy-image`, `haproxy-log-level`, `traefik-api-enabled`, `openresty-image`, `openresty-letsencrypt-email`, `openresty-letsencrypt-server`, `openresty-allowed-letsencrypt-domains-func-base64`, etc.) have also been replaced by the `global-` and `computed-` pair. - The `ps` and `cron` plugins now follow the same `-global-` / `-computed-` convention. The `ps:report` keys `stop-timeout-seconds`, `global-stop-timeout-seconds`, and `computed-stop-timeout-seconds` have been renamed to `ps-stop-timeout-seconds`, `ps-global-stop-timeout-seconds`, and `ps-computed-stop-timeout-seconds`. The `cron:report` keys `cron-mailfrom` and `cron-mailto` have been renamed to `cron-global-mailfrom` and `cron-global-mailto`, and new `cron-computed-mailfrom` and `cron-computed-mailto` keys have been added. The corresponding user-facing `--` arguments to `ps:report` and `cron:report` were renamed alongside the JSON keys; no aliases are kept. Additionally, both `ps:report --global` and `cron:report --global` now emit the `-computed-` keys for every settable global property with a default (`ps-computed-procfile-path`, `ps-computed-stop-timeout-seconds`, `cron-computed-maintenance`, `cron-computed-mailfrom`, `cron-computed-mailto`), matching the shape used by the other plugins. +- A second round of `:report` additions surfaces every remaining settable-but-unreported property under the same raw/global/computed convention so external tooling can verify drift via `:report --format json` without falling back to a generic bash task. The `ps` plugin gains `--ps-dockerfile-start-cmd` and `--ps-computed-dockerfile-start-cmd`, `--ps-start-cmd` and `--ps-computed-start-cmd`, and the `--ps-skip-deploy` / `--ps-global-skip-deploy` / `--ps-computed-skip-deploy` triple (default `false`). The `builder` plugin gains the `--builder-skip-cleanup` triple (default `false`). The `scheduler` plugin gains the `--scheduler-shell` triple. The `proxy` plugin gains the `--proxy-proxy-port` and `--proxy-proxy-ssl-port` triples and exposes the raw `disabled` property as `--proxy-disabled` / `--proxy-computed-disabled`, alongside the existing inverted `--proxy-enabled`. The `openresty` plugin gains `--openresty-global-log-level` and `--openresty-computed-log-level` (default `ERROR`). The `nginx` plugin gains the `--nginx-nginx-service-command` triple. The `scheduler-k3s` plugin gains `--scheduler-k3s-global-token`, but the value is masked as `*******` in default stdout output; the raw value is returned only when the report is requested via `--format json` or when this flag is queried explicitly by name. The traefik `dns-provider-` keys now follow the same explicit-query rule - previously they were unmasked only for `--format json`, but a query like `dokku traefik:report --traefik-dns-provider-cf_api_key` now returns the actual value instead of `*******`. - The `scheduler-k3s` plugin now manages env config and the dokku-generated image pull Secret as their own helm releases with stable names (`config-{app}` and `pull-secret-{app}`) rather than bundling them into the app helm chart with a per-deploy timestamp suffix (`env-{app}.{ts}` / `ims-{app}.{ts}`). This fixes two bugs: a helm rollback of the app chart no longer deletes Secrets that older ReplicaSets still reference, and the Deployment's `imagePullSecrets` list no longer accumulates references to nonexistent Secrets across deploys. The next deploy of an app switches the Deployment's `envFrom` and `imagePullSecrets` references to the stable names and prunes any leaked entries; existing live Deployments do not need to be patched manually. App rename now also uninstalls the old `tls-{app}`, `config-{app}`, and `pull-secret-{app}` releases under the previous app name; the new name's releases are recreated on the next deploy or certs sync. - The storage plugin now treats persistent volumes as named, scheduler-aware first-class resources via `storage:create`, `storage:mount`, `storage:set`, and `storage:destroy`. The legacy `storage:mount :` colon form continues to work on docker-local apps but is deprecated; on k3s apps it is rejected. Existing colon-form mounts are migrated automatically the first time the new storage plugin runs (during the install trigger) - they appear as `legacy-` entries in `storage:list-entries`. The migration is idempotent and tied to a per-app flag file at `$DOKKU_LIB_ROOT/config/storage/.migrated/`; deleting that file forces a re-scan on the next install. The `storage:ensure-directory` command keeps working but now emits a deprecation warning - prefer `storage:create []` (the path defaults to the same `$DOKKU_LIB_ROOT/data/storage/` location). Storage entry names must now be DNS-1123 labels of 45 characters or less so they can be used verbatim as Helm release and Kubernetes resource names; underscores and uppercase characters that the older `ensure-directory` validator accepted are rejected for new names. The migration synthesizer always uses lowercase hex hashes so existing data is never locked out. diff --git a/docs/deployment/builders/builder-management.md b/docs/deployment/builders/builder-management.md index 593ce20a0..cce3703d5 100644 --- a/docs/deployment/builders/builder-management.md +++ b/docs/deployment/builders/builder-management.md @@ -181,7 +181,7 @@ For a simple example of how to implement this trigger, see `builder-pack`, which |---|---|---|---|---| | `build-dir` | app + global | none | `--builder-build-dir`, `--builder-global-build-dir`, `--builder-computed-build-dir` | Subdirectory within the repository to use as the build context | | `selected` | app + global | none | `--builder-selected`, `--builder-global-selected`, `--builder-computed-selected` | Builder plugin to use; overrides automatic detection | -| `skip-cleanup` | app + global | none | (not in report) | When `true`, leaves intermediate build artifacts in place after the build | +| `skip-cleanup` | app + global | `false` | `--builder-skip-cleanup`, `--builder-global-skip-cleanup`, `--builder-computed-skip-cleanup` | When `true`, leaves intermediate build artifacts in place after the build | ### Read-only flags diff --git a/docs/deployment/schedulers/k3s.md b/docs/deployment/schedulers/k3s.md index 0afaed933..1acac303c 100644 --- a/docs/deployment/schedulers/k3s.md +++ b/docs/deployment/schedulers/k3s.md @@ -807,5 +807,5 @@ If unspecified for any task, the default reservation will be `.1` CPU and `128Mi | `network-interface` | global only | `eth0` | `--scheduler-k3s-global-network-interface`, `--scheduler-k3s-computed-network-interface` | Host network interface used by k3s | | `rollback-on-failure` | app + global | `false` | `--scheduler-k3s-rollback-on-failure`, `--scheduler-k3s-global-rollback-on-failure`, `--scheduler-k3s-computed-rollback-on-failure` | When `true`, helm rolls back the release if a deploy fails | | `shm-size` | app + global | none | `--scheduler-k3s-shm-size`, `--scheduler-k3s-global-shm-size`, `--scheduler-k3s-computed-shm-size` | `/dev/shm` size override applied to app containers | -| `token` | global only | none | (not in report) | Cluster join token used by `scheduler-k3s:cluster-add` | +| `token` | global only | none | `--scheduler-k3s-global-token` (masked as `*******` in default stdout output; the raw value is returned when queried via `--format json` or when this flag is requested explicitly) | Cluster join token used by `scheduler-k3s:cluster-add` | | `chart..` | global only | none | `--scheduler-k3s-global-chart..` (dynamic per chart/property) | Override a value injected into the helm chart named `` (one row per chart/property pair) | diff --git a/docs/deployment/schedulers/scheduler-management.md b/docs/deployment/schedulers/scheduler-management.md index 0fcde8b65..e511b3531 100644 --- a/docs/deployment/schedulers/scheduler-management.md +++ b/docs/deployment/schedulers/scheduler-management.md @@ -155,4 +155,4 @@ Deployment tasks are currently executed directly on the primary Dokku server. | Property | Scope | Default | Report flags | Description | |---|---|---|---|---| | `selected` | app + global | `docker-local` | `--scheduler-selected`, `--scheduler-global-selected`, `--scheduler-computed-selected` | Scheduler plugin used to deploy this app (`docker-local`, `k3s`, etc.) | -| `shell` | app + global | none | (not in report) | Shell used by `enter`/`run` commands when entering a container | +| `shell` | app + global | none | `--scheduler-shell`, `--scheduler-global-shell`, `--scheduler-computed-shell` | Shell used by `enter`/`run` commands when entering a container | diff --git a/docs/networking/proxies/nginx.md b/docs/networking/proxies/nginx.md index bf6900ef6..b5f6609d4 100644 --- a/docs/networking/proxies/nginx.md +++ b/docs/networking/proxies/nginx.md @@ -645,7 +645,7 @@ All nginx-vhosts properties are settable at both the app and global scope. | `keepalive-timeout` | app + global | `75s` | `--nginx-keepalive-timeout`, `--nginx-global-keepalive-timeout`, `--nginx-computed-keepalive-timeout` | Time an idle keep-alive connection stays open | | `lingering-timeout` | app + global | `5s` | `--nginx-lingering-timeout`, `--nginx-global-lingering-timeout`, `--nginx-computed-lingering-timeout` | Time nginx waits for more client data when closing a connection | | `nginx-conf-sigil-path` | app + global | `nginx.conf.sigil` | `--nginx-nginx-conf-sigil-path`, `--nginx-global-nginx-conf-sigil-path`, `--nginx-computed-nginx-conf-sigil-path` | Path within the app to a custom `nginx.conf.sigil` template | -| `nginx-service-command` | app + global | none | (not in report) | Override command used by `nginx:start`/`nginx:stop`/`nginx:reload` | +| `nginx-service-command` | app + global | none | `--nginx-nginx-service-command`, `--nginx-global-nginx-service-command`, `--nginx-computed-nginx-service-command` | Override command used by `nginx:start`/`nginx:stop`/`nginx:reload` | | `proxy-buffer-size` | app + global | _system pagesize_ | `--nginx-proxy-buffer-size`, `--nginx-global-proxy-buffer-size`, `--nginx-computed-proxy-buffer-size` | Buffer size for reading the first part of the upstream response | | `proxy-buffering` | app + global | `on` | `--nginx-proxy-buffering`, `--nginx-global-proxy-buffering`, `--nginx-computed-proxy-buffering` | Whether nginx buffers upstream responses (`on` or `off`) | | `proxy-buffers` | app + global | _`8 {pagesize}`_ | `--nginx-proxy-buffers`, `--nginx-global-proxy-buffers`, `--nginx-computed-proxy-buffers` | Number and size of buffers used for an upstream response | diff --git a/docs/networking/proxies/openresty.md b/docs/networking/proxies/openresty.md index ed8caf404..867f514e2 100644 --- a/docs/networking/proxies/openresty.md +++ b/docs/networking/proxies/openresty.md @@ -308,7 +308,7 @@ Global-only properties expose two report flags: `--openresty-global-` | `letsencrypt-email` | global only | none | `--openresty-global-letsencrypt-email`, `--openresty-computed-letsencrypt-email` | Contact email enabling letsencrypt; empty disables https issuance | | `letsencrypt-server` | global only | `https://acme-v02.api.letsencrypt.org/directory` | `--openresty-global-letsencrypt-server`, `--openresty-computed-letsencrypt-server` | ACME directory used when requesting certificates | | `lingering-timeout` | app only | `5s` | `--openresty-lingering-timeout` | Time openresty waits for more client data when closing a connection | -| `log-level` | global only | `ERROR` | (not in report) | Openresty log level | +| `log-level` | global only | `ERROR` | `--openresty-global-log-level`, `--openresty-computed-log-level` | Openresty log level | | `proxy-buffer-size` | app only | _system pagesize_ | `--openresty-proxy-buffer-size` | Buffer size for reading the first part of the upstream response | | `proxy-buffering` | app only | `on` | `--openresty-proxy-buffering` | Whether openresty buffers upstream responses (`on` or `off`) | | `proxy-buffers` | app only | _`8 {pagesize}`_ | `--openresty-proxy-buffers` | Number and size of buffers used for an upstream response | diff --git a/docs/networking/proxies/traefik.md b/docs/networking/proxies/traefik.md index 9eb00db7f..2d079cc21 100644 --- a/docs/networking/proxies/traefik.md +++ b/docs/networking/proxies/traefik.md @@ -408,7 +408,7 @@ All traefik properties are global only. Set with `traefik:set --global ` | global only | none | (no report flag) | Per-provider environment variables passed to the Traefik container; `` is the upstream variable name (e.g. `dns-provider-cloudflare-api-token`) | +| `dns-provider-` | global only | none | `--traefik-dns-provider-` (masked as `*******` in the default stdout report; the raw value is returned when queried via `--format json` or when this flag is requested explicitly) | Per-provider environment variables passed to the Traefik container; `` is the upstream variable name (e.g. `dns-provider-cloudflare-api-token`) | | `http-entry-point` | global only | `http` | `--traefik-global-http-entry-point`, `--traefik-computed-http-entry-point` | Entry point name handling plaintext HTTP traffic | | `https-entry-point` | global only | `https` | `--traefik-global-https-entry-point`, `--traefik-computed-https-entry-point` | Entry point name handling TLS-terminated HTTPS traffic | | `image` | global only | _parsed from `plugins/traefik-vhosts/Dockerfile`_ | `--traefik-global-image`, `--traefik-computed-image` | Docker image used to run the Traefik container | diff --git a/docs/networking/proxy-management.md b/docs/networking/proxy-management.md index 242b77b64..5531bbef7 100644 --- a/docs/networking/proxy-management.md +++ b/docs/networking/proxy-management.md @@ -243,9 +243,9 @@ Finally, proxy implementations _may_ install extra software needed for the proxy | Property | Scope | Default | Report flags | Description | |---|---|---|---|---| -| `disabled` | app only | `false` | (exposed inverted as `--proxy-enabled`) | When `true`, disables proxy integration for this app (`proxy:enable`/`proxy:disable` write this) | -| `proxy-port` | app + global | none | (not in report) | Override port used for the HTTP listener in the generated proxy config | -| `proxy-ssl-port` | app + global | none | (not in report) | Override port used for the HTTPS listener in the generated proxy config | +| `disabled` | app only | `false` | `--proxy-disabled`, `--proxy-computed-disabled` (also exposed inverted as `--proxy-enabled`) | When `true`, disables proxy integration for this app (`proxy:enable`/`proxy:disable` write this) | +| `proxy-port` | app + global | none | `--proxy-proxy-port`, `--proxy-global-proxy-port`, `--proxy-computed-proxy-port` | Override port used for the HTTP listener in the generated proxy config | +| `proxy-ssl-port` | app + global | none | `--proxy-proxy-ssl-port`, `--proxy-global-proxy-ssl-port`, `--proxy-computed-proxy-ssl-port` | Override port used for the HTTPS listener in the generated proxy config | | `type` | app + global | `nginx` | `--proxy-type`, `--proxy-global-type`, `--proxy-computed-type` | Proxy implementation handling traffic for the app (`nginx`, `caddy`, `haproxy`, `traefik`, `openresty`, or a custom plugin) | ### Read-only flags diff --git a/docs/processes/process-management.md b/docs/processes/process-management.md index f9cf40175..ca445c2b1 100644 --- a/docs/processes/process-management.md +++ b/docs/processes/process-management.md @@ -470,12 +470,12 @@ dokku ps:set node-js-app restore | Property | Scope | Default | Report flags | Description | |---|---|---|---|---| -| `dockerfile-start-cmd` | app only | none | (not in report) | Override `CMD` for Dockerfile-based apps | +| `dockerfile-start-cmd` | app only | none | `--ps-dockerfile-start-cmd`, `--ps-computed-dockerfile-start-cmd` | Override `CMD` for Dockerfile-based apps | | `procfile-path` | app + global | `Procfile` | `--ps-procfile-path`, `--ps-global-procfile-path`, `--ps-computed-procfile-path` | Path to the app's Procfile, relative to the build root | | `restart-policy` | app only | `on-failure:10` | `--ps-restart-policy` | Docker restart policy applied to deployed containers (`no`, `always`, `unless-stopped`, `on-failure[:max-retries]`) | | `restore` | app only | `true` | `--restore` | When `true`, the app is restarted automatically by `ps:retire` after a host reboot | -| `skip-deploy` | app + global | `false` | (not in report) | When `true`, skips the deploy phase after a successful build | -| `start-cmd` | app only | none | (not in report) | Override start command for buildpack apps | +| `skip-deploy` | app + global | `false` | `--ps-skip-deploy`, `--ps-global-skip-deploy`, `--ps-computed-skip-deploy` | When `true`, skips the deploy phase after a successful build | +| `start-cmd` | app only | none | `--ps-start-cmd`, `--ps-computed-start-cmd` | Override start command for buildpack apps | | `stop-timeout-seconds` | app + global | `30` | `--ps-stop-timeout-seconds`, `--ps-global-stop-timeout-seconds`, `--ps-computed-stop-timeout-seconds` | Seconds Docker waits before SIGKILLing a container on stop | ### Read-only flags diff --git a/plugins/builder/report.go b/plugins/builder/report.go index bedf9c39d..8fa76c6aa 100644 --- a/plugins/builder/report.go +++ b/plugins/builder/report.go @@ -15,18 +15,23 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { var flags map[string]common.ReportFunc if appName == "--global" { flags = map[string]common.ReportFunc{ - "--builder-global-selected": reportGlobalSelected, - "--builder-global-build-dir": reportGlobalBuildDir, + "--builder-global-selected": reportGlobalSelected, + "--builder-global-build-dir": reportGlobalBuildDir, + "--builder-global-skip-cleanup": reportGlobalSkipCleanup, + "--builder-computed-skip-cleanup": reportComputedSkipCleanup, } } else { flags = map[string]common.ReportFunc{ - "--builder-computed-selected": reportComputedSelected, - "--builder-global-selected": reportGlobalSelected, - "--builder-selected": reportSelected, - "--builder-detected": reportDetected, - "--builder-computed-build-dir": reportComputedBuildDir, - "--builder-global-build-dir": reportGlobalBuildDir, - "--builder-build-dir": reportBuildDir, + "--builder-computed-selected": reportComputedSelected, + "--builder-global-selected": reportGlobalSelected, + "--builder-selected": reportSelected, + "--builder-detected": reportDetected, + "--builder-computed-build-dir": reportComputedBuildDir, + "--builder-global-build-dir": reportGlobalBuildDir, + "--builder-build-dir": reportBuildDir, + "--builder-computed-skip-cleanup": reportComputedSkipCleanup, + "--builder-global-skip-cleanup": reportGlobalSkipCleanup, + "--builder-skip-cleanup": reportSkipCleanup, } } @@ -77,3 +82,23 @@ func reportGlobalBuildDir(appName string) string { func reportBuildDir(appName string) string { return common.PropertyGet("builder", appName, "build-dir") } + +func reportComputedSkipCleanup(appName string) string { + value := reportSkipCleanup(appName) + if value == "" { + value = reportGlobalSkipCleanup(appName) + } + if value == "" { + value = "false" + } + + return value +} + +func reportGlobalSkipCleanup(appName string) string { + return common.PropertyGet("builder", "--global", "skip-cleanup") +} + +func reportSkipCleanup(appName string) string { + return common.PropertyGet("builder", appName, "skip-cleanup") +} diff --git a/plugins/nginx-vhosts/command-functions b/plugins/nginx-vhosts/command-functions index e48032d00..961303970 100755 --- a/plugins/nginx-vhosts/command-functions +++ b/plugins/nginx-vhosts/command-functions @@ -97,6 +97,9 @@ cmd-nginx-report-single() { "--nginx-nginx-conf-sigil-path: $(fn-nginx-nginx-conf-sigil-path "$APP")" "--nginx-computed-nginx-conf-sigil-path: $(fn-nginx-computed-nginx-conf-sigil-path "$APP")" "--nginx-global-nginx-conf-sigil-path: $(fn-nginx-global-nginx-conf-sigil-path "$APP")" + "--nginx-nginx-service-command: $(fn-nginx-nginx-service-command "$APP")" + "--nginx-computed-nginx-service-command: $(fn-nginx-computed-nginx-service-command "$APP")" + "--nginx-global-nginx-service-command: $(fn-nginx-global-nginx-service-command "$APP")" "--nginx-proxy-buffer-size: $(fn-nginx-proxy-buffer-size "$APP")" "--nginx-computed-proxy-buffer-size: $(fn-nginx-computed-proxy-buffer-size "$APP")" "--nginx-global-proxy-buffer-size: $(fn-nginx-global-proxy-buffer-size "$APP")" diff --git a/plugins/openresty-vhosts/command-functions b/plugins/openresty-vhosts/command-functions index 89e53ef96..dfe090fc2 100755 --- a/plugins/openresty-vhosts/command-functions +++ b/plugins/openresty-vhosts/command-functions @@ -80,6 +80,8 @@ cmd-openresty-report-single() { "--openresty-computed-letsencrypt-email: $(fn-openresty-computed-letsencrypt-email)" "--openresty-global-letsencrypt-server: $(fn-openresty-global-letsencrypt-server)" "--openresty-computed-letsencrypt-server: $(fn-openresty-computed-letsencrypt-server)" + "--openresty-global-log-level: $(fn-openresty-global-log-level)" + "--openresty-computed-log-level: $(fn-openresty-computed-log-level)" ) else verify_app_name "$APP" @@ -107,6 +109,8 @@ cmd-openresty-report-single() { "--openresty-computed-letsencrypt-email: $(fn-openresty-computed-letsencrypt-email)" "--openresty-global-letsencrypt-server: $(fn-openresty-global-letsencrypt-server)" "--openresty-computed-letsencrypt-server: $(fn-openresty-computed-letsencrypt-server)" + "--openresty-global-log-level: $(fn-openresty-global-log-level)" + "--openresty-computed-log-level: $(fn-openresty-computed-log-level)" "--openresty-lingering-timeout: $(fn-openresty-lingering-timeout "$APP")" "--openresty-proxy-buffer-size: $(fn-openresty-proxy-buffer-size "$APP")" "--openresty-proxy-buffering: $(fn-openresty-proxy-buffering "$APP")" diff --git a/plugins/openresty-vhosts/internal-functions b/plugins/openresty-vhosts/internal-functions index c6ae8cb0b..e3ab20099 100755 --- a/plugins/openresty-vhosts/internal-functions +++ b/plugins/openresty-vhosts/internal-functions @@ -190,6 +190,23 @@ fn-openresty-computed-letsencrypt-server() { echo "$value" } +fn-openresty-global-log-level() { + declare desc="get the raw configured log level" + + fn-plugin-property-get-default "openresty" "--global" "log-level" "" +} + +fn-openresty-computed-log-level() { + declare desc="get the effective log level, falling back to ERROR" + local value + + value="$(fn-openresty-global-log-level)" + if [[ -z "$value" ]]; then + value="ERROR" + fi + echo "$value" +} + fn-openresty-log-root() { declare desc="get the openresty log root" local OPENRESTY_LOG_ROOT="/var/log/nginx" diff --git a/plugins/proxy/functions.go b/plugins/proxy/functions.go index ec3f4ed75..1e1f5df7f 100644 --- a/plugins/proxy/functions.go +++ b/plugins/proxy/functions.go @@ -23,3 +23,50 @@ func getComputedProxyType(appName string) string { func getGlobalProxyType() string { return common.PropertyGet("proxy", "--global", "type") } + +func getAppProxyPort(appName string) string { + return common.PropertyGet("proxy", appName, "proxy-port") +} + +func getGlobalProxyPort() string { + return common.PropertyGet("proxy", "--global", "proxy-port") +} + +func getComputedProxyPort(appName string) string { + value := getAppProxyPort(appName) + if value == "" { + value = getGlobalProxyPort() + } + + return value +} + +func getAppProxySSLPort(appName string) string { + return common.PropertyGet("proxy", appName, "proxy-ssl-port") +} + +func getGlobalProxySSLPort() string { + return common.PropertyGet("proxy", "--global", "proxy-ssl-port") +} + +func getComputedProxySSLPort(appName string) string { + value := getAppProxySSLPort(appName) + if value == "" { + value = getGlobalProxySSLPort() + } + + return value +} + +func getAppDisabled(appName string) string { + return common.PropertyGet("proxy", appName, "disabled") +} + +func getComputedDisabled(appName string) string { + value := getAppDisabled(appName) + if value == "" { + value = "false" + } + + return value +} diff --git a/plugins/proxy/report.go b/plugins/proxy/report.go index 1f55a7c78..b971500d2 100644 --- a/plugins/proxy/report.go +++ b/plugins/proxy/report.go @@ -15,15 +15,27 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { var flags map[string]common.ReportFunc if appName == "--global" { flags = map[string]common.ReportFunc{ - "--proxy-computed-type": reportComputedType, - "--proxy-global-type": reportGlobalType, + "--proxy-computed-proxy-port": reportComputedProxyPort, + "--proxy-computed-proxy-ssl-port": reportComputedProxySSLPort, + "--proxy-computed-type": reportComputedType, + "--proxy-global-proxy-port": reportGlobalProxyPort, + "--proxy-global-proxy-ssl-port": reportGlobalProxySSLPort, + "--proxy-global-type": reportGlobalType, } } else { flags = map[string]common.ReportFunc{ - "--proxy-enabled": reportEnabled, - "--proxy-computed-type": reportComputedType, - "--proxy-global-type": reportGlobalType, - "--proxy-type": reportType, + "--proxy-computed-disabled": reportComputedDisabled, + "--proxy-computed-proxy-port": reportComputedProxyPort, + "--proxy-computed-proxy-ssl-port": reportComputedProxySSLPort, + "--proxy-computed-type": reportComputedType, + "--proxy-disabled": reportDisabled, + "--proxy-enabled": reportEnabled, + "--proxy-global-proxy-port": reportGlobalProxyPort, + "--proxy-global-proxy-ssl-port": reportGlobalProxySSLPort, + "--proxy-global-type": reportGlobalType, + "--proxy-proxy-port": reportProxyPort, + "--proxy-proxy-ssl-port": reportProxySSLPort, + "--proxy-type": reportType, } } @@ -58,3 +70,35 @@ func reportGlobalType(appName string) string { func reportType(appName string) string { return getAppProxyType(appName) } + +func reportDisabled(appName string) string { + return getAppDisabled(appName) +} + +func reportComputedDisabled(appName string) string { + return getComputedDisabled(appName) +} + +func reportProxyPort(appName string) string { + return getAppProxyPort(appName) +} + +func reportGlobalProxyPort(appName string) string { + return getGlobalProxyPort() +} + +func reportComputedProxyPort(appName string) string { + return getComputedProxyPort(appName) +} + +func reportProxySSLPort(appName string) string { + return getAppProxySSLPort(appName) +} + +func reportGlobalProxySSLPort(appName string) string { + return getGlobalProxySSLPort() +} + +func reportComputedProxySSLPort(appName string) string { + return getComputedProxySSLPort(appName) +} diff --git a/plugins/ps/report.go b/plugins/ps/report.go index 5e9c9b291..c5a7a9cda 100644 --- a/plugins/ps/report.go +++ b/plugins/ps/report.go @@ -20,24 +20,33 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { if appName == "--global" { flags = map[string]common.ReportFunc{ "--ps-computed-procfile-path": reportComputedProcfilePath, + "--ps-computed-skip-deploy": reportComputedSkipDeploy, "--ps-computed-stop-timeout-seconds": reportComputedStopTimeoutSeconds, "--ps-global-procfile-path": reportGlobalProcfilePath, + "--ps-global-skip-deploy": reportGlobalSkipDeploy, "--ps-global-stop-timeout-seconds": reportGlobalStopTimeoutSeconds, } } else { flags = map[string]common.ReportFunc{ - "--deployed": reportDeployed, - "--processes": reportProcesses, - "--ps-can-scale": reportCanScale, - "--ps-restart-policy": reportRestartPolicy, - "--ps-computed-procfile-path": reportComputedProcfilePath, - "--ps-global-procfile-path": reportGlobalProcfilePath, - "--ps-procfile-path": reportProcfilePath, - "--restore": reportRestore, - "--running": reportRunningState, - "--ps-global-stop-timeout-seconds": reportGlobalStopTimeoutSeconds, - "--ps-computed-stop-timeout-seconds": reportComputedStopTimeoutSeconds, - "--ps-stop-timeout-seconds": reportStopTimeoutSeconds, + "--deployed": reportDeployed, + "--processes": reportProcesses, + "--ps-can-scale": reportCanScale, + "--ps-computed-dockerfile-start-cmd": reportComputedDockerfileStartCmd, + "--ps-computed-procfile-path": reportComputedProcfilePath, + "--ps-computed-skip-deploy": reportComputedSkipDeploy, + "--ps-computed-start-cmd": reportComputedStartCmd, + "--ps-computed-stop-timeout-seconds": reportComputedStopTimeoutSeconds, + "--ps-dockerfile-start-cmd": reportDockerfileStartCmd, + "--ps-global-procfile-path": reportGlobalProcfilePath, + "--ps-global-skip-deploy": reportGlobalSkipDeploy, + "--ps-global-stop-timeout-seconds": reportGlobalStopTimeoutSeconds, + "--ps-procfile-path": reportProcfilePath, + "--ps-restart-policy": reportRestartPolicy, + "--ps-skip-deploy": reportSkipDeploy, + "--ps-start-cmd": reportStartCmd, + "--ps-stop-timeout-seconds": reportStopTimeoutSeconds, + "--restore": reportRestore, + "--running": reportRunningState, } extraFlags := addStatusFlags(appName, infoFlag) @@ -99,6 +108,14 @@ func reportCanScale(appName string) string { return canScale } +func reportComputedDockerfileStartCmd(appName string) string { + return reportDockerfileStartCmd(appName) +} + +func reportDockerfileStartCmd(appName string) string { + return common.PropertyGet("ps", appName, "dockerfile-start-cmd") +} + func reportComputedProcfilePath(appName string) string { value := reportProcfilePath(appName) if value == "" { @@ -150,6 +167,34 @@ func reportRestore(appName string) string { return common.PropertyGetDefault("ps", appName, "restore", "true") } +func reportComputedSkipDeploy(appName string) string { + value := reportSkipDeploy(appName) + if value == "" { + value = reportGlobalSkipDeploy(appName) + } + if value == "" { + value = "false" + } + + return value +} + +func reportGlobalSkipDeploy(appName string) string { + return common.PropertyGet("ps", "--global", "skip-deploy") +} + +func reportSkipDeploy(appName string) string { + return common.PropertyGet("ps", appName, "skip-deploy") +} + +func reportComputedStartCmd(appName string) string { + return reportStartCmd(appName) +} + +func reportStartCmd(appName string) string { + return common.PropertyGet("ps", appName, "start-cmd") +} + func reportRunningState(appName string) string { return getRunningState(appName) } diff --git a/plugins/ps/triggers.go b/plugins/ps/triggers.go index 7c4c128b4..7217592fa 100644 --- a/plugins/ps/triggers.go +++ b/plugins/ps/triggers.go @@ -332,11 +332,3 @@ func TriggerPsGetProperty(appName string, property string) error { fmt.Println(fn(appName)) return nil } - -func reportComputedSkipDeploy(appName string) string { - value := common.PropertyGet("ps", appName, "skip-deploy") - if value == "" { - value = common.PropertyGet("ps", "--global", "skip-deploy") - } - return value -} diff --git a/plugins/scheduler-k3s/report.go b/plugins/scheduler-k3s/report.go index 9456932f7..7bbdbea97 100644 --- a/plugins/scheduler-k3s/report.go +++ b/plugins/scheduler-k3s/report.go @@ -7,6 +7,9 @@ import ( "github.com/dokku/dokku/plugins/common" ) +// tokenMask is shown in place of the raw token value in default stdout output. +const tokenMask = "*******" + // ReportSingleApp is an internal function that displays the scheduler-k3s report for one or more apps func ReportSingleApp(appName string, format string, infoFlag string) error { if appName != "--global" { @@ -17,6 +20,12 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { var flags map[string]common.ReportFunc if appName == "--global" { + tokenFlag := "--scheduler-k3s-global-token" + tokenReportFunc := reportMaskedGlobalToken + if format == "json" || infoFlag == tokenFlag { + tokenReportFunc = reportGlobalToken + } + flags = map[string]common.ReportFunc{ "--scheduler-k3s-computed-deploy-timeout": reportComputedDeployTimeout, "--scheduler-k3s-global-deploy-timeout": reportGlobalDeployTimeout, @@ -44,6 +53,7 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { "--scheduler-k3s-global-rollback-on-failure": reportGlobalRollbackOnFailure, "--scheduler-k3s-computed-shm-size": reportComputedShmSize, "--scheduler-k3s-global-shm-size": reportGlobalShmSize, + tokenFlag: tokenReportFunc, } } else { flags = map[string]common.ReportFunc{ @@ -267,3 +277,15 @@ func reportGlobalShmSize(appName string) string { func reportShmSize(appName string) string { return getShmSize(appName) } + +func reportGlobalToken(appName string) string { + return getGlobalGlobalToken() +} + +func reportMaskedGlobalToken(appName string) string { + value := getGlobalGlobalToken() + if value == "" { + return "" + } + return tokenMask +} diff --git a/plugins/scheduler/report.go b/plugins/scheduler/report.go index 801b3fb4b..02570d8ba 100644 --- a/plugins/scheduler/report.go +++ b/plugins/scheduler/report.go @@ -17,12 +17,17 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { flags = map[string]common.ReportFunc{ "--scheduler-computed-selected": reportComputedSelected, "--scheduler-global-selected": reportGlobalSelected, + "--scheduler-computed-shell": reportComputedShell, + "--scheduler-global-shell": reportGlobalShell, } } else { flags = map[string]common.ReportFunc{ "--scheduler-computed-selected": reportComputedSelected, "--scheduler-global-selected": reportGlobalSelected, "--scheduler-selected": reportSelected, + "--scheduler-computed-shell": reportComputedShell, + "--scheduler-global-shell": reportGlobalShell, + "--scheduler-shell": reportShell, } } @@ -56,3 +61,20 @@ func reportGlobalSelected(appName string) string { func reportSelected(appName string) string { return common.PropertyGet("scheduler", appName, "selected") } + +func reportComputedShell(appName string) string { + value := reportShell(appName) + if value == "" { + value = reportGlobalShell(appName) + } + + return value +} + +func reportGlobalShell(appName string) string { + return common.PropertyGet("scheduler", "--global", "shell") +} + +func reportShell(appName string) string { + return common.PropertyGet("scheduler", appName, "shell") +} diff --git a/plugins/traefik-vhosts/command-functions b/plugins/traefik-vhosts/command-functions index 6ccf88128..2d742dde0 100755 --- a/plugins/traefik-vhosts/command-functions +++ b/plugins/traefik-vhosts/command-functions @@ -111,7 +111,7 @@ cmd-traefik-report-single() { key="$(echo "$line" | cut -d' ' -f1)" value="$(echo "$line" | cut -d' ' -f2-)" if [[ -n "$key" ]]; then - if [[ "$FORMAT" == "json" ]]; then + if [[ "$FORMAT" == "json" ]] || [[ "$INFO_FLAG" == "--traefik-${key}" ]]; then flag_map+=("--traefik-${key}: ${value}") else flag_map+=("--traefik-${key}: *******") diff --git a/tests/unit/builder.bats b/tests/unit/builder.bats index 2e7574631..a09136aab 100644 --- a/tests/unit/builder.bats +++ b/tests/unit/builder.bats @@ -7,6 +7,7 @@ setup() { } teardown() { + dokku builder:set --global skip-cleanup >/dev/null 2>/dev/null || true destroy_app } @@ -307,6 +308,55 @@ teardown() { assert_success } +@test "(builder:report) skip-cleanup raw vs computed vs global" { + run /bin/bash -c "dokku builder:set --global skip-cleanup" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-skip-cleanup" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-skip-cleanup" + assert_success + assert_output_not_exists + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-skip-cleanup" + assert_success + assert_output "false" + + run /bin/bash -c "dokku builder:set --global skip-cleanup true" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-skip-cleanup" + assert_success + assert_output "true" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-skip-cleanup" + assert_success + assert_output "true" + + run /bin/bash -c "dokku builder:set $TEST_APP skip-cleanup false" + assert_success + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-skip-cleanup" + assert_success + assert_output "false" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-global-skip-cleanup" + assert_success + assert_output "true" + + run /bin/bash -c "dokku builder:report $TEST_APP --builder-computed-skip-cleanup" + assert_success + assert_output "false" + + run /bin/bash -c "dokku builder:set $TEST_APP skip-cleanup" + assert_success + + run /bin/bash -c "dokku builder:set --global skip-cleanup" + assert_success +} + @test "(builder:set)" { run deploy_app python echo "output: $output" diff --git a/tests/unit/nginx-vhosts_properties.bats b/tests/unit/nginx-vhosts_properties.bats index 70c9636ab..586908eec 100644 --- a/tests/unit/nginx-vhosts_properties.bats +++ b/tests/unit/nginx-vhosts_properties.bats @@ -105,4 +105,5 @@ assert_nginx_property_set_get() { assert_nginx_property_set_get "underscore-in-headers" "on" "off" assert_nginx_property_set_get "proxy-keepalive" "8" "16" assert_nginx_property_set_get "nginx-conf-sigil-path" "custom.sigil" "global.sigil" + assert_nginx_property_set_get "nginx-service-command" "/usr/sbin/nginx-app" "/usr/sbin/nginx-global" } diff --git a/tests/unit/openresty.bats b/tests/unit/openresty.bats index f47cf4704..5acf6feeb 100644 --- a/tests/unit/openresty.bats +++ b/tests/unit/openresty.bats @@ -12,6 +12,7 @@ setup() { } teardown() { + dokku openresty:set --global log-level >/dev/null 2>&1 || true global_teardown destroy_app dokku openresty:stop @@ -151,6 +152,66 @@ teardown() { assert_output_exists } +@test "(openresty:report) --global log-level raw vs computed" { + run /bin/bash -c "dokku openresty:report --global --openresty-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku openresty:report --global --openresty-computed-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "ERROR" + + run /bin/bash -c "dokku openresty:set --global log-level DEBUG" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku openresty:report --global --openresty-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "DEBUG" + + run /bin/bash -c "dokku openresty:report --global --openresty-computed-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "DEBUG" + + run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"global-log-level\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "DEBUG" + + run /bin/bash -c "dokku openresty:report --global --format json | jq -r '.\"computed-log-level\"'" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "DEBUG" + + run /bin/bash -c "dokku openresty:set --global log-level" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku openresty:report --global --openresty-global-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "" + + run /bin/bash -c "dokku openresty:report --global --openresty-computed-log-level" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "ERROR" +} + @test "(openresty) global-only keys" { for key in allowed-letsencrypt-domains-func-base64 image log-level letsencrypt-email letsencrypt-server; do run /bin/bash -c "dokku openresty:set $TEST_APP $key somevalue" diff --git a/tests/unit/proxy.bats b/tests/unit/proxy.bats index 77d9cd625..3ffb867fb 100644 --- a/tests/unit/proxy.bats +++ b/tests/unit/proxy.bats @@ -9,6 +9,8 @@ setup() { } teardown() { + dokku proxy:set --global proxy-port >/dev/null 2>&1 || true + dokku proxy:set --global proxy-ssl-port >/dev/null 2>&1 || true destroy_app [[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST" global_teardown @@ -125,6 +127,154 @@ teardown() { assert_success } +@test "(proxy:report) proxy-port raw vs computed vs global" { + run /bin/bash -c "dokku proxy:set --global proxy-port" + assert_success + + run /bin/bash -c "dokku proxy:set $TEST_APP proxy-port" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-proxy-port\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-port\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-port\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:set --global proxy-port 5000" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-port\"'" + assert_success + assert_output "5000" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-port\"'" + assert_success + assert_output "5000" + + run /bin/bash -c "dokku proxy:set $TEST_APP proxy-port 6000" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-proxy-port\"'" + assert_success + assert_output "6000" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-port\"'" + assert_success + assert_output "5000" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-port\"'" + assert_success + assert_output "6000" + + run /bin/bash -c "dokku proxy:set $TEST_APP proxy-port" + assert_success + + run /bin/bash -c "dokku proxy:set --global proxy-port" + assert_success +} + +@test "(proxy:report) proxy-ssl-port raw vs computed vs global" { + run /bin/bash -c "dokku proxy:set --global proxy-ssl-port" + assert_success + + run /bin/bash -c "dokku proxy:set $TEST_APP proxy-ssl-port" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-proxy-ssl-port\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-ssl-port\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-ssl-port\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:set --global proxy-ssl-port 5443" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-ssl-port\"'" + assert_success + assert_output "5443" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-ssl-port\"'" + assert_success + assert_output "5443" + + run /bin/bash -c "dokku proxy:set $TEST_APP proxy-ssl-port 6443" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-proxy-ssl-port\"'" + assert_success + assert_output "6443" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-global-proxy-ssl-port\"'" + assert_success + assert_output "5443" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-proxy-ssl-port\"'" + assert_success + assert_output "6443" + + run /bin/bash -c "dokku proxy:set $TEST_APP proxy-ssl-port" + assert_success + + run /bin/bash -c "dokku proxy:set --global proxy-ssl-port" + assert_success +} + +@test "(proxy:report) disabled raw and computed match disabled state" { + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-disabled\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-disabled\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-enabled\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku proxy:disable $TEST_APP" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-disabled\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-disabled\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-enabled\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku proxy:enable $TEST_APP" + assert_success + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-disabled\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-computed-disabled\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku proxy:report $TEST_APP --format json | jq -r '.\"proxy-enabled\"'" + assert_success + assert_output "true" +} + @test "(proxy:set) invalid port mapping set" { run /bin/bash -c "dokku proxy:set $TEST_APP http:80:80" echo "output: $output" diff --git a/tests/unit/ps-general-1.bats b/tests/unit/ps-general-1.bats index 31e3a18f0..020591f88 100644 --- a/tests/unit/ps-general-1.bats +++ b/tests/unit/ps-general-1.bats @@ -93,6 +93,114 @@ teardown() { assert_success } +@test "(ps:set) skip-deploy raw/global/computed" { + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-skip-deploy\"'" + echo "output: $output" + echo "status: $status" + assert_output "false" + assert_success + + run /bin/bash -c "dokku ps:set --global skip-deploy true" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-skip-deploy\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-skip-deploy\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-skip-deploy\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku ps:set $TEST_APP skip-deploy false" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-skip-deploy\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-skip-deploy\"'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-skip-deploy\"'" + assert_success + assert_output "false" + + run /bin/bash -c "dokku ps:set $TEST_APP skip-deploy" + assert_success + + run /bin/bash -c "dokku ps:set --global skip-deploy" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-global-skip-deploy\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-skip-deploy\"'" + assert_success + assert_output "false" +} + +@test "(ps:set) dockerfile-start-cmd raw and computed" { + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-dockerfile-start-cmd\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-dockerfile-start-cmd\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku ps:set $TEST_APP dockerfile-start-cmd 'node app.js'" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-dockerfile-start-cmd\"'" + assert_success + assert_output "node app.js" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-dockerfile-start-cmd\"'" + assert_success + assert_output "node app.js" + + run /bin/bash -c "dokku ps:set $TEST_APP dockerfile-start-cmd" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-dockerfile-start-cmd\"'" + assert_success + assert_output "" +} + +@test "(ps:set) start-cmd raw and computed" { + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-start-cmd\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-start-cmd\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku ps:set $TEST_APP start-cmd 'bundle exec rails server'" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-start-cmd\"'" + assert_success + assert_output "bundle exec rails server" + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-computed-start-cmd\"'" + assert_success + assert_output "bundle exec rails server" + + run /bin/bash -c "dokku ps:set $TEST_APP start-cmd" + assert_success + + run /bin/bash -c "dokku ps:report $TEST_APP --format json | jq -r '.\"ps-start-cmd\"'" + assert_success + assert_output "" +} + @test "(ps:scale) procfile commands extraction" { source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions" cat <"$DOKKU_LIB_ROOT/data/ps/$TEST_APP/Procfile" diff --git a/tests/unit/scheduler-k3s-report.bats b/tests/unit/scheduler-k3s-report.bats index 045e0976d..f38547d3f 100644 --- a/tests/unit/scheduler-k3s-report.bats +++ b/tests/unit/scheduler-k3s-report.bats @@ -7,7 +7,7 @@ setup() { } teardown() { - for prop in deploy-timeout image-pull-secrets ingress-class kubeconfig-path kube-context kustomize-root-path namespace network-interface rollback-on-failure shm-size; do + for prop in deploy-timeout image-pull-secrets ingress-class kubeconfig-path kube-context kustomize-root-path namespace network-interface rollback-on-failure shm-size token; do dokku scheduler-k3s:set --global "$prop" >/dev/null 2>/dev/null || true done global_teardown @@ -122,3 +122,39 @@ assert_k3s_global_unset_set() { assert_success assert_output "" } + +@test "(scheduler-k3s:report --global) token masked in stdout but exposed via json or explicit flag" { + run /bin/bash -c "dokku scheduler-k3s:set --global token" + assert_success + + run /bin/bash -c "dokku scheduler-k3s:report --global --format json | jq -e 'has(\"scheduler-k3s-global-token\")'" + assert_success + assert_output "true" + + run /bin/bash -c "dokku scheduler-k3s:report --global --format json | jq -r '.\"scheduler-k3s-global-token\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler-k3s:report --global --scheduler-k3s-global-token" + assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler-k3s:set --global token sometoken" + assert_success + + run /bin/bash -c "dokku scheduler-k3s:report --global" + assert_success + assert_output_contains "*******" + assert_output_not_contains "sometoken" + + run /bin/bash -c "dokku scheduler-k3s:report --global --format json | jq -r '.\"scheduler-k3s-global-token\"'" + assert_success + assert_output "sometoken" + + run /bin/bash -c "dokku scheduler-k3s:report --global --scheduler-k3s-global-token" + assert_success + assert_output "sometoken" + + run /bin/bash -c "dokku scheduler-k3s:set --global token" + assert_success +} diff --git a/tests/unit/scheduler.bats b/tests/unit/scheduler.bats index 9cee44778..235557bf3 100644 --- a/tests/unit/scheduler.bats +++ b/tests/unit/scheduler.bats @@ -9,6 +9,7 @@ setup() { teardown() { dokku scheduler:set --global selected >/dev/null 2>&1 || true + dokku scheduler:set --global shell >/dev/null 2>&1 || true destroy_app global_teardown } @@ -76,6 +77,55 @@ teardown() { assert_success } +@test "(scheduler:report) shell raw vs computed vs global" { + run /bin/bash -c "dokku scheduler:set --global shell" + assert_success + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-shell\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-global-shell\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-computed-shell\"'" + assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler:set --global shell sh" + assert_success + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-global-shell\"'" + assert_success + assert_output "sh" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-computed-shell\"'" + assert_success + assert_output "sh" + + run /bin/bash -c "dokku scheduler:set $TEST_APP shell bash" + assert_success + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-shell\"'" + assert_success + assert_output "bash" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-global-shell\"'" + assert_success + assert_output "sh" + + run /bin/bash -c "dokku scheduler:report $TEST_APP --format json | jq -r '.\"scheduler-computed-shell\"'" + assert_success + assert_output "bash" + + run /bin/bash -c "dokku scheduler:set $TEST_APP shell" + assert_success + + run /bin/bash -c "dokku scheduler:set --global shell" + assert_success +} + @test "(scheduler:report) --global --format json" { run /bin/bash -c "dokku scheduler:set --global selected" assert_success diff --git a/tests/unit/traefik.bats b/tests/unit/traefik.bats index ac9edf1b8..839ba1fb7 100644 --- a/tests/unit/traefik.bats +++ b/tests/unit/traefik.bats @@ -549,7 +549,13 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - assert_output "*******" + assert_output "test@example.com" + + run /bin/bash -c "dokku traefik:report $TEST_APP --traefik-dns-provider-cf_api_key" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "secret-key" run /bin/bash -c "dokku traefik:set --global dns-provider-cf_api_email" echo "output: $output"