CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-kubernetes--client-node

Comprehensive Node.js client library for interacting with Kubernetes clusters with full API coverage and TypeScript support

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

pod-operations.mddocs/

Pod Operations

High-level classes for interactive pod operations including command execution, container attachment, port forwarding, and file transfer. These classes provide convenient abstractions over WebSocket-based Kubernetes APIs.

Capabilities

Exec Class

Execute commands in pod containers with support for interactive sessions, TTY mode, and stream handling.

/**
 * Execute commands in pod containers
 */
class Exec {
  constructor(config: KubeConfig, wsInterface?: WebSocketInterface);
  
  /**
   * Execute a command in a container
   * @param namespace - Pod namespace
   * @param podName - Pod name
   * @param containerName - Container name
   * @param command - Command to execute (string or array)
   * @param stdout - Output stream for stdout
   * @param stderr - Output stream for stderr
   * @param stdin - Input stream for stdin
   * @param tty - Enable TTY mode
   * @param statusCallback - Callback for command status
   * @returns Promise that resolves to WebSocket connection
   */
  exec(
    namespace: string,
    podName: string,
    containerName: string,
    command: string | string[],
    stdout: stream.Writable | null,
    stderr: stream.Writable | null,
    stdin: stream.Readable | null,
    tty: boolean,
    statusCallback?: (status: V1Status) => void
  ): Promise<WebSocket.WebSocket>;
}

Usage Examples:

import { KubeConfig, Exec } from '@kubernetes/client-node';
import * as stream from 'stream';

const kc = new KubeConfig();
kc.loadFromDefault();

const exec = new Exec(kc);

// Execute a simple command
const stdout = new stream.PassThrough();
const stderr = new stream.PassThrough();

stdout.on('data', (data) => {
  console.log('STDOUT:', data.toString());
});

stderr.on('data', (data) => {
  console.error('STDERR:', data.toString());
});

try {
  const ws = await exec.exec(
    'default',           // namespace
    'my-pod',           // pod name
    'my-container',     // container name
    ['ls', '-la', '/'], // command
    stdout,             // stdout stream
    stderr,             // stderr stream
    null,               // stdin stream
    false,              // tty mode
    (status) => {       // status callback
      console.log('Command status:', status);
    }
  );
  
  // Handle WebSocket events
  ws.on('close', (code, reason) => {
    console.log('Connection closed:', code, reason);
  });
} catch (error) {
  console.error('Exec error:', error);
}

// Interactive shell session with TTY
const process = require('process');

const interactiveExec = async () => {
  try {
    const ws = await exec.exec(
      'default',
      'my-pod',
      'my-container',
      ['/bin/bash'],    // shell command
      process.stdout,   // stdout to console
      process.stderr,   // stderr to console
      process.stdin,    // stdin from console
      true              // TTY mode for interactive session
    );
    
    // Handle process signals
    process.on('SIGINT', () => {
      ws.close();
    });
  } catch (error) {
    console.error('Interactive exec error:', error);
  }
};

Attach Class

Attach to running containers to interact with their primary process.

/**
 * Attach to running containers
 */
class Attach {
  constructor(config: KubeConfig, websocketInterface?: WebSocketInterface);
  
  /**
   * Attach to a running container
   * @param namespace - Pod namespace
   * @param podName - Pod name
   * @param containerName - Container name
   * @param stdout - Output stream for stdout
   * @param stderr - Output stream for stderr
   * @param stdin - Input stream for stdin
   * @param tty - Enable TTY mode
   * @returns Promise that resolves to WebSocket connection
   */
  attach(
    namespace: string,
    podName: string,
    containerName: string,
    stdout: stream.Writable | any,
    stderr: stream.Writable | any,
    stdin: stream.Readable | any,
    tty: boolean
  ): Promise<WebSocket.WebSocket>;
}

Usage Examples:

import { KubeConfig, Attach } from '@kubernetes/client-node';

const kc = new KubeConfig();
kc.loadFromDefault();

const attach = new Attach(kc);

// Attach to container's main process
try {
  const ws = await attach.attach(
    'default',
    'my-pod',
    'my-container',
    process.stdout,  // stdout
    process.stderr,  // stderr
    process.stdin,   // stdin
    true            // TTY mode
  );
  
  console.log('Attached to container');
  
  ws.on('close', () => {
    console.log('Detached from container');
  });
} catch (error) {
  console.error('Attach error:', error);
}

PortForward Class

Forward local ports to pod ports for accessing services running inside containers.

/**
 * Forward local ports to pod ports
 */
class PortForward {
  constructor(config: KubeConfig, disconnectOnErr?: boolean, handler?: WebSocketInterface);
  
  /**
   * Forward ports to a pod
   * @param namespace - Pod namespace
   * @param podName - Pod name
   * @param targetPorts - Array of port numbers to forward
   * @param output - Output stream for data
   * @param err - Error stream
   * @param input - Input stream for data
   * @param retryCount - Number of retry attempts
   * @returns Promise that resolves to WebSocket or connection function
   */
  portForward(
    namespace: string,
    podName: string,
    targetPorts: number[],
    output: stream.Writable,
    err: stream.Writable | null,
    input: stream.Readable,
    retryCount?: number
  ): Promise<WebSocket.WebSocket | (() => WebSocket.WebSocket | null)>;
}

Usage Examples:

import { KubeConfig, PortForward } from '@kubernetes/client-node';
import * as net from 'net';

const kc = new KubeConfig();
kc.loadFromDefault();

const portForward = new PortForward(kc);

// Forward local port 8080 to pod port 80
const forwardPort = async () => {
  const server = net.createServer((socket) => {
    portForward.portForward(
      'default',      // namespace
      'my-pod',       // pod name
      [80],          // target ports
      socket,        // output stream
      null,          // error stream
      socket,        // input stream
      0              // retry count
    ).then((ws) => {
      console.log('Port forward established');
      
      socket.on('close', () => {
        if (typeof ws === 'function') {
          const connection = ws();
          if (connection) {
            connection.close();
          }
        } else {
          ws.close();
        }
      });
    }).catch((error) => {
      console.error('Port forward error:', error);
      socket.destroy();
    });
  });
  
  server.listen(8080, () => {
    console.log('Local server listening on port 8080');
    console.log('Forwarding to pod my-pod:80');
  });
};

forwardPort();

// Simple port forwarding with streams
const simplePortForward = async () => {
  const output = new stream.PassThrough();
  const input = new stream.PassThrough();
  
  try {
    const ws = await portForward.portForward(
      'default',
      'my-pod',
      [3000, 8080],  // Forward multiple ports
      output,
      process.stderr,
      input
    );
    
    console.log('Port forwarding active');
    
    // Handle data
    output.on('data', (data) => {
      console.log('Received data:', data.toString());
    });
    
  } catch (error) {
    console.error('Port forward failed:', error);
  }
};

Cp Class

Copy files to and from pod containers using tar-based transfer.

/**
 * Copy files to/from pod containers
 */
class Cp {
  constructor(config: KubeConfig, execInstance?: Exec);
  
  /**
   * Copy file from pod to local filesystem
   * @param namespace - Pod namespace
   * @param podName - Pod name
   * @param containerName - Container name
   * @param srcPath - Source path in container
   * @param tgtPath - Target path on local filesystem
   * @returns Promise that resolves when copy is complete
   */
  cpFromPod(
    namespace: string,
    podName: string,
    containerName: string,
    srcPath: string,
    tgtPath: string
  ): Promise<void>;
  
  /**
   * Copy file from local filesystem to pod
   * @param namespace - Pod namespace
   * @param podName - Pod name
   * @param containerName - Container name
   * @param srcPath - Source path on local filesystem
   * @param tgtPath - Target path in container
   * @returns Promise that resolves when copy is complete
   */
  cpToPod(
    namespace: string,
    podName: string,
    containerName: string,
    srcPath: string,
    tgtPath: string
  ): Promise<void>;
}

Usage Examples:

import { KubeConfig, Cp } from '@kubernetes/client-node';

const kc = new KubeConfig();
kc.loadFromDefault();

const cp = new Cp(kc);

// Copy file from pod to local system
const copyFromPod = async () => {
  try {
    await cp.cpFromPod(
      'default',              // namespace
      'my-pod',              // pod name
      'my-container',        // container name
      '/app/config.json',    // source path in pod
      './local-config.json'  // target path locally
    );
    
    console.log('File copied from pod successfully');
  } catch (error) {
    console.error('Copy from pod failed:', error);
  }
};

// Copy file from local system to pod
const copyToPod = async () => {
  try {
    await cp.cpToPod(
      'default',              // namespace
      'my-pod',              // pod name
      'my-container',        // container name
      './local-data.txt',    // source path locally
      '/tmp/data.txt'        // target path in pod
    );
    
    console.log('File copied to pod successfully');
  } catch (error) {
    console.error('Copy to pod failed:', error);
  }
};

// Copy directory from pod
const copyDirectoryFromPod = async () => {
  try {
    await cp.cpFromPod(
      'default',
      'my-pod',
      'my-container',
      '/app/logs/',          // source directory in pod
      './pod-logs/'          // target directory locally
    );
    
    console.log('Directory copied from pod successfully');
  } catch (error) {
    console.error('Directory copy failed:', error);
  }
};

// Batch file operations
const batchOperations = async () => {
  const operations = [
    // Backup configuration
    () => cp.cpFromPod('default', 'my-pod', 'app', '/etc/app/config.yaml', './backups/config.yaml'),
    
    // Update configuration
    () => cp.cpToPod('default', 'my-pod', 'app', './new-config.yaml', '/etc/app/config.yaml'),
    
    // Copy logs
    () => cp.cpFromPod('default', 'my-pod', 'app', '/var/log/app.log', './logs/app.log')
  ];
  
  for (const operation of operations) {
    try {
      await operation();
    } catch (error) {
      console.error('Operation failed:', error);
    }
  }
};

WebSocket Interface

All pod operations use WebSocket connections for real-time communication.

/**
 * WebSocket interface for customizing WebSocket behavior
 */
interface WebSocketInterface {
  connect(
    path: string,
    textHandler: (text: string) => void,
    binaryHandler: (binary: Buffer) => void
  ): WebSocket.WebSocket;
}

/**
 * Default WebSocket handler
 */
class WebSocketHandler implements WebSocketInterface {
  connect(
    path: string,
    textHandler: (text: string) => void,
    binaryHandler: (binary: Buffer) => void
  ): WebSocket.WebSocket;
}

Error Handling

Pod operations can fail for various reasons. Always handle errors appropriately:

import { ApiException } from '@kubernetes/client-node';

const handlePodOperation = async () => {
  try {
    const ws = await exec.exec(
      'default',
      'my-pod',
      'my-container',
      ['echo', 'hello'],
      stdout,
      stderr,
      null,
      false
    );
  } catch (error) {
    if (error instanceof ApiException) {
      console.error('API Error:', error.code);
      if (error.code === 404) {
        console.error('Pod not found');
      } else if (error.code === 403) {
        console.error('Access denied');
      }
    } else {
      console.error('Network or other error:', error.message);
    }
  }
};

Advanced Usage

Custom WebSocket handling:

import { Exec, WebSocketInterface } from '@kubernetes/client-node';

class CustomWebSocketHandler implements WebSocketInterface {
  connect(path: string, textHandler: (text: string) => void, binaryHandler: (binary: Buffer) => void) {
    // Custom WebSocket implementation
    const ws = new WebSocket(path);
    
    ws.on('message', (data) => {
      if (typeof data === 'string') {
        textHandler(data);
      } else {
        binaryHandler(data as Buffer);
      }
    });
    
    return ws;
  }
}

const exec = new Exec(kc, new CustomWebSocketHandler());

Stream processing with transforms:

import { Transform } from 'stream';

const colorOutput = new Transform({
  transform(chunk, encoding, callback) {
    // Add color codes to output
    const colored = `\x1b[32m${chunk.toString()}\x1b[0m`;
    callback(null, colored);
  }
});

const ws = await exec.exec(
  'default',
  'my-pod',
  'my-container',
  ['tail', '-f', '/var/log/app.log'],
  colorOutput.pipe(process.stdout),
  process.stderr,
  null,
  false
);

docs

api-clients.md

configuration.md

index.md

monitoring.md

pod-operations.md

utilities.md

tile.json