mirror of
https://github.com/dokku/dokku.git
synced 2026-08-29 10:08:53 +02:00
feat: port vhost proxy :report subcommands to golang
The bash :report implementations for the caddy, haproxy, openresty, and traefik proxy plugins are replaced with a compiled golang binary that collects report keys in parallel and marshals json directly. The traefik dns-provider values keep their masking behaviour, remaining hidden in the default stdout report while surfacing for --format json or an explicit flag query. These four plugins previously had no unit tests, so a bats suite covering the report matrix is added for each.
This commit is contained in:
4
plugins/traefik-vhosts/.gitignore
vendored
Normal file
4
plugins/traefik-vhosts/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/report
|
||||
/report-subcommand
|
||||
/triggers
|
||||
/subcommands/report
|
||||
13
plugins/traefik-vhosts/Makefile
Normal file
13
plugins/traefik-vhosts/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
GOARCH ?= amd64
|
||||
TRIGGERS = triggers/report
|
||||
BUILD = report-subcommand triggers
|
||||
PLUGIN_NAME = traefik-vhosts
|
||||
|
||||
clean-report-subcommand:
|
||||
rm -rf report-subcommand
|
||||
|
||||
report-subcommand: clean-report-subcommand src/subcommands/subcommands.go
|
||||
GOARCH=$(GOARCH) go build -mod=readonly -ldflags="-s -w" $(GO_ARGS) -o report-subcommand src/subcommands/subcommands.go
|
||||
ln -sf ../report-subcommand subcommands/report
|
||||
|
||||
include ../../common.mk
|
||||
125
plugins/traefik-vhosts/command-functions
Executable file → Normal file
125
plugins/traefik-vhosts/command-functions
Executable file → Normal file
@@ -30,131 +30,6 @@ cmd-traefik-labels-show() {
|
||||
cmd-proxy-labels-show "proxy:labels:show" "traefik" "$@"
|
||||
}
|
||||
|
||||
cmd-traefik-report() {
|
||||
declare desc="displays a traefik report for one or more apps"
|
||||
declare cmd="traefik:report"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
fn-report-parse-args "$@"
|
||||
set -- "${REPORT_ARGS[@]}"
|
||||
declare APP="${1:-}" INFO_FLAG="${2:-}"
|
||||
|
||||
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
|
||||
INFO_FLAG="$APP"
|
||||
APP=""
|
||||
fi
|
||||
|
||||
if [[ "$REPORT_IS_GLOBAL" == "true" ]]; then
|
||||
APP="--global"
|
||||
fi
|
||||
|
||||
if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then
|
||||
INFO_FLAG="true"
|
||||
fi
|
||||
|
||||
if [[ "$APP" == "--global" ]]; then
|
||||
cmd-traefik-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
|
||||
elif [[ -z "$APP" ]]; then
|
||||
for app in $(dokku_apps); do
|
||||
cmd-traefik-report-single "$app" "$INFO_FLAG" "$REPORT_FORMAT" | tee || true
|
||||
done
|
||||
else
|
||||
cmd-traefik-report-single "$APP" "$INFO_FLAG" "$REPORT_FORMAT"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-traefik-report-single() {
|
||||
declare APP="$1" INFO_FLAG="$2" FORMAT="${3:-stdout}"
|
||||
if [[ "$INFO_FLAG" == "true" ]]; then
|
||||
INFO_FLAG=""
|
||||
fi
|
||||
if [[ "$APP" != "--global" ]]; then
|
||||
verify_app_name "$APP"
|
||||
fi
|
||||
local flag_map=(
|
||||
"--traefik-computed-api-enabled: $(fn-traefik-computed-api-enabled)"
|
||||
"--traefik-computed-api-entry-point: $(fn-traefik-computed-api-entry-point)"
|
||||
"--traefik-computed-api-entry-point-address: $(fn-traefik-computed-api-entry-point-address)"
|
||||
"--traefik-computed-api-vhost: $(fn-traefik-computed-api-vhost)"
|
||||
"--traefik-computed-basic-auth-password: $(fn-traefik-computed-basic-auth-password)"
|
||||
"--traefik-computed-basic-auth-username: $(fn-traefik-computed-basic-auth-username)"
|
||||
"--traefik-computed-challenge-mode: $(fn-traefik-computed-challenge-mode)"
|
||||
"--traefik-computed-dashboard-enabled: $(fn-traefik-computed-dashboard-enabled)"
|
||||
"--traefik-computed-dns-provider: $(fn-traefik-computed-dns-provider)"
|
||||
"--traefik-computed-http-entry-point: $(fn-traefik-computed-http-entry-point)"
|
||||
"--traefik-computed-https-entry-point: $(fn-traefik-computed-https-entry-point)"
|
||||
"--traefik-computed-image: $(fn-traefik-computed-image)"
|
||||
"--traefik-computed-letsencrypt-email: $(fn-traefik-computed-letsencrypt-email)"
|
||||
"--traefik-computed-letsencrypt-server: $(fn-traefik-computed-letsencrypt-server)"
|
||||
"--traefik-computed-log-level: $(fn-traefik-computed-log-level)"
|
||||
"--traefik-global-api-enabled: $(fn-traefik-global-api-enabled)"
|
||||
"--traefik-global-api-entry-point: $(fn-traefik-global-api-entry-point)"
|
||||
"--traefik-global-api-entry-point-address: $(fn-traefik-global-api-entry-point-address)"
|
||||
"--traefik-global-api-vhost: $(fn-traefik-global-api-vhost)"
|
||||
"--traefik-global-basic-auth-password: $(fn-traefik-global-basic-auth-password)"
|
||||
"--traefik-global-basic-auth-username: $(fn-traefik-global-basic-auth-username)"
|
||||
"--traefik-global-challenge-mode: $(fn-traefik-global-challenge-mode)"
|
||||
"--traefik-global-dashboard-enabled: $(fn-traefik-global-dashboard-enabled)"
|
||||
"--traefik-global-dns-provider: $(fn-traefik-global-dns-provider)"
|
||||
"--traefik-global-http-entry-point: $(fn-traefik-global-http-entry-point)"
|
||||
"--traefik-global-https-entry-point: $(fn-traefik-global-https-entry-point)"
|
||||
"--traefik-global-image: $(fn-traefik-global-image)"
|
||||
"--traefik-global-letsencrypt-email: $(fn-traefik-global-letsencrypt-email)"
|
||||
"--traefik-global-letsencrypt-server: $(fn-traefik-global-letsencrypt-server)"
|
||||
"--traefik-global-log-level: $(fn-traefik-global-log-level)"
|
||||
)
|
||||
|
||||
local dns_provider_env_vars
|
||||
dns_provider_env_vars="$(fn-traefik-dns-provider-env-vars)"
|
||||
if [[ -n "$dns_provider_env_vars" ]]; then
|
||||
while IFS= read -r line; do
|
||||
local key value
|
||||
key="$(echo "$line" | cut -d' ' -f1)"
|
||||
value="$(echo "$line" | cut -d' ' -f2-)"
|
||||
if [[ -n "$key" ]]; then
|
||||
if [[ "$FORMAT" == "json" ]] || [[ "$INFO_FLAG" == "--traefik-${key}" ]]; then
|
||||
flag_map+=("--traefik-${key}: ${value}")
|
||||
else
|
||||
flag_map+=("--traefik-${key}: *******")
|
||||
fi
|
||||
fi
|
||||
done <<<"$dns_provider_env_vars"
|
||||
fi
|
||||
|
||||
fn-report-validate-format "$FORMAT" "$INFO_FLAG"
|
||||
|
||||
if [[ "$FORMAT" == "json" ]]; then
|
||||
fn-report-emit-json flag_map "traefik"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -z "$INFO_FLAG" ]]; then
|
||||
if [[ "$APP" == "--global" ]]; then
|
||||
dokku_log_info2_quiet "global traefik information"
|
||||
else
|
||||
dokku_log_info2_quiet "${APP} traefik information"
|
||||
fi
|
||||
for flag in "${flag_map[@]}"; do
|
||||
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
|
||||
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"
|
||||
done
|
||||
else
|
||||
local match=false
|
||||
for flag in "${flag_map[@]}"; do
|
||||
valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)"
|
||||
if [[ "$flag" == "${INFO_FLAG}:"* ]]; then
|
||||
value=${flag#*: }
|
||||
size="${#value}"
|
||||
if [[ "$size" -ne 0 ]]; then
|
||||
echo "$value" && match=true
|
||||
else
|
||||
match=true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
[[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-traefik-logs() {
|
||||
declare desc="display traefik logs from command line"
|
||||
declare cmd="traefik:logs"
|
||||
|
||||
29
plugins/traefik-vhosts/go.mod
Normal file
29
plugins/traefik-vhosts/go.mod
Normal file
@@ -0,0 +1,29 @@
|
||||
module github.com/dokku/dokku/plugins/traefik-vhosts
|
||||
|
||||
go 1.26.2
|
||||
|
||||
require (
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/spf13/pflag v1.0.10
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
|
||||
github.com/fatih/color v1.19.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/melbahja/goph v1.5.1 // indirect
|
||||
github.com/otiai10/copy v1.14.1 // indirect
|
||||
github.com/otiai10/mint v1.6.3 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/sftp v1.13.10 // indirect
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
|
||||
golang.org/x/crypto v0.53.0 // indirect
|
||||
golang.org/x/sync v0.21.0 // indirect
|
||||
golang.org/x/sys v0.46.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
55
plugins/traefik-vhosts/go.sum
Normal file
55
plugins/traefik-vhosts/go.sum
Normal file
@@ -0,0 +1,55 @@
|
||||
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
|
||||
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
|
||||
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/melbahja/goph v1.5.1 h1:gdZyjn5nM6FO6mAZrv7XqE2gArQbb+V6FdIyH3Ru3vA=
|
||||
github.com/melbahja/goph v1.5.1/go.mod h1:dDwo+44cmvfDLdiVpc6fJxexf5BA5yEDUeE5YgtuDO4=
|
||||
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
|
||||
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU=
|
||||
github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
|
||||
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
||||
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
|
||||
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
|
||||
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/command-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-traefik-report-single "$@"
|
||||
271
plugins/traefik-vhosts/report.go
Normal file
271
plugins/traefik-vhosts/report.go
Normal file
@@ -0,0 +1,271 @@
|
||||
package traefikvhosts
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
// ReportSingleApp is an internal function that displays the traefik report for one or more apps
|
||||
func ReportSingleApp(appName string, format string, infoFlag string) error {
|
||||
if appName != "--global" {
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
flags := map[string]common.ReportFunc{
|
||||
"--traefik-computed-api-enabled": reportComputedAPIEnabled,
|
||||
"--traefik-computed-api-entry-point": reportComputedAPIEntryPoint,
|
||||
"--traefik-computed-api-entry-point-address": reportComputedAPIEntryPointAddress,
|
||||
"--traefik-computed-api-vhost": reportComputedAPIVhost,
|
||||
"--traefik-computed-basic-auth-password": reportComputedBasicAuthPassword,
|
||||
"--traefik-computed-basic-auth-username": reportComputedBasicAuthUsername,
|
||||
"--traefik-computed-challenge-mode": reportComputedChallengeMode,
|
||||
"--traefik-computed-dashboard-enabled": reportComputedDashboardEnabled,
|
||||
"--traefik-computed-dns-provider": reportComputedDNSProvider,
|
||||
"--traefik-computed-http-entry-point": reportComputedHTTPEntryPoint,
|
||||
"--traefik-computed-https-entry-point": reportComputedHTTPSEntryPoint,
|
||||
"--traefik-computed-image": reportComputedImage,
|
||||
"--traefik-computed-letsencrypt-email": reportComputedLetsencryptEmail,
|
||||
"--traefik-computed-letsencrypt-server": reportComputedLetsencryptServer,
|
||||
"--traefik-computed-log-level": reportComputedLogLevel,
|
||||
"--traefik-global-api-enabled": reportGlobalAPIEnabled,
|
||||
"--traefik-global-api-entry-point": reportGlobalAPIEntryPoint,
|
||||
"--traefik-global-api-entry-point-address": reportGlobalAPIEntryPointAddress,
|
||||
"--traefik-global-api-vhost": reportGlobalAPIVhost,
|
||||
"--traefik-global-basic-auth-password": reportGlobalBasicAuthPassword,
|
||||
"--traefik-global-basic-auth-username": reportGlobalBasicAuthUsername,
|
||||
"--traefik-global-challenge-mode": reportGlobalChallengeMode,
|
||||
"--traefik-global-dashboard-enabled": reportGlobalDashboardEnabled,
|
||||
"--traefik-global-dns-provider": reportGlobalDNSProvider,
|
||||
"--traefik-global-http-entry-point": reportGlobalHTTPEntryPoint,
|
||||
"--traefik-global-https-entry-point": reportGlobalHTTPSEntryPoint,
|
||||
"--traefik-global-image": reportGlobalImage,
|
||||
"--traefik-global-letsencrypt-email": reportGlobalLetsencryptEmail,
|
||||
"--traefik-global-letsencrypt-server": reportGlobalLetsencryptServer,
|
||||
"--traefik-global-log-level": reportGlobalLogLevel,
|
||||
}
|
||||
|
||||
// dns-provider-* env vars are dynamic; their values are masked in the default
|
||||
// stdout report, but shown for --format json or when queried explicitly by name
|
||||
dnsProviderVars, err := common.PropertyGetAllByPrefix("traefik", "--global", "dns-provider-")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for key, value := range dnsProviderVars {
|
||||
flagName := "--traefik-" + key
|
||||
realValue := value
|
||||
if format == "json" || infoFlag == flagName {
|
||||
flags[flagName] = func(string) string { return realValue }
|
||||
} else {
|
||||
flags[flagName] = func(string) string { return "*******" }
|
||||
}
|
||||
}
|
||||
|
||||
flagKeys := []string{}
|
||||
for flagKey := range flags {
|
||||
flagKeys = append(flagKeys, flagKey)
|
||||
}
|
||||
|
||||
infoFlags := common.CollectReport(appName, infoFlag, flags)
|
||||
return common.ReportSingleApp(common.ReportSingleAppInput{
|
||||
ReportType: "traefik",
|
||||
AppName: appName,
|
||||
InfoFlag: infoFlag,
|
||||
InfoFlags: infoFlags,
|
||||
InfoFlagKeys: flagKeys,
|
||||
Format: format,
|
||||
TrimPrefix: true,
|
||||
UppercaseFirstCharacter: true,
|
||||
EmitLegacyPrefix: false,
|
||||
})
|
||||
}
|
||||
|
||||
func reportGlobalAPIEnabled(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "api-enabled")
|
||||
}
|
||||
|
||||
func reportComputedAPIEnabled(appName string) string {
|
||||
value := reportGlobalAPIEnabled(appName)
|
||||
if value == "" {
|
||||
value = "false"
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalAPIEntryPoint(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "api-entry-point")
|
||||
}
|
||||
|
||||
func reportComputedAPIEntryPoint(appName string) string {
|
||||
return reportGlobalAPIEntryPoint(appName)
|
||||
}
|
||||
|
||||
func reportGlobalAPIEntryPointAddress(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "api-entry-point-address")
|
||||
}
|
||||
|
||||
func reportComputedAPIEntryPointAddress(appName string) string {
|
||||
return reportGlobalAPIEntryPointAddress(appName)
|
||||
}
|
||||
|
||||
func reportGlobalAPIVhost(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "api-vhost")
|
||||
}
|
||||
|
||||
func reportComputedAPIVhost(appName string) string {
|
||||
value := reportGlobalAPIVhost(appName)
|
||||
if value == "" {
|
||||
value = "traefik.dokku.me"
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalBasicAuthPassword(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "basic-auth-password")
|
||||
}
|
||||
|
||||
func reportComputedBasicAuthPassword(appName string) string {
|
||||
return reportGlobalBasicAuthPassword(appName)
|
||||
}
|
||||
|
||||
func reportGlobalBasicAuthUsername(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "basic-auth-username")
|
||||
}
|
||||
|
||||
func reportComputedBasicAuthUsername(appName string) string {
|
||||
return reportGlobalBasicAuthUsername(appName)
|
||||
}
|
||||
|
||||
func reportGlobalChallengeMode(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "challenge-mode")
|
||||
}
|
||||
|
||||
func reportComputedChallengeMode(appName string) string {
|
||||
value := reportGlobalChallengeMode(appName)
|
||||
if value == "" {
|
||||
value = "tls"
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalDashboardEnabled(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "dashboard-enabled")
|
||||
}
|
||||
|
||||
func reportComputedDashboardEnabled(appName string) string {
|
||||
value := reportGlobalDashboardEnabled(appName)
|
||||
if value == "" {
|
||||
value = "false"
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalDNSProvider(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "dns-provider")
|
||||
}
|
||||
|
||||
func reportComputedDNSProvider(appName string) string {
|
||||
return reportGlobalDNSProvider(appName)
|
||||
}
|
||||
|
||||
func reportGlobalHTTPEntryPoint(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "http-entry-point")
|
||||
}
|
||||
|
||||
func reportComputedHTTPEntryPoint(appName string) string {
|
||||
value := reportGlobalHTTPEntryPoint(appName)
|
||||
if value == "" {
|
||||
value = "http"
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalHTTPSEntryPoint(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "https-entry-point")
|
||||
}
|
||||
|
||||
func reportComputedHTTPSEntryPoint(appName string) string {
|
||||
value := reportGlobalHTTPSEntryPoint(appName)
|
||||
if value == "" {
|
||||
value = "https"
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalImage(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "image")
|
||||
}
|
||||
|
||||
func reportComputedImage(appName string) string {
|
||||
value := reportGlobalImage(appName)
|
||||
if value == "" {
|
||||
value = dockerfileFromImage("traefik-vhosts")
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalLetsencryptEmail(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "letsencrypt-email")
|
||||
}
|
||||
|
||||
func reportComputedLetsencryptEmail(appName string) string {
|
||||
return reportGlobalLetsencryptEmail(appName)
|
||||
}
|
||||
|
||||
func reportGlobalLetsencryptServer(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "letsencrypt-server")
|
||||
}
|
||||
|
||||
func reportComputedLetsencryptServer(appName string) string {
|
||||
value := reportGlobalLetsencryptServer(appName)
|
||||
if value == "" {
|
||||
value = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func reportGlobalLogLevel(appName string) string {
|
||||
return common.PropertyGet("traefik", "--global", "log-level")
|
||||
}
|
||||
|
||||
func reportComputedLogLevel(appName string) string {
|
||||
value := reportGlobalLogLevel(appName)
|
||||
if value == "" {
|
||||
value = "ERROR"
|
||||
}
|
||||
|
||||
return strings.ToUpper(value)
|
||||
}
|
||||
|
||||
// dockerfileFromImage returns the image referenced by the FROM line of the named
|
||||
// plugin's Dockerfile, or an empty string when it cannot be read
|
||||
func dockerfileFromImage(pluginName string) string {
|
||||
pluginPath := os.Getenv("PLUGIN_AVAILABLE_PATH")
|
||||
data, err := os.ReadFile(filepath.Join(pluginPath, pluginName, "Dockerfile"))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
if strings.Contains(line, "FROM") {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 2 {
|
||||
return fields[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
40
plugins/traefik-vhosts/src/subcommands/subcommands.go
Normal file
40
plugins/traefik-vhosts/src/subcommands/subcommands.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
traefikvhosts "github.com/dokku/dokku/plugins/traefik-vhosts"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// main entrypoint to all subcommands
|
||||
func main() {
|
||||
parts := strings.Split(os.Args[0], "/")
|
||||
subcommand := parts[len(parts)-1]
|
||||
|
||||
var err error
|
||||
switch subcommand {
|
||||
case "report":
|
||||
args := flag.NewFlagSet("traefik-vhosts:report", flag.ExitOnError)
|
||||
format := args.String("format", "stdout", "format: [ stdout | json ]")
|
||||
reportArgs, flagErr := common.ParseReportArgs("traefik-vhosts", os.Args[2:])
|
||||
if flagErr == nil {
|
||||
args.Parse(reportArgs.OSArgs)
|
||||
appName := args.Arg(0)
|
||||
if reportArgs.IsGlobal {
|
||||
appName = "--global"
|
||||
}
|
||||
err = traefikvhosts.CommandReport(appName, *format, reportArgs.InfoFlag)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
common.LogFailWithError(err)
|
||||
}
|
||||
}
|
||||
31
plugins/traefik-vhosts/src/triggers/triggers.go
Normal file
31
plugins/traefik-vhosts/src/triggers/triggers.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
traefikvhosts "github.com/dokku/dokku/plugins/traefik-vhosts"
|
||||
)
|
||||
|
||||
// main entrypoint to all triggers
|
||||
func main() {
|
||||
parts := strings.Split(os.Args[0], "/")
|
||||
trigger := parts[len(parts)-1]
|
||||
flag.Parse()
|
||||
|
||||
var err error
|
||||
switch trigger {
|
||||
case "report":
|
||||
appName := flag.Arg(0)
|
||||
err = traefikvhosts.ReportSingleApp(appName, "", "")
|
||||
default:
|
||||
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
common.LogFailWithError(err)
|
||||
}
|
||||
}
|
||||
29
plugins/traefik-vhosts/subcommands.go
Normal file
29
plugins/traefik-vhosts/subcommands.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package traefikvhosts
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
// CommandReport displays a traefik-vhosts report for one or more apps
|
||||
func CommandReport(appName string, format string, infoFlag string) error {
|
||||
if len(appName) == 0 {
|
||||
apps, err := common.DokkuApps()
|
||||
if err != nil {
|
||||
if errors.Is(err, common.NoAppsExist) {
|
||||
common.LogWarn(err.Error())
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
for _, appName := range apps {
|
||||
if err := ReportSingleApp(appName, format, infoFlag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return ReportSingleApp(appName, format, infoFlag)
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/command-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-traefik-report "$@"
|
||||
Reference in New Issue
Block a user