86 lines
3.3 KiB
Bash
86 lines
3.3 KiB
Bash
#!/bin/bash
|
|
# Shared primitives for TCP Gateway listener and TCPRoute lifecycle.
|
|
#
|
|
# Source from component *-lib.sh scripts. Requires _kubectl to be defined
|
|
# in the calling context (standard in all catalog component libs).
|
|
#
|
|
# Functions:
|
|
# _lib_gateway_patch_tcp <gw_name> <gw_ns> <listener_name> <port>
|
|
# _lib_gateway_remove_tcp <gw_name> <gw_ns> <listener_name>
|
|
# _lib_upsert_tcproute <route_name> <route_ns> <gw_name> <gw_ns> <section_name> <svc_name> <port>
|
|
# _lib_delete_tcproute <route_name> <route_ns>
|
|
|
|
# Upsert a TCP listener on a Gateway. Idempotent.
|
|
_lib_gateway_patch_tcp() {
|
|
local gw_name="$1" gw_ns="$2" listener_name="$3" port="$4"
|
|
|
|
# kubectl does the lookup server-side (jsonpath filter by name) — the node
|
|
# receives only the matched name, so no JSON parser is needed here.
|
|
local exists=""
|
|
[ -n "$(_kubectl get gateway "$gw_name" -n "$gw_ns" \
|
|
-o "jsonpath={.spec.listeners[?(@.name=='${listener_name}')].name}" 2>/dev/null)" ] \
|
|
&& exists="yes"
|
|
|
|
if [ "${exists:-no}" = "yes" ]; then
|
|
echo " [skip] gateway listener ${listener_name} (TCP:${port}) already exists"
|
|
return 0
|
|
fi
|
|
|
|
local patch
|
|
patch=$(printf '[{"op":"add","path":"/spec/listeners/-","value":{"name":"%s","port":%s,"protocol":"TCP","allowedRoutes":{"namespaces":{"from":"All"}}}}]' \
|
|
"$listener_name" "$port")
|
|
_kubectl patch gateway "$gw_name" -n "$gw_ns" --type=json -p "$patch"
|
|
echo " [ok] gateway ${gw_name}: TCP listener ${listener_name} added on port ${port}"
|
|
}
|
|
|
|
# Remove a TCP listener from a Gateway by name. No-op if absent.
|
|
_lib_gateway_remove_tcp() {
|
|
local gw_name="$1" gw_ns="$2" listener_name="$3"
|
|
|
|
# Find the listener's array index for the JSON-patch path. kubectl streams the
|
|
# names in order (jsonpath range); bash counts to the match — no JSON parser.
|
|
local idx="" _i=0 _n
|
|
while IFS= read -r _n; do
|
|
[ "$_n" = "$listener_name" ] && { idx="$_i"; break; }
|
|
_i=$((_i + 1))
|
|
done < <(_kubectl get gateway "$gw_name" -n "$gw_ns" \
|
|
-o 'jsonpath={range .spec.listeners[*]}{.name}{"\n"}{end}' 2>/dev/null)
|
|
|
|
[ -z "$idx" ] && { echo " [skip] gateway listener ${listener_name} not found"; return 0; }
|
|
|
|
_kubectl patch gateway "$gw_name" -n "$gw_ns" --type=json \
|
|
-p "[{\"op\":\"remove\",\"path\":\"/spec/listeners/${idx}\"}]"
|
|
echo " [ok] gateway ${gw_name}: TCP listener ${listener_name} removed"
|
|
}
|
|
|
|
# Create or replace a TCPRoute routing a Gateway TCP listener to a ClusterIP Service.
|
|
_lib_upsert_tcproute() {
|
|
local route_name="$1" route_ns="$2" gw_name="$3" gw_ns="$4" section_name="$5" svc_name="$6" port="$7"
|
|
|
|
_kubectl apply -f - <<ROUTE
|
|
apiVersion: gateway.networking.k8s.io/v1alpha2
|
|
kind: TCPRoute
|
|
metadata:
|
|
name: ${route_name}
|
|
namespace: ${route_ns}
|
|
labels:
|
|
app.kubernetes.io/managed-by: provisioning
|
|
spec:
|
|
parentRefs:
|
|
- name: ${gw_name}
|
|
namespace: ${gw_ns}
|
|
sectionName: ${section_name}
|
|
rules:
|
|
- backendRefs:
|
|
- name: ${svc_name}
|
|
port: ${port}
|
|
ROUTE
|
|
echo " [ok] TCPRoute ${route_ns}/${route_name} → ${svc_name}:${port} via ${gw_name}/${section_name}"
|
|
}
|
|
|
|
# Delete a TCPRoute. No-op if absent.
|
|
_lib_delete_tcproute() {
|
|
local route_name="$1" route_ns="$2"
|
|
_kubectl delete tcproute/"${route_name}" --namespace "${route_ns}" --ignore-not-found
|
|
echo " [ok] TCPRoute ${route_ns}/${route_name} deleted (if existed)"
|
|
}
|