or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-clients.mdconfiguration.mdindex.mdmonitoring.mdpod-operations.mdutilities.md
tile.json

utilities.mddocs/

0

# Object Management and Utilities

1

2

Generic object management, YAML processing, health checking, patch strategies, and utility functions for working with Kubernetes resources and cluster operations.

3

4

## Capabilities

5

6

### KubernetesObjectApi

7

8

Generic API for working with any Kubernetes object type without needing specific API client classes.

9

10

```typescript { .api }

11

/**

12

* Generic API for any Kubernetes object type

13

*/

14

class KubernetesObjectApi {

15

/**

16

* Create instance from KubeConfig

17

*/

18

static makeApiClient(kc: KubeConfig): KubernetesObjectApi;

19

20

/**

21

* Create a Kubernetes object

22

* @param spec - Kubernetes object specification to create

23

* @param pretty - Pretty-print the output

24

* @param dryRun - Dry run mode ('All' or 'Server')

25

* @param fieldManager - Field manager name for server-side apply

26

* @param options - Optional configuration options

27

* @returns Promise that resolves to created object

28

*/

29

create<T extends KubernetesObject>(

30

spec: T,

31

pretty?: string,

32

dryRun?: string,

33

fieldManager?: string,

34

options?: Configuration

35

): Promise<T>;

36

37

/**

38

* Delete a Kubernetes object

39

* @param spec - Kubernetes object to delete

40

* @param pretty - Pretty-print the output

41

* @param dryRun - Dry run mode

42

* @param gracePeriodSeconds - Grace period for deletion

43

* @param orphanDependents - Whether to orphan dependents

44

* @param propagationPolicy - Propagation policy for deletion

45

* @param options - Optional configuration options

46

* @returns Promise that resolves to deletion status

47

*/

48

delete(

49

spec: KubernetesObject,

50

pretty?: string,

51

dryRun?: string,

52

gracePeriodSeconds?: number,

53

orphanDependents?: boolean,

54

propagationPolicy?: string,

55

options?: Configuration

56

): Promise<V1Status>;

57

58

/**

59

* Read a Kubernetes object

60

* @param spec - Kubernetes object header (only metadata.name and metadata.namespace used)

61

* @param pretty - Pretty-print the output

62

* @param exact - Should the export be exact

63

* @param exportt - Should this request return an export

64

* @param options - Optional configuration options

65

* @returns Promise that resolves to object

66

*/

67

read<T extends KubernetesObject>(

68

spec: KubernetesObjectHeader<T>,

69

pretty?: string,

70

exact?: boolean,

71

exportt?: boolean,

72

options?: Configuration

73

): Promise<T>;

74

75

/**

76

* Patch a Kubernetes object

77

* @param spec - Kubernetes object to patch

78

* @param pretty - Pretty-print the output

79

* @param dryRun - Dry run mode

80

* @param fieldManager - Field manager name

81

* @param force - Force the patch

82

* @param patchStrategy - Patch strategy to use

83

* @param options - Optional configuration options

84

* @returns Promise that resolves to patched object

85

*/

86

patch<T extends KubernetesObject>(

87

spec: T,

88

pretty?: string,

89

dryRun?: string,

90

fieldManager?: string,

91

force?: boolean,

92

patchStrategy?: PatchStrategy,

93

options?: Configuration

94

): Promise<T>;

95

96

/**

97

* Replace a Kubernetes object

98

* @param spec - Kubernetes object to replace

99

* @param pretty - Pretty-print the output

100

* @param dryRun - Dry run mode

101

* @param fieldManager - Field manager name

102

* @param options - Optional configuration options

103

* @returns Promise that resolves to replaced object

104

*/

105

replace<T extends KubernetesObject>(

106

spec: T,

107

pretty?: string,

108

dryRun?: string,

109

fieldManager?: string,

110

options?: Configuration

111

): Promise<T>;

112

113

/**

114

* List Kubernetes objects

115

* @param apiVersion - API version (e.g., 'v1', 'apps/v1')

116

* @param kind - Object kind (e.g., 'Pod', 'Deployment')

117

* @param namespace - Optional namespace filter

118

* @param pretty - Pretty-print the output

119

* @param allowWatchBookmarks - Allow watch bookmarks

120

* @param _continue - Continue token for pagination

121

* @param fieldSelector - Field selector for filtering

122

* @param labelSelector - Label selector for filtering

123

* @param limit - Maximum number of items to return

124

* @param resourceVersion - Resource version for consistency

125

* @param resourceVersionMatch - Resource version match strategy

126

* @param sendInitialEvents - Send initial events for watch

127

* @param timeoutSeconds - Request timeout

128

* @param watch - Watch for changes

129

* @returns Promise that resolves to object list

130

*/

131

list(

132

apiVersion: string,

133

kind: string,

134

namespace?: string,

135

pretty?: string,

136

allowWatchBookmarks?: boolean,

137

_continue?: string,

138

fieldSelector?: string,

139

labelSelector?: string,

140

limit?: number,

141

resourceVersion?: string,

142

resourceVersionMatch?: string,

143

sendInitialEvents?: boolean,

144

timeoutSeconds?: number,

145

watch?: boolean

146

): Promise<KubernetesObject>;

147

}

148

149

type KubernetesApiAction = 'create' | 'delete' | 'patch' | 'read' | 'list' | 'replace';

150

151

type KubernetesObjectHeader<T extends KubernetesObject> = Pick<T, 'apiVersion' | 'kind'> & {

152

metadata: {

153

name: string;

154

namespace?: string;

155

};

156

};

157

```

158

159

**Usage Examples:**

160

161

```typescript

162

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

163

164

const kc = new KubeConfig();

165

kc.loadFromDefault();

166

167

const k8sObjectApi = KubernetesObjectApi.makeApiClient(kc);

168

169

// Create any type of Kubernetes object

170

const createObject = async () => {

171

const configMap = {

172

apiVersion: 'v1',

173

kind: 'ConfigMap',

174

metadata: {

175

name: 'my-config',

176

namespace: 'default'

177

},

178

data: {

179

'config.json': JSON.stringify({ app: 'my-app', version: '1.0' })

180

}

181

};

182

183

try {

184

const created = await k8sObjectApi.create(configMap);

185

console.log('Created ConfigMap:', created.metadata?.name);

186

} catch (error) {

187

console.error('Failed to create ConfigMap:', error);

188

}

189

};

190

191

// Read any object by reference

192

const readObject = async () => {

193

const objectRef = {

194

apiVersion: 'v1',

195

kind: 'Pod',

196

metadata: {

197

name: 'my-pod',

198

namespace: 'default'

199

}

200

};

201

202

try {

203

const pod = await k8sObjectApi.read(objectRef);

204

console.log('Pod status:', pod.status?.phase);

205

} catch (error) {

206

console.error('Failed to read pod:', error);

207

}

208

};

209

210

// Patch objects with different strategies

211

const patchObject = async () => {

212

const objectRef = {

213

apiVersion: 'apps/v1',

214

kind: 'Deployment',

215

metadata: {

216

name: 'my-deployment',

217

namespace: 'default'

218

}

219

};

220

221

const patch = {

222

spec: {

223

replicas: 5

224

}

225

};

226

227

try {

228

const patched = await k8sObjectApi.patch(

229

objectRef,

230

patch,

231

undefined, // pretty

232

undefined, // dryRun

233

'my-controller' // fieldManager

234

);

235

console.log('Deployment scaled to:', patched.spec?.replicas);

236

} catch (error) {

237

console.error('Failed to patch deployment:', error);

238

}

239

};

240

241

// List objects of any type

242

const listObjects = async () => {

243

try {

244

const services = await k8sObjectApi.list(

245

'v1', // apiVersion

246

'Service', // kind

247

'default', // namespace

248

undefined, // pretty

249

undefined, // allowWatchBookmarks

250

undefined, // continue

251

undefined, // fieldSelector

252

'app=web' // labelSelector

253

);

254

255

console.log('Found services:', services.items?.length);

256

} catch (error) {

257

console.error('Failed to list services:', error);

258

}

259

};

260

261

// Delete objects with options

262

const deleteObject = async () => {

263

const objectRef = {

264

apiVersion: 'batch/v1',

265

kind: 'Job',

266

metadata: {

267

name: 'completed-job',

268

namespace: 'default'

269

}

270

};

271

272

try {

273

const status = await k8sObjectApi.delete(

274

objectRef,

275

undefined, // pretty

276

undefined, // dryRun

277

0, // gracePeriodSeconds (immediate deletion)

278

false, // orphanDependents

279

'Background' // propagationPolicy

280

);

281

console.log('Deletion status:', status.status);

282

} catch (error) {

283

console.error('Failed to delete job:', error);

284

}

285

};

286

287

// Generic object management functions

288

const manageCustomResource = async () => {

289

const customResource = {

290

apiVersion: 'apps.example.com/v1',

291

kind: 'MyApp',

292

metadata: {

293

name: 'my-app-instance',

294

namespace: 'production'

295

},

296

spec: {

297

replicas: 3,

298

image: 'my-app:v1.2.3',

299

environment: 'production'

300

}

301

};

302

303

try {

304

// Create

305

const created = await k8sObjectApi.create(customResource);

306

console.log('Custom resource created');

307

308

// Update

309

customResource.spec.replicas = 5;

310

const updated = await k8sObjectApi.replace(customResource);

311

console.log('Custom resource updated');

312

313

// Clean up

314

await k8sObjectApi.delete(customResource);

315

console.log('Custom resource deleted');

316

} catch (error) {

317

console.error('Custom resource management failed:', error);

318

}

319

};

320

```

321

322

### YAML Utilities

323

324

YAML parsing and serialization utilities for working with Kubernetes manifest files.

325

326

```typescript { .api }

327

/**

328

* Parse YAML string to JavaScript object

329

* @param data - YAML string to parse

330

* @param opts - YAML parsing options

331

* @returns Parsed object

332

*/

333

function loadYaml<T>(data: string, opts?: yaml.LoadOptions): T;

334

335

/**

336

* Parse multiple YAML documents from a single string

337

* @param data - YAML string containing multiple documents

338

* @param opts - YAML parsing options

339

* @returns Array of parsed objects

340

*/

341

function loadAllYaml(data: string, opts?: yaml.LoadOptions): any[];

342

343

/**

344

* Serialize JavaScript object to YAML string

345

* @param object - Object to serialize

346

* @param opts - YAML serialization options

347

* @returns YAML string

348

*/

349

function dumpYaml(object: any, opts?: yaml.DumpOptions): string;

350

```

351

352

**Usage Examples:**

353

354

```typescript

355

import { loadYaml, loadAllYaml, dumpYaml } from '@kubernetes/client-node';

356

import * as fs from 'fs';

357

358

// Load single YAML document

359

const loadManifest = () => {

360

const yamlContent = `

361

apiVersion: v1

362

kind: Pod

363

metadata:

364

name: my-pod

365

namespace: default

366

spec:

367

containers:

368

- name: app

369

image: nginx:latest

370

ports:

371

- containerPort: 80

372

`;

373

374

try {

375

const pod = loadYaml(yamlContent);

376

console.log('Loaded pod:', pod.metadata?.name);

377

return pod;

378

} catch (error) {

379

console.error('YAML parsing error:', error);

380

}

381

};

382

383

// Load multiple YAML documents

384

const loadMultipleManifests = () => {

385

const yamlContent = `

386

apiVersion: v1

387

kind: ConfigMap

388

metadata:

389

name: app-config

390

data:

391

app.conf: |

392

server_name = my-app

393

port = 8080

394

---

395

apiVersion: apps/v1

396

kind: Deployment

397

metadata:

398

name: my-app

399

spec:

400

replicas: 3

401

selector:

402

matchLabels:

403

app: my-app

404

template:

405

metadata:

406

labels:

407

app: my-app

408

spec:

409

containers:

410

- name: app

411

image: my-app:latest

412

`;

413

414

try {

415

const manifests = loadAllYaml(yamlContent);

416

console.log(`Loaded ${manifests.length} manifests`);

417

418

manifests.forEach((manifest, index) => {

419

console.log(`${index + 1}. ${manifest.kind}: ${manifest.metadata?.name}`);

420

});

421

422

return manifests;

423

} catch (error) {

424

console.error('Multi-YAML parsing error:', error);

425

}

426

};

427

428

// Load YAML from file

429

const loadManifestFromFile = async (filePath: string) => {

430

try {

431

const yamlContent = fs.readFileSync(filePath, 'utf8');

432

const manifest = loadYaml(yamlContent);

433

console.log('Loaded from file:', manifest.metadata?.name);

434

return manifest;

435

} catch (error) {

436

console.error('File loading error:', error);

437

}

438

};

439

440

// Convert objects to YAML

441

const exportToYaml = () => {

442

const deployment = {

443

apiVersion: 'apps/v1',

444

kind: 'Deployment',

445

metadata: {

446

name: 'web-server',

447

namespace: 'production',

448

labels: {

449

app: 'web-server',

450

version: 'v1.0'

451

}

452

},

453

spec: {

454

replicas: 3,

455

selector: {

456

matchLabels: {

457

app: 'web-server'

458

}

459

},

460

template: {

461

metadata: {

462

labels: {

463

app: 'web-server',

464

version: 'v1.0'

465

}

466

},

467

spec: {

468

containers: [{

469

name: 'web',

470

image: 'nginx:1.20',

471

ports: [{

472

containerPort: 80

473

}],

474

env: [{

475

name: 'ENVIRONMENT',

476

value: 'production'

477

}]

478

}]

479

}

480

}

481

}

482

};

483

484

try {

485

const yamlString = dumpYaml(deployment, {

486

indent: 2,

487

quotingType: '"',

488

forceQuotes: false

489

});

490

491

console.log('Generated YAML:');

492

console.log(yamlString);

493

494

// Save to file

495

fs.writeFileSync('./deployment.yaml', yamlString);

496

console.log('Saved to deployment.yaml');

497

498

} catch (error) {

499

console.error('YAML serialization error:', error);

500

}

501

};

502

503

// Process multiple manifest files

504

const processManifestDirectory = (dirPath: string) => {

505

const files = fs.readdirSync(dirPath)

506

.filter(file => file.endsWith('.yaml') || file.endsWith('.yml'));

507

508

const allManifests = [];

509

510

files.forEach(file => {

511

const filePath = `${dirPath}/${file}`;

512

const content = fs.readFileSync(filePath, 'utf8');

513

514

try {

515

const manifests = loadAllYaml(content);

516

allManifests.push(...manifests);

517

console.log(`Loaded ${manifests.length} manifests from ${file}`);

518

} catch (error) {

519

console.error(`Error processing ${file}:`, error);

520

}

521

});

522

523

return allManifests;

524

};

525

526

// Validate YAML structure

527

const validateKubernetesYaml = (yamlContent: string) => {

528

try {

529

const manifest = loadYaml(yamlContent);

530

531

// Basic validation

532

if (!manifest.apiVersion) {

533

throw new Error('Missing apiVersion');

534

}

535

if (!manifest.kind) {

536

throw new Error('Missing kind');

537

}

538

if (!manifest.metadata?.name) {

539

throw new Error('Missing metadata.name');

540

}

541

542

console.log('YAML validation passed');

543

return true;

544

} catch (error) {

545

console.error('YAML validation failed:', error.message);

546

return false;

547

}

548

};

549

```

550

551

### Patch Strategies

552

553

Constants and utilities for different Kubernetes patch strategies.

554

555

```typescript { .api }

556

/**

557

* Kubernetes patch strategy constants

558

*/

559

const PatchStrategy = {

560

/** JSON Patch (RFC 6902) */

561

JsonPatch: 'application/json-patch+json',

562

/** JSON Merge Patch (RFC 7396) */

563

MergePatch: 'application/merge-patch+json',

564

/** Strategic Merge Patch (Kubernetes-specific) */

565

StrategicMergePatch: 'application/strategic-merge-patch+json',

566

/** Server-Side Apply */

567

ServerSideApply: 'application/apply-patch+yaml'

568

} as const;

569

570

type PatchStrategy = typeof PatchStrategy[keyof typeof PatchStrategy];

571

```

572

573

**Usage Examples:**

574

575

```typescript

576

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

577

578

const kc = new KubeConfig();

579

kc.loadFromDefault();

580

const k8sApi = kc.makeApiClient(CoreV1Api);

581

582

// JSON Patch (RFC 6902)

583

const jsonPatch = async () => {

584

const patch = [

585

{

586

op: 'replace',

587

path: '/spec/replicas',

588

value: 5

589

},

590

{

591

op: 'add',

592

path: '/metadata/labels/environment',

593

value: 'production'

594

}

595

];

596

597

try {

598

await k8sApi.patchNamespacedDeployment(

599

'my-deployment',

600

'default',

601

patch,

602

undefined, // pretty

603

undefined, // dryRun

604

undefined, // fieldManager

605

undefined, // fieldValidation

606

undefined, // force

607

{

608

headers: {

609

'Content-Type': PatchStrategy.JsonPatch

610

}

611

}

612

);

613

console.log('JSON Patch applied');

614

} catch (error) {

615

console.error('JSON Patch failed:', error);

616

}

617

};

618

619

// Strategic Merge Patch

620

const strategicMergePatch = async () => {

621

const patch = {

622

spec: {

623

template: {

624

spec: {

625

containers: [{

626

name: 'app',

627

env: [{

628

name: 'DEBUG',

629

value: 'true'

630

}]

631

}]

632

}

633

}

634

}

635

};

636

637

try {

638

await k8sApi.patchNamespacedDeployment(

639

'my-deployment',

640

'default',

641

patch,

642

undefined,

643

undefined,

644

undefined,

645

undefined,

646

undefined,

647

{

648

headers: {

649

'Content-Type': PatchStrategy.StrategicMergePatch

650

}

651

}

652

);

653

console.log('Strategic Merge Patch applied');

654

} catch (error) {

655

console.error('Strategic Merge Patch failed:', error);

656

}

657

};

658

659

// Merge Patch

660

const mergePatch = async () => {

661

const patch = {

662

metadata: {

663

labels: {

664

version: 'v2.0',

665

environment: 'staging'

666

}

667

}

668

};

669

670

try {

671

await k8sApi.patchNamespacedPod(

672

'my-pod',

673

'default',

674

patch,

675

undefined,

676

undefined,

677

undefined,

678

undefined,

679

undefined,

680

{

681

headers: {

682

'Content-Type': PatchStrategy.MergePatch

683

}

684

}

685

);

686

console.log('Merge Patch applied');

687

} catch (error) {

688

console.error('Merge Patch failed:', error);

689

}

690

};

691

692

// Server-Side Apply

693

const serverSideApply = async () => {

694

const manifest = {

695

apiVersion: 'v1',

696

kind: 'ConfigMap',

697

metadata: {

698

name: 'app-config',

699

namespace: 'default'

700

},

701

data: {

702

'app.properties': 'debug=true\nport=8080'

703

}

704

};

705

706

try {

707

await k8sApi.patchNamespacedConfigMap(

708

'app-config',

709

'default',

710

manifest,

711

undefined,

712

undefined,

713

'my-controller', // fieldManager is required

714

undefined,

715

true, // force

716

{

717

headers: {

718

'Content-Type': PatchStrategy.ServerSideApply

719

}

720

}

721

);

722

console.log('Server-Side Apply completed');

723

} catch (error) {

724

console.error('Server-Side Apply failed:', error);

725

}

726

};

727

```

728

729

### Health Checking

730

731

Health checking utilities for monitoring Kubernetes cluster readiness and liveness.

732

733

```typescript { .api }

734

/**

735

* Kubernetes cluster health checking

736

*/

737

class Health {

738

constructor(config: KubeConfig);

739

740

/**

741

* Check cluster readiness endpoint

742

* @param opts - Request options

743

* @returns Promise that resolves to readiness status

744

*/

745

readyz(opts: RequestOptions): Promise<boolean>;

746

747

/**

748

* Check cluster liveness endpoint

749

* @param opts - Request options

750

* @returns Promise that resolves to liveness status

751

*/

752

livez(opts: RequestOptions): Promise<boolean>;

753

}

754

755

interface RequestOptions {

756

/** Request timeout in milliseconds */

757

timeout?: number;

758

/** Additional headers */

759

headers?: Record<string, string>;

760

}

761

```

762

763

**Usage Examples:**

764

765

```typescript

766

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

767

768

const kc = new KubeConfig();

769

kc.loadFromDefault();

770

771

const health = new Health(kc);

772

773

// Check cluster readiness

774

const checkReadiness = async () => {

775

try {

776

const isReady = await health.readyz({ timeout: 5000 });

777

console.log('Cluster ready:', isReady);

778

return isReady;

779

} catch (error) {

780

console.error('Readiness check failed:', error);

781

return false;

782

}

783

};

784

785

// Check cluster liveness

786

const checkLiveness = async () => {

787

try {

788

const isLive = await health.livez({ timeout: 5000 });

789

console.log('Cluster live:', isLive);

790

return isLive;

791

} catch (error) {

792

console.error('Liveness check failed:', error);

793

return false;

794

}

795

};

796

797

// Continuous health monitoring

798

const monitorClusterHealth = () => {

799

const interval = setInterval(async () => {

800

try {

801

const [ready, live] = await Promise.all([

802

health.readyz({ timeout: 3000 }),

803

health.livez({ timeout: 3000 })

804

]);

805

806

const status = ready && live ? '✅ HEALTHY' : '❌ UNHEALTHY';

807

console.log(`Cluster status: ${status} (ready: ${ready}, live: ${live})`);

808

809

if (!ready || !live) {

810

console.warn('Cluster health issues detected');

811

}

812

813

} catch (error) {

814

console.error('Health check error:', error);

815

}

816

}, 30000); // Check every 30 seconds

817

818

// Stop monitoring on process exit

819

process.on('SIGINT', () => {

820

clearInterval(interval);

821

console.log('Health monitoring stopped');

822

process.exit(0);

823

});

824

};

825

826

// Health check with retries

827

const checkHealthWithRetry = async (maxRetries = 3) => {

828

for (let attempt = 1; attempt <= maxRetries; attempt++) {

829

try {

830

const [ready, live] = await Promise.all([

831

health.readyz({ timeout: 2000 }),

832

health.livez({ timeout: 2000 })

833

]);

834

835

if (ready && live) {

836

console.log(`Cluster healthy (attempt ${attempt})`);

837

return true;

838

}

839

840

console.warn(`Cluster unhealthy (attempt ${attempt}/${maxRetries})`);

841

842

} catch (error) {

843

console.error(`Health check attempt ${attempt} failed:`, error.message);

844

}

845

846

if (attempt < maxRetries) {

847

await new Promise(resolve => setTimeout(resolve, 1000));

848

}

849

}

850

851

console.error('Cluster health check failed after all retries');

852

return false;

853

};

854

```

855

856

### HTTP Middleware

857

858

HTTP request/response middleware utilities for customizing API client behavior.

859

860

```typescript { .api }

861

/**

862

* Create header middleware for HTTP requests

863

* @param key - Header name

864

* @param value - Header value

865

* @returns Observable middleware

866

*/

867

function setHeaderMiddleware(key: string, value: string): ObservableMiddleware;

868

869

/**

870

* Create header options for configuration

871

* @param key - Header name

872

* @param value - Header value

873

* @param opt - Optional existing configuration options

874

* @returns Configuration options with header middleware

875

*/

876

function setHeaderOptions(

877

key: string,

878

value: string,

879

opt?: ConfigurationOptions

880

): ConfigurationOptions;

881

```

882

883

**Usage Examples:**

884

885

```typescript

886

import {

887

KubeConfig,

888

CoreV1Api,

889

createConfiguration,

890

setHeaderMiddleware,

891

setHeaderOptions

892

} from '@kubernetes/client-node';

893

894

const kc = new KubeConfig();

895

kc.loadFromDefault();

896

897

// Add custom headers to all requests

898

const setupCustomHeaders = () => {

899

const headerOptions = setHeaderOptions('X-Custom-Header', 'my-value');

900

const config = createConfiguration(headerOptions);

901

902

// Use configuration with custom headers

903

const k8sApi = new CoreV1Api(config);

904

return k8sApi;

905

};

906

907

// Add multiple custom headers

908

const setupMultipleHeaders = () => {

909

let options = setHeaderOptions('X-Client-Version', '1.0.0');

910

options = setHeaderOptions('X-Environment', 'production', options);

911

options = setHeaderOptions('X-User-Agent', 'my-app/1.0', options);

912

913

const config = createConfiguration(options);

914

const k8sApi = new CoreV1Api(config);

915

return k8sApi;

916

};

917

918

// Custom middleware for request logging

919

const setupLoggingMiddleware = () => {

920

const loggingMiddleware = {

921

pre: (context) => {

922

console.log(`Making request to: ${context.url}`);

923

console.log(`Method: ${context.init.method || 'GET'}`);

924

return Promise.resolve(context);

925

},

926

post: (context) => {

927

console.log(`Response status: ${context.response.status}`);

928

return Promise.resolve(context);

929

}

930

};

931

932

const config = createConfiguration({

933

middleware: [loggingMiddleware]

934

});

935

936

const k8sApi = new CoreV1Api(config);

937

return k8sApi;

938

};

939

940

// Authentication middleware

941

const setupAuthMiddleware = (token: string) => {

942

const authMiddleware = {

943

pre: (context) => {

944

context.init.headers = {

945

...context.init.headers,

946

'Authorization': `Bearer ${token}`

947

};

948

return Promise.resolve(context);

949

}

950

};

951

952

const config = createConfiguration({

953

middleware: [authMiddleware]

954

});

955

956

return new CoreV1Api(config);

957

};

958

```

959

960

### Resource Utilities

961

962

Utility functions for working with Kubernetes resources, quantities, and common operations.

963

964

```typescript { .api }

965

/**

966

* Get all pods running on a specific node

967

* @param api - CoreV1Api instance

968

* @param nodeName - Name of the node

969

* @returns Promise that resolves to array of pods

970

*/

971

function podsForNode(api: CoreV1Api, nodeName: string): Promise<V1Pod[]>;

972

973

/**

974

* Convert Kubernetes quantity to scalar number

975

* @param quantity - Kubernetes quantity string (e.g., "100m", "1Gi")

976

* @returns Numeric value

977

*/

978

function quantityToScalar(quantity: string): number | bigint;

979

980

/**

981

* Extract unit suffix from quantity string

982

* @param quantity - Kubernetes quantity string

983

* @returns Unit suffix

984

*/

985

function findSuffix(quantity: string): string;

986

987

/**

988

* Utility function to add log options to URL search parameters

989

* @param options - Log streaming options

990

* @param searchParams - URLSearchParams object to modify

991

*/

992

function AddOptionsToSearchParams(options: LogOptions, searchParams: URLSearchParams): void;

993

```

994

995

**Usage Examples:**

996

997

```typescript

998

import {

999

KubeConfig,

1000

CoreV1Api,

1001

podsForNode,

1002

quantityToScalar,

1003

findSuffix

1004

} from '@kubernetes/client-node';

1005

1006

const kc = new KubeConfig();

1007

kc.loadFromDefault();

1008

const k8sApi = kc.makeApiClient(CoreV1Api);

1009

1010

// Get pods on specific node

1011

const getNodePods = async (nodeName: string) => {

1012

try {

1013

const pods = await podsForNode(k8sApi, nodeName);

1014

console.log(`Found ${pods.length} pods on node ${nodeName}`);

1015

1016

pods.forEach(pod => {

1017

console.log(`- ${pod.metadata?.name} (${pod.status?.phase})`);

1018

});

1019

1020

return pods;

1021

} catch (error) {

1022

console.error('Failed to get node pods:', error);

1023

}

1024

};

1025

1026

// Convert resource quantities

1027

const convertQuantities = () => {

1028

const quantities = ['100m', '1Gi', '500Mi', '2', '1.5'];

1029

1030

quantities.forEach(quantity => {

1031

const scalar = quantityToScalar(quantity);

1032

const suffix = findSuffix(quantity);

1033

1034

console.log(`${quantity}: ${scalar} (suffix: ${suffix})`);

1035

});

1036

};

1037

1038

// Analyze resource usage

1039

const analyzeResourceUsage = async () => {

1040

try {

1041

const nodes = await k8sApi.listNode();

1042

1043

for (const node of nodes.body.items) {

1044

const nodeName = node.metadata?.name;

1045

if (!nodeName) continue;

1046

1047

console.log(`\nNode: ${nodeName}`);

1048

1049

// Get node capacity

1050

const cpuCapacity = node.status?.capacity?.cpu;

1051

const memoryCapacity = node.status?.capacity?.memory;

1052

1053

if (cpuCapacity) {

1054

const cpuScalar = quantityToScalar(cpuCapacity);

1055

console.log(`CPU Capacity: ${cpuCapacity} (${cpuScalar} cores)`);

1056

}

1057

1058

if (memoryCapacity) {

1059

const memoryScalar = quantityToScalar(memoryCapacity);

1060

console.log(`Memory Capacity: ${memoryCapacity} (${memoryScalar} bytes)`);

1061

}

1062

1063

// Get pods on this node

1064

const pods = await podsForNode(k8sApi, nodeName);

1065

console.log(`Running Pods: ${pods.length}`);

1066

1067

// Calculate total requests/limits

1068

let totalCpuRequests = 0;

1069

let totalMemoryRequests = 0;

1070

1071

pods.forEach(pod => {

1072

pod.spec?.containers?.forEach(container => {

1073

const cpuRequest = container.resources?.requests?.cpu;

1074

const memoryRequest = container.resources?.requests?.memory;

1075

1076

if (cpuRequest) {

1077

totalCpuRequests += quantityToScalar(cpuRequest) as number;

1078

}

1079

if (memoryRequest) {

1080

totalMemoryRequests += quantityToScalar(memoryRequest) as number;

1081

}

1082

});

1083

});

1084

1085

console.log(`Total CPU Requests: ${totalCpuRequests}`);

1086

console.log(`Total Memory Requests: ${totalMemoryRequests}`);

1087

}

1088

} catch (error) {

1089

console.error('Resource analysis failed:', error);

1090

}

1091

};

1092

1093

// Utility for resource comparison

1094

const compareResources = (resource1: string, resource2: string) => {

1095

const scalar1 = quantityToScalar(resource1);

1096

const scalar2 = quantityToScalar(resource2);

1097

1098

if (scalar1 > scalar2) {

1099

return `${resource1} > ${resource2}`;

1100

} else if (scalar1 < scalar2) {

1101

return `${resource1} < ${resource2}`;

1102

} else {

1103

return `${resource1} = ${resource2}`;

1104

}

1105

};

1106

1107

// Example usage

1108

console.log(compareResources('1Gi', '1024Mi')); // Should be equal

1109

console.log(compareResources('500m', '1')); // 500m < 1

1110

```