feat: add scheduler-k3s annotations:report and labels:report
The scheduler-k3s plugin exposes `annotations:set` and `labels:set` but no matching report subcommands, so scripts could not inspect the configured state for idempotent management without reading the property files directly. The new `scheduler-k3s:annotations:report` and `scheduler-k3s:labels:report` surface the configured entries with stdout, JSON, single-flag query, and `--process-type` / `--resource-type` filtering, mirroring the recently added `scheduler-k3s:charts:report`. The literal `GlobalProcessType` value `--global` is rendered as `global` in report keys to avoid leading dashes. The `scheduler-k3s:autoscaling-auth:report` command is updated alongside to loop over every app when no app and no `--global` flag is provided, matching the convention used by `scheduler-k3s:report`.
This commit is contained in:
@@ -5,8 +5,9 @@
|
|||||||
|
|
||||||
```
|
```
|
||||||
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: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: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: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 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:charts:report [<chart>] [--format stdout|json] # Displays a scheduler-k3s chart override report
|
scheduler-k3s:charts:report [<chart>] [--format stdout|json] # Displays a scheduler-k3s chart override report
|
||||||
scheduler-k3s:charts:set <chart-name.property> (<value>) # Set or clear a chart-specific helm value
|
scheduler-k3s:charts:set <chart-name.property> (<value>) # Set or clear a chart-specific helm value
|
||||||
scheduler-k3s:cluster:add [ssh://user@host:port] # Adds a server node to a Dokku-managed cluster
|
scheduler-k3s:cluster:add [ssh://user@host:port] # Adds a server node to a Dokku-managed cluster
|
||||||
@@ -15,6 +16,7 @@ scheduler-k3s:cluster:remove [node-id] # Removes client node to a D
|
|||||||
scheduler-k3s:ensure-charts # Ensures the k3s charts are installed
|
scheduler-k3s:ensure-charts # Ensures the k3s charts are installed
|
||||||
scheduler-k3s:initialize # Initializes a cluster
|
scheduler-k3s:initialize # Initializes a cluster
|
||||||
scheduler-k3s:labels:set <app|--global> <property> (<value>) [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE> # Set or clear a label for a given app/process-type/resource-type combination
|
scheduler-k3s:labels:set <app|--global> <property> (<value>) [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE> # Set or clear a label for a given app/process-type/resource-type combination
|
||||||
|
scheduler-k3s:labels:report [<app>|--global] [--format stdout|json] [--process-type PROCESS_TYPE] [--resource-type RESOURCE_TYPE] # Displays a scheduler-k3s labels report for one or more apps
|
||||||
scheduler-k3s:profiles:add <profile> [--role ROLE] [--insecure-allow-unknown-hosts] [--taint-scheduling] [--kubelet-args KUBELET_ARGS] Adds a node profile to the k3s cluster
|
scheduler-k3s:profiles:add <profile> [--role ROLE] [--insecure-allow-unknown-hosts] [--taint-scheduling] [--kubelet-args KUBELET_ARGS] Adds a node profile to the k3s cluster
|
||||||
scheduler-k3s:profiles:list [--format json|stdout] # Lists all node profiles in the k3s cluster
|
scheduler-k3s:profiles:list [--format json|stdout] # Lists all node profiles in the k3s cluster
|
||||||
scheduler-k3s:profiles:remove <profile> # Removes a node profile from the k3s cluster
|
scheduler-k3s:profiles:remove <profile> # Removes a node profile from the k3s cluster
|
||||||
@@ -387,6 +389,35 @@ dokku scheduler-k3s:annotations:set node-js-app annotation.key --resource-type d
|
|||||||
|
|
||||||
A `ps:restart` is required after removing annotations in order to remove them from running resources.
|
A `ps:restart` is required after removing annotations in order to remove them from running resources.
|
||||||
|
|
||||||
|
#### Displaying annotations
|
||||||
|
|
||||||
|
Configured annotations can be inspected with the `scheduler-k3s:annotations:report` command. Without arguments, it iterates every app and prints all annotations. Passing an app name (or `--global`) scopes the report:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dokku scheduler-k3s:annotations:report
|
||||||
|
dokku scheduler-k3s:annotations:report node-js-app
|
||||||
|
dokku scheduler-k3s:annotations:report --global
|
||||||
|
```
|
||||||
|
|
||||||
|
`--process-type` and `--resource-type` flags narrow the output to a specific scope, matching the flags accepted by `scheduler-k3s:annotations:set`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dokku scheduler-k3s:annotations:report node-js-app --resource-type deployment
|
||||||
|
dokku scheduler-k3s:annotations:report node-js-app --process-type web --resource-type deployment
|
||||||
|
```
|
||||||
|
|
||||||
|
JSON output emits flat keys of the form `{process_type}.{resource_type}.{annotation_key}`. The literal `--global` process type is rendered as `global` to keep keys free of leading dashes:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dokku scheduler-k3s:annotations:report node-js-app --format json
|
||||||
|
```
|
||||||
|
|
||||||
|
A single value can also be read directly with a flag of the form `--scheduler-k3s-annotations.{process_type}.{resource_type}.{annotation_key}`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dokku scheduler-k3s:annotations:report node-js-app --scheduler-k3s-annotations.global.deployment.annotation.key
|
||||||
|
```
|
||||||
|
|
||||||
#### Setting Labels
|
#### Setting Labels
|
||||||
|
|
||||||
Dokku injects certain labels into each created resource by default, but it may be necessary to inject others for tighter integration with third-party tools. The `scheduler-k3s:labels:set` command can be used to perform this task. The command takes an app name and a required `--resource-type` flag.
|
Dokku injects certain labels into each created resource by default, but it may be necessary to inject others for tighter integration with third-party tools. The `scheduler-k3s:labels:set` command can be used to perform this task. The command takes an app name and a required `--resource-type` flag.
|
||||||
@@ -428,6 +459,20 @@ dokku scheduler-k3s:labels:set node-js-app label.key --resource-type deployment
|
|||||||
|
|
||||||
A `ps:restart` is required after removing labels in order to remove them from running resources.
|
A `ps:restart` is required after removing labels in order to remove them from running resources.
|
||||||
|
|
||||||
|
#### Displaying labels
|
||||||
|
|
||||||
|
Configured labels can be inspected with the `scheduler-k3s:labels:report` command. The surface mirrors `scheduler-k3s:annotations:report`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dokku scheduler-k3s:labels:report
|
||||||
|
dokku scheduler-k3s:labels:report node-js-app
|
||||||
|
dokku scheduler-k3s:labels:report --global
|
||||||
|
dokku scheduler-k3s:labels:report node-js-app --resource-type deployment
|
||||||
|
dokku scheduler-k3s:labels:report node-js-app --process-type web --resource-type deployment
|
||||||
|
dokku scheduler-k3s:labels:report node-js-app --format json
|
||||||
|
dokku scheduler-k3s:labels:report node-js-app --scheduler-k3s-labels.global.deployment.label.key
|
||||||
|
```
|
||||||
|
|
||||||
### Autoscaling
|
### Autoscaling
|
||||||
|
|
||||||
#### Workload Autoscaling
|
#### Workload Autoscaling
|
||||||
@@ -566,10 +611,12 @@ dokku scheduler-k3s:autoscaling-auth:set $APP $TRIGGER_TYPE
|
|||||||
|
|
||||||
##### Displaying an Authentication Resource report
|
##### Displaying an Authentication Resource report
|
||||||
|
|
||||||
To see a list of authentication resources managed by Dokku, run the `scheduler-k3s:autoscaling-auth:report` command.
|
To see a list of authentication resources managed by Dokku, run the `scheduler-k3s:autoscaling-auth:report` command. Without arguments, the report iterates every app; passing an app name (or `--global`) scopes the report:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
dokku scheduler-k3s:autoscaling-auth:report
|
||||||
dokku scheduler-k3s:autoscaling-auth:report node-js-app
|
dokku scheduler-k3s:autoscaling-auth:report node-js-app
|
||||||
|
dokku scheduler-k3s:autoscaling-auth:report --global
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
SUBCOMMANDS = subcommands/annotations:set subcommands/autoscaling-auth:set subcommands/autoscaling-auth:report subcommands/charts:report subcommands/charts:set subcommands/cluster:add subcommands/cluster:list subcommands/cluster:remove subcommands/ensure-charts subcommands/initialize subcommands/labels:set subcommands/profiles:add subcommands/profiles:list subcommands/profiles:remove subcommands/report subcommands/set subcommands/show-kubeconfig subcommands/uninstall
|
SUBCOMMANDS = subcommands/annotations:set subcommands/annotations:report subcommands/autoscaling-auth:set subcommands/autoscaling-auth:report subcommands/charts:report subcommands/charts:set subcommands/cluster:add subcommands/cluster:list subcommands/cluster:remove subcommands/ensure-charts subcommands/initialize subcommands/labels:set subcommands/labels:report subcommands/profiles:add subcommands/profiles:list subcommands/profiles:remove subcommands/report subcommands/set subcommands/show-kubeconfig subcommands/uninstall
|
||||||
TRIGGERS = triggers/core-post-deploy triggers/core-post-extract triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-certs-update triggers/post-certs-remove triggers/post-create triggers/post-delete triggers/report triggers/scheduler-app-status triggers/scheduler-deploy triggers/scheduler-enter triggers/scheduler-is-deployed triggers/scheduler-logs triggers/scheduler-proxy-config triggers/scheduler-proxy-logs triggers/scheduler-post-delete triggers/scheduler-run triggers/scheduler-run-list triggers/scheduler-stop triggers/scheduler-cron-write triggers/storage-create triggers/storage-destroy triggers/storage-status triggers/scheduler-storage-exec
|
TRIGGERS = triggers/core-post-deploy triggers/core-post-extract triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-certs-update triggers/post-certs-remove triggers/post-create triggers/post-delete triggers/report triggers/scheduler-app-status triggers/scheduler-deploy triggers/scheduler-enter triggers/scheduler-is-deployed triggers/scheduler-logs triggers/scheduler-proxy-config triggers/scheduler-proxy-logs triggers/scheduler-post-delete triggers/scheduler-run triggers/scheduler-run-list triggers/scheduler-stop triggers/scheduler-cron-write triggers/storage-create triggers/storage-destroy triggers/storage-status triggers/scheduler-storage-exec
|
||||||
BUILD = commands subcommands triggers
|
BUILD = commands subcommands triggers
|
||||||
PLUGIN_NAME = scheduler-k3s
|
PLUGIN_NAME = scheduler-k3s
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
package scheduler_k3s
|
package scheduler_k3s
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/dokku/dokku/plugins/common"
|
"github.com/dokku/dokku/plugins/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
annotationsReportType = "scheduler-k3s-annotations"
|
||||||
|
labelsReportType = "scheduler-k3s-labels"
|
||||||
|
|
||||||
|
// reportProcessTypeGlobal is the rendered form of GlobalProcessType in annotation
|
||||||
|
// and label report keys (both JSON and single-flag). Real process types cannot
|
||||||
|
// collide because they cannot contain "--".
|
||||||
|
reportProcessTypeGlobal = "global"
|
||||||
|
)
|
||||||
|
|
||||||
// tokenMask is shown in place of the raw token value in default stdout output.
|
// tokenMask is shown in place of the raw token value in default stdout output.
|
||||||
const tokenMask = "*******"
|
const tokenMask = "*******"
|
||||||
|
|
||||||
@@ -161,6 +173,304 @@ func ReportAutoscalingAuthSingleApp(appName string, format string, includeMetada
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExtractReportInfoFlag scans arguments for a single info flag whose name starts with
|
||||||
|
// the given prefix (e.g. "--scheduler-k3s-annotations.") and returns it separately from
|
||||||
|
// the remaining passthrough arguments. Returns an error if more than one matching flag
|
||||||
|
// is present. Matching args are removed from the passthrough list so the caller's
|
||||||
|
// flag.FlagSet sees only its own flags and positional arguments.
|
||||||
|
func ExtractReportInfoFlag(prefix string, arguments []string) ([]string, string, error) {
|
||||||
|
passthrough := []string{}
|
||||||
|
infoFlag := ""
|
||||||
|
for _, argument := range arguments {
|
||||||
|
if strings.HasPrefix(argument, prefix) {
|
||||||
|
if infoFlag != "" {
|
||||||
|
return nil, "", fmt.Errorf("only a single info flag may be specified")
|
||||||
|
}
|
||||||
|
infoFlag = argument
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
passthrough = append(passthrough, argument)
|
||||||
|
}
|
||||||
|
return passthrough, infoFlag, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// annotationsLabelsReportEntry is a parsed (processType, resourceType, key) triple
|
||||||
|
// produced when scanning the property store for annotations or labels.
|
||||||
|
type annotationsLabelsReportEntry struct {
|
||||||
|
ProcessType string
|
||||||
|
ResourceType string
|
||||||
|
Key string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReportAnnotationsSingleApp displays the scheduler-k3s annotations report for one app.
|
||||||
|
func ReportAnnotationsSingleApp(appName string, format string, processType string, resourceType string, infoFlag string) error {
|
||||||
|
if appName != "--global" {
|
||||||
|
if err := common.VerifyAppName(appName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries, err := collectAnnotationsEntries(appName, processType, resourceType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderAnnotationsLabelsReport(annotationsLabelsRenderInput{
|
||||||
|
AppName: appName,
|
||||||
|
ReportType: annotationsReportType,
|
||||||
|
Heading: "annotations",
|
||||||
|
RowLabel: "Annotation",
|
||||||
|
Entries: entries,
|
||||||
|
Format: format,
|
||||||
|
InfoFlag: infoFlag,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReportLabelsSingleApp displays the scheduler-k3s labels report for one app.
|
||||||
|
func ReportLabelsSingleApp(appName string, format string, processType string, resourceType string, infoFlag string) error {
|
||||||
|
if appName != "--global" {
|
||||||
|
if err := common.VerifyAppName(appName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries, err := collectLabelsEntries(appName, processType, resourceType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderAnnotationsLabelsReport(annotationsLabelsRenderInput{
|
||||||
|
AppName: appName,
|
||||||
|
ReportType: labelsReportType,
|
||||||
|
Heading: "labels",
|
||||||
|
RowLabel: "Label",
|
||||||
|
Entries: entries,
|
||||||
|
Format: format,
|
||||||
|
InfoFlag: infoFlag,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// collectAnnotationsEntries scans the property store for annotation entries on appName,
|
||||||
|
// optionally filtered by processType/resourceType.
|
||||||
|
func collectAnnotationsEntries(appName string, processType string, resourceType string) ([]annotationsLabelsReportEntry, error) {
|
||||||
|
properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to get property list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
knownResourceTypes := map[string]bool{}
|
||||||
|
for _, rt := range AnnotationResourceTypes {
|
||||||
|
knownResourceTypes[rt] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
entries := []annotationsLabelsReportEntry{}
|
||||||
|
for propertyName := range properties {
|
||||||
|
if isReservedAnnotationProperty(propertyName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dot := strings.LastIndex(propertyName, ".")
|
||||||
|
if dot <= 0 || dot == len(propertyName)-1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
propProcessType := propertyName[:dot]
|
||||||
|
propResourceType := propertyName[dot+1:]
|
||||||
|
if !knownResourceTypes[propResourceType] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if processType != "" && propProcessType != processType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if resourceType != "" && propResourceType != resourceType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
annotationMap, err := getAnnotation(appName, propProcessType, propResourceType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to read annotation %s: %w", propertyName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range annotationMap {
|
||||||
|
entries = append(entries, annotationsLabelsReportEntry{
|
||||||
|
ProcessType: propProcessType,
|
||||||
|
ResourceType: propResourceType,
|
||||||
|
Key: key,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// collectLabelsEntries scans the property store for label entries on appName,
|
||||||
|
// optionally filtered by processType/resourceType.
|
||||||
|
func collectLabelsEntries(appName string, processType string, resourceType string) ([]annotationsLabelsReportEntry, error) {
|
||||||
|
properties, err := common.PropertyGetAllByPrefix("scheduler-k3s", appName, "labels.")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to get property list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
knownResourceTypes := map[string]bool{}
|
||||||
|
for _, rt := range LabelResourceTypes {
|
||||||
|
knownResourceTypes[rt] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
entries := []annotationsLabelsReportEntry{}
|
||||||
|
for propertyName := range properties {
|
||||||
|
suffix := strings.TrimPrefix(propertyName, "labels.")
|
||||||
|
dot := strings.LastIndex(suffix, ".")
|
||||||
|
if dot <= 0 || dot == len(suffix)-1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
propProcessType := suffix[:dot]
|
||||||
|
propResourceType := suffix[dot+1:]
|
||||||
|
if !knownResourceTypes[propResourceType] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if processType != "" && propProcessType != processType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if resourceType != "" && propResourceType != resourceType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
labelMap, err := getLabel(appName, propProcessType, propResourceType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to read label %s: %w", propertyName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range labelMap {
|
||||||
|
entries = append(entries, annotationsLabelsReportEntry{
|
||||||
|
ProcessType: propProcessType,
|
||||||
|
ResourceType: propResourceType,
|
||||||
|
Key: key,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isReservedAnnotationProperty(propertyName string) bool {
|
||||||
|
for _, prefix := range reservedAnnotationPrefixes {
|
||||||
|
if strings.HasPrefix(propertyName, prefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type annotationsLabelsRenderInput struct {
|
||||||
|
AppName string
|
||||||
|
ReportType string
|
||||||
|
// Heading is the plural noun used in stdout headers (e.g. "annotations", "labels").
|
||||||
|
Heading string
|
||||||
|
// RowLabel is the singular noun used to prefix each stdout row (e.g. "Annotation").
|
||||||
|
RowLabel string
|
||||||
|
Entries []annotationsLabelsReportEntry
|
||||||
|
Format string
|
||||||
|
InfoFlag string
|
||||||
|
}
|
||||||
|
|
||||||
|
// renderAnnotationsLabelsReport dispatches to stdout/json/single-flag rendering for the
|
||||||
|
// annotations and labels reports.
|
||||||
|
func renderAnnotationsLabelsReport(input annotationsLabelsRenderInput) 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 := "--" + input.ReportType + "."
|
||||||
|
for _, entry := range input.Entries {
|
||||||
|
composedKey := renderProcessType(entry.ProcessType) + "." + entry.ResourceType + "." + entry.Key
|
||||||
|
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, ", "))
|
||||||
|
}
|
||||||
|
fmt.Println(value)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
entriesByGroup := map[string][]annotationsLabelsReportEntry{}
|
||||||
|
for _, entry := range input.Entries {
|
||||||
|
groupKey := renderProcessType(entry.ProcessType) + "/" + entry.ResourceType
|
||||||
|
entriesByGroup[groupKey] = append(entriesByGroup[groupKey], entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
groupKeys := []string{}
|
||||||
|
for groupKey := range entriesByGroup {
|
||||||
|
groupKeys = append(groupKeys, groupKey)
|
||||||
|
}
|
||||||
|
sort.Strings(groupKeys)
|
||||||
|
|
||||||
|
common.LogInfo2Quiet(fmt.Sprintf("%s %s information", input.AppName, input.Heading))
|
||||||
|
if len(groupKeys) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, groupKey := range groupKeys {
|
||||||
|
groupEntries := entriesByGroup[groupKey]
|
||||||
|
sort.Slice(groupEntries, func(i, j int) bool {
|
||||||
|
return groupEntries[i].Key < groupEntries[j].Key
|
||||||
|
})
|
||||||
|
|
||||||
|
length := 31
|
||||||
|
for _, entry := range groupEntries {
|
||||||
|
label := fmt.Sprintf("%s (%s) %s:", input.RowLabel, groupKey, entry.Key)
|
||||||
|
if len(label) > length {
|
||||||
|
length = len(label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range groupEntries {
|
||||||
|
label := fmt.Sprintf("%s (%s) %s:", input.RowLabel, groupKey, entry.Key)
|
||||||
|
common.LogVerbose(fmt.Sprintf("%s%s", common.RightPad(label, length, " "), entry.Value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// renderProcessType normalizes the in-storage process type for display in JSON keys,
|
||||||
|
// stdout headers, and single-flag lookups. GlobalProcessType (literal "--global") is
|
||||||
|
// rendered as "global"; real process types pass through unchanged.
|
||||||
|
func renderProcessType(processType string) string {
|
||||||
|
if processType == GlobalProcessType {
|
||||||
|
return reportProcessTypeGlobal
|
||||||
|
}
|
||||||
|
return processType
|
||||||
|
}
|
||||||
|
|
||||||
func reportComputedDeployTimeout(appName string) string {
|
func reportComputedDeployTimeout(appName string) string {
|
||||||
return getComputedDeployTimeout(appName)
|
return getComputedDeployTimeout(appName)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,54 @@ const KubeConfigPath = "/etc/rancher/k3s/k3s.yaml"
|
|||||||
const DefaultKubeContext = ""
|
const DefaultKubeContext = ""
|
||||||
const TriggerAuthPropertyPrefix = "trigger-auth."
|
const TriggerAuthPropertyPrefix = "trigger-auth."
|
||||||
|
|
||||||
|
// AnnotationResourceTypes lists the kubernetes resource types that scheduler-k3s
|
||||||
|
// supports user-provided annotations for. The order here is also the iteration order
|
||||||
|
// used when rendering reports.
|
||||||
|
var AnnotationResourceTypes = []string{
|
||||||
|
"certificate",
|
||||||
|
"cronjob",
|
||||||
|
"deployment",
|
||||||
|
"ingress",
|
||||||
|
"job",
|
||||||
|
"keda_scaled_object",
|
||||||
|
"keda_secret",
|
||||||
|
"keda_trigger_authentication",
|
||||||
|
"pod",
|
||||||
|
"secret",
|
||||||
|
"service",
|
||||||
|
"serviceaccount",
|
||||||
|
"traefik_ingressroute",
|
||||||
|
"traefik_middleware",
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelResourceTypes lists the kubernetes resource types that scheduler-k3s
|
||||||
|
// supports user-provided labels for. Differs from AnnotationResourceTypes because
|
||||||
|
// keda resources do not currently flow user labels through.
|
||||||
|
var LabelResourceTypes = []string{
|
||||||
|
"certificate",
|
||||||
|
"cronjob",
|
||||||
|
"deployment",
|
||||||
|
"ingress",
|
||||||
|
"job",
|
||||||
|
"pod",
|
||||||
|
"secret",
|
||||||
|
"service",
|
||||||
|
"serviceaccount",
|
||||||
|
"traefik_ingressroute",
|
||||||
|
"traefik_middleware",
|
||||||
|
}
|
||||||
|
|
||||||
|
// reservedAnnotationPrefixes lists property name prefixes that are not annotations
|
||||||
|
// even though their trailing segment may collide with an AnnotationResourceTypes value
|
||||||
|
// (e.g. "chart.cert-manager.deployment"). The annotations report uses this list to
|
||||||
|
// exclude such properties when scanning the property store.
|
||||||
|
var reservedAnnotationPrefixes = []string{
|
||||||
|
"chart.",
|
||||||
|
"labels.",
|
||||||
|
"node-profile-",
|
||||||
|
TriggerAuthPropertyPrefix,
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
runtimeScheme = runtime.NewScheme()
|
runtimeScheme = runtime.NewScheme()
|
||||||
codecs = serializer.NewCodecFactory(runtimeScheme)
|
codecs = serializer.NewCodecFactory(runtimeScheme)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ Additional commands:`
|
|||||||
helpContent = `
|
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:set <app|--global> <trigger> [<--metadata key=value>...], Set or clear a scheduler-k3s autoscaling keda trigger authentication resource for an app
|
||||||
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: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
|
scheduler-k3s:charts:report [<chart>] [--format stdout|json], Displays a scheduler-k3s chart override report
|
||||||
scheduler-k3s:charts:set <chart-name.property> (<value>), Set or clear a chart-specific helm value
|
scheduler-k3s:charts:set <chart-name.property> (<value>), Set or clear a chart-specific helm value
|
||||||
scheduler-k3s:cluster:add [--profile PROFILE] [--role ROLE] [--insecure-allow-unknown-hosts] [--server-ip SERVER_IP] [--taint-scheduling] [--kubelet-args KUBELET_ARGS] <ssh://user@host:port>, Adds a server node to a Dokku-managed cluster
|
scheduler-k3s:cluster:add [--profile PROFILE] [--role ROLE] [--insecure-allow-unknown-hosts] [--server-ip SERVER_IP] [--taint-scheduling] [--kubelet-args KUBELET_ARGS] <ssh://user@host:port>, Adds a server node to a Dokku-managed cluster
|
||||||
@@ -27,6 +28,7 @@ Additional commands:`
|
|||||||
scheduler-k3s:ensure-charts, Ensures the k3s charts are installed
|
scheduler-k3s:ensure-charts, Ensures the k3s charts are installed
|
||||||
scheduler-k3s:initialize [--server-ip SERVER_IP] [--taint-scheduling], Initializes a cluster
|
scheduler-k3s:initialize [--server-ip SERVER_IP] [--taint-scheduling], Initializes a cluster
|
||||||
scheduler-k3s:labels:set <app|--global> <property> (<value>) [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear a label for a given app/process-type/resource-type combination
|
scheduler-k3s:labels:set <app|--global> <property> (<value>) [--process-type PROCESS_TYPE] <--resource-type RESOURCE_TYPE>, Set or clear a label for a given app/process-type/resource-type combination
|
||||||
|
scheduler-k3s:labels:report [<app>|--global] [--format stdout|json] [--process-type PROCESS_TYPE] [--resource-type RESOURCE_TYPE], Displays a scheduler-k3s labels report for one or more apps
|
||||||
scheduler-k3s:profiles:add <profile> [--role ROLE] [--insecure-allow-unknown-hosts] [--taint-scheduling] [--kubelet-args KUBELET_ARGS], Adds a node profile to the k3s cluster
|
scheduler-k3s:profiles:add <profile> [--role ROLE] [--insecure-allow-unknown-hosts] [--taint-scheduling] [--kubelet-args KUBELET_ARGS], Adds a node profile to the k3s cluster
|
||||||
scheduler-k3s:profiles:list [--format json|stdout], Lists all node profiles in the k3s cluster
|
scheduler-k3s:profiles:list [--format json|stdout], Lists all node profiles in the k3s cluster
|
||||||
scheduler-k3s:profiles:remove <profile>, Removes a node profile from the k3s cluster
|
scheduler-k3s:profiles:remove <profile>, Removes a node profile from the k3s cluster
|
||||||
|
|||||||
@@ -34,6 +34,23 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = scheduler_k3s.CommandAnnotationsSet(appName, *processType, *resourceType, property, value)
|
err = scheduler_k3s.CommandAnnotationsSet(appName, *processType, *resourceType, property, value)
|
||||||
|
case "annotations:report":
|
||||||
|
args := flag.NewFlagSet("scheduler-k3s:annotations:report", flag.ExitOnError)
|
||||||
|
global := args.Bool("global", false, "--global: show the global report")
|
||||||
|
format := args.String("format", "stdout", "format: [ stdout | json ]")
|
||||||
|
processType := args.String("process-type", "", "--process-type: filter by process-type")
|
||||||
|
resourceType := args.String("resource-type", "", "--resource-type: filter by resource-type")
|
||||||
|
passthroughArgs, infoFlag, flagErr := scheduler_k3s.ExtractReportInfoFlag("--scheduler-k3s-annotations.", os.Args[2:])
|
||||||
|
if flagErr != nil {
|
||||||
|
err = flagErr
|
||||||
|
break
|
||||||
|
}
|
||||||
|
args.Parse(passthroughArgs)
|
||||||
|
appName := args.Arg(0)
|
||||||
|
if *global {
|
||||||
|
appName = "--global"
|
||||||
|
}
|
||||||
|
err = scheduler_k3s.CommandAnnotationsReport(appName, *format, *processType, *resourceType, infoFlag)
|
||||||
case "autoscaling-auth:set":
|
case "autoscaling-auth:set":
|
||||||
args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:set", flag.ExitOnError)
|
args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:set", flag.ExitOnError)
|
||||||
global := args.Bool("global", false, "--global: set a global property")
|
global := args.Bool("global", false, "--global: set a global property")
|
||||||
@@ -48,12 +65,15 @@ func main() {
|
|||||||
err = scheduler_k3s.CommandAutoscalingAuthSet(appName, trigger, *metadata, *global)
|
err = scheduler_k3s.CommandAutoscalingAuthSet(appName, trigger, *metadata, *global)
|
||||||
case "autoscaling-auth:report":
|
case "autoscaling-auth:report":
|
||||||
args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:report", flag.ExitOnError)
|
args := flag.NewFlagSet("scheduler-k3s:autoscaling-auth:report", flag.ExitOnError)
|
||||||
global := args.Bool("global", false, "--global: show a global report")
|
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 in the report")
|
||||||
format := args.String("format", "stdout", "format: [ stdout | json ]")
|
format := args.String("format", "stdout", "format: [ stdout | json ]")
|
||||||
args.Parse(os.Args[2:])
|
args.Parse(os.Args[2:])
|
||||||
appName := args.Arg(0)
|
appName := args.Arg(0)
|
||||||
err = scheduler_k3s.CommandAutoscalingAuthReport(appName, *format, *global, *includeMetadata)
|
if *global {
|
||||||
|
appName = "--global"
|
||||||
|
}
|
||||||
|
err = scheduler_k3s.CommandAutoscalingAuthReport(appName, *format, *includeMetadata)
|
||||||
case "charts:set":
|
case "charts:set":
|
||||||
args := flag.NewFlagSet("scheduler-k3s:charts:set", flag.ExitOnError)
|
args := flag.NewFlagSet("scheduler-k3s:charts:set", flag.ExitOnError)
|
||||||
args.Parse(os.Args[2:])
|
args.Parse(os.Args[2:])
|
||||||
@@ -121,6 +141,23 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = scheduler_k3s.CommandLabelsSet(appName, *processType, *resourceType, property, value)
|
err = scheduler_k3s.CommandLabelsSet(appName, *processType, *resourceType, property, value)
|
||||||
|
case "labels:report":
|
||||||
|
args := flag.NewFlagSet("scheduler-k3s:labels:report", flag.ExitOnError)
|
||||||
|
global := args.Bool("global", false, "--global: show the global report")
|
||||||
|
format := args.String("format", "stdout", "format: [ stdout | json ]")
|
||||||
|
processType := args.String("process-type", "", "--process-type: filter by process-type")
|
||||||
|
resourceType := args.String("resource-type", "", "--resource-type: filter by resource-type")
|
||||||
|
passthroughArgs, infoFlag, flagErr := scheduler_k3s.ExtractReportInfoFlag("--scheduler-k3s-labels.", os.Args[2:])
|
||||||
|
if flagErr != nil {
|
||||||
|
err = flagErr
|
||||||
|
break
|
||||||
|
}
|
||||||
|
args.Parse(passthroughArgs)
|
||||||
|
appName := args.Arg(0)
|
||||||
|
if *global {
|
||||||
|
appName = "--global"
|
||||||
|
}
|
||||||
|
err = scheduler_k3s.CommandLabelsReport(appName, *format, *processType, *resourceType, infoFlag)
|
||||||
case "profiles:add":
|
case "profiles:add":
|
||||||
args := flag.NewFlagSet("scheduler-k3s:profiles:add", flag.ExitOnError)
|
args := flag.NewFlagSet("scheduler-k3s:profiles:add", flag.ExitOnError)
|
||||||
role := args.String("role", "worker", "role: [ server | worker ]")
|
role := args.String("role", "worker", "role: [ server | worker ]")
|
||||||
|
|||||||
@@ -124,26 +124,69 @@ func CommandAutoscalingAuthSet(appName string, trigger string, metadata map[stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CommandAutoscalingAuthReport displays a scheduler-k3s autoscaling keda trigger authentication report for one or more apps
|
// CommandAutoscalingAuthReport displays a scheduler-k3s autoscaling keda trigger authentication report for one or more apps
|
||||||
func CommandAutoscalingAuthReport(appName string, format string, global bool, includeMetadata bool) error {
|
func CommandAutoscalingAuthReport(appName string, format string, includeMetadata bool) error {
|
||||||
if len(appName) == 0 && !global {
|
if len(appName) == 0 {
|
||||||
return fmt.Errorf("Missing required app name or --global flag")
|
apps, err := common.DokkuApps()
|
||||||
}
|
if err != nil {
|
||||||
|
if errors.Is(err, common.NoAppsExist) {
|
||||||
if len(appName) > 0 && global {
|
common.LogWarn(err.Error())
|
||||||
return fmt.Errorf("Cannot specify both app name and --global flag")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !global {
|
|
||||||
if err := common.VerifyAppName(appName); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, app := range apps {
|
||||||
|
if err := ReportAutoscalingAuthSingleApp(app, format, includeMetadata); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(appName) > 0 {
|
return ReportAutoscalingAuthSingleApp(appName, format, includeMetadata)
|
||||||
return ReportAutoscalingAuthSingleApp(appName, format, includeMetadata)
|
}
|
||||||
|
|
||||||
|
// CommandAnnotationsReport displays a scheduler-k3s annotations report for one or more apps
|
||||||
|
func CommandAnnotationsReport(appName string, format string, processType string, resourceType 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 _, app := range apps {
|
||||||
|
if err := ReportAnnotationsSingleApp(app, format, processType, resourceType, infoFlag); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReportAutoscalingAuthSingleApp("--global", format, includeMetadata)
|
return ReportAnnotationsSingleApp(appName, format, processType, resourceType, infoFlag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommandLabelsReport displays a scheduler-k3s labels report for one or more apps
|
||||||
|
func CommandLabelsReport(appName string, format string, processType string, resourceType 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 _, app := range apps {
|
||||||
|
if err := ReportLabelsSingleApp(app, format, processType, resourceType, infoFlag); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReportLabelsSingleApp(appName, format, processType, resourceType, infoFlag)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandInitialize initializes a k3s cluster on the local server
|
// CommandInitialize initializes a k3s cluster on the local server
|
||||||
|
|||||||
88
tests/unit/scheduler-k3s-annotations.bats
Normal file
88
tests/unit/scheduler-k3s-annotations.bats
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load test_helper
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
global_setup
|
||||||
|
dokku apps:create $TEST_APP >/dev/null 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
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
|
||||||
|
for resource in deployment service pod cronjob job secret ingress serviceaccount; do
|
||||||
|
dokku scheduler-k3s:annotations:set --global --resource-type "$resource" foo "" >/dev/null 2>/dev/null || true
|
||||||
|
dokku scheduler-k3s:annotations:set --global --resource-type "$resource" bar "" >/dev/null 2>/dev/null || true
|
||||||
|
done
|
||||||
|
global_teardown
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "(scheduler-k3s:annotations:report) lists annotations after set, clears them after unset" {
|
||||||
|
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 | jq -r '.\"global.deployment.foo\"'"
|
||||||
|
assert_success
|
||||||
|
assert_output "bar"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP"
|
||||||
|
assert_success
|
||||||
|
assert_output_contains "$TEST_APP annotations information"
|
||||||
|
assert_output_contains "Annotation (global/deployment) foo:"
|
||||||
|
assert_output_contains "bar"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --scheduler-k3s-annotations.global.deployment.foo"
|
||||||
|
assert_success
|
||||||
|
assert_output "bar"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment foo"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --format json"
|
||||||
|
assert_success
|
||||||
|
assert_output "{}"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "(scheduler-k3s:annotations:report) honours --process-type and --resource-type filters" {
|
||||||
|
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:set $TEST_APP --process-type web --resource-type deployment baz qux"
|
||||||
|
assert_success
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type service alpha beta"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --resource-type deployment --format json | jq -r 'keys | sort | join(\",\")'"
|
||||||
|
assert_success
|
||||||
|
assert_output "global.deployment.foo,web.deployment.baz"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --process-type web --format json | jq -r 'keys | sort | join(\",\")'"
|
||||||
|
assert_success
|
||||||
|
assert_output "web.deployment.baz"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:report $TEST_APP --process-type web --resource-type deployment --format json | jq -r '.\"web.deployment.baz\"'"
|
||||||
|
assert_success
|
||||||
|
assert_output "qux"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "(scheduler-k3s:annotations:report) supports --global scope and no-arg multi-app loop" {
|
||||||
|
run /bin/bash -c "dokku apps:create ${TEST_APP}-2"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:set --global --resource-type deployment foo global-val"
|
||||||
|
assert_success
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:set $TEST_APP --resource-type deployment foo app1-val"
|
||||||
|
assert_success
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:set ${TEST_APP}-2 --resource-type deployment bar app2-val"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:report --global --format json | jq -r '.\"global.deployment.foo\"'"
|
||||||
|
assert_success
|
||||||
|
assert_output "global-val"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:annotations:report"
|
||||||
|
assert_success
|
||||||
|
assert_output_contains "$TEST_APP annotations information"
|
||||||
|
assert_output_contains "${TEST_APP}-2 annotations information"
|
||||||
|
assert_output_contains "app1-val"
|
||||||
|
assert_output_contains "app2-val"
|
||||||
|
}
|
||||||
30
tests/unit/scheduler-k3s-autoscaling-auth.bats
Normal file
30
tests/unit/scheduler-k3s-autoscaling-auth.bats
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load test_helper
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
global_setup
|
||||||
|
dokku apps:create $TEST_APP >/dev/null 2>/dev/null || true
|
||||||
|
dokku apps:create ${TEST_APP}-2 >/dev/null 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
dokku scheduler-k3s:autoscaling-auth:set $TEST_APP datadog >/dev/null 2>/dev/null || true
|
||||||
|
dokku scheduler-k3s:autoscaling-auth:set ${TEST_APP}-2 datadog >/dev/null 2>/dev/null || true
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "(scheduler-k3s:autoscaling-auth:report) no-arg loops all apps" {
|
||||||
|
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}-2 datadog --metadata apiKey=secret-2"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
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 "Datadog:" 2
|
||||||
|
}
|
||||||
88
tests/unit/scheduler-k3s-labels.bats
Normal file
88
tests/unit/scheduler-k3s-labels.bats
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load test_helper
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
global_setup
|
||||||
|
dokku apps:create $TEST_APP >/dev/null 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
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
|
||||||
|
for resource in deployment service pod cronjob job secret ingress serviceaccount; do
|
||||||
|
dokku scheduler-k3s:labels:set --global --resource-type "$resource" foo "" >/dev/null 2>/dev/null || true
|
||||||
|
dokku scheduler-k3s:labels:set --global --resource-type "$resource" bar "" >/dev/null 2>/dev/null || true
|
||||||
|
done
|
||||||
|
global_teardown
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "(scheduler-k3s:labels:report) lists labels after set, clears them after unset" {
|
||||||
|
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 | jq -r '.\"global.deployment.foo\"'"
|
||||||
|
assert_success
|
||||||
|
assert_output "bar"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP"
|
||||||
|
assert_success
|
||||||
|
assert_output_contains "$TEST_APP labels information"
|
||||||
|
assert_output_contains "Label (global/deployment) foo:"
|
||||||
|
assert_output_contains "bar"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP --scheduler-k3s-labels.global.deployment.foo"
|
||||||
|
assert_success
|
||||||
|
assert_output "bar"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:set $TEST_APP --resource-type deployment foo"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP --format json"
|
||||||
|
assert_success
|
||||||
|
assert_output "{}"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "(scheduler-k3s:labels:report) honours --process-type and --resource-type filters" {
|
||||||
|
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:set $TEST_APP --process-type web --resource-type deployment baz qux"
|
||||||
|
assert_success
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:set $TEST_APP --resource-type service alpha beta"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP --resource-type deployment --format json | jq -r 'keys | sort | join(\",\")'"
|
||||||
|
assert_success
|
||||||
|
assert_output "global.deployment.foo,web.deployment.baz"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP --process-type web --format json | jq -r 'keys | sort | join(\",\")'"
|
||||||
|
assert_success
|
||||||
|
assert_output "web.deployment.baz"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:report $TEST_APP --process-type web --resource-type deployment --format json | jq -r '.\"web.deployment.baz\"'"
|
||||||
|
assert_success
|
||||||
|
assert_output "qux"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "(scheduler-k3s:labels:report) supports --global scope and no-arg multi-app loop" {
|
||||||
|
run /bin/bash -c "dokku apps:create ${TEST_APP}-2"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:set --global --resource-type deployment foo global-val"
|
||||||
|
assert_success
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:set $TEST_APP --resource-type deployment foo app1-val"
|
||||||
|
assert_success
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:set ${TEST_APP}-2 --resource-type deployment bar app2-val"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:report --global --format json | jq -r '.\"global.deployment.foo\"'"
|
||||||
|
assert_success
|
||||||
|
assert_output "global-val"
|
||||||
|
|
||||||
|
run /bin/bash -c "dokku scheduler-k3s:labels:report"
|
||||||
|
assert_success
|
||||||
|
assert_output_contains "$TEST_APP labels information"
|
||||||
|
assert_output_contains "${TEST_APP}-2 labels information"
|
||||||
|
assert_output_contains "app1-val"
|
||||||
|
assert_output_contains "app2-val"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user