Skip to main content

Kubernetes Functions

Utah provides Kubernetes integration functions for managing clusters, workloads, and resources directly from your shell scripts. These functions wrap kubectl commands into clean, type-safe operations.

Available Functions

Cluster & Context

FunctionReturnsDescription
k8s.getContext()stringGet the current kubectl context name
k8s.setContext(name)voidSwitch to a different kubectl context
k8s.getNamespace()stringGet the current namespace (defaults to "default")
k8s.setNamespace(name)voidSet the active namespace for the current context
k8s.clientVersion()stringGet the kubectl client version
k8s.serverVersion()stringGet the Kubernetes server version

Resource Operations

FunctionReturnsDescription
k8s.get(resource, name?, namespace?)stringGet resource(s) as JSON output
k8s.describe(resource, name, namespace?)stringGet detailed description of a resource
k8s.exists(resource, name, namespace?)booleanCheck if a resource exists

Pod Operations

FunctionReturnsDescription
k8s.logs(pod, container?, tail?, previous?)stringGet pod logs with optional filtering
k8s.exec(pod, command, container?)stringExecute a command inside a pod
k8s.portForward(pod, localPort, remotePort)stringForward a local port to a pod (returns PID)
k8s.isReady(pod, namespace?)booleanCheck if a pod is in Ready state

Scaling

FunctionReturnsDescription
k8s.scale(resource, name, replicas)voidScale a resource to the specified number of replicas

Secrets

FunctionReturnsDescription
k8s.getSecret(name, key?, namespace?)stringGet a secret (full JSON or base64-decoded key value)
k8s.setSecret(name, key, value)voidCreate a generic secret with a key-value pair

Monitoring

FunctionReturnsDescription
k8s.topPods(namespace?)stringShow resource usage (CPU/memory) for pods
k8s.topNodes()stringShow resource usage (CPU/memory) for nodes

Cluster & Context

k8s.getContext()

Returns the name of the current kubectl context.

let ctx: string = k8s.getContext();
console.log("Current context: ${ctx}");

Generated Bash:

# k8s.getContext() becomes:
ctx=$(kubectl config current-context)

Test Coverage:

  • File: tests/positive_fixtures/k8s_context.shx

k8s.setContext()

Switches to a different kubectl context.

// Switch to production context
k8s.setContext("production");

// Switch using a variable
let targetCtx: string = "staging";
k8s.setContext(targetCtx);

Generated Bash:

# k8s.setContext("production") becomes:
kubectl config use-context "production"

# k8s.setContext(targetCtx) with a variable becomes:
kubectl config use-context ${targetCtx}

Test Coverage:

  • File: tests/positive_fixtures/k8s_context.shx

k8s.getNamespace()

Returns the current namespace. Falls back to "default" if no namespace is explicitly set.

let ns: string = k8s.getNamespace();
console.log("Namespace: ${ns}");

Generated Bash:

# k8s.getNamespace() becomes:
ns=$(kubectl config view --minify --output 'jsonpath={..namespace}' 2>/dev/null || echo "default")

Test Coverage:

  • File: tests/positive_fixtures/k8s_context.shx

k8s.setNamespace()

Sets the active namespace for the current context.

k8s.setNamespace("kube-system");

let targetNs: string = "monitoring";
k8s.setNamespace(targetNs);

Generated Bash:

# k8s.setNamespace("kube-system") becomes:
kubectl config set-context --current --namespace="kube-system"

Test Coverage:

  • File: tests/positive_fixtures/k8s_context.shx

k8s.clientVersion()

Returns the kubectl client version string.

let clientVer: string = k8s.clientVersion();
console.log("Client: ${clientVer}");

Generated Bash:

# k8s.clientVersion() becomes:
clientVer=$(kubectl version --client -o json 2>/dev/null | jq -r '.clientVersion.gitVersion')

Test Coverage:

  • File: tests/positive_fixtures/k8s_version.shx

k8s.serverVersion()

Returns the Kubernetes server version string.

let serverVer: string = k8s.serverVersion();
console.log("Server: ${serverVer}");

Generated Bash:

# k8s.serverVersion() becomes:
serverVer=$(kubectl version -o json 2>/dev/null | jq -r '.serverVersion.gitVersion')

Test Coverage:

  • File: tests/positive_fixtures/k8s_version.shx

Resource Operations

k8s.get()

Gets resource(s) as JSON output. Supports optional name and namespace filtering.

// Get all pods
let allPods: string = k8s.get("pods");

// Get a specific pod
let pod: string = k8s.get("pods", "my-pod");

// Get a resource in a specific namespace
let svc: string = k8s.get("services", "api-gateway", "production");

// Using variables
let resourceType: string = "deployments";
let resourceName: string = "web-app";
let result: string = k8s.get(resourceType, resourceName);

Generated Bash:

# k8s.get("pods") becomes:
allPods=$(kubectl get "pods" -o json)

# k8s.get("pods", "my-pod") becomes:
pod=$(kubectl get "pods" "my-pod" -o json)

# k8s.get("services", "api-gateway", "production") becomes:
svc=$(kubectl get "services" "api-gateway" -n "production" -o json)

# k8s.get(resourceType, resourceName) with variables becomes:
result=$(kubectl get ${resourceType} ${resourceName} -o json)

Test Coverage:

  • File: tests/positive_fixtures/k8s_resources.shx

k8s.describe()

Gets a detailed description of a resource.

// Describe a pod
let desc: string = k8s.describe("pod", "my-pod");

// Describe with namespace
let details: string = k8s.describe("deployment", "web-app", "staging");

Generated Bash:

# k8s.describe("pod", "my-pod") becomes:
desc=$(kubectl describe "pod" "my-pod")

# k8s.describe("deployment", "web-app", "staging") becomes:
details=$(kubectl describe "deployment" "web-app" -n "staging")

Test Coverage:

  • File: tests/positive_fixtures/k8s_resources.shx

k8s.exists()

Returns a boolean indicating whether a resource exists. Works directly in if conditions.

let exists: boolean = k8s.exists("pod", "my-pod");
if (exists) {
console.log("Pod exists");
}

// With namespace
if (!k8s.exists("service", "api-svc", "default")) {
console.log("Service not found");
}

Generated Bash:

# k8s.exists("pod", "my-pod") becomes:
exists=$(kubectl get "pod" "my-pod" > /dev/null 2>&1 && echo "true" || echo "false")

# In an if condition:
if [ "${exists}" = "true" ]; then
echo "Pod exists"
fi

Test Coverage:

  • File: tests/positive_fixtures/k8s_resources.shx

Pod Operations

k8s.logs()

Returns pod logs with optional container, tail, and previous container filtering.

// Basic pod logs
let output: string = k8s.logs("my-pod");

// Logs from a specific container
let containerLogs: string = k8s.logs("my-pod", "nginx");

// Tail the last 100 lines
let tailedLogs: string = k8s.logs("my-pod", "nginx", 100);

// Get previous container logs (useful for crash debugging)
let prevLogs: string = k8s.logs("my-pod", "sidecar", 50, true);

// Using variables
let podName: string = "api-server";
let containerName: string = "app";
let logs: string = k8s.logs(podName, containerName);

Generated Bash:

# k8s.logs("my-pod") becomes:
output=$(kubectl logs "my-pod")

# k8s.logs("my-pod", "nginx", 100) becomes:
tailedLogs=$(kubectl logs "my-pod" --container="nginx" --tail=100)

# k8s.logs("my-pod", "sidecar", 50, true) becomes:
prevLogs=$(kubectl logs "my-pod" --container="sidecar" --tail=50 --previous)

Test Coverage:

  • File: tests/positive_fixtures/k8s_logs.shx

k8s.exec()

Executes a command inside a pod. Supports optional container targeting.

// Execute a command
let result: string = k8s.exec("my-pod", "ls /app");

// Execute in a specific container
let config: string = k8s.exec("my-pod", "cat /etc/config", "nginx");

// Execute as a statement (no return value needed)
k8s.exec("my-pod", "nginx -s reload");

// Using variables
let pod: string = "web-server";
let cmd: string = "whoami";
k8s.exec(pod, cmd);

Generated Bash:

# k8s.exec("my-pod", "ls /app") becomes:
result=$(kubectl exec "my-pod" -- ls /app)

# k8s.exec("my-pod", "cat /etc/config", "nginx") becomes:
config=$(kubectl exec "my-pod" --container="nginx" -- cat /etc/config)

# k8s.exec("my-pod", "nginx -s reload") as statement becomes:
kubectl exec "my-pod" -- nginx -s reload

Test Coverage:

  • File: tests/positive_fixtures/k8s_exec.shx

k8s.portForward()

Forwards a local port to a pod. Runs in the background and returns the PID when used as an expression.

// Port forward as a statement (runs in background)
k8s.portForward("my-pod", 8080, 80);

// Port forward and capture PID
let pid: string = k8s.portForward("api-pod", 3000, 8080);
console.log("Port forward PID: ${pid}");

Generated Bash:

# k8s.portForward("my-pod", 8080, 80) as statement becomes:
kubectl port-forward "my-pod" 8080:80 > /dev/null 2>&1 &

# k8s.portForward("api-pod", 3000, 8080) as expression becomes:
pid=$(kubectl port-forward "api-pod" 3000:8080 > /dev/null 2>&1 & echo $!)

Test Coverage:

  • File: tests/positive_fixtures/k8s_port_forward.shx

k8s.isReady()

Returns a boolean indicating whether a pod is in Ready state. Works directly in if conditions.

let ready: boolean = k8s.isReady("my-pod");
if (ready) {
console.log("Pod is ready");
}

// With namespace
if (!k8s.isReady("api-pod", "production")) {
console.log("Pod is not ready yet");
}

Generated Bash:

# k8s.isReady("my-pod") becomes:
ready=$(kubectl get pod "my-pod" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null | grep -qi "true" && echo "true" || echo "false")

# In an if condition:
if [ "${ready}" = "true" ]; then
echo "Pod is ready"
fi

Test Coverage:

  • File: tests/positive_fixtures/k8s_is_ready.shx

Scaling

k8s.scale()

Scales a resource to the specified number of replicas.

// Scale a deployment
k8s.scale("deployment", "web-app", 3);

// Scale using variables
let resource: string = "statefulset";
let name: string = "database";
let replicas: number = 5;
k8s.scale(resource, name, replicas);

// Capture output
let result: string = k8s.scale("deployment", "api-server", 2);

Generated Bash:

# k8s.scale("deployment", "web-app", 3) becomes:
kubectl scale deployment/web-app --replicas=3

# k8s.scale(resource, name, replicas) with variables becomes:
kubectl scale ${resource}/${name} --replicas=${replicas}

Test Coverage:

  • File: tests/positive_fixtures/k8s_scale.shx

Secrets

k8s.getSecret()

Gets a Kubernetes secret. Returns full JSON when called with just a name, or the base64-decoded value of a specific key.

// Get full secret as JSON
let secretData: string = k8s.getSecret("my-secret");

// Get a specific key (automatically base64 decoded)
let password: string = k8s.getSecret("db-credentials", "password");

// Get a secret key from a specific namespace
let token: string = k8s.getSecret("api-key", "token", "production");

Generated Bash:

# k8s.getSecret("my-secret") becomes:
secretData=$(kubectl get secret "my-secret" -o json)

# k8s.getSecret("db-credentials", "password") becomes:
password=$(kubectl get secret "db-credentials" -o jsonpath='{.data.password}' | base64 -d)

# k8s.getSecret("api-key", "token", "production") becomes:
token=$(kubectl get secret "api-key" -n "production" -o jsonpath='{.data.token}' | base64 -d)

Test Coverage:

  • File: tests/positive_fixtures/k8s_secrets.shx

k8s.setSecret()

Creates a generic Kubernetes secret with a key-value pair.

// Create a secret
k8s.setSecret("my-secret", "api-key", "abc123");

// Create using variables
let secretName: string = "db-creds";
let key: string = "password";
let value: string = "s3cret";
k8s.setSecret(secretName, key, value);

Generated Bash:

# k8s.setSecret("my-secret", "api-key", "abc123") becomes:
kubectl create secret generic "my-secret" --from-literal=api-key=abc123

# k8s.setSecret(secretName, key, value) with variables becomes:
kubectl create secret generic ${secretName} --from-literal=${key}=${value}

Test Coverage:

  • File: tests/positive_fixtures/k8s_secrets.shx

Monitoring

k8s.topPods()

Shows resource usage (CPU/memory) for pods. Supports optional namespace filtering.

// Get pod resource usage
let podUsage: string = k8s.topPods();
console.log("Pod usage: ${podUsage}");

// Get pod usage in a specific namespace
let nsUsage: string = k8s.topPods("kube-system");

// Using a variable
let ns: string = "monitoring";
let monUsage: string = k8s.topPods(ns);

Generated Bash:

# k8s.topPods() becomes:
podUsage=$(kubectl top pods)

# k8s.topPods("kube-system") becomes:
nsUsage=$(kubectl top pods -n "kube-system")

Test Coverage:

  • File: tests/positive_fixtures/k8s_monitoring.shx

k8s.topNodes()

Shows resource usage (CPU/memory) for cluster nodes.

let nodeUsage: string = k8s.topNodes();
console.log("Node usage: ${nodeUsage}");

Generated Bash:

# k8s.topNodes() becomes:
nodeUsage=$(kubectl top nodes)

Test Coverage:

  • File: tests/positive_fixtures/k8s_monitoring.shx

Practical Examples

Deployment Script

let env: string = "production";

// Switch to the right context and namespace
k8s.setContext(env);
k8s.setNamespace("app");

// Check if old deployment exists
if (k8s.exists("deployment", "web-app")) {
// Scale down before updating
k8s.scale("deployment", "web-app", 0);
}

// Scale up the new deployment
k8s.scale("deployment", "web-app", 3);

// Wait and verify readiness
let ready: boolean = k8s.isReady("web-app-pod");
if (ready) {
console.log("Deployment successful");
} else {
console.log("Deployment may need attention");
let logs: string = k8s.logs("web-app-pod");
console.log("Logs: ${logs}");
}

Cluster Health Check

let ctx: string = k8s.getContext();
console.log("Checking cluster: ${ctx}");

let clientVer: string = k8s.clientVersion();
let serverVer: string = k8s.serverVersion();
console.log("Client: ${clientVer}, Server: ${serverVer}");

// Check critical pods
let pods: string[] = ["api-server", "database", "cache"];
for (let pod: string in pods) {
if (k8s.isReady(pod)) {
console.log("✓ ${pod} is ready");
} else {
console.log("✗ ${pod} is NOT ready");
let logs: string = k8s.logs(pod, "", 20);
console.log("Recent logs: ${logs}");
}
}

// Show resource usage
let nodeUsage: string = k8s.topNodes();
console.log("Node resources: ${nodeUsage}");

Secret Rotation

let secretName: string = "api-credentials";
let ns: string = "production";

// Get current secret value
let currentKey: string = k8s.getSecret(secretName, "api-key", ns);
console.log("Current key starts with: ${currentKey}");

// Set new secret
let newKey: string = utility.uuid();
k8s.setSecret(secretName, "api-key", newKey);
console.log("Secret rotated successfully");

// Restart the deployment to pick up new secret
k8s.scale("deployment", "api-server", 0);
k8s.scale("deployment", "api-server", 3);

Debug a Pod

let podName: string = "web-server";
let ns: string = "staging";

// Check if pod exists and is ready
if (!k8s.exists("pod", podName, ns)) {
console.log("Pod ${podName} not found in ${ns}");
exit(1);
}

let ready: boolean = k8s.isReady(podName, ns);
console.log("Pod ready: ${ready}");

// Get recent logs
let logs: string = k8s.logs(podName, "", 50);
console.log("Recent logs: ${logs}");

// Check resource usage
let usage: string = k8s.topPods(ns);
console.log("Resource usage: ${usage}");

// Port forward for local debugging
let pid: string = k8s.portForward(podName, 8080, 80);
console.log("Port forwarding on localhost:8080 (PID: ${pid})");

// Exec into the pod for investigation
let env: string = k8s.exec(podName, "env");
console.log("Environment: ${env}");

Technical Notes

  • All functions require kubectl to be installed and configured
  • k8s.clientVersion() and k8s.serverVersion() require jq for JSON parsing
  • k8s.getNamespace() falls back to "default" if no namespace is set
  • k8s.portForward() runs in the background using & and redirects output to /dev/null
  • k8s.isReady() checks the pod's Ready condition status via jsonpath
  • k8s.getSecret() with a key automatically pipes through base64 -d for decoding
  • k8s.exists() and k8s.isReady() work as boolean expressions in if conditions, including negation with !