api

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 17, 2025 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

internal/api/auth_handlers.go

internal/api/helpers.go

internal/api/info_handlers.go

internal/api/lab_handlers.go

internal/api/routes.go

internal/api/tools_handlers.go

internal/api/topology_handlers.go

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AuthMiddleware

func AuthMiddleware() gin.HandlerFunc

AuthMiddleware validates the JWT token from the Authorization header

func CheckVersionHandler

func CheckVersionHandler(c *gin.Context)

@Summary Check for Containerlab Updates @Description Checks if a newer version of containerlab is available by running 'clab version check'. @Tags Version @Security BearerAuth @Produce json @Success 200 {object} models.VersionCheckResponse "Result of the version check" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/version/check [get]

func CreateCAHandler

func CreateCAHandler(c *gin.Context)

@Summary Create Certificate Authority (CA) @Description Creates a CA certificate and private key. Requires SUPERUSER privileges. Files are stored in the user's ~/.clab/certs/<ca_name>/ directory on the server. @Tags Tools - Certificates @Security BearerAuth @Accept json @Produce json @Param ca_request body models.CACreateRequest true "CA Generation Parameters" @Success 200 {object} models.CertResponse "CA created successfully" @Failure 400 {object} models.ErrorResponse "Invalid input parameters" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 403 {object} models.ErrorResponse "Forbidden (User is not a superuser)" @Failure 500 {object} models.ErrorResponse "Internal server error (filesystem, clab execution)" @Router /api/v1/tools/certs/ca [post]

func CreateVethHandler

func CreateVethHandler(c *gin.Context)

@Summary Create vEth Pair @Description Creates a virtual Ethernet (vEth) pair between two specified endpoints (container, host, bridge, ovs-bridge). Requires SUPERUSER privileges. @Tags Tools - vEth @Security BearerAuth @Accept json @Produce json @Param veth_request body models.VethCreateRequest true "vEth Creation Parameters" @Success 200 {object} models.GenericSuccessResponse "vEth pair created successfully" @Failure 400 {object} models.ErrorResponse "Invalid input parameters (endpoints, MTU)" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 403 {object} models.ErrorResponse "Forbidden (User is not a superuser)" @Failure 500 {object} models.ErrorResponse "Internal server error (clab execution failed)" @Router /api/v1/tools/veth [post]

func CreateVxlanHandler

func CreateVxlanHandler(c *gin.Context)

@Summary Create VxLAN Tunnel @Description Creates a VxLAN tunnel interface and sets up tc rules for traffic redirection. Requires SUPERUSER privileges. @Tags Tools - VxLAN @Security BearerAuth @Accept json @Produce json @Param vxlan_request body models.VxlanCreateRequest true "VxLAN Creation Parameters" @Success 200 {object} models.GenericSuccessResponse "VxLAN tunnel created successfully" @Failure 400 {object} models.ErrorResponse "Invalid input parameters (remote, link, id, port, etc.)" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 403 {object} models.ErrorResponse "Forbidden (User is not a superuser)" @Failure 500 {object} models.ErrorResponse "Internal server error (clab execution failed)" @Router /api/v1/tools/vxlan [post]

func DeleteVxlanHandler

func DeleteVxlanHandler(c *gin.Context)

@Summary Delete VxLAN Tunnels by Prefix @Description Deletes VxLAN tunnel interfaces matching a given prefix (default: 'vx-'). Requires SUPERUSER privileges. @Tags Tools - VxLAN @Security BearerAuth @Produce json @Param prefix query string false "Prefix of VxLAN interfaces to delete" default(vx-) example="vx-" @Success 200 {object} models.GenericSuccessResponse "VxLAN tunnels deleted successfully" @Failure 400 {object} models.ErrorResponse "Invalid prefix format" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 403 {object} models.ErrorResponse "Forbidden (User is not a superuser)" @Failure 500 {object} models.ErrorResponse "Internal server error (clab execution failed)" @Router /api/v1/tools/vxlan [delete]

func DeployLabArchiveHandler

func DeployLabArchiveHandler(c *gin.Context)

@Summary Deploy Lab from Archive @Description Deploys a containerlab topology provided as a .zip or .tar.gz archive. The archive must contain the .clab.yml file and any necessary bind-mount files/directories. The lab will be owned by the authenticated user. @Description The lab name is taken from the 'labName' query parameter. The archive is extracted to the user's ~/.clab/<labName>/ directory. @Description Deployment is DENIED if a lab with the target name already exists, UNLESS 'reconfigure=true' is specified AND the authenticated user owns the existing lab. @Tags Labs @Security BearerAuth @Accept multipart/form-data @Produce json @Param labArchive formData file true "Lab archive (.zip or .tar.gz) containing topology file and bind mounts." @Param labName query string true "Name for the lab. This determines the extraction directory (~/.clab/<labName>)." example="my-archived-lab" @Param reconfigure query boolean false "Allow overwriting an existing lab IF owned by the user (default: false)." example="true" @Param maxWorkers query int false "Limit concurrent workers (0 or omit for default)." example="4" @Param exportTemplate query string false "Custom Go template file for topology data export ('__full' for full export)." example="__full" @Param nodeFilter query string false "Comma-separated list of node names to deploy." example="srl1,router2" @Param skipPostDeploy query boolean false "Skip post-deploy actions defined for nodes (default: false)." example="false" @Param skipLabdirAcl query boolean false "Skip setting extended ACLs on lab directory (default: false)." example="true" @Success 200 {object} object "Raw JSON output from 'clab deploy' (or plain text on error)" @Failure 400 {object} models.ErrorResponse "Invalid input (e.g., missing archive, invalid labName, invalid archive format, missing topology file in archive)" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 403 {object} models.ErrorResponse "Forbidden (Attempting to reconfigure a lab owned by another user)" @Failure 409 {object} models.ErrorResponse "Conflict (Lab already exists and reconfigure=false or not specified)" @Failure 500 {object} models.ErrorResponse "Internal server error (e.g., file system errors, extraction errors, clab execution failed)" @Router /api/v1/labs/archive [post]

func DeployLabHandler

func DeployLabHandler(c *gin.Context)

@Summary Deploy Lab @Description Deploys a containerlab topology. Requires EITHER 'topologyContent' OR 'topologySourceUrl' in the request body, but not both. The lab will be owned by the authenticated user. @Description Deployment is DENIED if a lab with the target name already exists, UNLESS 'reconfigure=true' is specified AND the authenticated user owns the existing lab. @Description Optional deployment flags are provided as query parameters. @Tags Labs @Security BearerAuth @Accept json @Produce json @Param deploy_request body models.DeployRequest true "Deployment Source: Provide 'topologyContent' OR 'topologySourceUrl'." @Param labNameOverride query string false "Overrides the 'name' field within the topology or inferred from URL." example="my-specific-lab-run" @Param reconfigure query boolean false "Allow overwriting an existing lab IF owned by the user (default: false)." example="true" @Param maxWorkers query int false "Limit concurrent workers (0 or omit for default)." example="4" @Param exportTemplate query string false "Custom Go template file for topology data export ('__full' for full export)." example="__full" @Param nodeFilter query string false "Comma-separated list of node names to deploy." example="srl1,router2" @Param skipPostDeploy query boolean false "Skip post-deploy actions defined for nodes (default: false)." example="false" @Param skipLabdirAcl query boolean false "Skip setting extended ACLs on lab directory (default: false)." example="true" @Success 200 {object} object "Raw JSON output from 'clab deploy' (or plain text on error)" @Failure 400 {object} models.ErrorResponse "Invalid input (e.g., missing/both content/URL, invalid flags/params, invalid topology name)" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 403 {object} models.ErrorResponse "Forbidden (Attempting to reconfigure a lab owned by another user)" @Failure 409 {object} models.ErrorResponse "Conflict (Lab already exists and reconfigure=false or not specified)" @Failure 500 {object} models.ErrorResponse "Internal server error (e.g., file system errors, clab execution failed)" @Router /api/v1/labs [post]

func DestroyLabHandler

func DestroyLabHandler(c *gin.Context)

@Summary Destroy Lab @Description Destroys a lab by name, checking ownership via 'owner' field from clab inspect. @Description Optionally cleans up the lab directory (~/.clab/<labname>) if 'cleanup=true' is passed and the API deployed it from content. @Tags Labs @Security BearerAuth @Produce json @Param labName path string true "Name of the lab to destroy" example="my-test-lab" @Param cleanup query boolean false "Remove lab directory (~/.clab/<labname>) after destroy (default: false)" example="true" @Param graceful query boolean false "Attempt graceful shutdown of containers (default: false)" example="true" @Param keepMgmtNet query boolean false "Keep the management network (default: false)" example="true" @Param nodeFilter query string false "Destroy only specific nodes (comma-separated)" example="srl1,srl2" @Success 200 {object} models.GenericSuccessResponse @Failure 400 {object} models.ErrorResponse "Invalid lab name or node filter" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 404 {object} models.ErrorResponse "Lab not found or not owned by user" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName} [delete]

func DisableTxOffloadHandler

func DisableTxOffloadHandler(c *gin.Context)

@Summary Disable TX Checksum Offload @Description Disables TX checksum offload for the eth0 interface of a specific container. Requires SUPERUSER privileges. @Tags Tools @Security BearerAuth @Accept json @Produce json @Param tx_request body models.DisableTxOffloadRequest true "Container Name" @Success 200 {object} models.GenericSuccessResponse "Offload disabled successfully" @Failure 400 {object} models.ErrorResponse "Invalid input" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 403 {object} models.ErrorResponse "Forbidden (User is not a superuser)" @Failure 404 {object} models.ErrorResponse "Container not found" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/tools/disable-tx-offload [post]

func ExecCommandHandler

func ExecCommandHandler(c *gin.Context)

@Summary Execute Command in Lab @Description Executes a command on nodes within a specific lab. Checks ownership. Supports filtering by a single node name. @Tags Labs @Security BearerAuth @Accept json @Produce json @Param labName path string true "Name of the lab where the command should be executed" example="my-test-lab" @Param nodeFilter query string false "Execute only on this specific node (must match container name, e.g., clab-my-test-lab-srl1)" example="clab-my-test-lab-srl1" @Param format query string false "Output format ('plain' or 'json'). Default is 'json'." example="json" @Param exec_request body models.ExecRequest true "Command to execute" @Success 200 {object} models.ExecResponse "Structured output (if format=json)" @Success 200 {string} string "Plain text output (if format=plain)" @Failure 400 {object} models.ErrorResponse "Invalid input (lab name, node filter, format, request body)" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 404 {object} models.ErrorResponse "Lab not found or not owned by user" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName}/exec [post]

func GenerateTopologyHandler

func GenerateTopologyHandler(c *gin.Context)

@Summary Generate Topology @Description Generates a containerlab topology file based on CLOS definitions. Optionally deploys it, setting the owner to the authenticated user. @Description Deployment is DENIED if a lab with the target name already exists. @Description The 'images' and 'licenses' fields expect a map where the key is the node 'kind' and the value is the corresponding image or license path (e.g., {"nokia_srlinux": "ghcr.io/..."}). @Description If Deploy=true, the topology is saved to the user's ~/.clab/<labName>/ directory before deployment, and the 'outputFile' field is ignored. @Description If Deploy=false and 'outputFile' is empty, YAML is returned directly. @Description If Deploy=false and 'outputFile' is set, the file is saved to that path on the server (requires API server write permissions). @Tags Topology Generation @Security BearerAuth @Accept json @Produce json @Param generate_request body models.GenerateRequest true "Topology generation parameters. Note: 'images'/'licenses' format is { \"kind\": \"path\" }." example({ "defaultKind": "nokia_srlinux", "deploy": true, "groupPrefix": "clos-tier", "images": { "nokia_srlinux": "ghcr.io/nokia/srlinux:latest" }, "ipv4Subnet": "172.50.20.0/24", "licenses": {}, "ipv6Subnet": "2001:172:20:20::/64", "managementNetwork": "clos-mgmt", "maxWorkers": 0, "name": "3-tier-clos", "nodePrefix": "clos-node", "outputFile": "", "tiers": [ { "count": 4, "kind": "nokia_srlinux", "type": "ixrd3" } ] }) // Example structure @Success 200 {object} models.GenerateResponse "Generation successful (YAML or deploy output)" @Failure 400 {object} models.ErrorResponse "Invalid input parameters" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 409 {object} models.ErrorResponse "Conflict (Lab already exists and Deploy=true)" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/generate [post]

func GetVersionHandler

func GetVersionHandler(c *gin.Context)

@Summary Get Containerlab Version @Description Retrieves the installed containerlab version information by running 'clab version'. @Tags Version @Security BearerAuth @Produce json @Success 200 {object} models.VersionResponse "Containerlab version details" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/version [get]

func InspectInterfacesHandler

func InspectInterfacesHandler(c *gin.Context)

@Summary List Lab Interfaces @Description Get network interface details for nodes in a specific lab, checking ownership. @Tags Labs @Security BearerAuth @Produce json @Param labName path string true "Name of the lab" example="my-test-lab" @Param node query string false "Filter interfaces for a specific node name" example="clab-my-test-lab-srl1" @Success 200 {object} models.ClabInspectInterfacesOutput "JSON output from 'clab inspect interfaces'" @Failure 400 {object} models.ErrorResponse "Invalid lab name or node name" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 404 {object} models.ErrorResponse "Lab not found or not owned by user" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName}/interfaces [get]

func InspectLabHandler

func InspectLabHandler(c *gin.Context)

@Summary Inspect Lab @Description Get details about a specific running lab, checking ownership via 'owner' field. Supports '--details'. @Tags Labs @Security BearerAuth @Produce json @Param labName path string true "Name of the lab to inspect" example="my-test-lab" @Param details query boolean false "Include full container details (like docker inspect)" example="true" @Success 200 {object} models.ClabInspectOutput "Standard JSON output from 'clab inspect'" @Success 200 {object} object "Raw JSON output if 'details=true' is used (structure matches 'docker inspect')" @Failure 400 {object} models.ErrorResponse "Invalid lab name" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 404 {object} models.ErrorResponse "Lab not found or not owned by user" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName} [get]

func ListLabsHandler

func ListLabsHandler(c *gin.Context)

@Summary List All Labs @Description Get details about all running labs, filtered by the 'owner' field matching the authenticated user (unless user is in SUPERUSER_GROUP). @Tags Labs @Security BearerAuth @Produce json @Success 200 {object} models.ClabInspectOutput "Filtered JSON output from 'clab inspect --all'" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs [get]

func LoginHandler

func LoginHandler(c *gin.Context)

LoginHandler - Handles user authentication @Summary Login @Description Authenticate user and return JWT token @Tags Auth @Accept json @Produce json @Param credentials body models.LoginRequest true "User Credentials" @Success 200 {object} models.LoginResponse @Failure 400 {object} models.ErrorResponse "Invalid input" @Failure 401 {object} models.ErrorResponse "Invalid credentials" @Failure 500 {object} models.ErrorResponse "Internal server error (PAM config?)" @Router /login [post]

func RedeployLabHandler

func RedeployLabHandler(c *gin.Context)

@Summary Redeploy Lab @Description Redeploys a lab by name, effectively running destroy and then deploy. Checks ownership. @Description Uses the original topology file path found during inspection. @Tags Labs @Security BearerAuth @Accept json @Produce json @Param labName path string true "Name of the lab to redeploy" example="my-test-lab" @Param redeploy_request body models.RedeployRequest true "Redeployment options" @Success 200 {object} object "Raw JSON output from 'clab redeploy' (or plain text on error)" @Failure 400 {object} models.ErrorResponse "Invalid lab name or options" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 404 {object} models.ErrorResponse "Lab not found or not owned by user" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName} [put]

func ResetNetemHandler

func ResetNetemHandler(c *gin.Context)

@Summary Reset Network Emulation @Description Removes all network impairments from a specific interface of a node (container) within a lab. Checks container ownership. @Tags Tools - Netem @Security BearerAuth @Produce json @Param labName path string true "Name of the lab" example="my-lab" @Param nodeName path string true "Full name of the container (node)" example="clab-my-lab-srl1" // CLARIFIED @Param interfaceName path string true "Name of the interface within the container" example="eth1" @Success 200 {object} models.GenericSuccessResponse "Impairments reset successfully" @Failure 400 {object} models.ErrorResponse "Invalid input (lab/container/interface name)" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 404 {object} models.ErrorResponse "Lab, container (node), or interface not found / not owned" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName}/nodes/{nodeName}/interfaces/{interfaceName}/netem [delete] // KEEP /nodes/{nodeName}

func SaveLabConfigHandler

func SaveLabConfigHandler(c *gin.Context)

@Summary Save Lab Configuration @Description Saves the running configuration for nodes in a specific lab. Checks ownership. @Tags Labs @Security BearerAuth @Produce json @Param labName path string true "Name of the lab to save configuration for" example="my-test-lab" @Param nodeFilter query string false "Save config only for specific nodes (comma-separated)" example="srl1,srl2" @Success 200 {object} models.SaveConfigResponse "Configuration save command executed, includes detailed output." @Failure 400 {object} models.ErrorResponse "Invalid lab name or node filter" @Failure 401 {object} models.ErrorResponse "Unauthorized" @Failure 404 {object} models.ErrorResponse "Lab not found or not owned by user" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName}/save [post]

func SetNetemHandler

func SetNetemHandler(c *gin.Context)

@Summary Set Network Emulation @Description Sets network impairments (delay, jitter, loss, rate, corruption) on a specific interface of a node (container) within a lab. Checks container ownership. @Tags Tools - Netem @Security BearerAuth @Accept json @Produce json @Param labName path string true "Name of the lab" example="my-lab" @Param nodeName path string true "Full name of the container (node)" example="clab-my-lab-srl1" // CLARIFIED example/description @Param interfaceName path string true "Name of the interface within the container" example="eth1" @Param netem_params body models.NetemSetRequest true "Network Emulation Parameters" @Success 200 {object} models.GenericSuccessResponse "Impairments set successfully" @Failure 400 {object} models.ErrorResponse "Invalid input (lab/container/interface name, netem params)" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 404 {object} models.ErrorResponse "Lab, container (node), or interface not found / not owned" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName}/nodes/{nodeName}/interfaces/{interfaceName}/netem [put] // KEEP /nodes/{nodeName}

func SetupRoutes

func SetupRoutes(router *gin.Engine)

func ShowNetemHandler

func ShowNetemHandler(c *gin.Context)

@Summary Show Network Emulation @Description Shows network impairments for all interfaces on a specific node (container) within a lab. Checks container ownership. @Tags Tools - Netem @Security BearerAuth @Produce json @Param labName path string true "Name of the lab" example="my-lab" @Param nodeName path string true "Full name of the container (node)" example="clab-my-lab-srl1" // CLARIFIED @Success 200 {object} models.NetemShowResponse "Current network emulation parameters" @Failure 400 {object} models.ErrorResponse "Invalid input (lab/container name)" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 404 {object} models.ErrorResponse "Lab or container (node) not found / not owned" @Failure 500 {object} models.ErrorResponse "Internal server error or clab execution failed" @Router /api/v1/labs/{labName}/nodes/{nodeName}/netem [get] // KEEP /nodes/{nodeName}

func SignCertHandler

func SignCertHandler(c *gin.Context)

@Summary Sign Certificate @Description Creates a certificate/key and signs it with a previously generated CA. Requires SUPERUSER privileges. Files are stored in the user's ~/.clab/certs/<ca_name>/ directory. @Tags Tools - Certificates @Security BearerAuth @Accept json @Produce json @Param sign_request body models.CertSignRequest true "Certificate Signing Parameters" @Success 200 {object} models.CertResponse "Certificate signed successfully" @Failure 400 {object} models.ErrorResponse "Invalid input parameters (name, hosts, CA name, etc.)" @Failure 401 {object} models.ErrorResponse "Unauthorized (JWT)" @Failure 403 {object} models.ErrorResponse "Forbidden (User is not a superuser)" @Failure 404 {object} models.ErrorResponse "Specified CA not found" @Failure 500 {object} models.ErrorResponse "Internal server error (filesystem, clab execution)" @Router /api/v1/tools/certs/sign [post]

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL