Merge pull request #7296 from dokku/k3s-nginx-show-config
Implement nginx:show-config for k3s plugin
This commit is contained in:
@@ -528,13 +528,17 @@ This plugin implements various functionality through `plugn` triggers to integra
|
||||
- `enter`
|
||||
- `deploy`
|
||||
- healthchecks
|
||||
- Due to Kubernetes limitations, only a single healthcheck is supported for each of the `liveness`, `readiness`, and `startup` healthchecks
|
||||
- Due to Kubernetes limitations, content checks are not supported
|
||||
- Ports specified in the `app.json` are ignored in favor of the container port on the port mapping detected
|
||||
- Due to Kubernetes limitations, only a single healthcheck is supported for each of the `liveness`, `readiness`, and `startup` healthchecks
|
||||
- Due to Kubernetes limitations, content checks are not supported
|
||||
- Ports specified in the `app.json` are ignored in favor of the container port on the port mapping detected
|
||||
- `logs`
|
||||
- `nginx`
|
||||
- Properties set by the `nginx` plugin will be respected, either by turning them into annotations or creating a custom server/location snippet that the `ingress-nginx` project can use.
|
||||
- The `nginx:access-logs` and `nginx:error-logs` commands will fetch logs from one running `ingress-nginx` pod.
|
||||
- The `nginx:show-config` command will retrieve any `server` blocks associated with a domain attached to the app from one running `ingress-nginx` pod.
|
||||
- `ps:stop`
|
||||
- `run`
|
||||
- The `scheduler-post-run` trigger is not always triggered
|
||||
- The `scheduler-post-run` trigger is not always triggered
|
||||
- `run:detached`
|
||||
- `run:list`
|
||||
|
||||
|
||||
@@ -158,8 +158,21 @@ cmd-nginx-show-config() {
|
||||
declare cmd="nginx:show-config"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1"
|
||||
local proxy_type
|
||||
|
||||
verify_app_name "$APP"
|
||||
proxy_type="$(plugn trigger proxy-type "$APP")"
|
||||
|
||||
local DOKKU_SCHEDULER=$(get_app_scheduler "$APP")
|
||||
if [[ "$DOKKU_SCHEDULER" != "docker-local" ]]; then
|
||||
plugn trigger scheduler-proxy-config "$DOKKU_SCHEDULER" "$APP" "$proxy_type"
|
||||
return $?
|
||||
fi
|
||||
|
||||
if [[ "$proxy_type" != "nginx" ]]; then
|
||||
dokku_log_fail "This command is only available for apps with the nginx proxy type"
|
||||
fi
|
||||
|
||||
if [[ ! -f "$DOKKU_ROOT/$APP/nginx.conf" ]]; then
|
||||
dokku_log_fail "No nginx.conf exists for $APP"
|
||||
fi
|
||||
|
||||
@@ -66,6 +66,7 @@ restart_nginx() {
|
||||
nginx_logs() {
|
||||
declare desc="display app nginx logs"
|
||||
declare NGINX_LOGS_TYPE="${1#nginx:}" APP="$2"
|
||||
local proxy_type
|
||||
|
||||
local NGINX_LOGS_TYPE=${NGINX_LOGS_TYPE%-logs}
|
||||
local NGINX_LOGS_PATH="$("fn-nginx-computed-${NGINX_LOGS_TYPE}-log-path" "$APP")"
|
||||
@@ -74,6 +75,8 @@ nginx_logs() {
|
||||
dokku_log_fail "$NGINX_LOGS_TYPE logs are disabled for this app"
|
||||
fi
|
||||
|
||||
proxy_type="$(plugn trigger proxy-type "$APP")"
|
||||
|
||||
local tail=false
|
||||
local num=0
|
||||
if [[ $3 == "-t" ]]; then
|
||||
@@ -84,7 +87,7 @@ nginx_logs() {
|
||||
|
||||
local DOKKU_SCHEDULER=$(get_app_scheduler "$APP")
|
||||
if [[ "$DOKKU_SCHEDULER" != "docker-local" ]]; then
|
||||
plugn trigger scheduler-proxy-logs "$DOKKU_SCHEDULER" "$APP" "nginx" "$NGINX_LOGS_TYPE" "$tail" "$num"
|
||||
plugn trigger scheduler-proxy-logs "$DOKKU_SCHEDULER" "$APP" "$proxy_type" "$NGINX_LOGS_TYPE" "$tail" "$num"
|
||||
return $?
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SUBCOMMANDS = subcommands/annotations:set subcommands/autoscaling-auth:set subcommands/autoscaling-auth:report subcommands/cluster-add subcommands/cluster-list subcommands/cluster-remove subcommands/initialize subcommands/labels:set subcommands/report subcommands/set subcommands/show-kubeconfig subcommands/uninstall
|
||||
TRIGGERS = triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report triggers/scheduler-app-status triggers/scheduler-deploy triggers/scheduler-enter triggers/scheduler-logs triggers/scheduler-proxy-logs triggers/scheduler-post-delete triggers/scheduler-run triggers/scheduler-run-list triggers/scheduler-stop
|
||||
TRIGGERS = triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report triggers/scheduler-app-status triggers/scheduler-deploy triggers/scheduler-enter 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
|
||||
BUILD = commands subcommands triggers
|
||||
PLUGIN_NAME = scheduler-k3s
|
||||
|
||||
|
||||
@@ -312,6 +312,12 @@ type ExecCommandInput struct {
|
||||
|
||||
// Namespace is the Kubernetes namespace
|
||||
Namespace string
|
||||
|
||||
// Stderr is the error writer
|
||||
Stderr io.Writer
|
||||
|
||||
// Stdout is the output writer
|
||||
Stdout io.Writer
|
||||
}
|
||||
|
||||
// ExecCommand executes a command in a Kubernetes pod
|
||||
@@ -340,11 +346,26 @@ func (k KubernetesClient) ExecCommand(ctx context.Context, input ExecCommandInpu
|
||||
req.Param("command", cmd)
|
||||
}
|
||||
|
||||
var stdout io.Writer
|
||||
if input.Stdout == nil {
|
||||
stdout = os.Stdout
|
||||
} else {
|
||||
stdout = input.Stdout
|
||||
}
|
||||
|
||||
var stderr io.Writer
|
||||
if input.Stderr == nil {
|
||||
stderr = os.Stderr
|
||||
} else {
|
||||
stderr = input.Stderr
|
||||
}
|
||||
|
||||
t := term.TTY{
|
||||
In: os.Stdin,
|
||||
Out: os.Stdout,
|
||||
Out: stdout,
|
||||
Raw: true,
|
||||
}
|
||||
|
||||
size := t.GetSize()
|
||||
sizeQueue := t.MonitorSize(size)
|
||||
|
||||
@@ -356,8 +377,8 @@ func (k KubernetesClient) ExecCommand(ctx context.Context, input ExecCommandInpu
|
||||
|
||||
return exec.StreamWithContext(ctx, remotecommand.StreamOptions{
|
||||
Stdin: os.Stdin,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
Tty: true,
|
||||
TerminalSizeQueue: sizeQueue,
|
||||
})
|
||||
|
||||
@@ -84,6 +84,11 @@ func main() {
|
||||
}
|
||||
|
||||
err = scheduler_k3s.TriggerSchedulerLogs(scheduler, appName, processType, tail, quiet, numLines)
|
||||
case "scheduler-proxy-config":
|
||||
scheduler := flag.Arg(0)
|
||||
appName := flag.Arg(1)
|
||||
proxyType := flag.Arg(2)
|
||||
err = scheduler_k3s.TriggerSchedulerProxyConfig(scheduler, appName, proxyType)
|
||||
case "scheduler-proxy-logs":
|
||||
var tail bool
|
||||
var numLines int64
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package scheduler_k3s
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
@@ -841,9 +843,102 @@ func TriggerSchedulerLogs(scheduler string, appName string, processType string,
|
||||
})
|
||||
}
|
||||
|
||||
// TriggerSchedulerProxyConfig displays nginx config for a given application
|
||||
func TriggerSchedulerProxyConfig(scheduler string, appName string, proxyType string) error {
|
||||
if scheduler != "k3s" || proxyType != "k3s" {
|
||||
return nil
|
||||
}
|
||||
|
||||
clientset, err := NewKubernetesClient()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating kubernetes client: %w", err)
|
||||
}
|
||||
|
||||
pods, err := clientset.ListPods(context.Background(), ListPodsInput{
|
||||
Namespace: "ingress-nginx",
|
||||
LabelSelector: "app.kubernetes.io/name=ingress-nginx",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error listing pods: %w", err)
|
||||
}
|
||||
|
||||
if len(pods) == 0 {
|
||||
return errors.New("No pods found for ingress-nginx")
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
w := io.MultiWriter(&buf)
|
||||
|
||||
command := []string{"cat", "/etc/nginx/nginx.conf"}
|
||||
err = clientset.ExecCommand(context.Background(), ExecCommandInput{
|
||||
Command: command,
|
||||
ContainerName: "controller",
|
||||
Name: pods[0].Name,
|
||||
Namespace: "ingress-nginx",
|
||||
Stdout: w,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error reading nginx config: %w", err)
|
||||
}
|
||||
|
||||
// split buffer string into lines
|
||||
lines := strings.Split(buf.String(), "\n")
|
||||
|
||||
// get every domain block from the nginx config
|
||||
// domain blocks begin with "## start server DOMAIN_NAME" and end with "## end server DOMAIN_NAME"
|
||||
// each line also may have space characters at the beginning
|
||||
domainBlocks := map[string][]string{}
|
||||
for i, line := range lines {
|
||||
strippedLine := strings.TrimSpace(line)
|
||||
if strings.HasPrefix(strippedLine, "## start server ") {
|
||||
domainName := strings.TrimPrefix(strippedLine, "## start server ")
|
||||
domainBlocks[domainName] = []string{}
|
||||
for _, nextLine := range lines[i+1:] {
|
||||
nextStrippedLine := strings.TrimSpace(nextLine)
|
||||
if strings.HasPrefix(nextStrippedLine, "## end server "+domainName) {
|
||||
break
|
||||
}
|
||||
domainBlocks[domainName] = append(domainBlocks[domainName], nextLine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get all domains for this app
|
||||
domains := []string{}
|
||||
_, err = common.CallPlugnTrigger(common.PlugnTriggerInput{
|
||||
Trigger: "domains-vhost-enabled",
|
||||
Args: []string{appName},
|
||||
StreamStdio: true,
|
||||
})
|
||||
if err == nil {
|
||||
results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
|
||||
Trigger: "domains-list",
|
||||
Args: []string{appName},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting domains for deployment: %w", err)
|
||||
}
|
||||
|
||||
for _, domain := range strings.Split(results.StdoutContents(), "\n") {
|
||||
domain = strings.TrimSpace(domain)
|
||||
if domain != "" {
|
||||
domains = append(domains, domain)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, domain := range domains {
|
||||
if domainBlock, ok := domainBlocks[domain]; ok {
|
||||
fmt.Println(strings.Join(domainBlock, "\n"))
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// TriggerSchedulerProxyLogs displays nginx logs for a given application
|
||||
func TriggerSchedulerProxyLogs(scheduler string, appName string, proxyType string, logType string, tail bool, numLines int64) error {
|
||||
if scheduler != "k3s" || proxyType != "nginx" {
|
||||
if scheduler != "k3s" || proxyType != "k3s" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user