Go 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 (*Model, error). Check err first; use pointer helpers (eveiac.Ptr, eveiac.Deref) for optional fields.

plan, err := client.PlanProject(ctx, packed)
if err != nil {
    if eveiac.IsAuthError(err) { /* re-login */ }
    if ae, ok := err.(*eveiac.AgentError); ok && ae.Code == "lab_busy" { /* retry */ }
    return err
}
if plan.PlanIdentity != nil {
    identity := *plan.PlanIdentity
    _ = identity
}

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

client, err := eveiac.NewClient(eveiac.Config{
    URL:       "https://eve.example:8787",
    Token:     "",
    CAPEM:     caPEM,
    TimeoutMs: 15000,
})

Authenticate / login

anon, err := eveiac.NewClient(eveiac.Config{URL: url, CAPEM: caPEM})
session, err := anon.Login(ctx, eveiac.LoginRequest{Username: "admin", Password: "secret"})
token := ""
if session != nil && session.Token != nil {
    token = *session.Token
}
client, err := eveiac.NewClient(eveiac.Config{URL: url, Token: token, CAPEM: caPEM})

Get session

session, err := client.GetSession(ctx)

List templates

templates, err := client.ListTemplates(ctx, nil)
listed, err := client.ListTemplates(ctx, &eveiac.ListTemplatesQuery{Provisioned: eveiac.Ptr("true")})

Import an existing EVE-NG lab

imported, err := client.ImportProject(ctx, eveiac.ImportProjectRequest{
    Lab:      "/IaC/example.unl",
    Manifest: eveiac.Ptr(manifest),
    YAML:     eveiac.Ptr(yaml),
    Files:    files,
})
// Import writes IaC intent. It does not deploy. It is not reconcile from_eve.

Validate

result, err := client.ValidateProject(ctx, eveiac.ValidateProjectRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files})

Plan

plan, err := client.PlanProject(ctx, eveiac.PlanProjectRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files})

Deploy

deployed, err := client.DeployProject(ctx, eveiac.DeployProjectRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files})

Reconcile to_eve

applied, err := client.ReconcileProject(ctx, eveiac.ReconcileProjectRequest{
    Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files, Direction: eveiac.Ptr("to_eve"),
})
// Omitted Confirm is live-safe. Remaining requires_stop needs Confirm + matching PlanIdentity.

Reconcile from_eve

pulled, err := client.ReconcileProject(ctx, eveiac.ReconcileProjectRequest{
    Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files, Direction: eveiac.Ptr("from_eve"),
})

Export running config

saved, err := client.ExportProjectConfig(ctx, map[string]any{
    "lab": lab, "manifest": manifest, "yaml": yaml, "files": files,
    "configset": "default", "nodes": []string{"n_1"},
})
// Does not write topology.yml or configs/**. A later from_eve adopts the blob.

Status

status, err := client.GetProjectStatus(ctx, eveiac.GetProjectStatusRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files})
if err != nil {
    return err
}
if status != nil && status.Live != nil && status.Live.Available != nil && *status.Live.Available {
    for _, node := range status.Live.Nodes {
        _ = node.StateLabel
    }
}

Inspect

observed, err := client.InspectProject(ctx, eveiac.InspectProjectRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files, Refresh: eveiac.Ptr(true)})
// Structural snapshot. Poll live node state with GetProjectStatus.

Start nodes

result, err := client.ExecProject(ctx, eveiac.ExecProjectRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files, Action: "start"})

Stop nodes

result, err := client.ExecProject(ctx, eveiac.ExecProjectRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files, Action: "stop"})

Wipe nodes

result, err := client.ExecProject(ctx, eveiac.ExecProjectRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files, Action: "wipe"})

List consoles

consoles, err := client.ListProjectConsoles(ctx, eveiac.ListProjectConsolesRequest{Lab: eveiac.Ptr(lab), Manifest: eveiac.Ptr(manifest), YAML: eveiac.Ptr(yaml), Files: files})

Execute a console command

data, err := client.ExecConsole(ctx, eveiac.ExecConsoleRequest{Lab: eveiac.Ptr(lab), Node: eveiac.Ptr("n_1"), Command: eveiac.Ptr("show version")})

Stream console

attached, err := client.AttachConsole(ctx, eveiac.AttachConsoleRequest{Lab: eveiac.Ptr(lab), Node: eveiac.Ptr("n_1")})
ticket := ""
if attached != nil && attached.Stream != nil {
    ticket = eveiac.ConsoleStreamTicket(*attached.Stream)
}
conn, err := client.StreamConsole(ctx, ticket)

Error handling

session, err := client.GetSession(ctx)
if err != nil {
    if eveiac.IsAuthError(err) {
        return err
    }
    return err
}
_ = session