TypeScript examples

Generated from eve-iac OpenAPI/semantics. Do not edit manually.

Task-oriented examples using the current public SDK. These snippets are generated with the API reference.

Working with responses

Methods return typed objects (PlanData, BulkResult, …). Use property access (plan.plan_identity, result.started).

Failures reject with AgentError (message, code, status, optional data). Branch on code.

import { AgentError, isAuthError } from "eve-iac";

try {
  const plan = await client.planProject(packed);
} catch (err) {
  if (err instanceof AgentError && isAuthError(err)) { /* re-login */ }
  if (err instanceof AgentError && err.code === "lab_busy") { /* retry */ }
  throw err;
}

CLI --json failure stdout:

{
  "error": "unauthenticated",
  "code": "unauthenticated",
  "status": 401
}

Import versus from_eve

  • Import (importProject / import_project / ImportProject) reads an existing EVE source lab into a new IaC project. It writes intent and does not deploy. It must not mutate source_lab.
  • from_eve is reconcileProject with direction: "from_eve". It updates files in an existing project from that project's managed lab. It is not Import. It reads startup-config blobs already stored on the lab, not NOS memory.
  • exportProjectConfig copies the running NOS configuration into an existing startup-config set. It does not write topology.yml or configs/**. A later from_eve adopts that blob.

Create a client

import { createEveIacClient } from "@eve-iac/sdk";

const client = createEveIacClient({
  url: "https://eve.example:8787",
  token: "",
  caPem,
  timeoutMs: 15000,
});

Authenticate / login

import { createEveIacClient } from "@eve-iac/sdk";

const anon = createEveIacClient({ url, token: "", caPem });
const session = await anon.login({ username: "admin", password: "secret" });
const client = createEveIacClient({ url, token: session.token ?? "", caPem });

Get session

const session = await client.getSession();

List templates

const templates = await client.listTemplates();
const provisioned = await client.listTemplates({ provisioned: "true" });

Import an existing EVE-NG lab

const imported = await client.importProject({
  lab: "/IaC/example.unl",
  manifest,
  yaml,
  files,
});
// Import writes IaC intent. It does not deploy. It is not reconcile from_eve.

Validate

const result = await client.validateProject({ lab, manifest, yaml, files });

Plan

const plan = await client.planProject({ lab, manifest, yaml, files });
// Omitted direction is to_eve. Plan never writes Local files or EVE.

Deploy

const deployed = await client.deployProject({ lab, manifest, yaml, files });

Reconcile to_eve

const applied = await client.reconcileProject({
  lab,
  manifest,
  yaml,
  files,
  direction: "to_eve",
});
// Omitted confirm is live-safe. Remaining requires_stop:
// await client.reconcileProject({ ...packed, confirm: true, plan_identity: applied.plan_identity });

Reconcile from_eve

const pulled = await client.reconcileProject({
  lab,
  manifest,
  yaml,
  files,
  direction: "from_eve",
});
// Persist Local files yourself; this SDK call does not write the Git tree.

Export running config

const saved = await client.exportProjectConfig({
  lab,
  manifest,
  yaml,
  files,
  configset: "default",
  nodes: ["n_1"],
});
// Does not write topology.yml or configs/**. Pull from EVE is a later reconcile.

Status

const status = await client.getProjectStatus({ lab, manifest, yaml, files });
if (status.live?.available) {
  for (const node of status.live.nodes ?? []) {
    console.log(`${node.key}: ${node.state_label}`);
  }
}

Inspect

const observed = await client.inspectProject({ lab, manifest, yaml, files, refresh: true });
// Structural snapshot. Poll live node state with getProjectStatus.

Public IaC JSON

const topology = await client.getPublicProject({ yaml, files, file: "topology" });
const node = await client.getPublicProject({ yaml, files, file: "topology", path: "/nodes/core_r1" });

Public schema fragments

const schema = await client.getPublicSchema({ sections: ["traffic_filters", "tasks"] });
const filters = schema.sections?.traffic_filters;

Edit topology JSON

const edited = await client.editProject({
  yaml,
  files,
  operations: [
    { op: "add", section: "nodes", key: "core_r3", value: { name: "R3", template: "ceos" } },
  ],
});
if (!edited.applied) throw new Error("edit not applied");

Start nodes

const result = await client.execProject({ lab, manifest, yaml, files, action: "start" });

Stop nodes

const result = await client.execProject({ lab, manifest, yaml, files, action: "stop" });

Wipe nodes

const result = await client.execProject({ lab, manifest, yaml, files, action: "wipe" });
const result = await client.applyLinkQuality({
  lab, manifest, yaml, files,
  match: { endpoints: [{ node: "n_1", interface: "e0/0" }, { node: "n_2", interface: "e0/1" }] },
  source_impairment: { delay: 50, loss: 1 },
  save: true,
});
const result = await client.setLinkSuspend({
  lab, manifest, yaml, files,
  match: { endpoints: [{ node: "n_1", interface: "e0/0" }, { node: "n_2", interface: "e0/1" }] },
  suspended: true,
});

List consoles

const consoles = await client.listProjectConsoles({ lab, manifest, yaml, files });

Execute a console command

const data = await client.execConsole({ lab, node: "n_1", command: "show version" });

Stream console

const attached = await client.attachConsole({ lab, node: "n_1" });
const ticket = attached.stream?.split("/").pop() ?? "";
const sock = await client.streamConsole(ticket);

Error handling

import { AgentError, isAuthError } from "@eve-iac/sdk";

try {
  await client.getSession();
} catch (err) {
  if (isAuthError(err)) {
    throw new Error((err as AgentError).code);
  }
  throw err;
}