Skip to content

virt.kubernetes #

Kubernetes Client

A comprehensive Kubernetes client for HeroLib that wraps kubectl with additional safety and validation features.

Features

  • Connection Testing: Validate cluster connectivity before operations
  • YAML Validation: Validate K8s YAML before applying
  • Resource Management: Create, read, update, delete K8s resources
  • Cluster Info: Get cluster status and metrics
  • Pod Management: Logs, exec, port-forwarding
  • Model-Based: Type-safe resource specifications
  • HeroScript Integration: Full playbook support

Installation

##curl -LO 'https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl'
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

##mkdir -p ~/.kube
cp /path/to/kubeconfig ~/.kube/config
chmod 600 ~/.kube/config

Usage

Basic Connection

import incubaid.herolib.virt.kubernetes

mut k8s := kubernetes.new(name: 'production')!
k8s.start()!
info := k8s.cluster_info()!
println(info)

Apply YAML

mut k8s := kubernetes.get(name: 'production')!
k8s.apply_yaml('deployment.yaml')!

Validate YAML

result := kubernetes.yaml_validate('my-deployment.yaml')!
if result.valid {
    println('YAML is valid: ${result.kind}/${result.metadata.name}')
} else {
    println('Validation errors: ${result.errors}')
}

Get Resources

mut k8s := kubernetes.get(name: 'production')!
pods := k8s.get_pods('default')!
for pod in pods {
    println(pod)
}

HeroScript

!!kubernetes.configure
 name: 'production'
 kubeconfig_path: '~/.kube/config'

!!kubernetes.apply
 name: 'production'
 yaml_path: '/path/to/deployment.yaml'

!!kubernetes.info
 name: 'production'

!!kubernetes.delete
 name: 'production'
 kind: 'deployment'
 resource_name: 'my-app'
 namespace: 'default'

API Reference

Configuration

Parameter Type Default Description
name string 'default' Client instance name
kubeconfig_path string ~/.kube/config Path to kubeconfig
context string '' K8s context to use
namespace string 'default' Default namespace
kubectl_path string 'kubectl' Path to kubectl binary

Main Methods

  • test_connection() !bool - Test cluster connectivity
  • cluster_info() !ClusterInfo - Get cluster status
  • apply_yaml(path: string) !KubectlResult - Apply YAML file
  • delete_resource(kind, name, namespace) !KubectlResult - Delete resource
  • get_pods(namespace) ![]map - List pods
  • get_deployments(namespace) ![]map - List deployments
  • logs(pod, namespace) !string - Get pod logs
  • exec_pod(pod, namespace, cmd) !string - Execute in pod

Best Practices

  1. Always validate YAML before applying
  2. Test connection before operations
  3. Use namespaces to isolate workloads
  4. Check rollout status for deployments
  5. Monitor logs for troubleshooting

Example: Complete Workflow

#!/usr/bin/env -S v -cg -gc none -cc tcc -d use_openssl -enable-globals run

import incubaid.herolib.virt.kubernetes as k8s_mod
import incubaid.herolib.ui.console

// Create and connect
mut k8s := k8s_mod.new(
    name: 'my-cluster'
    kubeconfig_path: '~/.kube/config'
)!

k8s.start()!

// Validate YAML
result := k8s_mod.yaml_validate('my-deployment.yaml')!
if !result.valid {
    console.print_stderr('Invalid YAML: ${result.errors.join(", ")}')
    exit(1)
}

// Apply
k8s.apply_yaml('my-deployment.yaml')!

// Monitor rollout
if k8s.watch_deployment('my-app', 'default', 300)! {
    console.print_green('Deployment successful!')
} else {
    console.print_stderr('Deployment failed!')
}

// Check status
info := k8s.cluster_info()!
console.print_debug('Cluster: ${info.nodes} nodes, ${info.running_pods} pods')

k8s.stop()!

Troubleshooting

kubectl not found

which kubectl
##export PATH=$PATH:/usr/local/bin

Kubeconfig not found

export KUBECONFIG=~/.kube/config
##

Connection refused

##kubectl cluster-info
##kubectl config view

YAML validation errors

##kubectl apply -f myfile.yaml --dry-run=client

Constants #

const version = '0.0.0'

fn delete #

fn delete(args ArgsGet) !

fn exists #

fn exists(args ArgsGet) !bool

does the config exists?

fn get #

fn get(args ArgsGet) !&KubeClient

fn heroscript_loads #

fn heroscript_loads(heroscript string) !KubeClient

///////////NORMALLY NO NEED TO TOUCH

fn list #

fn list(args ArgsList) ![]&KubeClient

if fromdb set: load from filesystem, and not from mem, will also reset what is in mem

fn new #

fn new(args ArgsGet) !&KubeClient

fn play #

fn play(mut plbook PlayBook) !

fn set #

fn set(o KubeClient) !

register the config for the future

fn switch #

fn switch(name string)

switch instance to be used for kubernetes

fn yaml_from_configmap #

fn yaml_from_configmap(spec ConfigMapSpec) !string

fn yaml_from_deployment #

fn yaml_from_deployment(spec DeploymentSpec) !string

Generate YAML from model

fn yaml_from_service #

fn yaml_from_service(spec ServiceSpec) !string

fn yaml_validate #

fn yaml_validate(yaml_path string) !K8sValidationResult

Parse YAML file and return validation result

struct ArgsGet #

@[params]
struct ArgsGet {
pub mut:
	name   string = 'default'
	fromdb bool // will load from filesystem
	create bool // default will not create if not exist
}

///////FACTORY

struct ArgsList #

@[params]
struct ArgsList {
pub mut:
	fromdb bool // will load from filesystem
}

struct ClusterInfo #

struct ClusterInfo {
pub mut:
	version      string
	nodes        int
	namespaces   int
	running_pods int
	api_server   string
}

Cluster info

struct ConfigMapSpec #

@[params]
struct ConfigMapSpec {
pub mut:
	metadata K8sMetadata
	data     map[string]string
}

ConfigMap

struct ContainerPort #

@[params]
struct ContainerPort {
pub mut:
	name           string
	container_port int
	protocol       string = 'TCP'
	host_port      int
}

struct ContainerSpec #

@[params]
struct ContainerSpec {
pub mut:
	name              string
	image             string
	image_pull_policy string = 'IfNotPresent'
	ports             []ContainerPort
	env               []EnvVar
	resources         ResourceRequirements
	volume_mounts     []VolumeMount
	command           []string
	args              []string
}

Pod Specification

struct Deployment #

struct Deployment {
pub mut:
	name               string
	namespace          string
	replicas           int
	ready_replicas     int
	available_replicas int
	updated_replicas   int
	labels             map[string]string
	created_at         string
}

Deployment runtime information

struct DeploymentSpec #

@[params]
struct DeploymentSpec {
pub mut:
	metadata                  K8sMetadata
	replicas                  int = 1
	selector                  map[string]string
	template                  PodSpec
	strategy                  DeploymentStrategy
	progress_deadline_seconds int = 600
}

Deployment Specification

struct DeploymentStrategy #

@[params]
struct DeploymentStrategy {
pub mut:
	strategy_type  string = 'RollingUpdate'
	rolling_update RollingUpdateStrategy
}

struct DescribeResourceArgs #

@[params]
struct DescribeResourceArgs {
pub mut:
	resource      string // Resource type: pod, node, service, deployment, tfgw, etc.
	resource_name string // Name of the specific resource instance
	namespace     string // Namespace (empty string for cluster-scoped resources)
}

Args for describing a resource

struct EnvVar #

@[params]
struct EnvVar {
pub mut:
	name  string
	value string
}

struct K8sMetadata #

@[params]
struct K8sMetadata {
pub mut:
	name            string
	namespace       string = 'default'
	labels          map[string]string
	annotations     map[string]string
	owner_reference string
}

K8s API Version and Kind tracking

struct K8sValidationResult #

struct K8sValidationResult {
pub mut:
	valid       bool
	kind        string
	api_version string
	metadata    K8sMetadata
	errors      []string
}

Validation result for YAML files

struct KubeClient #

@[heap]
struct KubeClient {
pub mut:
	name              string = 'default'
	kubeconfig_path   string     // Path to kubeconfig file
	config            KubeConfig // Kubernetes configuration
	connected         bool       // Connection status
	api_version       string = 'v1'
	cache_enabled     bool   = true
	cache_ttl_seconds int    = 300
}

fn (KubeClient) apply_yaml #

fn (mut k KubeClient) apply_yaml(yaml_path string) !KubectlResult

Apply YAML file

fn (KubeClient) cluster_info #

fn (mut k KubeClient) cluster_info() !ClusterInfo

Get cluster info

fn (KubeClient) create_namespace #

fn (mut k KubeClient) create_namespace(namespace_name string) !KubectlResult

Create namespace

fn (KubeClient) delete_resource #

fn (mut k KubeClient) delete_resource(kind string, name string, namespace string) !KubectlResult

Delete resource

fn (KubeClient) describe_resource #

fn (mut k KubeClient) describe_resource(args DescribeResourceArgs) !KubectlResult

Describe resource - provides detailed information about a specific resource

fn (KubeClient) exec_pod #

fn (mut k KubeClient) exec_pod(pod_name string, namespace string, container string, cmd_args []string) !string

Exec into container

fn (KubeClient) get_deployments #

fn (mut k KubeClient) get_deployments(namespace string) ![]Deployment

fn (KubeClient) get_nodes #

fn (mut k KubeClient) get_nodes() ![]Node

Get nodes from cluster

fn (KubeClient) get_pods #

fn (mut k KubeClient) get_pods(namespace string) ![]Pod

Get resources (Pods, Deployments, Services, etc.)

fn (KubeClient) get_services #

fn (mut k KubeClient) get_services(namespace string) ![]Service

fn (KubeClient) kubectl_exec #

fn (mut k KubeClient) kubectl_exec(args KubectlExecArgs) !KubectlResult

Execute kubectl command with proper error handling

fn (KubeClient) logs #

fn (mut k KubeClient) logs(pod_name string, namespace string, follow bool) !string

Get logs

fn (KubeClient) port_forward #

fn (mut k KubeClient) port_forward(pod_name string, local_port int, remote_port int, namespace string) !string

Port forward

fn (KubeClient) test_connection #

fn (mut k KubeClient) test_connection() !bool

Test connection to cluster

fn (KubeClient) watch_deployment #

fn (mut k KubeClient) watch_deployment(name string, namespace string, timeout_seconds int) !bool

Watch resources (returns status)

struct KubeConfig #

@[params]
struct KubeConfig {
pub mut:
	kubeconfig_path          string
	context                  string
	namespace                string = 'default'
	api_server               string
	ca_cert_path             string
	client_cert_path         string
	client_key_path          string
	token                    string
	insecure_skip_tls_verify bool
}

Kube Client Configuration

struct KubectlExecArgs #

@[params]
struct KubectlExecArgs {
pub mut:
	command string
	timeout int = 30
	retry   int
}

struct KubectlResult #

struct KubectlResult {
pub mut:
	exit_code int
	stdout    string
	stderr    string
	success   bool
}

struct Node #

struct Node {
pub mut:
	name              string
	internal_ip       string   // Primary internal IP (first in list)
	external_ip       string   // Primary external IP (first in list)
	internal_ips      []string // All internal IPs (for dual-stack support)
	external_ips      []string // All external IPs (for dual-stack support)
	hostname          string
	status            string // Ready, NotReady, Unknown
	roles             []string
	kubelet_version   string
	os_image          string
	kernel_version    string
	container_runtime string
	labels            map[string]string
	created_at        string
}

Node runtime information

struct Pod #

struct Pod {
pub mut:
	name       string
	namespace  string
	status     string
	node       string
	ip         string
	containers []string
	labels     map[string]string
	created_at string
}

Pod runtime information

struct PodSpec #

@[params]
struct PodSpec {
pub mut:
	metadata        K8sMetadata
	containers      []ContainerSpec
	restart_policy  string = 'Always'
	service_account string
	volumes         []Volume
}

struct ResourceRequirements #

@[params]
struct ResourceRequirements {
pub mut:
	requests map[string]string // cpu, memory
	limits   map[string]string
}

struct RollingUpdateStrategy #

@[params]
struct RollingUpdateStrategy {
pub mut:
	max_surge       string = '25%'
	max_unavailable string = '25%'
}

struct SecretSpec #

@[params]
struct SecretSpec {
pub mut:
	metadata    K8sMetadata
	secret_type string = 'Opaque'
	data        map[string]string // base64 encoded
}

Secret

struct Service #

struct Service {
pub mut:
	name         string
	namespace    string
	service_type string
	cluster_ip   string
	external_ip  string
	ports        []string
	labels       map[string]string
	created_at   string
}

Service runtime information

struct ServicePort #

@[params]
struct ServicePort {
pub mut:
	name        string
	protocol    string = 'TCP'
	port        int
	target_port int
	node_port   int
}

struct ServiceSpec #

@[params]
struct ServiceSpec {
pub mut:
	metadata         K8sMetadata
	service_type     string = 'ClusterIP' // ClusterIP, NodePort, LoadBalancer
	selector         map[string]string
	ports            []ServicePort
	cluster_ip       string
	external_ips     []string
	session_affinity string
}

Service Specification

struct VersionInfo #

struct VersionInfo {
pub mut:
	major       string
	minor       string
	git_version string
	git_commit  string
	build_date  string
	platform    string
}

Version information from kubectl version command

struct Volume #

@[params]
struct Volume {
pub mut:
	name       string
	config_map string
	secret     string
	empty_dir  bool
}

struct VolumeMount #

@[params]
struct VolumeMount {
pub mut:
	name       string
	mount_path string
	read_only  bool
}