#!/usr/bin/env bash
# nerf-kubectl-port-forward -- Forward a local port to a pod or service in the cluster. Wrapped with coreutils "timeout" so unattended runs cannot hang -- the forward is terminated after --timeout-seconds (required). Note that the wrapper exits 124 (the standard "timeout" exit code) when the time bound is reached; this is the expected success path for unattended diagnostics.
# Generated from kubectl manifest. Do not edit directly.
# nerf:threat:read=remote
# nerf:threat:write=remote

set -euo pipefail

_NERF_DRY_RUN=""

usage() {
  cat >&2 <<'EOF'
Usage: nerf-kubectl-port-forward --timeout-seconds <timeout_seconds> [--namespace|-n <namespace>] <target> <ports>

Options:
  --timeout-seconds <timeout_seconds> (required)
      Maximum seconds to keep the forward open (required; passed to coreutils timeout)
      Must match: ^[1-9][0-9]*$
  --namespace, -n <namespace>
      Namespace
      Must match: ^[a-z0-9-]+$

Arguments:
  <target> (required)
      Resource to forward to (e.g. pod/<name> or svc/<name>)
      Must match: ^(pod|svc|service|deployment|deploy|statefulset|sts)/[a-z0-9]([-a-z0-9.]*[a-z0-9])?$
  <ports> (required)
      Port mapping (local:remote)
      Must match: ^[0-9]+:[0-9]+$

Maps to: timeout <timeout_seconds> kubectl port-forward <namespace> <target> <ports>

Forward a local port to a pod or service in the cluster. Wrapped with coreutils "timeout" so unattended runs cannot hang -- the forward is terminated after --timeout-seconds (required). Note that the wrapper exits 124 (the standard "timeout" exit code) when the time bound is reached; this is the expected success path for unattended diagnostics.
EOF
  exit 1
}

TIMEOUT_SECONDS=""
_TIMEOUT_SECONDS_SET=""
NAMESPACE=""
_NAMESPACE_SET=""

while [[ $# -gt 0 ]]; do
  case "$1" in
    --timeout-seconds) if [[ -n "${_TIMEOUT_SECONDS_SET}" ]]; then echo "error: --timeout-seconds can only be specified once" >&2; exit 1; fi; TIMEOUT_SECONDS="$2"; _TIMEOUT_SECONDS_SET=true; shift 2 ;;
    --namespace|-n) if [[ -n "${_NAMESPACE_SET}" ]]; then echo "error: --namespace can only be specified once" >&2; exit 1; fi; NAMESPACE="$2"; _NAMESPACE_SET=true; shift 2 ;;
    --nerf-dry-run) _NERF_DRY_RUN="true"; shift 1 ;;
    -h|--help) usage ;;
    --) shift; break ;;
    *) break ;;
  esac
done

_TARGET_SET=""
if [[ $# -gt 0 ]]; then
  TARGET="$1"
  _TARGET_SET=true
  shift
else
  TARGET=""
fi
_PORTS_SET=""
if [[ $# -gt 0 ]]; then
  PORTS="$1"
  _PORTS_SET=true
  shift
else
  PORTS=""
fi
if [[ $# -gt 0 ]]; then
  echo "error: nerf-kubectl-port-forward: unexpected extra arguments: $*" >&2
  echo "  hint: switches and options must come before positional arguments" >&2
  exit 1
fi

if [[ -z "${TIMEOUT_SECONDS}" ]]; then
  echo "error: nerf-kubectl-port-forward: missing required option --timeout-seconds" >&2
  echo "  hint: provide --timeout-seconds <value>" >&2
  usage
fi

_NERF_PATTERN='^[1-9][0-9]*$'
if [[ -n "${_TIMEOUT_SECONDS_SET}" ]] && ! [[ "${TIMEOUT_SECONDS}" =~ $_NERF_PATTERN ]]; then
  echo "error: nerf-kubectl-port-forward: option --timeout-seconds does not match required pattern" >&2
  echo "  value:   \"${TIMEOUT_SECONDS}\"" >&2
  echo "  pattern: ^[1-9][0-9]*$" >&2
  echo "  hint: value must match ^[1-9][0-9]*$" >&2
  exit 1
fi

_NERF_PATTERN='^[a-z0-9-]+$'
if [[ -n "${_NAMESPACE_SET}" ]] && ! [[ "${NAMESPACE}" =~ $_NERF_PATTERN ]]; then
  echo "error: nerf-kubectl-port-forward: option --namespace does not match required pattern" >&2
  echo "  value:   \"${NAMESPACE}\"" >&2
  echo "  pattern: ^[a-z0-9-]+$" >&2
  echo "  hint: value must match ^[a-z0-9-]+$" >&2
  exit 1
fi

if [[ -n "${_TARGET_SET}" ]] && [[ "${TARGET}" == -* ]]; then
  echo "error: nerf-kubectl-port-forward: <target> cannot start with '-'" >&2
  echo "  hint: use -- before positional arguments if needed" >&2
  exit 1
fi

if [[ -z "${TARGET}" ]]; then
  echo "error: nerf-kubectl-port-forward: missing required argument <target>" >&2
  echo "  hint: provide a value for <target>" >&2
  usage
fi

_NERF_PATTERN='^(pod|svc|service|deployment|deploy|statefulset|sts)/[a-z0-9]([-a-z0-9.]*[a-z0-9])?$'
if [[ -n "${_TARGET_SET}" ]] && ! [[ "${TARGET}" =~ $_NERF_PATTERN ]]; then
  echo "error: nerf-kubectl-port-forward: argument <target> does not match required pattern" >&2
  echo "  value:   \"${TARGET}\"" >&2
  echo "  pattern: ^(pod|svc|service|deployment|deploy|statefulset|sts)/[a-z0-9]([-a-z0-9.]*[a-z0-9])?$" >&2
  echo "  hint: value must match ^(pod|svc|service|deployment|deploy|statefulset|sts)/[a-z0-9]([-a-z0-9.]*[a-z0-9])?$" >&2
  exit 1
fi

if [[ -n "${_PORTS_SET}" ]] && [[ "${PORTS}" == -* ]]; then
  echo "error: nerf-kubectl-port-forward: <ports> cannot start with '-'" >&2
  echo "  hint: use -- before positional arguments if needed" >&2
  exit 1
fi

if [[ -z "${PORTS}" ]]; then
  echo "error: nerf-kubectl-port-forward: missing required argument <ports>" >&2
  echo "  hint: provide a value for <ports>" >&2
  usage
fi

_NERF_PATTERN='^[0-9]+:[0-9]+$'
if [[ -n "${_PORTS_SET}" ]] && ! [[ "${PORTS}" =~ $_NERF_PATTERN ]]; then
  echo "error: nerf-kubectl-port-forward: argument <ports> does not match required pattern" >&2
  echo "  value:   \"${PORTS}\"" >&2
  echo "  pattern: ^[0-9]+:[0-9]+$" >&2
  echo "  hint: value must match ^[0-9]+:[0-9]+$" >&2
  exit 1
fi

which timeout > /dev/null 2>&1 || { echo 'error: nerf-kubectl-port-forward: "timeout" (from coreutils) is required but not found. Pre-installed on Linux and recent macOS.' >&2; exit 1; }

if [[ "$_NERF_DRY_RUN" == "true" ]]; then
  _NERF_DRY_CMD=(timeout "${TIMEOUT_SECONDS}" kubectl port-forward ${_NAMESPACE_SET:+"--namespace"} ${_NAMESPACE_SET:+"$NAMESPACE"} "${TARGET}" "${PORTS}")
  printf 'dry-run:'
  for _a in "${_NERF_DRY_CMD[@]}"; do printf " %q" "$_a"; done
  echo
  exit 0
fi

exec timeout "${TIMEOUT_SECONDS}" kubectl port-forward ${_NAMESPACE_SET:+"--namespace"} ${_NAMESPACE_SET:+"$NAMESPACE"} "${TARGET}" "${PORTS}"
