What can I help you with?
NVIDIA NVOS User Manual for NVLink Switches v25.02.1884

On This Page

NVUE OpenAPI

This section provides information about using the NVUE API.

In addition to the CLI, NVUE supports a REST API. Instead of accessing NVOS using SSH, you can interact with the switch using an HTTP client, such as cURL or a web browser.

The nued service provides access to the NVUE REST API. NVOS exposes the HTTP endpoint internally, which makes the NVUE REST API accessible locally within the NVOS switch. The NVUE CLI also communicates with the nvued service using internal APIs. To provide external access to the NVUE REST API, NVOS uses an HTTP reverse proxy server, and supports HTTPS and TLS connections from external REST API clients.

The following illustration shows the NVUE REST API architecture and illustrates how NVOS forwards the requests internally.

The NVUE REST API supports the following methods:

  • The GET method displays configuration and operational data, and is equivalent to the nv show commands.

  • The POST method creates and submits operations. You typically use this method for nv action commands and for the nv config command to create revisions.

  • The PATCH method replaces or unsets a configuration. You use this method for the nv set and nv config apply commands. You can either perform:

    • A targeted configuration patch to make a configuration change, where you run a specific NVUE REST API targeted at a particular OpenAPI end-point URI. Based on the NVUE schema definition, you need to direct the PATCH REST API request at a particular endpoint (for example, /nvue_v1/interface/<interface-id>/link/mtu) and provide the payload that conforms to the schema. With a targeted configuration patch, you can control individual resources.

    • A root patch, where you run the NVUE PATCH API on the root node of the schema so that a single PATCH operation can change one, some, or the entire configuration in a single payload. The payload of the PATCH method must be aware of the entire NVUE object model schema because you make the configuration changes relative to the root node /nvue_v1. You typically perform a root patch to push all configurations to the switch in bulk; for example, if you use an SDN controller or a network management system to push the entire switch configuration every time you need to make a change, regardless of how small or large. A root patch can also make configuration changes with fewer round trips to the switch.

    • The input payload in a PATCH request can have either a set or unset json object for the same resource, but not both. The order in which the API executes the set and unset objects is not deterministic and not supported.

  • The DELETE method deletes a configuration and is equivalent to the nv unset commands.

The NVUE REST API supports HTTP basic authentication, and the same underlying authentication methods for username and password that the NVUE CLI supports. User accounts work the same on both the API and the CLI.

Certificates

NVOS includes a self-signed certificate and private key to use on the server so that it works out of the box. The switch generates the self-signed certificate and private key when it boots for the first time. The X.509 certificate with the public key is in /etc/ssl/certs/nvue.pem and the corresponding private key is in /etc/ssl/private/nvue.key.

NVIDIA recommends you use your own certificates and keys. For the steps to generate self-signed certificates and keys, refer to the Ubuntu Certificates and Security documentation.

NVOS lets you manage CA certificates (such as DigiCert or Verisign) and entity (end-point) certificates. Both a CA certificate and an entity certificate can contain a chain of certificates.

You can import certificates onto the switch (fetch certificates from an external source), set which certificate you want to use for the NVUE REST API, and show information about a certificate, such as the serial number, and the date and time during which the certificate is valid.

Import a Certificate

Note
  • You can import a maximum of 25 entity certificates and a maximum of 25 CA certificates.

  • The certificate you import contains sensitive private key information. NVIDIA recommends that you use a secure transport such as SFTP, SCP, or HTTPS.

  • To import an entity certificate, run an nv action import system security certificate <cert-id>command.

  • To import a CA certificate, run an nv action import system security ca-certificate <cert-id> command.

If the certificate is passphrase protected, you need to include the passphrase.

You must provide a certificate ID (<cert-id>) to uniquely identify the certificate you import.

The following example imports a CA certificate with a public key and calls the certificate tls-cert-1. The certificate is passphrase protected with mypassphrase. The public key is a Base64 ASCII encoded PEM string.

Copy
Copied!
            

nvos@switch:~$ nv action import system security ca-certificate tls-cert-1 passphrase mypassphrase data "<public-key>"

The following example imports an entity certificate bundle and calls the certificate tls-cert-1. The certificate bundle is passphrase protected with mypassphrase.

A certificate bundle must be in .PFX or .P12 format.

Copy
Copied!
            

nvos@switch:~$ nv action import system security certificate tls-cert-1 passphrase mypassphrase uri-bundle scp://user@pass:1.2.3.4:/opt/certs/cert.p12 

The following example imports an entity certificate with the public key URI scp://user@pass:1.2.3.4 and private key URI scp://user@pass:1.2.3.4, and calls the certificate tls-cert-1. The certificate is not passphrase protected.

A CA certificate must be in .pem, .p7a, or .p7c format.

Copy
Copied!
            

nvos@switch:~$ nv action import system security certificate tls-cert-1 uri-public-key scp://user@pass:1.2.3.4 uri-private-key scp://user@pass:1.2.3.4


Set the Certificate to Use

You can configure the NVUE REST API to use a specific certificate.

The following example configures the API to use the certificate tls-cert-1:

Copy
Copied!
            

nvos@switch:~$ nv set system api certificate tls-cert-1  nvos@switch:~$ nv config apply

The following example configures the API to use the self-signed certificate:

Copy
Copied!
            

nvos@switch:~$ nv set system api certificate self-signed nvos@switch:~$ nv config apply

To unset the certificate to use with the NVUE REST API:

Copy
Copied!
            

nvos@switch:~$ nv unset system api certificate tls-cert-1


Delete Certificates

  • To delete an entity certificate and the key data stored on the switch, run the nv action delete system security certificate <cert-id> command.

  • To delete a CA certificate and the key data stored on the switch, run the nv action delete system security ca-certificate <cert-id> command.

The following command deletes the certificate tls-cert-1:

Copy
Copied!
            

nvos@switch:~$ nv action delete system security certificate tls-cert-1 


Show Certificate Information

  • To show all the entity certificates on the switch, run the nv show system security certificate command.

  • To show all the CA certificates on the switch, run the nv show system security ca-certificate command.

The following example shows all the entity certificates on the switch:

Copy
Copied!
            

nvos@switch:~$ nv show system security certificate

  • To show the applications that are using a specific entity certificate, run the nv show system security certificate <cert-id> installed command.

  • To show the applications that are using a specific CA certificate, run the nv show system security ca-certificate <cert-id> installed command.

The following example shows the applications that are using a specific entity certificate.

Copy
Copied!
            

nvos@switch:~$ nv show system security certificate tls-cert-1 installed

  • To show detailed information about a specific entity certificate, run the nv show system security certificate <cert-id> dump command.

  • To show detailed information about a specific CA certificate, run the nv show system security ca-certificate <cert-id> dump command.

The following example shows detailed information about the CA certificate tls-cert-1:

Copy
Copied!
            

nvos@switch:~$ nv show system security ca-certificate tls-cert-1 dump

Control Plane ACLs

You can secure the API by configuring:

This example shows how to create ACLs to allow users from the management subnet and the local switch to communicate with the switch using REST APIs, and restrict all other access.

Copy
Copied!
            

nvos@switch:~$ nv set acl API-PROTECT type ipv4   nvos@switch:~$ nv set acl API-PROTECT rule 10 action permit nvos@switch:~$ nv set acl API-PROTECT rule 10 match ip .protocol tcp .dest-port 8765 .source-ip 192.168.200.0/24  nvos@switch:~$ nv set acl API-PROTECT rule 10 remark "Allow the Management Subnet to talk to API"   nvos@switch:~$ nv set acl API-PROTECT rule 20 action permit nvos@switch:~$ nv set acl API-PROTECT rule 20 match ip .protocol tcp .dest-port 8765 .source-ip 127.0.0.1  nvos@switch:~$ nv set acl API-PROTECT rule 20 remark "Allow the local switch to talk to the API"   nvos@switch:~$ nv set acl API-PROTECT rule 30 action deny nvos@switch:~$ nv set acl API-PROTECT rule 30 match ip .protocol tcp .dest-port 8765  nvos@switch:~$ nv set acl API-PROTECT rule 30 remark "Block everyone else from talking to the API"   nvos@switch:~$ nv set system control-plane acl API-PROTECT inbound


The NVUE object model supports most features on the NVOS switch. The following list shows the supported objects. The NVUE API supports more objects within each of these objects. You can find a full listing of the supported API endpoints here.

High-level Objects

Description

acl

Access control lists.

interface

Interface configuration.

platform

Platform configuration, such as hardware and software components.

system

Global system settings, such as system login messages, switch reboot history, syslog, ntp etc..

vrf

Get VRF.

ib

IB Devices.

The NVUE CLI and the REST API are equivalent in functionality; you can run all management operations from the REST API or from the CLI. The NVUE object model drives both the REST API and the CLI management operations. All operations are consistent; for example, the CLI nv show commands reflect any PATCH operation (create and update) you run through the REST API.

NVUE follows a declarative model, removing context-specific commands and settings. The structure of NVUE is like a big tree that represents the entire state of a NVOS instance. At the base of the tree are high level branches representing objects, such as system and interface. Under each of these branches are more branches. As you navigate through the tree, you gain a more specific context. At the leaves of the tree are actual attributes, represented as key-value pairs. The path through the tree is similar to a filesystem path.

NVOS enables the NVUE REST API by default. To disable the NVUE REST API, run the nv set system api state disabled command.

Note

To use the NVUE REST API in NVOS, you must change the password for the admin user; otherwise you see 403 responses when you run commands.

API Port and Listening Address

This section shows how to:

  • Set the NVUE REST API port. If you do not set a port, NVOS uses the default port 8765.

  • Specify the NVUE REST API listening address; you can specify an IPv4 address, IPv6 address, or localhost. If you do not specify a listening address, NGINX listens on all addresses for the target port.

NVUE Commands

The following example sets the port to 8888:

Copy
Copied!
            

nvos@switch:~$ nv set system api port 8888  nvos@switch:~$ nv config apply

You can listen on multiple interfaces by specifying different listening addresses:

Copy
Copied!
            

nvos@switch:~$ nv set system api listening-address 10.10.10.1  nvos@switch:~$ nv set system api listening-address 10.10.20.1  nvos@switch:~$ nv config apply

The following example configures the listening address on eth0, which has IP address 172.0.24.0 and uses the management VRF by default:

Copy
Copied!
            

nvos@switch:~$ nv set system api listening-address 172.0.24.0  nvos@switch:~$ nv config apply

Curl Command

The following example sets the port to 8888:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k --request PATCH https://localhost:8765/nvue_v1/system/api?rev=2 -H 'Content-Type:application/json' -d '{"port": 8888 }'

You can listen on multiple interfaces by specifying different listening addresses. The following example sets localhost, interface address 10.10.10.1, and 10.10.20.1 as listen-addresses.

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k --request PATCH https://localhost:8765/nvue_v1/system/api/listening-address?rev=2 -H 'Content-Type:application/json' -d '{ "localhost": {}, "10.10.10.1": {}, "10.10.20.1": {}}'

The following example configures the listening address on eth0, which has IP address 172.0.24.0 and uses the management VRF by default:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k --request PATCH https://localhost:8765/nvue_v1/system/api/listening-address?rev=2 -H 'Content-Type:application/json' -d '{"172.0.24.0": {}}'

Show NVUE REST API Information

To show REST API port configuration, state (enabled or disabled), certificate, listening address, and connection information:

NVUE Commands

Run the nv show system api command:

Copy
Copied!
            

nvos@switch:~$ nv show system api operational applied ------------------- ----------- ----------- state enabled enabled port 443 443 certificate self-signed self-signed [listening-address] any connections active 1 accepted 2 handled 2 requests 2 reading 0 writing 1 waiting 0

To show connection information only, run the nv show system api connections command:

Copy
Copied!
            

nvos@switch:~$ nv show system api connections operational -------- ----------- active 2 accepted 8 handled 8 requests 8 reading 0 writing 2 waiting 0

To show the configured listening address, run the nv show system api listening-address command:

Copy
Copied!
            

nvos@switch:~$ nv show system api listening-address --------- localhost

To show all the certificates installed on the switch, run the nv show system security certificate command. To show information about a specific certificate, such as the serial number and how long the certificate is valid, run the nv show system security certificate <certificate> command:

Copy
Copied!
            

nvos@switch:~$ nv show system security certificate tls-cert-1  operational applied ------------- ------------------------- ------- installed app TLS serial-number 67:03:3B:B4:6E:35:D3 valid-from 2023-02-14T00:35:18+00:00  valid-to 2033-02-11T00:35:18+00:00 

Curl Command

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k --request GET https://localhost:443/nvue_v1/system/api?rev=2 -H "accept: application/json" { "certificate": "self-signed", "listening-address": { "10.10.10.1": {}, "10.10.20.1": {}, "172.0.24.0": {}, "localhost": {} }, "port": 8888, "state": "enabled" }

To show the configured listening address:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k --request GET https://localhost:443/nvue_v1/system/api/listening-address?rev=2 -H "accept: application/json" { "10.10.10.1": {}, "10.10.20.1": {} }

To show the certificates on the switch:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k --request GET https://localhost:443/nvue_v1/system/api/certificate?rev=2 -H "accept: application/json" { "tls-cert-1": {}, "tls-cert-2": {} }

To show information about a specific certificate, such as the serial number and how long the certificate is valid:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k --request GET https://localhost:443/nvue_v1/system/api/certificate/tls-cert-1?rev=2 -H "accept: application/json" { "serial-number": "67:03:3B:B4:6E:35:D3", "valid-from": "2023-02-14T00:35:18+00:00", "valid-to": "2033-02-11T00:35:18+00:00" }


Run cURL Commands

You can run the cURL commands from the command line. Use the username and password for the switch. For example:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' --insecure https://127.0.0.1:443/nvue_v1/interface { "eth0": { "ip": { "address": { "192.168.200.12/24": {} } }, "link": { "mtu": 1500, "state": { "up": {} }, "stats": { "carrier-transitions": 2, "in-bytes": 184151, "in-drops": 0, "in-errors": 0, "in-pkts": 2371, "out-bytes": 117506, "out-drops": 0, "out-errors": 0, "out-pkts": 762 } ...


The following examples show the primary API uses cases.

View a Configuration

Use the following example to obtain the current applied configuration on the switch. Change the rev argument to view any revision. Possible options for the rev argument include startup, pending, operational, and applied.

Curl Command

Copy
Copied!
            

nvos@switch:~$ curl -k -u 'admin:admin' -X GET "https://127.0.0.1:443/nvue_v1/?rev=applied&filled=false" "interface": { "eth0": { "acl": { "ACL_MGMT_INBOUND_CP_DEFAULT": { "inbound": { "control-plane": {} } }, "ACL_MGMT_INBOUND_CP_DEFAULT_IPV6": { "inbound": { "control-plane": {} } }, "ACL_MGMT_INBOUND_DEFAULT": { "inbound": {} }, "ACL_MGMT_INBOUND_DEFAULT_IPV6": { "inbound": {} }, "ACL_MGMT_OUTBOUND_CP_DEFAULT": { "outbound": { "control-plane": {} } }, "ACL_MGMT_OUTBOUND_CP_DEFAULT_IPV6": { "outbound": { "control-plane": {} } } }, "type": "eth" }, ...

Python Code

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   if __name__ == "__main__": r = requests.get(url=nvue_end_point + "/?rev=applied&filled=false", auth=auth, verify=False) print("=======Current Applied Revision=======") print(json.dumps(r.json(), indent=2))

NVUE CLI

Copy
Copied!
            

nvos@switch:~$ nv config show - set: fae: system: events: table-size: 600 interface: eth0-1: acl: ACL_MGMT_INBOUND_CP_DEFAULT: inbound: control-plane: {} ACL_MGMT_INBOUND_CP_DEFAULT_IPV6: inbound: control-plane: {} ACL_MGMT_INBOUND_DEFAULT: inbound: {} ACL_MGMT_INBOUND_DEFAULT_IPV6: inbound: {} ACL_MGMT_OUTBOUND_CP_DEFAULT: outbound: control-plane: {} ACL_MGMT_OUTBOUND_CP_DEFAULT_IPV6: outbound: control-plane: {} type: eth ...


Replace an Entire Configuration

To replace an entire configuration:

  1. Create a new revision ID with a POST:

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' --insecure -X POST https://127.0.0.1:443/nvue_v1/revision {  "1": { "state": "pending", "transition": { "issue": {}, "progress": "" } } }

  2. Record the revision ID. In the above example, the revision ID is "1".

  3. Do a root patch to delete the whole configuration.

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -d '{}' -H 'Content-Type: application/json' -k -X DELETE https://127.0.0.1:443/nvue_v1/?rev=1 {}

  4. Do a root patch to update the switch with the new configuration.

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -d '{ "system": { "hostname": "switch01" }, "interface": { "eth0": { "ip": { "address": { "192.168.200.6/24": {} }, }, "type": "eth" }, } }' -H 'Content-Type: application/json' -k -X PATCH https://127.0.0.1:443/nvue_v1/?rev=1 {}

  5. Apply the changes with a PATCH to the revision changeset.

    Curl Command

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -H 'Content-Type:application/json' -d '{"state": "apply", "auto-prompt": {"ays": "ays_yes"}}' -k -X PATCH https://127.0.0.1:443/nvue_v1/revision/1 { "state": "apply", "transition": { "issue": {}, "progress": "" } }

    NVUE CLI

    Copy
    Copied!
                

    nvos@switch:~$ nv config apply

  6. Review the status of the apply and the configuration:

    Curl Command

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -k -X GET https://127.0.0.1:443/nvue_v1/revision/1 { "state": "applied", "transition": { "issue": {}, "progress": "" } }

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' --insecure https://127.0.0.1:443/nvue_v1/system { "build": "NVOS Debian GNU/Linux 11 (bullseye)", "date-time": "2024-08-05 07:42:28", "health-status": "OK", "hostname": "switch", "platform": "x86_64-nvidia_q3200_ra-r0", "product-name": "nvos", "product-release": "25.02.0936-010", "status": "System is ready", "swap-memory": "0 MB used / 0 MB free / 0 MB total", "system-memory": "3250 MB used / 12564 MB free / 15814 MB total", "timezone": "Asia/Jerusalem", "uptime": 11659, "version": { "build-date": "Fri Jul 19 14:24:17 UTC 2024", "image": "nvos-25.02.0936-010", "kernel": "5.10.0-23-2-amd64", "onie": "2023.11-5.3.0012-rc6-115200-dev" } }

    Python Code

    Copy
    Copied!
                

    #!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5  # In seconds POLL_APPLIED = 1  # in seconds RETRIES = 10   def print_request(r: requests.Request):     print("=======Request=======")     print("URL:", r.url)     print("Headers:", r.headers)     print("Body:", r.body)   def print_response(r: requests.Response):     print("=======Response=======")     print("Headers:", r.headers)     print("Body:", json.dumps(r.json(), indent=2))   def create_nvue_changest():     r = requests.post(url=nvue_end_point + "/revision",                       auth=auth,                       verify=False)     print_request(r.request)     print_response(r)     response = r.json()     changeset = response.popitem()[0]     return changeset   def apply_nvue_changeset(changeset):     apply_payload = {"state": "apply", "auto-prompt": {"ays": "ays_yes"}}     url = nvue_end_point + "/revision/" + requests.utils.quote(changeset,                                                                safe="")     r = requests.patch(url=url,                        auth=auth,                        verify=False,                        data=json.dumps(apply_payload),                        headers=mime_header)     print_request(r.request)     print_response(r)   def is_config_applied(changeset) -> bool:     # Check if the configuration was indeed applied     global RETRIES     global POLL_APPLIED     retries = RETRIES     while retries > 0:         r = requests.get(url=nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe=""),                          auth=auth,                          verify=False)         response = r.json()         print(response)         if response["state"] == "applied":             return True         retries -= 1         time.sleep(POLL_APPLIED)       return False   def apply_new_config(path,payload):     # Create a new revision ID     changeset = create_nvue_changest()     print("Using NVUE Changeset: '{}'".format(changeset))       # Delete existing configuration     query_string = {"rev": changeset}     r = requests.delete(url=nvue_end_point + path,                        auth=auth,                        verify=False,                        params=query_string,                        headers=mime_header)     print_request(r.request)     print_response(r)       # Patch the new configuration          query_string = {"rev": changeset}     r = requests.patch(url=nvue_end_point + path,                        auth=auth,                        verify=False,                        data=json.dumps(payload),                        params=query_string,                        headers=mime_header)     print_request(r.request)     print_response(r)       # Apply the changes to the new revision changeset     apply_nvue_changeset(changeset)       # Check if the changeset was applied     is_config_applied(changeset)   def nvue_get(path):     r = requests.get(url=nvue_end_point + path,                      auth=auth,                      verify=False)     print_request(r.request)     print_response(r)   if __name__ == "__main__":     payload = {       "system": {         "hostname": "switch01"       },       "interface": {         "eth0": {           "ip": {             "address": {               "192.168.200.6/24": {}             },           },           "type": "eth" }       },     }     apply_new_config("/",payload)     time.sleep(DUMMY_SLEEP)     print("=====Verifying some of the configurations=====")     nvue_get("/system")     nvue_get("/interface")

    NVUE CLI

    Copy
    Copied!
                

    nvos@switch:~$ nv show system operational --------------- --------------------------------------------- build NVOS Debian GNU/Linux 11 (bullseye) uptime 3:20:04 hostname croc-88-mgmt2 product-name nvos product-release 25.02.0936-010 platform x86_64-nvidia_q3200_ra-r0 system-memory 3268 MB used / 12546 MB free / 15814 MB total swap-memory 0 MB used / 0 MB free / 0 MB total health-status Not OK date-time 2024-08-05 07:48:13 status System is ready timezone Asia/Jerusalem

Make a Configuration Change

To make a configuration change:

  1. Create a new revision ID with a POST:

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' --insecure -X POST https://127.0.0.1:443/nvue_v1/revision { "2": { "state": "pending", "transition": { "issue": {}, "progress": "" } } }

  2. Record the revision ID. In the above example, the revision ID is "2".

  3. Make the change with a PATCH and link it to the revision ID:

    Curl Command

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -d '{"99.99.99.99/32": {}}' -H 'Content-Type: application/json' -k -X PATCH https://127.0.0.1:443/nvue_v1/interface/eth0/ip/address?rev=2 { "99.99.99.99/32": {} }

    NVUE CLI

    Copy
    Copied!
                

    nvos@switch:~$ nv set interface eth0 ip address 99.99.99.99/32

  4. Apply the changes with a PATCH to the revision changeset:

    Curl Command

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -H 'Content-Type:application/json' -k -X PATCH https://127.0.0.1:443/nvue_v1/revision/2 { "state": "apply", "transition": { "issue": {}, "progress": "" } }

    NVUE CLI

    Copy
    Copied!
                

    nvos@switch:~$ nv config apply

  5. Review the status of the apply and the configuration:

    Curl Command

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -k -X GET https://127.0.0.1:443/nvue_v1/revision/2 { "state": "applied", "transition": { "issue": {}, "progress": "" } }

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -k -X GET https://127.0.0.1:443/nvue_v1/revision/2 { "state": "applied", "transition": { "issue": {}, "progress": "" } }

    Python Code

    Copy
    Copied!
                

    #!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def create_nvue_changest(): r = requests.post(url=nvue_end_point + "/revision", auth=auth, verify=False) print_request(r.request) print_response(r) response = r.json() changeset = response.popitem()[0] return changeset   def apply_nvue_changeset(changeset): apply_payload = {"state": "apply", "auto-prompt": {"ays": "ays_yes"}} url = nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe="") r = requests.patch(url=url, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r)   def is_config_applied(changeset) -> bool: # Check if the configuration was indeed applied global RETRIES global POLL_APPLIED retries = RETRIES while retries > 0: r = requests.get(url=nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe=""), auth=auth, verify=False) response = r.json() print(response) if response["state"] == "applied": return True retries -= 1 time.sleep(POLL_APPLIED)   return False   def apply_new_config(path,payload): # Create a new revision ID changeset = create_nvue_changest() print("Using NVUE Changeset: '{}'".format(changeset))   # Delete existing configuration query_string = {"rev": changeset} r = requests.delete(url=nvue_end_point + path, auth=auth, verify=False, params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Patch the new configuration query_string = {"rev": changeset} r = requests.patch(url=nvue_end_point + path, auth=auth, verify=False, data=json.dumps(payload), params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Apply the changes to the new revision changeset apply_nvue_changeset(changeset)   # Check if the changeset was applied is_config_applied(changeset)   def nvue_get(path): r = requests.get(url=nvue_end_point + path, auth=auth, verify=False) print_request(r.request) print_response(r)   if __name__ == "__main__": payload = { "99.99.99.99/32": {} } apply_new_config("/interface/eth0/ip/address",payload) time.sleep(DUMMY_SLEEP) nvue_get("/interface/eth0/ip/address")

    NVUE CLI

    Copy
    Copied!
                

    nvos@switch:~$ nv show interface eth0 ip address ------------- 99.99.99.99/32 127.0.0.1/8 ::1/128

To view differences between configurations, run the API GET /nvue_v1/<resource>?rev=<rev-A>&diff=<rev-B> method with the configurations you want to diff. This method is equivalent to the NVUE nv config diff <rev-A> <rev-B> command.

To see the difference between the startup revision and the applied revision:

Copy
Copied!
            

$ curl -u 'admin:admin' --insecure -X GET /nvue_v1/interface?rev=startup&diff=applied

To see the difference between revision 1 and revision 2:

Copy
Copied!
            

$ curl -u 'admin:admin' --insecure -X GET /nvue_v1/<resource>?rev=1&diff=2

The order of the revisions can be changed; for example, GET /nvue_v1/<resource>?rev=2&diff=1.

When a configuration change fails, you see an error in the change request.

Configuration Apply Fails with Warnings

In some cases, such as the first push with NVUE or if you change a file manually instead of using NVUE, you see a warning prompt and the apply fails.

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' --insecure -X GET https://127.0.0.1:443/nvue_v1/revision/6 { "6": { "state": "ays_fail", "transition": { "issue": { "0": { "code": "client_timeout", "data": {}, "message": "Timeout while waiting for client response", "severity": "error" } }, "progress": "Aborted apply after warnings" } }

To resolve this issue, observe the failures or errors, then inspect the configuration that you are trying to apply. After you resolve the errors, retry the API. If you prefer to overlook the errors and force an apply, add "auto-prompt":{"ays": "ays_yes"} to the configuration apply.

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -d '{"state":"apply","auto-prompt":{"ays": "ays_yes"}}' -H 'Content-Type:application/json' --insecure -X PATCH https://127.0.0.1:443/nvue_v1/revision/6


To save an applied configuration change to the startup configuration file (/etc/nvue.d/startup.yaml) so that the changes persist after a reboot, use a PATCH to the applied revision with the save state.

Curl Command

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k -X PATCH -d '{"state": "save", "auto-prompt": {"ays": "ays_yes"}}' -H 'Content-Type: application/json' https://127.0.0.1:443/nvue_v1/revision/applied { "state": "save", "transition": { "issue": {}, "progress": "" } }

Python Code

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def save_nvue_changeset(): apply_payload = {"state": "save", "auto-prompt": {"ays": "ays_yes"}} url = nvue_end_point + "/revision/applied" r = requests.patch(url=url, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r)   if __name__ == "__main__": save_nvue_changeset()

NVUE CLI

Copy
Copied!
            

nvos@switch:~$ nv config save saved

To unset a change, use the null value to the key. For example, to delete start configuration from eth1 port, use the following syntax:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -d '{"eth1":null}' -H 'Content-Type: application/json' --insecure -X PATCH https://127.0.0.1:443/nvue_v1/interface/rev=4

When you unset a change, you must still use the PATCH action. The value indicates removal of the entry. The data is {"eth1":null} with the PATCH action.

The example below fetches the counters for interface sw1p1.

Curl Command

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k -X GET https://127.0.0.1:443/nvue_v1/interface/sw1p1/link/counters { "buffer-overrun-errors": 0, "in-bytes": 16128, "in-drops": 0, "in-errors": 0, "in-pkts": 56, "in-symbol-errors": 0, "link-downed": 0, "link-error-recovery": 0, "local-link-integrity-errors": 0, "out-bytes": 16128, "out-drops": 0, "out-errors": 0, "out-pkts": 56, "out-wait": 0, "port-rcv-constraint-errors": 0, "port-rcv-remote-physical-errors": 0, "port-rcv-switch-relay-errors": 0, "qp1-drops": 0, "rcv-icrc-errors": 0, "tx-parity-errors": 0 }

Python Code

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   if __name__ == "__main__": r = requests.get(url=nvue_end_point + "/interface/sw1p1/link/counters", auth=auth, verify=False) print("=======Interface sw1p1 Counters=======") print(json.dumps(r.json(), indent=2))

NVUE CLI

Copy
Copied!
            

nvos@switch:~$ nv show interface sw1p1 link counters --view detail operational description ------------------------------- ----------- ---------------------------------------------------------------------- in-bytes 15.75 KB Total number of bytes received on the interface in-pkts 56 Total number of packets received on the interface in-drops 0 Number of received packets dropped in-errors 0 Number of received packets with errors out-bytes 15.75 KB Total number of bytes transmitted out of the interface out-pkts 56 Total number of packets transmitted out of the interface out-drops 0 The number of outbound packets that were chosen to be discarded even though no errors had been detected to prevent their being transmitted. out-errors 0 The number of outbound packets that could not be transmitted because of errors. in-symbol-errors 0 Total number of minor errors detected on one or more physical lanes out-wait 0 The number of ticks during which the port selected by PortSelect had data to transmit but no data was sent during the entire tick because of insufficient credits or of lack of arbitration. link-error-recovery 0 Total number of times the Port Training state machine has successfully completed the link error recovery process link-downed 0 Total number of times the Port Training state machine has failed the link error recovery process and downed the link port-rcv-remote-physical-errors 0 Total number of packets marked with the EBP delimiter received on the port port-rcv-switch-relay-errors 0 Total number of packets received on the port that were discarded because they could not be forwarded by the switch relay port-rcv-constraint-errors 0 Total number of packets received on the switch physical port that are discarded due to constraints local-link-integrity-errors 0 Total number of times that the count of local physical errors exceeded the threshold specified by Local Phy Errors qp1-drops 0 Total number of QP1 MADs (packets) dropped due to resource limitations buffer-overrun-errors 0 The number of times that Overrun-Errors consecutive flow control update periods occur rcv-icrc-errors 0 Total number of icrc payload corruption rx errors tx-parity-errors 0 Total number of icrc payload corruption tx parity errors

NVUE provides views for certain show commands. A view is a subset of information.

To see the views available for a show command, run the command with --view and press TAB:

Copy
Copied!
            

nvos@switch:~$ nv show interface --view <<TAB>> brief detail link-diagnostics lldp mac small

To retrieve view types through the REST API, you use the curl -u 'admin:admin' -k -X GET http://path?view=<brief> syntax. For example, the equivalent REST API method for the NVUE nv show interface --view=brief command is:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k -X GET https://127.0.0.1:443/nvue_v1/interface?view=brief

You can take a configuration change from the CLI and use the API to configure the same set of changes.

  1. Make your configuration changes on the system with the NVUE CLI.

    Copy
    Copied!
                

    nvos@switch:~$ nv set system hostname switch01 nvos@switch:~$ nv set interface eth0 ip address 192.168.200.6/24 

  2. View the changes as a JSON blob.

    Copy
    Copied!
                

    nvos@switch:~$ nv config diff -o json [ { "set": { "interface": { "eth0": { "ip": { "address": { "192.168.200.6/24": {} } } } }, "system": { "hostname": "switch01" } } } ]

  3. Staple the JSON blob to a root patch request as the payload.

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -d '{ "interface": { "eth0": { "ip": { "address": { "192.168.200.6/24": {} } } } }, "system": { "hostname": "switch01" } }' -k -X PATCH https://127.0.0.1:443/nvue_v1/?rev=3

  4. Apply the changes with a PATCH to the revision changeset.

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -H 'Content-Type:application/json' -k -d '{"state": "apply", "auto-prompt": {"ays": "ays_yes"}}' -X PATCH https://127.0.0.1:443/nvue_v1/revision/3 { "state": "apply", "transition": { "issue": {}, "progress": "" } }

  5. Review the status of the apply and the configuration:

    Curl Command

    Copy
    Copied!
                

    nvos@switch:~$ curl -u 'admin:admin' -k -X GET https://127.0.0.1:443/nvue_v1/revision/3 { "state": "applied", "transition": { "issue": {}, "progress": "" } }

    Python Code

    Copy
    Copied!
                

    #!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def create_nvue_changest(): r = requests.post(url=nvue_end_point + "/revision", auth=auth, verify=False) print_request(r.request) print_response(r) response = r.json() changeset = response.popitem()[0] return changeset   def apply_nvue_changeset(changeset): # apply_payload = {"state": "apply"} apply_payload = {"state": "apply", "auto-prompt": {"ays": "ays_yes"}} url = nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe="") r = requests.patch(url=url, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r)   def is_config_applied(changeset) -> bool: # Check if the configuration was indeed applied global RETRIES global POLL_APPLIED retries = RETRIES while retries > 0: r = requests.get(url=nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe=""), auth=auth, verify=False) response = r.json() print(response)   if response["state"] == "applied": return True retries -= 1 time.sleep(POLL_APPLIED)   return False   def apply_new_config(path,payload): # Create a new revision ID changeset = create_nvue_changest() print("Using NVUE Changeset: '{}'".format(changeset))   # Delete existing configuration query_string = {"rev": changeset} r = requests.delete(url=nvue_end_point + path, auth=auth, verify=False, params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Patch the new configuration query_string = {"rev": changeset} r = requests.patch(url=nvue_end_point + path, auth=auth, verify=False, data=json.dumps(payload), params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Apply the changes to the new revision changeset apply_nvue_changeset(changeset)   # Check if the changeset was applied is_config_applied(changeset)   def nvue_get(path): r = requests.get(url=nvue_end_point + path, auth=auth, verify=False) print_request(r.request) print_response(r)   if __name__ == "__main__": payload = { "interface": { "eth": { "ip": { "address": { "192.168.200.6/24": {} } } } }, "system": { "hostname": "switch01" } } apply_new_config("/",payload) time.sleep(DUMMY_SLEEP) nvue_get("/interface/eth0") nvue_get("/system")

The following section provides practical API examples.

Configure the System

To set the system hostname, pre-login or post-login message, and time zone on the switch, send a targeted API request to /nvue_v1/system.

Curl Command

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -d '{"system": {"hostname":"switch01","timezone":"America/Los_Angeles","message":{"pre-login":"Welcome to NVOS","post-login":"You have successfully logged in to switch01"}}}' -k -X PATCH https://127.0.0.1:443/nvue_v1/?rev=4

Python Code

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def create_nvue_changest(): r = requests.post(url=nvue_end_point + "/revision", auth=auth, verify=False) print_request(r.request) print_response(r) response = r.json() changeset = response.popitem()[0] return changeset   def apply_nvue_changeset(changeset): # apply_payload = {"state": "apply"} apply_payload = {"state": "apply", "auto-prompt": {"ays": "ays_yes"}} url = nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe="") r = requests.patch(url=url, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r)   def is_config_applied(changeset) -> bool: # Check if the configuration was indeed applied global RETRIES global POLL_APPLIED retries = RETRIES while retries > 0: r = requests.get(url=nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe=""), auth=auth, verify=False) response = r.json() print(response)   if response["state"] == "applied": return True retries -= 1 time.sleep(POLL_APPLIED)   return False   def apply_new_config(path,payload): # Create a new revision ID changeset = create_nvue_changest() print("Using NVUE Changeset: '{}'".format(changeset))   # Delete existing configuration query_string = {"rev": changeset} r = requests.delete(url=nvue_end_point + path, auth=auth, verify=False, params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Patch the new configuration query_string = {"rev": changeset} r = requests.patch(url=nvue_end_point + path, auth=auth, verify=False, data=json.dumps(payload), params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Apply the changes to the new revision changeset apply_nvue_changeset(changeset)   # Check if the changeset was applied is_config_applied(changeset)   def nvue_get(path): r = requests.get(url=nvue_end_point + path, auth=auth, verify=False) print_request(r.request) print_response(r)   if __name__ == "__main__": payload = { "system": { "hostname":"switch01", "timezone":"America/Los_Angeles", "message": { "pre-login":"Welcome to NVOS", "post-login:"You have successfully logged in to switch01" } } } apply_new_config("/",payload) # Root patch time.sleep(DUMMY_SLEEP) nvue_get("/system")

NVUE CLI

Copy
Copied!
            

nvos@switch:~$ nv set system hostname switch01 nvos@switch:~$ nv set system timezone America/Los_Angeles nvos@switch:~$ nv set system message pre-login "Welcome to NVOS"  nvos@switch:~$ nv set system message post-login "You have successfully logged into switch01"


Configure Services

To set up NTP, SYSLOG, and SNMP on the switch, send a targeted API request to /nvue_v1/system.

Curl Command

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -d '{"system": { "ntp": {"server":{"4.nvos.pool.ntp.org":{}}}}}' -k -X PATCH https://127.0.0.1:443/nvue_v1/?rev=5

Python Code

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def create_nvue_changest(): r = requests.post(url=nvue_end_point + "/revision", auth=auth, verify=False) print_request(r.request) print_response(r) response = r.json() changeset = response.popitem()[0] return changeset   def apply_nvue_changeset(changeset): # apply_payload = {"state": "apply"} apply_payload = {"state": "apply", "auto-prompt": {"ays": "ays_yes"}} url = nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe="") r = requests.patch(url=url, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r)   def is_config_applied(changeset) -> bool: # Check if the configuration was indeed applied global RETRIES global POLL_APPLIED retries = RETRIES while retries > 0: r = requests.get(url=nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe=""), auth=auth, verify=False) response = r.json() print(response)   if response["state"] == "applied": return True retries -= 1 time.sleep(POLL_APPLIED)   return False   def apply_new_config(path,payload): # Create a new revision ID changeset = create_nvue_changest() print("Using NVUE Changeset: '{}'".format(changeset))   # Delete existing configuration query_string = {"rev": changeset} r = requests.delete(url=nvue_end_point + path, auth=auth, verify=False, params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Patch the new configuration query_string = {"rev": changeset} r = requests.patch(url=nvue_end_point + path, auth=auth, verify=False, data=json.dumps(payload), params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Apply the changes to the new revision changeset apply_nvue_changeset(changeset)   # Check if the changeset was applied is_config_applied(changeset)   def nvue_get(path): r = requests.get(url=nvue_end_point + path, auth=auth, verify=False) print_request(r.request) print_response(r)   if __name__ == "__main__": payload = { "system": { "ntp": { "server: { "4.nvos.pool.ntp.org": {} } }, } } apply_new_config("/",payload) # Root patch time.sleep(DUMMY_SLEEP) nvue_get("/system/ntp")

NVUE CLI

Copy
Copied!
            

nvos@switch:~$ nv set system ntp server 4.nvos.pool.ntp.org


Configure Users

The following example creates a new user, then deletes the user.

Curl Command

This example creates a new user called test1 .

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -d '{"system": {"aaa": {"user": {"test1": {"hashed-password":"72b28582708d749c6c82f3b3f226041f1bd37090281641eaeba8d44bd915d0042d609a92759d9f6fb96475cb0601cf428cd22613df8a53a09461e0b426cf0a35","role": "monitor","state": "enabled","full-name": "Test User"}}}}}' -k -X PATCH https://127.0.0.1:443/nvue_v1/?rev=5

This example deletes the test1 user.

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k -X DELETE https://127.0.0.1:443/nvue_v1/system/aaa/user/test1?rev=6

Python Code

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def create_nvue_changest(): r = requests.post(url=nvue_end_point + "/revision", auth=auth, verify=False) print_request(r.request) print_response(r) response = r.json() changeset = response.popitem()[0] return changeset   def apply_nvue_changeset(changeset): # apply_payload = {"state": "apply"} apply_payload = {"state": "apply", "auto-prompt": {"ays": "ays_yes"}} url = nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe="") r = requests.patch(url=url, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r)   def is_config_applied(changeset) -> bool: # Check if the configuration was indeed applied global RETRIES global POLL_APPLIED retries = RETRIES while retries > 0: r = requests.get(url=nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe=""), auth=auth, verify=False) response = r.json() print(response)   if response["state"] == "applied": return True retries -= 1 time.sleep(POLL_APPLIED)   return False   def apply_new_config(path,payload): # Create a new revision ID changeset = create_nvue_changest() print("Using NVUE Changeset: '{}'".format(changeset))   # Delete existing configuration query_string = {"rev": changeset} r = requests.delete(url=nvue_end_point + path, auth=auth, verify=False, params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Patch the new configuration query_string = {"rev": changeset} r = requests.patch(url=nvue_end_point + path, auth=auth, verify=False, data=json.dumps(payload), params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Apply the changes to the new revision changeset apply_nvue_changeset(changeset)   # Check if the changeset was applied is_config_applied(changeset)   def delete_config(path): # Create an NVUE changeset changeset = create_nvue_changest() print("Using NVUE Changeset: '{}'".format(changeset))   # Equivalent to JSON `null` payload = None   # Stage the change query_string = {"rev": changeset} r = requests.delete(url=nvue_end_point + path, auth=auth, verify=False, data=json.dumps(payload), params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Apply the staged changeset apply_nvue_changeset(changeset)   # Check if the changeset was applied is_config_applied(changeset)   def nvue_get(path): r = requests.get(url=nvue_end_point + path, auth=auth, verify=False) print_request(r.request) print_response(r)   if __name__ == "__main__":   # Need to create a hashed password - The supported password # Here in this example, we use SHA-512 import crypt hashed_password = crypt.crypt("hello$world#2023", salt=crypt.METHOD_SHA512) payload = { "system": { "aaa": { "user": { "test1": { "hashed-password": hashed_password, "role": "monitor", "state": "enabled", "full-name": "Test User", } } } } } apply_new_config("/",payload) # Root patch time.sleep(DUMMY_SLEEP) nvue_get("/system/user/aaa")   """Delete an existing user account using the AAA API.""" delete_config("/system/aaa/user/test1") time.sleep(DUMMY_SLEEP) nvue_get("/system/user/aaa")

NVUE CLI

This example creates a new user test1 .

Copy
Copied!
            

nvos@switch:~$ nv set system aaa user test1 nvos@switch:~$ nv set system aaa user test1 full-name "Test User"   nvos@switch:~$ nv set system aaa user test1 password "abcd@test"  nvos@switch:~$ nv set system aaa user test1 role monitor nvos@switch:~$ nv set system aaa user test1 state enabled

This example deletes the user test1 .

Copy
Copied!
            

nvos@switch:~$ nv unset system aaa user test1


Configure an Interface

The following example configures an interface.

Curl Command

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -k -d '{"eth1": {"link":{"state":{"up": {}}}}}' -H 'Content-Type: application/json' -k -X PATCH https://127.0.0.1:443/nvue_v1/interface?rev=21

Python Code

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def create_nvue_changest(): r = requests.post(url=nvue_end_point + "/revision", auth=auth, verify=False) print_request(r.request) print_response(r) response = r.json() changeset = response.popitem()[0] return changeset   def apply_nvue_changeset(changeset): # apply_payload = {"state": "apply"} apply_payload = {"state": "apply", "auto-prompt": {"ays": "ays_yes"}} url = nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe="") r = requests.patch(url=url, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r)   def is_config_applied(changeset) -> bool: # Check if the configuration was indeed applied global RETRIES global POLL_APPLIED retries = RETRIES while retries > 0: r = requests.get(url=nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe=""), auth=auth, verify=False) response = r.json() print(response)   if response["state"] == "applied": return True retries -= 1 time.sleep(POLL_APPLIED)   return False   def apply_new_config(path,payload): # Create a new revision ID changeset = create_nvue_changest() print("Using NVUE Changeset: '{}'".format(changeset))   # Delete existing configuration query_string = {"rev": changeset} r = requests.delete(url=nvue_end_point + path, auth=auth, verify=False, params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Patch the new configuration query_string = {"rev": changeset} r = requests.patch(url=nvue_end_point + path, auth=auth, verify=False, data=json.dumps(payload), params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Apply the changes to the new revision changeset apply_nvue_changeset(changeset)   # Check if the changeset was applied is_config_applied(changeset)   def nvue_get(path): r = requests.get(url=nvue_end_point + path, auth=auth, verify=False) print_request(r.request) print_response(r)   if __name__ == "__main__": payload = { "eth1": { "type": "eth", "link": { "state":"up" } } } apply_new_config("/interface",payload) time.sleep(DUMMY_SLEEP) nvue_get("/interface/eth1")

NVUE CLI

Copy
Copied!
            

nvos@switch:~$ nv set interface eth1

Action Operations

The NVUE action operations are ephemeral operations that do not modify the state of the configuration; they reset counters for interfaces, reboot the system etc...

Curl Command

To clear counters on sw1p1:

Copy
Copied!
            

nvos@switch:~$ curl -u 'admin:admin' -H 'Content-Type:application/json' -d '{"@clear": {"state": "start", "parameters": {}}}' -k -X POST https://127.0.0.1:443/nvue_v1/interface/sw1p1/link/counters 1  nvos@switch:~$ curl -u 'admin:admin' -X GET https://127.0.0.1:443/nvue_v1/action/1 -k {"detail":"sw1p1 counters cleared.","http_status":200,"issue":[],"state":"action_success","status":"sw1p1 counters cleared.","timeout":60,"type":""}

Python Code

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def nvue_action(): r = requests.post(url=nvue_end_point + path, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r) return response   def nvue_get(path): r = requests.get(url=nvue_end_point + path, auth=auth, verify=False) print_request(r.request) print_response(r)   if __name__ == "__main__": payload = { "@clear": { "state": "start", "parameters": {} } } action_id=nvue_action("/interface/sw1p1/link/counters",payload) time.sleep(DUMMY_SLEEP) nvue_get(f"/action/{action_id}")

NVUE CLI

Copy
Copied!
            

nvos@switch:~$ nv action clear interface sw1p1 link counters


In the following python example, the full_config_example() method sets the system pre-login message, and changes a few other configuration settings in a single bulk operation. The API end-point goes to the root node /nvue_v1.

Copy
Copied!
            

#!/usr/bin/env python3   import requests from requests.auth import HTTPBasicAuth import json import time   auth = HTTPBasicAuth(username="admin", password="password") nvue_end_point = "https://127.0.0.1:443/nvue_v1" mime_header = {"Content-Type": "application/json"}   DUMMY_SLEEP = 5 # In seconds POLL_APPLIED = 1 # in seconds RETRIES = 10   def print_request(r: requests.Request): print("=======Request=======") print("URL:", r.url) print("Headers:", r.headers) print("Body:", r.body)   def print_response(r: requests.Response): print("=======Response=======") print("Headers:", r.headers) print("Body:", json.dumps(r.json(), indent=2))   def sanity(): # Basic retrieval to check connectivity r = requests.get(url=nvue_end_point + "/system", auth=auth, verify=False) print_request(r.request) print_response(r)   def create_nvue_changest(): r = requests.post(url=nvue_end_point + "/revision", auth=auth, verify=False) print_request(r.request) print_response(r) response = r.json() changeset = response.popitem()[0] return changeset   def apply_nvue_changeset(changeset): # apply_payload = {"state": "apply"} apply_payload = {"state": "apply", "auto-prompt": {"ays": "ays_yes"}} url = nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe="") r = requests.patch(url=url, auth=auth, verify=False, data=json.dumps(apply_payload), headers=mime_header) print_request(r.request) print_response(r)   def full_config_example(): # Create an NVUE changeset changeset = create_nvue_changest() print("Using NVUE Changeset: '{}'".format(changeset))   # https://www.asciiart.eu/comics/batman pre_login_message = u""" ,.ood888888888888boo., .od888P^"" ""^Y888bo. .od8P'' ..oood88888888booo. ``Y8bo. .odP'" .ood8888888888888888888888boo. "`Ybo. .d8' od8'd888888888f`8888't888888888b`8bo `Yb. d8' od8^ 8888888888[ `' ]8888888888 ^8bo `8b .8P d88' 8888888888P Y8888888888 `88b Y8. d8' .d8' `Y88888888' `88888888P' `8b. `8b .8P .88P """" """" Y88. Y8. 88 888 888 88 88 888 888 88 88 888. .. .. .888 88 `8b `88b, d8888b.od8bo. .od8bo.d8888b ,d88' d8' Y8. `Y88. 8888888888888b d8888888888888 .88P' .8P `8b Y88b. `88888888888888 88888888888888' .d88P d8' Y8. ^Y88bod8888888888888..8888888888888bod88P^ .8P `Y8. ^Y888888888888888LS888888888888888P^ .8P' `^Yb., `^^Y8888888888888888888888P^^' ,.dP^' `^Y8b.. ``^^^Y88888888P^^^' ..d8P^' `^Y888bo., ,.od888P^' "`^^Y888888888888P^^'" """   # https://www.asciiart.eu/comics/superman post_login_message = u''' _____________________________________________ //:::::::::::::::::::::::::::::::::::::::::::::\\ //:::_______:::::::::________::::::::::_____:::::::\\ //:::_/ _-"":::_--""" """--_::::\_ ):::::::::\\  //:::/ /:::::_" "-_:::\/:::::|^\:::\\ //:::/ /~::::::I__ \:::::::::| \:::\\ \\:::\ (::::::::::""""---___________ "--------" /:::// \\:::\ |::::::::::::::::::::::::::::""""==____ /:::// \\:::"\/::::::::::::::::::::::::::::::::::::::\ /~:::// \\:::::::::::::::::::::::::::::::::::::::::::)/~:::// \\::::\""""""------_____:::::::::::::::::::::::// \\:::"\ """""-----_____::::::// \\:::"\ __----__ ):::// \\:::"\/~::::::::~\_ __/~::// \\::::::::::::::::""----"""::::// \\:::::::::::::::::::::::::// \\:::\^""--._.--""^/:::// \\::"\ /"::// \\::"\ /"::// \\::"\_/"::// \\:::::// \\_// " '''   # Prepare payload which configures a few # different switch configurations payload = { "interface":{ "eth0":{ "description": "management port" } }, "system":{ "message":{ "pre-login": pre_login_message, "post-login": post_login_message }, "timezone": "Europe/Paris", }, } # Stage the change query_string = {"rev": changeset} r = requests.patch(url=nvue_end_point + "/", # Root patch auth=auth, verify=False, data=json.dumps(payload), params=query_string, headers=mime_header) print_request(r.request) print_response(r)   # Apply the staged changeset apply_nvue_changeset(changeset)   # Check if the changeset was applied is_config_applied(changeset)     def message_get(): # Get the system pre-login/post-login # message that was configured. r = requests.get(url=nvue_end_point + "/system/message", auth=auth, verify=False) print_request(r.request) print_response(r)   def is_config_applied(changeset) -> bool: # Check if the configuration was indeed applied global RETRIES global POLL_APPLIED retries = RETRIES while retries > 0: r = requests.get(url=nvue_end_point + "/revision/" + requests.utils.quote(changeset, safe=""), auth=auth, verify=False) response = r.json() print(response)   if response["state"] == "applied": return True retries -= 1 time.sleep(POLL_APPLIED)   return False   if __name__ == "__main__": sanity() time.sleep(DUMMY_SLEEP) full_config_example() time.sleep(DUMMY_SLEEP) message_get()

To try out the NVUE REST API, use the NVUE API Lab available on NVIDIA Air. The lab provides a basic example to help you get started. You can also try out the other examples in this document.

For information about using the NVUE REST API, refer to the NVUE API Swagger documentation. The full object model download is available here.

  • Unlike the NVUE CLI, the NVUE API does not support configuring a plain text password for a user account; you must configure a hashed password for a user account with the NVUE API.

  • If you need to make multiple updates on the switch, NVIDIA recommends you use a root patch, which can make configuration changes with fewer round trips to the switch. Running many specific NVUE PATCH APIs to set or unset objects requires many round trips to the switch to set up the HTTP connection, transfer payload and responses, manage network utilization, and so on.

1. Send a PATCH request to save the currently applied configuration.

Copy
Copied!
            

curl -u '<username:password>'--insecure --request PATCH 'https://<IP>/nvue_v1/revision/applied' -H 'Content-Type: application/json' -d '{"state": "save"}'

1. Run the nv action disconnect

Copy
Copied!
            

$ curl -u '<username:password>' --insecure https://<IP>/nvue_v1/system/aaa/user -H 'Content-Type: application/json' -d ' {"@disconnect": {"state": "start", "parameters": {"user": "monitor"} } }'   3

2. Get the action ID from response; "3"

3. Check status

Copy
Copied!
            

$ curl -u '<username:password>' --request GET 'https://<IP>/nvue_v1/action/3' {"detail":"all sessions have been terminated","http_status":200,"issue":[],"state":"action_success","status":"all sessions have been terminated","timeout":60,"type":""}

© Copyright 2025, NVIDIA. Last updated on Mar 3, 2025.