Categorygithub.com/takescoop/kubectl-exec-forward
modulepackage
0.2.1
Repository: https://github.com/takescoop/kubectl-exec-forward.git
Documentation: pkg.go.dev

# README

kubectl-exec-forward

test workflow status

A kubectl plugin to run exec commands exposed on Kubernetes pod annotations during a port-forward action lifecycle.

Install

brew install takescoop/formulas/kubectl-exec-forward

Usage

kubectl exec-forward type/name port [flags] [-- command]

Flags

In addition to the standard kubectl flags, the following flags are available for the plugin

FlagShortDescriptionDefault
--arg-akey=value arguments passed to commands[]
--verbose-vWhether to log verboselyfalse
--pod-timeout-tTime to wait for an attachable pod to become available500 (ms)
--persist-pWhether to persist the forwarding connection after the main command has finishedfalse

Command

The main command can be customized by passing additional arguments to the CLI. The arguments for the original command are supplied to the passed override.

kubectl exec-forward type/name port -- psql -c 'select * from foo limit 1;'

Administration

Administrators can store complex behavior in Kubernetes pod annotations, allowing users to run a single kubectl command to interact with remote resources.

Lifecycle

NameDescription
pre-connectRun before establishing a port-forwarding connection
post-connectRun after establishing a port-forwarding connection
commandThe main command, run after post-connect. When command finishes, the port-forwarding connection is closed

Annotations

NameDescription
exec-forward.pod.kubernetes.io/argsArguments passed to commands for rendering, can be overridden from the CLI via --arg|-a
exec-forward.pod.kubernetes.io/pre-connectA JSON formatted list of commands executed before establishing a port-forwarding connection
exec-forward.pod.kubernetes.io/post-connectA JSON formatted list of commands executed after establishing a port-forwarding connection
exec-forward.pod.kubernetes.io/commandA single JSON formatted command ran after post-connect

Command

Object

The command object represents an exec command and associated configuration to be executed by the plugin during the port-forwarding lifecycle.

AttributeDescriptionRequiredDefault
idA unique identifier that can be used in subsequent commands to reference a previous command's outputfalse""
commandThe command to run as an array of stringstrue
interactiveWhether the command should be run in interactive mode and can receive user input. Default is false. Note: the main command is always run in interactive modefalsefalse
nameThe display name for the command, shown during executionfalse""
Rendering

Exec commands are rendered via Go templates using inputs from the CLI, the args annotation, configuration from the port-forwarding connection and previous command outputs.

NamespaceDescriptionExample
.ArgsArguments read from the args annotation and overridden using the --arg|-a CLI flags{{.Args.username}}
.OutputsStdout from previously ran commands, stored by command id{{.Outputs.foo}}
.LocalPortThe local port where the forwarding connection is opened{{.LocalPort }}
Template functions

In addition to the following, all standard Go templating functions are available for use

NameDescription
sensitiveReplaces the passed value with ******** when printing to console
trimRemoves white space from the beginning and end of a string, useful when piping to other template functions

Examples

Connect to an AWS RDS database using a generated password. socat is used to forward connections from the pod to the remote RDS database.

kind: Pod
metadata:
  name: db
  annotations:
    exec-forward.pod.kubernetes.io/args: '{"username":"read"}'
    exec-forward.pod.kubernetes.io/pre-connect: |
      [{
        "command": [
          "aws",
          "rds",
          "generate-db-auth-token",
          "--host",
          "...rds.amazonaws.com",
          "--port",
          "5432",
          "--username",
          "{{.Args.username}}"
        ],
        "id": "password",
        "name": "Generate temporary password"
      }]'
    exec-forward.pod.kubernetes.io/command: |
      {
        "command":[
          "psql",
          "postgres://{{.Args.username}}:{{ trim .Outputs.password.Stdout | urlquery | sensitive }}@localhost:{{.Config.LocalPort}}/db"
        ]
      }
spec:
  containers:
    image: alpine/socat
    - command:
      - socat
      - tcp-listen:5432,fork,reuseaddr
      - tcp-connect:...rds.amazonaws.com:5432
      ports:
        name: postgres
kubectl exec-forward pod/db postgres

Request data through a forwarded connection using a token generated

kind: Deployment
metadata:
  name: foo
...
spec:
  template:
    metadata:
      annotations:
        exec-forward.pod.kubernetes.io/pre-connect: |
          [{
            "command": [
              "curl",
              "-d",
              "user=user&pass={{.Args.password}}",
              "https://example.com/token"
            ],
            "name": "Generate token",
            "id": token"
          }]
        exec-forward.pod.kubernetes.io/command: |
          {
            "command": [
              "curl",
              "-H",
              "X-Auth-Token: {{.Outputs.token.Stdout}}",
              "localhost:{{.Config.LocalPort}}/data"
            ]
          }
      spec:
        containers:
          ...
          - ports:
              name: http
              ...
kubectl exec-forward deployment/foo http

# Packages

Package cmd implements the exec-forward CLI.