freeleaps-ops/cluster/bin/freeleaps-cluster-proxifier
zhenyus c8b68afc75 feat: Update Pinot configuration and RBAC rules
- Enhanced the Pinot Helm chart values.yaml with comprehensive configurations for controller, broker, server, minion, and zookeeper components.
- Added support for pod disruption budgets and custom resource definitions in RBAC rules.
- Introduced a new script for managing Kubernetes service port forwarding, allowing users to easily forward, stop, and list active services.
- Updated helm repository list to ensure proper access to necessary charts.

Signed-off-by: zhenyus <zhenyus@mathmast.com>
2025-05-20 16:00:32 +08:00

213 lines
7.1 KiB
Bash
Executable File

#!/bin/sh
set -eu
VERSION="0.0.1-20250509"
PROXIFIER_DIR="${HOME}/.freeleaps/proxifier"
help() {
echo "Freeleaps Cluster Proxifier (Version: ${VERSION})"
echo ""
echo "This script helps you to forward Kubernetes service ports to your local machine."
echo "It maintains the forwarding state and provides commands to manage port forwarding."
echo ""
echo "Usage: freeleaps-cluster-proxifier <sub-command>"
echo ""
echo "Sub Commands:"
echo " forward,-f,--forward <namespace>/<service> -p <local-port>:<service-port> Forward a service port to local"
echo " stop,-s,--stop <namespace>/<service> Stop forwarding a service"
echo " list,-l,--list List all forwarded services"
echo " list-available,-la,--list-available List all available services"
echo " help,-h,--help Show this help message"
}
ensure_proxifier_dir() {
if [ ! -d "${PROXIFIER_DIR}" ]; then
mkdir -p "${PROXIFIER_DIR}"
fi
}
get_process_file() {
namespace="$1"
service="$2"
echo "${PROXIFIER_DIR}/${namespace}-${service}.pid"
}
forward_port() {
if [ $# -lt 1 ]; then
echo "[ERROR] Invalid number of arguments for forward command"
echo "[TIP] Usage: freeleaps-cluster-proxifier forward <namespace>/<service> -p <local-port>:<service-port>"
exit 1
fi
# Parse namespace/service
IFS='/' read -r namespace service <<EOF
$1
EOF
if [ -z "${namespace}" ] || [ -z "${service}" ]; then
echo "[ERROR] Invalid format. Use namespace/service"
exit 1
fi
# Parse port mapping
if [ "$2" != "-p" ] || [ -z "$3" ]; then
echo "[ERROR] Invalid port format. Use -p <local-port>:<service-port>"
exit 1
fi
ports="$3"
# Validate service exists and user has permissions
if ! kubectl get svc "${service}" -n "${namespace}" >/dev/null 2>&1; then
if kubectl get namespace "${namespace}" >/dev/null 2>&1; then
echo "[ERROR] Either the service '${service}' doesn't exist in namespace '${namespace}' or you don't have permission to access it"
echo "[TIP] Please contact your cluster administrator to request access to this service"
else
echo "[ERROR] Namespace '${namespace}' doesn't exist or you don't have permission to access it"
echo "[TIP] Please contact your cluster administrator to request access to this namespace"
fi
exit 1
fi
process_file=$(get_process_file "${namespace}" "${service}")
if [ -f "${process_file}" ]; then
echo "[ERROR] Service ${service} in namespace ${namespace} is already being forwarded"
echo "[TIP] Use 'freeleaps-cluster-proxifier list' to see active forwards"
exit 1
fi
ensure_proxifier_dir
echo "[FORWARD] Starting port forward for ${service} in namespace ${namespace}..."
kubectl port-forward -n "${namespace}" "svc/${service}" "${ports}" > /dev/null 2>&1 &
pid=$!
# Store PID and port mapping
echo "${pid}:${ports}" > "${process_file}"
echo "[FORWARD] Port forward started successfully"
echo "[INFO] Service ${service}.${namespace} is now mapping with ${ports}"
}
stop_forward() {
if [ $# -ne 1 ]; then
echo "[ERROR] Invalid number of arguments for stop command"
echo "[TIP] Usage: freeleaps-cluster-proxifier stop <namespace>/<service>"
exit 1
fi
# Parse namespace/service
IFS='/' read -r namespace service <<EOF
$1
EOF
if [ -z "${namespace}" ] || [ -z "${service}" ]; then
echo "[ERROR] Invalid format. Use namespace/service"
exit 1
fi
process_file=$(get_process_file "${namespace}" "${service}")
if [ ! -f "${process_file}" ]; then
echo "[ERROR] No active forward found for service ${service} in namespace ${namespace}"
exit 1
fi
pid=$(cat "${process_file}" | cut -d: -f1)
if kill "${pid}" >/dev/null 2>&1; then
rm "${process_file}"
echo "[STOP] Stopped forwarding service ${service} in namespace ${namespace}"
else
echo "[WARNING] Process not found, cleaning up state file"
rm "${process_file}"
fi
}
list_forwards() {
ensure_proxifier_dir
echo "Belows are all active port forwards:"
printf "%-30s %-60s %-15s %-10s\n" "Namespace" "Service" "Port Mapping" "PID"
for file in "${PROXIFIER_DIR}"/*.pid; do
if [ -f "${file}" ]; then
name=$(basename "${file}" .pid)
namespace=$(echo "${name}" | cut -d'-' -f1)
service=$(echo "${name}" | cut -d'-' -f2-)
data=$(cat "${file}")
pid=$(echo "${data}" | cut -d: -f1)
ports=$(echo "${data}" | cut -d: -f2-)
# Check if process is still running
if kill -0 "${pid}" >/dev/null 2>&1; then
printf "%-30s %-60s %-15s %-10s\n" "${namespace}" "${service}" "${ports}" "${pid}"
else
echo "[WARNING] Cleaning up stale forward for ${service} in namespace ${namespace}"
rm "${file}"
fi
fi
done
}
list_available_services() {
echo "Belows are all available services that you can forward:"
printf "%-30s %-60s %-10s\n" "Namespace" "Service" "Ports"
# Get all namespaces user has access to
kubectl get namespaces -o name | cut -d'/' -f2 | while read -r ns; do
# Get services in each namespace
if kubectl auth can-i get services -n "${ns}" >/dev/null 2>&1; then
kubectl get services -n "${ns}" \
--no-headers \
-o custom-columns="Namespace:.metadata.namespace,Service:.metadata.name,Ports:.spec.ports[*].port" | \
while read -r line; do
# Only show if user has permission to port-forward
svc_name=$(echo "${line}" | awk '{print $2}')
if kubectl auth can-i get services/"${svc_name}" -n "${ns}" >/dev/null 2>&1; then
namespace=$(echo "${line}" | awk '{print $1}')
service=$(echo "${line}" | awk '{print $2}')
ports=$(echo "${line}" | awk '{print $3}')
printf "%-30s %-60s %-10s\n" "${namespace}" "${service}" "${ports}"
fi
done
fi
done
}
main() {
if [ $# -lt 1 ]; then
echo "[ERROR] No sub-command provided"
echo "[TIP] Run 'freeleaps-cluster-proxifier -h' to see available sub-commands"
exit 1
fi
subcommand="$1"
shift
case "${subcommand}" in
forward|-f|--forward)
forward_port "$@"
;;
stop|-s|--stop)
stop_forward "$@"
;;
list|-l|--list)
list_forwards
;;
list-available|-la|--list-available)
list_available_services
;;
help|-h|--help)
help
;;
*)
echo "[ERROR] Invalid sub-command: ${subcommand}"
help
exit 1
;;
esac
}
main "$@"