feat: expose scheduler-k3s autoscaling-auth state for read-back
Align autoscaling-auth:report with annotations and labels reporting so export tools can recover configured trigger auth via flat JSON keys and info flags, while stdout stays secret-safe unless --include-metadata is used. Closes #8800
This commit is contained in:
@@ -657,8 +657,8 @@ dokku scheduler-k3s:autoscaling-auth:report --global
|
||||
```
|
||||
|
||||
```
|
||||
====> $APP autoscaling-auth report
|
||||
datadog: configured
|
||||
====> node-js-app autoscaling-auth information
|
||||
Datadog: configured
|
||||
```
|
||||
|
||||
By default, the report will not display configured metadata - making it safe to include in Dokku report output. To include metadata and their values, add the `--include-metadata` flag:
|
||||
@@ -668,13 +668,25 @@ dokku scheduler-k3s:autoscaling-auth:report node-js-app --include-metadata
|
||||
```
|
||||
|
||||
```
|
||||
====> node-js-app autoscaling-auth report
|
||||
====> node-js-app autoscaling-auth information
|
||||
Datadog: configured
|
||||
Datadog apiKey: 1234567890
|
||||
Datadog appKey: asdfghjkl
|
||||
Datadog datadogSite: us5.datadoghq.com
|
||||
```
|
||||
|
||||
JSON output emits flat keys of the form `{trigger}.{metadata_key}` and includes the actual metadata values so export tools can reconstruct the configured state:
|
||||
|
||||
```shell
|
||||
dokku scheduler-k3s:autoscaling-auth:report node-js-app --format json
|
||||
```
|
||||
|
||||
A single configured metadata key can also be queried with a flag of the form `--scheduler-k3s-autoscaling-auth.{trigger}.{metadata_key}`. The returned value is masked in the same way as stdout output; use `--format json` to read the actual value:
|
||||
|
||||
```shell
|
||||
dokku scheduler-k3s:autoscaling-auth:report node-js-app --scheduler-k3s-autoscaling-auth.datadog.apiKey
|
||||
```
|
||||
|
||||
### Integrating Kustomize
|
||||
|
||||
Dokku supports integration with [Kustomize](https://kustomize.io/) to further customize the generated helm charts for app deployments. For example, a `config/kustomize/kustomization.yaml` file with the following contents will override the scale for each process deployed to `3`:
|
||||
|
||||
1
plugins/scheduler-k3s/.gitignore
vendored
1
plugins/scheduler-k3s/.gitignore
vendored
@@ -7,3 +7,4 @@
|
||||
/post-*
|
||||
/report
|
||||
/core-*
|
||||
/storage-*
|
||||
|
||||
@@ -10,8 +10,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
annotationsReportType = "scheduler-k3s-annotations"
|
||||
labelsReportType = "scheduler-k3s-labels"
|
||||
annotationsReportType = "scheduler-k3s-annotations"
|
||||
labelsReportType = "scheduler-k3s-labels"
|
||||
autoscalingAuthReportType = "scheduler-k3s-autoscaling-auth"
|
||||
|
||||
// reportProcessTypeGlobal is the rendered form of GlobalProcessType in annotation
|
||||
// and label report keys (both JSON and single-flag). Real process types cannot
|
||||
@@ -138,42 +139,164 @@ func ReportSingleApp(appName string, format string, infoFlag string) error {
|
||||
})
|
||||
}
|
||||
|
||||
// ReportAutoscalingAuthSingleApp is an internal function that displays the scheduler-k3s autoscaling-auth report for one app
|
||||
func ReportAutoscalingAuthSingleApp(appName string, format string, includeMetadata bool) error {
|
||||
properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, TriggerAuthPropertyPrefix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to get property list: %w", err)
|
||||
// autoscalingAuthReportEntry is a parsed trigger authentication metadata entry.
|
||||
type autoscalingAuthReportEntry struct {
|
||||
Trigger string
|
||||
MetadataKey string
|
||||
Value string
|
||||
}
|
||||
|
||||
// ReportAutoscalingAuthSingleApp displays the scheduler-k3s autoscaling-auth report for one app.
|
||||
func ReportAutoscalingAuthSingleApp(appName string, format string, includeMetadata bool, infoFlag string) error {
|
||||
if appName != "--global" {
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
infoFlags := map[string]string{}
|
||||
entries, err := collectAutoscalingAuthEntries(appName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return renderAutoscalingAuthReport(autoscalingAuthRenderInput{
|
||||
AppName: appName,
|
||||
Entries: entries,
|
||||
Format: format,
|
||||
IncludeMetadata: includeMetadata,
|
||||
InfoFlag: infoFlag,
|
||||
})
|
||||
}
|
||||
|
||||
// collectAutoscalingAuthEntries scans the property store for trigger authentication metadata.
|
||||
func collectAutoscalingAuthEntries(appName string) ([]autoscalingAuthReportEntry, error) {
|
||||
properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, TriggerAuthPropertyPrefix)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to get property list: %w", err)
|
||||
}
|
||||
|
||||
entries := []autoscalingAuthReportEntry{}
|
||||
for key, value := range properties {
|
||||
metadataKey := strings.TrimPrefix(key, TriggerAuthPropertyPrefix)
|
||||
authType := strings.SplitN(metadataKey, ".", 2)[0]
|
||||
if authType == "" {
|
||||
parts := strings.SplitN(metadataKey, ".", 2)
|
||||
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
infoFlags[authType] = "configured"
|
||||
if includeMetadata {
|
||||
infoFlags[strings.ReplaceAll(metadataKey, ".", "-")] = value
|
||||
entries = append(entries, autoscalingAuthReportEntry{
|
||||
Trigger: parts[0],
|
||||
MetadataKey: parts[1],
|
||||
Value: value,
|
||||
})
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
type autoscalingAuthRenderInput struct {
|
||||
AppName string
|
||||
Entries []autoscalingAuthReportEntry
|
||||
Format string
|
||||
IncludeMetadata bool
|
||||
InfoFlag string
|
||||
}
|
||||
|
||||
// renderAutoscalingAuthReport dispatches to stdout/json/single-flag rendering for trigger auth.
|
||||
func renderAutoscalingAuthReport(input autoscalingAuthRenderInput) error {
|
||||
if input.Format != "stdout" && input.Format != "json" {
|
||||
return fmt.Errorf("Invalid format: %s", input.Format)
|
||||
}
|
||||
if input.Format == "json" && input.InfoFlag != "" {
|
||||
return fmt.Errorf("--format flag cannot be specified when specifying an info flag")
|
||||
}
|
||||
|
||||
flatValues := map[string]string{}
|
||||
flagToValue := map[string]string{}
|
||||
flagPrefix := "--" + autoscalingAuthReportType + "."
|
||||
for _, entry := range input.Entries {
|
||||
composedKey := entry.Trigger + "." + entry.MetadataKey
|
||||
flatValues[composedKey] = entry.Value
|
||||
flagToValue[flagPrefix+composedKey] = entry.Value
|
||||
}
|
||||
|
||||
if input.InfoFlag != "" {
|
||||
value, ok := flagToValue[input.InfoFlag]
|
||||
if !ok {
|
||||
validFlags := []string{}
|
||||
for flag := range flagToValue {
|
||||
validFlags = append(validFlags, flag)
|
||||
}
|
||||
sort.Strings(validFlags)
|
||||
return fmt.Errorf("Invalid flag passed, valid flags: %s", strings.Join(validFlags, ", "))
|
||||
}
|
||||
if value != "" {
|
||||
fmt.Println(tokenMask)
|
||||
} else {
|
||||
fmt.Println("")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if input.Format == "json" {
|
||||
b, err := json.Marshal(flatValues)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to marshal json: %w", err)
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
return nil
|
||||
}
|
||||
|
||||
triggers := map[string]bool{}
|
||||
for _, entry := range input.Entries {
|
||||
triggers[entry.Trigger] = true
|
||||
}
|
||||
|
||||
triggerKeys := []string{}
|
||||
for trigger := range triggers {
|
||||
triggerKeys = append(triggerKeys, trigger)
|
||||
}
|
||||
sort.Strings(triggerKeys)
|
||||
|
||||
common.LogInfo2Quiet(fmt.Sprintf("%s autoscaling-auth information", input.AppName))
|
||||
if len(triggerKeys) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
length := 31
|
||||
if input.IncludeMetadata {
|
||||
for _, entry := range input.Entries {
|
||||
label := fmt.Sprintf("%s %s:", common.UcFirst(entry.Trigger), entry.MetadataKey)
|
||||
if len(label) > length {
|
||||
length = len(label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flagKeys := []string{}
|
||||
for flagKey := range infoFlags {
|
||||
flagKeys = append(flagKeys, flagKey)
|
||||
for _, trigger := range triggerKeys {
|
||||
label := fmt.Sprintf("%s:", common.UcFirst(trigger))
|
||||
common.LogVerbose(fmt.Sprintf("%s%s", common.RightPad(label, length, " "), "configured"))
|
||||
|
||||
if !input.IncludeMetadata {
|
||||
continue
|
||||
}
|
||||
|
||||
triggerEntries := []autoscalingAuthReportEntry{}
|
||||
for _, entry := range input.Entries {
|
||||
if entry.Trigger == trigger {
|
||||
triggerEntries = append(triggerEntries, entry)
|
||||
}
|
||||
}
|
||||
sort.Slice(triggerEntries, func(i, j int) bool {
|
||||
return triggerEntries[i].MetadataKey < triggerEntries[j].MetadataKey
|
||||
})
|
||||
|
||||
for _, entry := range triggerEntries {
|
||||
label := fmt.Sprintf("%s %s:", common.UcFirst(entry.Trigger), entry.MetadataKey)
|
||||
common.LogVerbose(fmt.Sprintf("%s%s", common.RightPad(label, length, " "), entry.Value))
|
||||
}
|
||||
}
|
||||
|
||||
return common.ReportSingleApp(common.ReportSingleAppInput{
|
||||
ReportType: "scheduler-k3s",
|
||||
AppName: appName,
|
||||
InfoFlags: infoFlags,
|
||||
InfoFlagKeys: flagKeys,
|
||||
Format: format,
|
||||
TrimPrefix: true,
|
||||
UppercaseFirstCharacter: true,
|
||||
EmitLegacyPrefix: true,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExtractReportInfoFlag scans arguments for a single info flag whose name starts with
|
||||
|
||||
271
plugins/scheduler-k3s/report_test.go
Normal file
271
plugins/scheduler-k3s/report_test.go
Normal file
@@ -0,0 +1,271 @@
|
||||
package scheduler_k3s
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
func setupReportTest(t *testing.T, apps ...string) {
|
||||
t.Helper()
|
||||
t.Setenv("PLUGIN_PATH", "/var/lib/dokku/plugins")
|
||||
t.Setenv("PLUGIN_ENABLED_PATH", "/var/lib/dokku/plugins/enabled")
|
||||
t.Setenv("DOKKU_LIB_ROOT", t.TempDir())
|
||||
t.Setenv("DOKKU_SYSTEM_USER", "root")
|
||||
t.Setenv("DOKKU_SYSTEM_GROUP", "root")
|
||||
dokkuRoot := t.TempDir()
|
||||
t.Setenv("DOKKU_ROOT", dokkuRoot)
|
||||
if err := common.PropertySetup("scheduler-k3s"); err != nil {
|
||||
t.Fatalf("PropertySetup: %v", err)
|
||||
}
|
||||
for _, appName := range apps {
|
||||
if err := os.MkdirAll(dokkuRoot+"/"+appName, 0o755); err != nil {
|
||||
t.Fatalf("MkdirAll: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func captureStdout(t *testing.T, fn func()) string {
|
||||
t.Helper()
|
||||
orig := os.Stdout
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatalf("os.Pipe: %v", err)
|
||||
}
|
||||
os.Stdout = w
|
||||
|
||||
done := make(chan string)
|
||||
go func() {
|
||||
var buf bytes.Buffer
|
||||
_, _ = io.Copy(&buf, r)
|
||||
done <- buf.String()
|
||||
}()
|
||||
|
||||
fn()
|
||||
|
||||
w.Close()
|
||||
os.Stdout = orig
|
||||
return <-done
|
||||
}
|
||||
|
||||
func TestExtractReportInfoFlag(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
prefix string
|
||||
args []string
|
||||
wantArgs []string
|
||||
wantFlag string
|
||||
wantError string
|
||||
}{
|
||||
{
|
||||
name: "no info flag",
|
||||
prefix: "--scheduler-k3s-annotations.",
|
||||
args: []string{"myapp", "--format", "json"},
|
||||
wantArgs: []string{"myapp", "--format", "json"},
|
||||
},
|
||||
{
|
||||
name: "single info flag",
|
||||
prefix: "--scheduler-k3s-labels.",
|
||||
args: []string{"myapp", "--scheduler-k3s-labels.global.deployment.foo"},
|
||||
wantArgs: []string{"myapp"},
|
||||
wantFlag: "--scheduler-k3s-labels.global.deployment.foo",
|
||||
},
|
||||
{
|
||||
name: "multiple info flags",
|
||||
prefix: "--scheduler-k3s-autoscaling-auth.",
|
||||
args: []string{"myapp", "--scheduler-k3s-autoscaling-auth.datadog.apiKey", "--scheduler-k3s-autoscaling-auth.datadog.appKey"},
|
||||
wantError: "only a single info flag may be specified",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
gotArgs, gotFlag, err := ExtractReportInfoFlag(tc.prefix, tc.args)
|
||||
if tc.wantError != "" {
|
||||
if err == nil || !strings.Contains(err.Error(), tc.wantError) {
|
||||
t.Fatalf("expected error containing %q, got %v", tc.wantError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gotFlag != tc.wantFlag {
|
||||
t.Fatalf("info flag = %q, want %q", gotFlag, tc.wantFlag)
|
||||
}
|
||||
if strings.Join(gotArgs, ",") != strings.Join(tc.wantArgs, ",") {
|
||||
t.Fatalf("passthrough args = %v, want %v", gotArgs, tc.wantArgs)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderProcessType(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if got := renderProcessType(GlobalProcessType); got != reportProcessTypeGlobal {
|
||||
t.Fatalf("renderProcessType(GlobalProcessType) = %q, want %q", got, reportProcessTypeGlobal)
|
||||
}
|
||||
if got := renderProcessType("web"); got != "web" {
|
||||
t.Fatalf("renderProcessType(\"web\") = %q, want %q", got, "web")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderAnnotationsLabelsReportJSON(t *testing.T) {
|
||||
out := captureStdout(t, func() {
|
||||
err := renderAnnotationsLabelsReport(annotationsLabelsRenderInput{
|
||||
AppName: "myapp",
|
||||
ReportType: annotationsReportType,
|
||||
Heading: "annotations",
|
||||
RowLabel: "Annotation",
|
||||
Entries: []annotationsLabelsReportEntry{
|
||||
{ProcessType: GlobalProcessType, ResourceType: "deployment", Key: "foo", Value: "bar"},
|
||||
{ProcessType: "web", ResourceType: "deployment", Key: "baz", Value: "qux"},
|
||||
},
|
||||
Format: "json",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("renderAnnotationsLabelsReport returned error: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
var got map[string]string
|
||||
if err := json.Unmarshal([]byte(strings.TrimSpace(out)), &got); err != nil {
|
||||
t.Fatalf("output is not valid JSON: %v\noutput: %s", err, out)
|
||||
}
|
||||
|
||||
want := map[string]string{
|
||||
"global.deployment.foo": "bar",
|
||||
"web.deployment.baz": "qux",
|
||||
}
|
||||
for key, value := range want {
|
||||
if got[key] != value {
|
||||
t.Fatalf("expected %q=%q, got %q=%q", key, value, key, got[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderAutoscalingAuthReportJSON(t *testing.T) {
|
||||
out := captureStdout(t, func() {
|
||||
err := renderAutoscalingAuthReport(autoscalingAuthRenderInput{
|
||||
AppName: "myapp",
|
||||
Entries: []autoscalingAuthReportEntry{
|
||||
{Trigger: "datadog", MetadataKey: "apiKey", Value: "secret-1"},
|
||||
{Trigger: "datadog", MetadataKey: "appKey", Value: "secret-2"},
|
||||
},
|
||||
Format: "json",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("renderAutoscalingAuthReport returned error: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
var got map[string]string
|
||||
if err := json.Unmarshal([]byte(strings.TrimSpace(out)), &got); err != nil {
|
||||
t.Fatalf("output is not valid JSON: %v\noutput: %s", err, out)
|
||||
}
|
||||
|
||||
want := map[string]string{
|
||||
"datadog.apiKey": "secret-1",
|
||||
"datadog.appKey": "secret-2",
|
||||
}
|
||||
for key, value := range want {
|
||||
if got[key] != value {
|
||||
t.Fatalf("expected %q=%q, got %q=%q", key, value, key, got[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportAutoscalingAuthSingleAppInfoFlag(t *testing.T) {
|
||||
setupReportTest(t, "myapp")
|
||||
|
||||
if err := common.PropertyWrite("scheduler-k3s", "myapp", "trigger-auth.datadog.apiKey", "secret-1"); err != nil {
|
||||
t.Fatalf("PropertyWrite: %v", err)
|
||||
}
|
||||
|
||||
out := captureStdout(t, func() {
|
||||
err := ReportAutoscalingAuthSingleApp("myapp", "stdout", false, "--scheduler-k3s-autoscaling-auth.datadog.apiKey")
|
||||
if err != nil {
|
||||
t.Fatalf("ReportAutoscalingAuthSingleApp returned error: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
if strings.TrimSpace(out) != tokenMask {
|
||||
t.Fatalf("info flag output = %q, want %q", strings.TrimSpace(out), tokenMask)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectAutoscalingAuthEntriesFromProperties(t *testing.T) {
|
||||
setupReportTest(t, "myapp")
|
||||
|
||||
if err := common.PropertyWrite("scheduler-k3s", "myapp", "trigger-auth.datadog.apiKey", "secret-1"); err != nil {
|
||||
t.Fatalf("PropertyWrite apiKey: %v", err)
|
||||
}
|
||||
if err := common.PropertyWrite("scheduler-k3s", "myapp", "trigger-auth.datadog.appKey", "secret-2"); err != nil {
|
||||
t.Fatalf("PropertyWrite appKey: %v", err)
|
||||
}
|
||||
|
||||
entries, err := collectAutoscalingAuthEntries("myapp")
|
||||
if err != nil {
|
||||
t.Fatalf("collectAutoscalingAuthEntries returned error: %v", err)
|
||||
}
|
||||
if len(entries) != 2 {
|
||||
t.Fatalf("expected 2 entries, got %d", len(entries))
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportAutoscalingAuthGlobalJSON(t *testing.T) {
|
||||
setupReportTest(t)
|
||||
|
||||
if err := common.PropertyWrite("scheduler-k3s", "--global", "trigger-auth.datadog.apiKey", "global-secret"); err != nil {
|
||||
t.Fatalf("PropertyWrite: %v", err)
|
||||
}
|
||||
|
||||
out := captureStdout(t, func() {
|
||||
err := ReportAutoscalingAuthSingleApp("--global", "json", false, "")
|
||||
if err != nil {
|
||||
t.Fatalf("ReportAutoscalingAuthSingleApp returned error: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
var got map[string]string
|
||||
if err := json.Unmarshal([]byte(strings.TrimSpace(out)), &got); err != nil {
|
||||
t.Fatalf("output is not valid JSON: %v\noutput: %s", err, out)
|
||||
}
|
||||
|
||||
if got["datadog.apiKey"] != "global-secret" {
|
||||
t.Fatalf("expected datadog.apiKey=global-secret, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderAutoscalingAuthReportStdoutIncludesMetadataValues(t *testing.T) {
|
||||
out := captureStdout(t, func() {
|
||||
err := renderAutoscalingAuthReport(autoscalingAuthRenderInput{
|
||||
AppName: "myapp",
|
||||
Entries: []autoscalingAuthReportEntry{
|
||||
{Trigger: "datadog", MetadataKey: "apiKey", Value: "secret-1"},
|
||||
},
|
||||
Format: "stdout",
|
||||
IncludeMetadata: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("renderAutoscalingAuthReport returned error: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
if !strings.Contains(out, "Datadog apiKey:") {
|
||||
t.Fatalf("expected metadata key in stdout, got: %s", out)
|
||||
}
|
||||
if !strings.Contains(out, "secret-1") {
|
||||
t.Fatalf("expected metadata value in stdout, got: %s", out)
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ Additional commands:`
|
||||
|
||||
helpContent = `
|
||||
scheduler-k3s:autoscaling-auth:set <app|--global> <trigger> [<--metadata key=value>...], Set or clear a scheduler-k3s autoscaling keda trigger authentication resource for an app
|
||||
scheduler-k3s:autoscaling-auth:report [<app>|--global] [--format stdout|json] [--include-metadata], Displays a scheduler-k3s autoscaling auth report for one or more apps
|
||||
scheduler-k3s:annotations:set <app|--global> <property> (<value>) [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear an annotation for a given app/process-type/resource-type combination
|
||||
scheduler-k3s:annotations:report [<app>|--global] [--format stdout|json] [--process-type PROCESS_TYPE] [--resource-type RESOURCE_TYPE], Displays a scheduler-k3s annotations report for one or more apps
|
||||
scheduler-k3s:charts:report [<chart>] [--format stdout|json], Displays a scheduler-k3s chart override report
|
||||
|
||||
@@ -66,14 +66,19 @@ func main() {
|
||||
case "autoscaling-auth:report":
|
||||
args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:report", flag.ExitOnError)
|
||||
global := args.Bool("global", false, "--global: show the global report")
|
||||
includeMetadata := args.Bool("include-metadata", false, "--include-metadata: include metadata in the report")
|
||||
includeMetadata := args.Bool("include-metadata", false, "--include-metadata: include metadata keys and values in the report")
|
||||
format := args.String("format", "stdout", "format: [ stdout | json ]")
|
||||
args.Parse(os.Args[2:])
|
||||
passthroughArgs, infoFlag, flagErr := scheduler_k3s.ExtractReportInfoFlag("--scheduler-k3s-autoscaling-auth.", os.Args[2:])
|
||||
if flagErr != nil {
|
||||
err = flagErr
|
||||
break
|
||||
}
|
||||
args.Parse(passthroughArgs)
|
||||
appName := args.Arg(0)
|
||||
if *global {
|
||||
appName = "--global"
|
||||
}
|
||||
err = scheduler_k3s.CommandAutoscalingAuthReport(appName, *format, *includeMetadata)
|
||||
err = scheduler_k3s.CommandAutoscalingAuthReport(appName, *format, *includeMetadata, infoFlag)
|
||||
case "charts:set":
|
||||
args := flag.NewFlagSet("scheduler-k3s:charts:set", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
|
||||
@@ -108,7 +108,7 @@ func CommandAutoscalingAuthSet(appName string, trigger string, metadata map[stri
|
||||
}
|
||||
|
||||
// CommandAutoscalingAuthReport displays a scheduler-k3s autoscaling keda trigger authentication report for one or more apps
|
||||
func CommandAutoscalingAuthReport(appName string, format string, includeMetadata bool) error {
|
||||
func CommandAutoscalingAuthReport(appName string, format string, includeMetadata bool, infoFlag string) error {
|
||||
if len(appName) == 0 {
|
||||
apps, err := common.DokkuApps()
|
||||
if err != nil {
|
||||
@@ -119,14 +119,14 @@ func CommandAutoscalingAuthReport(appName string, format string, includeMetadata
|
||||
return err
|
||||
}
|
||||
for _, app := range apps {
|
||||
if err := ReportAutoscalingAuthSingleApp(app, format, includeMetadata); err != nil {
|
||||
if err := ReportAutoscalingAuthSingleApp(app, format, includeMetadata, infoFlag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return ReportAutoscalingAuthSingleApp(appName, format, includeMetadata)
|
||||
return ReportAutoscalingAuthSingleApp(appName, format, includeMetadata, infoFlag)
|
||||
}
|
||||
|
||||
// CommandAnnotationsReport displays a scheduler-k3s annotations report for one or more apps
|
||||
|
||||
@@ -96,3 +96,20 @@ teardown() {
|
||||
assert_success
|
||||
assert_output "$value"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:annotations:report) rejects invalid format and info-flag combinations" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --format yaml"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid format"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment foo bar"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --format json --scheduler-k3s-annotations.global.deployment.foo"
|
||||
assert_failure
|
||||
assert_output_contains "--format flag cannot be specified when specifying an info flag"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --scheduler-k3s-annotations.global.deployment.missing"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,22 @@
|
||||
|
||||
load test_helper
|
||||
|
||||
scheduler_k3s_seed_trigger_auth() {
|
||||
local scope="$1"
|
||||
local trigger="$2"
|
||||
local key="$3"
|
||||
local value="$4"
|
||||
local dir="/var/lib/dokku/config/scheduler-k3s/$scope"
|
||||
sudo mkdir -p "$dir"
|
||||
echo -n "$value" | sudo tee "$dir/trigger-auth.${trigger}.${key}" >/dev/null
|
||||
}
|
||||
|
||||
scheduler_k3s_clear_trigger_auth() {
|
||||
local scope="$1"
|
||||
local trigger="$2"
|
||||
sudo rm -f "/var/lib/dokku/config/scheduler-k3s/$scope/trigger-auth.${trigger}."* 2>/dev/null || true
|
||||
}
|
||||
|
||||
setup() {
|
||||
global_setup
|
||||
dokku apps:create $TEST_APP >/dev/null 2>/dev/null || true
|
||||
@@ -10,7 +26,9 @@ setup() {
|
||||
|
||||
teardown() {
|
||||
dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog >/dev/null 2>/dev/null || true
|
||||
dokku scheduler-k3s:autoscaling-auth:set $TEST_APP memory >/dev/null 2>/dev/null || true
|
||||
dokku scheduler-k3s:autoscaling-auth:set ${TEST_APP}-2 datadog >/dev/null 2>/dev/null || true
|
||||
scheduler_k3s_clear_trigger_auth "--global" "datadog"
|
||||
dokku --force apps:destroy $TEST_APP >/dev/null 2>/dev/null || true
|
||||
dokku --force apps:destroy ${TEST_APP}-2 >/dev/null 2>/dev/null || true
|
||||
global_teardown
|
||||
@@ -24,7 +42,110 @@ teardown() {
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report"
|
||||
assert_success
|
||||
assert_output_contains "$TEST_APP scheduler-k3s information"
|
||||
assert_output_contains "${TEST_APP}-2 scheduler-k3s information"
|
||||
assert_output_contains "$TEST_APP autoscaling-auth information"
|
||||
assert_output_contains "${TEST_APP}-2 autoscaling-auth information"
|
||||
assert_output_contains "Datadog:" 2
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) lists metadata in json and clears after unset" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=secret-1 --metadata appKey=secret-2"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json | jq -r '.\"datadog.apiKey\"'"
|
||||
assert_success
|
||||
assert_output "secret-1"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json | jq -r '.\"datadog.appKey\"'"
|
||||
assert_success
|
||||
assert_output "secret-2"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --scheduler-k3s-autoscaling-auth.datadog.apiKey"
|
||||
assert_success
|
||||
assert_output "*******"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP"
|
||||
assert_success
|
||||
assert_output_contains "Datadog:"
|
||||
assert_output_not_contains "Datadog apiKey:"
|
||||
assert_output_not_contains "secret-1"
|
||||
assert_output_not_contains "secret-2"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --include-metadata"
|
||||
assert_success
|
||||
assert_output_contains "Datadog apiKey:"
|
||||
assert_output_contains "secret-1"
|
||||
assert_output_contains "secret-2"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json"
|
||||
assert_success
|
||||
assert_output "{}"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) stdout includes metadata values with --include-metadata" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=super-secret-value"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP"
|
||||
assert_success
|
||||
assert_output_contains "Datadog:"
|
||||
assert_output_contains "configured"
|
||||
assert_output_not_contains "Datadog apiKey:"
|
||||
assert_output_not_contains "super-secret-value"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --include-metadata"
|
||||
assert_success
|
||||
assert_output_contains "Datadog apiKey:"
|
||||
assert_output_contains "super-secret-value"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) reports multiple triggers in json" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=secret-1"
|
||||
assert_success
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP memory --metadata some-key=some-value"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json | jq -r 'keys | sort | join(\",\")'"
|
||||
assert_success
|
||||
assert_output "datadog.apiKey,memory.some-key"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) supports --global scope" {
|
||||
scheduler_k3s_seed_trigger_auth "--global" "datadog" "apiKey" "global-secret"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report --global --format json | jq -r '.\"datadog.apiKey\"'"
|
||||
assert_success
|
||||
assert_output "global-secret"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report --global --include-metadata"
|
||||
assert_success
|
||||
assert_output_contains "--global autoscaling-auth information"
|
||||
assert_output_contains "Datadog:"
|
||||
assert_output_contains "Datadog apiKey:"
|
||||
assert_output_contains "global-secret"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) returns empty json for unconfigured app" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json"
|
||||
assert_success
|
||||
assert_output "{}"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:autoscaling-auth:report) rejects invalid format and info-flag combinations" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format yaml"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid format"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog --metadata apiKey=secret-1"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --format json --scheduler-k3s-autoscaling-auth.datadog.apiKey"
|
||||
assert_failure
|
||||
assert_output_contains "--format flag cannot be specified when specifying an info flag"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:autoscaling-auth:report $TEST_APP --scheduler-k3s-autoscaling-auth.datadog.missing"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
@@ -96,3 +96,20 @@ teardown() {
|
||||
assert_success
|
||||
assert_output "$value"
|
||||
}
|
||||
|
||||
@test "(scheduler-k3s:labels:report) rejects invalid format and info-flag combinations" {
|
||||
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP --format yaml"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid format"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:labels:set $TEST_APP --resource-type deployment foo bar"
|
||||
assert_success
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP --format json --scheduler-k3s-labels.global.deployment.foo"
|
||||
assert_failure
|
||||
assert_output_contains "--format flag cannot be specified when specifying an info flag"
|
||||
|
||||
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP --scheduler-k3s-labels.global.deployment.missing"
|
||||
assert_failure
|
||||
assert_output_contains "Invalid flag passed"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user