Luna2 REST API
- Design decisions
- Changelog
- Rest resources
- URI Structure
- Fields
- API Usage
- Authenticate against the API (POST /token)
- Who am I (GET /whoami)
- Version
- Get version (GET /version)
- Booting
- Boot by MAC (or port detection)
- Manual boot
- iPXE boot menu (GET /boot)
- Shortened iPXE boot menu (GET /boot/short)
- Boot from local disk (GET /boot/disk)
- Boot lookup by MAC address (GET /boot/search/mac/{macaddress})
- Manual boot by group (GET /boot/manual/group/{groupname}/{macaddress})
- Manual boot by hostname (GET /boot/manual/hostname/{hostname}/{macaddress})
- Boot role (GET /boot/roles/{role})
- Boot script (GET /boot/scripts/{script})
- Boot profile (GET /boot/profiles/{profile})
- Kickstart installation template (GET /kickstart/install/{node})
- Switch ZTP recipe (GET /boot/switch/{name})
- Switch ZTP command list (GET /boot/switch/{name}/commands)
- Luna installation template (GET boot/install/{node})
- Group configuration
- Get a list of groups (GET /config/group)
- Get group information (GET /config/group/{group})
- Get a list members of the groups (GET /config/group/{group}/_member)
- Create or update & Rename(By newgroupname) group information (POST /config/group/{group})
- Clone (By newgroupname) a group (POST /config/group/{group}/_clone)
- Deleting a group (GET /config/group/{group}/_delete)
- Get group interface information (GET /config/group/{group}/interfaces)
- Create or update group interface information (POST /config/group/{group}/interfaces)
- Retrieve group interface information (GET /config/group/{group}/interfaces/{interface})
- Delete group interface (GET /config/group/{group}/interfaces/{interface}/_delete)
- Push the osimage to all nodes in the group (POST /config/group/{name}/_ospush)
- Get the group disk layout (GET /config/group/{name}/disklayout)
- Get the group mounts document (GET /config/group/{name}/mounts)
- Add or update a group mount (POST /config/group/{name}/mounts)
- Remove a group mount (POST /config/group/{name}/mounts/_remove)
- Assign a profile to a group (POST /config/group/{name}/profiles)
- Unassign a profile from a group (POST /config/group/{name}/profiles/_unassign)
- Preview a firmware push to a group (GET /config/group/{name}/firmware/_preview)
- Push firmware to all nodes in the group (POST /config/group/{name}/_firmwarepush)
- Push a BIOS configuration to all nodes in the group (POST /config/group/{name}/_biospush)
- Node configuration
- Get a list of nodes (GET /config/node)
- Get node information (GET /config/node/{node})
- Create or update node information (POST /config/node/{node})
- Clone a node (POST /config/node/{node}/_clone)
- Deleting a node (GET /config/node/{node}/_delete)
- Listing node interfaces (GET /config/node/{node}/interfaces)
- Updating node interfaces (POST /config/node/{node}/interfaces)
- Showing node interfaces (GET /config/node/{node}/interfaces/{interface})
- Delete node interfaces (GET /config/node/{node}/interfaces/{interface}/_delete)
- Grab an osimage from a node (POST /config/node/{name}/_osgrab)
- Push an osimage to a node (POST /config/node/{name}/_ospush)
- Get the node disk layout (GET /config/node/{name}/disklayout)
- Get the node mounts document (GET /config/node/{name}/mounts)
- Add or update a node mount (POST /config/node/{name}/mounts)
- Remove a node mount (POST /config/node/{name}/mounts/_remove)
- Assign a profile to a node (POST /config/node/{name}/profiles)
- Unassign a profile from a node (POST /config/node/{name}/profiles/_unassign)
- Get the inventory summary of all nodes (GET /config/node/inventory)
- Get node inventory (GET /config/node/{name}/inventory)
- Store a node inventory snapshot (POST /config/node/{name}/inventory)
- Collect node inventory over Redfish (GET /config/node/{name}/inventory/_redfish)
- Collect inventory over Redfish for several nodes (POST /config/node/inventory/_redfish)
- Provision Redfish accounts for several nodes (POST /config/node/redfishaccounts/_provision)
- Grab a BIOS configuration from a node (POST /config/node/{name}/_biosgrab)
- Push a BIOS configuration to a node (POST /config/node/{name}/_biospush)
- Preview a firmware push to a node (GET /config/node/{name}/firmware/_preview)
- Push firmware to a node (POST /config/node/{name}/_firmwarepush)
- Cluster information
- Get cluster information (GET /config/cluster)
- Update cluster information (POST /config/cluster)
- Export the cluster configuration (GET /config/cluster/export)
- Import a cluster configuration (POST /config/cluster/import)
- Get the cluster mounts document (GET /config/cluster/mounts)
- Add or update a cluster mount (POST /config/cluster/mounts)
- Remove a cluster mount (POST /config/cluster/mounts/_remove)
- Network Management
- Get the list of networks (GET /config/network)
- Get network information (GET /config/network/{networkname})
- Update network information (POST /config/network/{networkname})
- Deleting network information (GET /config/network/{networkname}/_delete)
- Get IP Address information (GET /config/network/{ipaddr})
- Get all taken IP address with device name (GET /config/network/{networkname}/_member)
- Get next available IP address (GET /config/network/{networkname}/_nextfreeip)
- Get the status of a single IP address (GET /config/network/{name}/{ipaddress})
- Get the list of static routes (GET /config/route)
- Get static route information (GET /config/route/{name})
- Create, update or rename a static route (POST /config/route/{name})
- Delete a static route (GET /config/route/{name}/_delete)
- Couple a static route (GET /config/route/{name}/{tableref}/{target}/_couple)
- Decouple a static route (GET /config/route/{name}/{tableref}/{target}/_decouple)
- BMC Management
- Get the list of BMC settings (GET /config/bmcsetup)
- Get the list of nodes in BMC setup (GET /config/bmcsetup/{name}/_member)
- Show BMC setup (GET /config/bmcsetup/{bmcname})
- Create, configure or rename BMC setup (POST /config/bmcsetup/{bmcname})
- Clone BMC setup (POST /config/bmcsetup/{bmcname}/_clone)
- Delete BMC setup (GET /config/bmcsetup/{bmcname}/_delete)
- Redfish management
- Get the list of Redfish setups (GET /config/redfishsetup)
- Show Redfish setup (GET /config/redfishsetup/{name})
- Get the list of members of a Redfish setup (GET /config/redfishsetup/{name}/_member)
- Create, configure or rename Redfish setup (POST /config/redfishsetup/{name})
- Clone Redfish setup (POST /config/redfishsetup/{name}/_clone)
- Delete Redfish setup (GET /config/redfishsetup/{name}/_delete)
- Delete an account from a Redfish setup (GET /config/redfishsetup/{name}/{account}/_delete)
- BIOS configuration
- Get the list of BIOS configurations (GET /config/biosconfig)
- Show BIOS configuration (GET /config/biosconfig/{name})
- Change or rename BIOS configuration (POST /config/biosconfig/{name})
- Clone BIOS configuration (POST /config/biosconfig/{name}/_clone)
- Delete BIOS configuration (GET /config/biosconfig/{name}/_delete)
- Get the BIOS status of all nodes (GET /config/biosconfig/status)
- Get the BIOS status of a node (GET /config/biosconfig/status/{name})
- Get the BIOS status of a group (GET /config/biosconfig/status/group/{name})
- Firmware catalogue
- Get the firmware catalogue (GET /config/firmwarecatalog)
- Show firmware catalogue entry (GET /config/firmwarecatalog/{name})
- Create, change or rename firmware catalogue entry (POST /config/firmwarecatalog/{name})
- Delete firmware catalogue entry (GET /config/firmwarecatalog/{name}/_delete)
- Get the firmware update status of all nodes (GET /config/firmwarecatalog/status)
- Get the firmware update status of a node (GET /config/firmwarecatalog/status/{name})
- Get the firmware update status of a group (GET /config/firmwarecatalog/status/group/{name})
- Image management
- Get a list of images (GET /config/osimage):
- Get a list members of the osimage (GET /config/osimage/{osimage}/_member)
- Get osimage information (GET /config/osimage/{osimage})
- Updating or creating osimage information (POST /config/osimage/{osimage})
- Delete osimage (GET /config/osimage/{osimage}/_delete)
- Renaming osimage (POST /config/osimage/{osimage})
- Cloning osimage (POST /config/osimage/{osimage}/_clone)
- Packing osimage (GET /config/osimage/{osimage}/_pack)
- Cancel an osimage pack (GET /config/osimage/{name}/_cancel)
- Changing kernel version in osimage (incl. pack) (POST /config/osimage/{osimage}/kernel)
- Update the CA certificates in an osimage (GET /config/osimage/{name}/_updatecerts)
- Get osimage+osimage tag information (GET /config/osimagetag)
- Get osimage+osimage tag information (GET /config/osimagetag/{osimage})
- Changing/creating tag in osimage (POST /config/osimage/{osimage}/tag)
- Delete osimagetag (GET /config/osimage/{osimage}/osimagetag/{tagname}/_delete)
- Secret management
- Get a list of secrets (GET /config/secrets):
- Retrieve all secrets for a node (GET /config/secrets/node/{node})
- Update all secrets for a node (POST /config/secrets/node/{node})
- Retrieve a single secret from a node (GET /config/secrets/node/{node}/{secret})
- Updating a single secret from a node (POST /config/secrets/node/{node}/{secret})
- Cloning a secret from a node (POST /config/secrets/node/{node}/{secret}/_clone)
- Deleting a secret from a node (GET /config/secrets/node/{node}/{secret}/_delete)
- Retrieve all secrets for a group (GET /config/secrets/group/{group})
- Updating all secrets for a group (POST /config/secrets/group/{group})
- Retrieve a single secret from a group (GET /config/secrets/group/{group}/{secret})
- Updating a single secret from a group (POST /config/secrets/group/{group}/{secret})
- Cloning a secret from a group (POST /config/secrets/group/{group}/{secret}/_clone)
- Deleting a secret from a group (GET /config/secrets/group/{group}/{secret}/_delete)
- Retrieve all cluster secrets (GET /config/secrets/cluster)
- Update all cluster secrets (POST /config/secrets/cluster)
- Retrieve a single cluster secret (GET /config/secrets/cluster/{secret})
- Updating a single cluster secret (POST /config/secrets/cluster/{secret})
- Cloning a cluster secret (POST /config/secrets/cluster/{secret}/_clone)
- Deleting a cluster secret (GET /config/secrets/cluster/{secret}/_delete)
- Profile management
- Get a list of profiles (GET /config/profiles)
- Get profile information (GET /config/profiles/{name})
- Get the members of a profile (GET /config/profiles/{name}/_member)
- Create, update or rename a profile (POST /config/profiles/{name})
- Clone a profile (POST /config/profiles/{name}/_clone)
- Delete a profile (GET /config/profiles/{name}/_delete)
- Delete a file from a profile (GET /config/profiles/{name}/{filename}/_delete)
- Get the profiles of a node (GET /config/profiles/node/{name})
- Get the profile status of all nodes (GET /config/profiles/status)
- Get the profile status of a node (GET /config/profiles/status/{name})
- Switch management
- Get a list of switches (GET /config/switch):
- Get switch information (GET /config/switch/{switch}):
- Create or update switch information (POST /config/switch/{switch}):
- Clone switch (POST /config/switch/{switch}/_clone):
- Delete switch (GET /config/switch/{switch}/_delete):
- Get switch interfaces (GET /config/switch/{name}/interfaces)
- Get a single switch interface (GET /config/switch/{name}/interfaces/{interface})
- Create or update switch interfaces (POST /config/switch/{name}/interfaces)
- Delete a switch interface (GET /config/switch/{name}/interfaces/{interface}/_delete)
- Other devices management
- Get a list of otherdev devices (GET /config/otherdev):
- Get otherdev information (GET /config/otherdev/{device}):
- Create or update otherdev information (POST/config/otherdev/{device}):
- Clone otherdev information (POST/config/otherdev/{device}/_clone):
- Deleting otherdev device (GET /config/otherdev/{device}/_delete):
- Service management
- Reload DNS
- Reload DHCP
- Reload Luna2
- Poll the result of a service action (GET /service/status/{request_id})
- Monitoring handles
- Monitoring DNS service
- Monitoring DHCP service
- Monitoring Luna2 service
- Node monitoring (GET /monitor/node/{node})
- Node monitoring (POST /monitor/node/{node})
- Cluster monitoring status (GET /monitor/status)
- Push cluster monitoring status (POST /monitor/status)
- Node monitoring state (GET /monitor/node)
- HA monitoring summary (GET /monitor/ha)
- HA monitoring for one controller (GET /monitor/ha/{name})
- Mother monitoring summary (GET /monitor/mother)
- Mother monitoring for one entry (GET /monitor/mother/{name})
- OS image monitoring summary (GET /monitor/osimage)
- OS image monitoring for one image (GET /monitor/osimage/{name})
- Task queue status (GET /monitor/queue)
- Sync monitoring summary (GET /monitor/sync)
- Sync monitoring for one entry (GET /monitor/sync/{name})
- Control API
- Control a single node (GET /control/action/{subsystem}/{hostname}/_{action})
- Control a list of nodes (POST /control/action/{subsystem}/_{action})
- Poll the result of a control action (GET /control/status/{request_id})
- Rack View
- Get all the racks in detailed view
- Get a single rack with detailed view
- Create a new or update a rack
- Get all the inventories in detailed view
- Get all the configured or unconfigured inventories in detailed view
- Update a Inventory
- Delete a Rack
- Delete a Inventory [Remove it from the Rack]
- Journal
- Get all the journal entries for a controller
- Update journal with entries on controller
- Get the journal for the calling controller (GET /journal)
- Get journal entries for a host (GET /journal/{name})
- Clear journal entries for a host (GET /journal/{name}/_delete)
- Cloud management
- Get a list of clouds (GET /config/cloud)
- Get a cloud (GET /config/cloud/{name})
- Create or update a cloud (POST /config/cloud/{name})
- Delete a cloud (GET /config/cloud/{name}/_delete)
- DNS management
- Get DNS record(s) for a network (GET /config/dns/{name})
- Create or update DNS records for a network (POST /config/dns/{name})
- Delete a DNS record from a network (GET /config/dns/{network}/{name}/_delete)
- OS user group management
- Get a list of OS groups (GET /config/osgroup)
- Get a single OS group (GET /config/osgroup/{name})
- Create or update an OS group (POST /config/osgroup/{name})
- Delete an OS group (GET /config/osgroup/{name}/_delete)
- OS user management
- Get a list of OS users (GET /config/osuser)
- Get a single OS user (GET /config/osuser/{name})
- Create or update an OS user (POST /config/osuser/{name})
- Delete an OS user (GET /config/osuser/{name}/_delete)
- User management (Luna)
- Get a list of Luna users (GET /config/user)
- Get a Luna user (GET /config/user/{name})
- Get what a Luna user may access (GET /config/user/{name}/_access)
- Create or update a Luna user (POST /config/user/{name})
- Delete a Luna user (GET /config/user/{name}/_delete)
- Usergroup management
- Get a list of usergroups (GET /config/usergroup)
- Get a usergroup (GET /config/usergroup/{name})
- Get what a usergroup may access (GET /config/usergroup/{name}/_access)
- Create or update a usergroup (POST /config/usergroup/{name})
- Delete a usergroup (GET /config/usergroup/{name}/_delete)
- Get the members of a usergroup (GET /config/usergroup/{name}/members)
- Add a member to a usergroup or change its role (POST /config/usergroup/{name}/members)
- Remove a member from a usergroup (POST /config/usergroup/{name}/members/_remove)
- Get the usergroup map (GET /config/usergroupmap)
- Add or change a usergroup map entry (POST /config/usergroupmap)
- Remove a usergroup map entry (POST /config/usergroupmap/_remove)
- Object access control
- Change the access mode of an object (POST /config/{entity}/{objectname}/_chmod)
- Change the usergroups of an object (POST /config/{entity}/{objectname}/_chgrp)
- Change the owners of an object (POST /config/{entity}/{objectname}/_chown)
- High Availability
- HA liveness check (GET /ping)
- HA state (GET /ha/state)
- HA master role (GET /ha/master)
- Become HA master (GET /ha/master/_set)
- Set HA overrule flag (GET /ha/overrule/_set)
- List HA controllers (GET /ha/controllers)
- Sync image to controller (GET /ha/syncimage/{name})
- File downloads
- List downloadable files (GET /files)
- Download a file (GET /files/{filename})
- Authenticated file-access check (GET /filesauth)
- Database tables
- Get hashes of all tables (GET /table/hashes)
- Get raw data for one table (GET /table/data/{name})
- Artefact checksums
- Get all artefact checksums (GET /hash)
- Get the checksums of an object (GET /hash/{object_type}/{name})
- Get the checksum of one artefact (GET /hash/{object_type}/{name}/{file})
- Provisioning tracker
- BitTorrent announce (GET /announce)
- BitTorrent scrape (GET /scrape)
- Plugin import and export
- Import data via an import plugin (POST /import/{name})
- Export data via an export plugin (GET /export/{name})
- TPM authentication
- Obtain a node token via TPM attestation (POST /tpm/{nodename})
- Asynchronous requests
- Poll the result of a configuration operation (GET /config/status/{request_id})
- Error handling
- Full spec JSON
Design decisions
-
No implementation of 300 (redirects)
-
Not all errors are implemented
-
Not all methods are supported, only GET and POST
-
All POST request body are required to have valid JSON (RFC 8259). The server will not validate for the client, simply reject any malformed request. There are ways to format and validate it in Linux / python.
-
Monitoring end-points are provided on /monitor.
-
HTTP codes must also be passed back
Changelog
Removals:
-
Removal of lweb (replaced by REST API), same port (7050)
-
auto creation of nodes is removed (Create=True), also removing the nodeprefix and nodedigits configuration items
Changes:
-
newfieldname can be used for cloning ({name}/_clone) and renaming ({name})
-
dhcp configuration has been removed from cluster level and moved to network (now enables/disables per network)
New features:
General:
-
Templating jinja2
-
Standardized jinja2 variables available in the LUNA installer for further customization
-
Full URI is also required in the request body and response body
-
URI is consistent with request and response body
Authentication
- Role based authentication, default group: admin
Provisioning
-
Provisioning default is torrent
-
Fallback via /files/{tarball} via webservice
-
Configurable via the cluster endpoint, override possible on group or node level
-
Configurable provisioning allows for future provisioning methods such as rsync, kickstart or anything scriptable
Group configuration:
-
Netboot (offering PXE menu or minimized boot menu -> LOCALDISK)
-
Localinstall (triggers Grub2 installation)
Network:
-
API to get next available IP (can be called manually) /config/network/_nextfreeip
-
Renumbering will not be done if:
-
the new group has the same network interfaces and networks
-
the IP is still valid in the new group
NTP configuration (cluster/network):
-
Can be configured cluster wide
-
Override possible on network level
BMC setup
-
Added gateway configuration (taken from network configuration)
-
Added NTP configuration (taken from network configuration)
Secrets
- Secrets can be configured on group or node level. These are placed inside the OSimage, preventing placement of sensitive information in images.
OSimage:
-
Changing kernel can be done with (/config/osimage/{osimage}/kernel) automatic packing or without (/config/osimage/{osimage}
-
Cloning includes copying of the files, done by ZFS so it should be very quick
-
Distribution flag (default redhat) which should trigger different dracut/packing in future releases
Monitor
-
Added monitoring endpoints for nodes
-
Self-monitoring daemon (/monitor/service/luna2)
Service control via daemon API
- Monitoring & control of dhcp and dns
Rest resources
Note: There is no cluster configuration. This is to be done by the ini files to prevent breaking installations
Examples
http://host:port/config/node/{node}
Structure of the URI
-
host and port define the host and port where the application lives
-
config is the context for updating or deleting the node at {node}
All POST Method(s) requires a valid token to get the response. Except /token
All Get Method will get the minimal response if the token isn’t set in the headers.
the ** key will hold the token against the apis.
Initially, Tokens are sha256 encoded.
URI Structure
See Luna2 REST API URI Structure
Fields
API Usage
Authenticate against the API (POST /token)
When talking to the API, a token is required. The token can be obtained from the token endpoint.
Request
POST /token
Request header
Request body
{
"username": "luna",
"password": "luna"
}
Response body
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
}
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if the credentials are invalid
HTTP 400 Bad request
when the request is invalid (field definitions)
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Who am I (GET /whoami)
Returns the Luna user the token belongs to: name, id, authentication source, whether it is an admin user, the usergroups it is a member of with the role held in each, and the usergroups among those that carry the hardware flag. Any valid token may ask. The account from the configuration file has id 0, is always an admin user and is a member of no usergroup.
Request
GET /whoami
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"user": "jdoe",
"id": 3,
"source": "ldap",
"admin": false,
"usergroups": {
"physics": "manager",
"chemistry": "reader"
},
"hardware": [
"physics"
]
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned for the token of a delegate user, which may only obtain tokens for others, and for a node token.
Version
A very simple endpoint. No auth required and no modifications allowed.
Returned:
-
Luna version
-
API version it supports (this document)
-
Commit (from Git)
Get version (GET /version)
Request
GET /version
Response body
{
"version": {
"luna": "2.0.0001",
"api": 1,
"commit": "hex(commit)"
}
}
Request header
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Booting
The boot menu entry will give out one of several templates (see the Boot process page):
-
templ_boot_ipxe.cfg (default)
-
templ_boot_disk.cfg
-
templ_boot_ipxe_short.cfg
The controller writes out the DHCP configuration. The normal iPXE menu is served when the
bootmenu
and
netboot
flags have been set to True.
Node is known |
Bootmenu |
Netboot |
Template |
|
|---|---|---|---|---|
1 |
Yes |
False |
True |
Short |
2 |
Yes |
True |
True |
Normal |
3 |
Yes |
Any |
False |
Disk |
4 |
No |
- |
- |
Normal |
The DHCP configuration is changed to reflect booting off different templates.
2 + 4:
host node001 {
hardware ethernet 18:c0:4d:45:00:eb;
fixed-address 10.141.0.1;
}
1:
host node001 {
hardware ethernet 18:c0:4d:45:00:eb;
fixed-address 10.141.0.1;
filename "http://10.141.255.254:7050/boot/short"
}
3:
host node001 {
hardware ethernet 18:c0:4d:45:00:eb;
fixed-address 10.141.0.1;
filename "http://10.141.255.254:7050/boot/disk"
}
Boot by MAC (or port detection)
The node will do a discovery (auto menu selection)
Request
GET /boot/search/mac/18:c0:4d:45:00:eb
Response
The response is an iPXE script which can be booted from.
#!ipxe
imgfetch -n kernel http://10.141.255.254:7050/boot/compute-vmlinuz-4.18.0-372.26.1.el8_6.x86_64
imgload kernel
imgargs kernel root=luna luna.bootproto=static luna.mac=18:c0:4d:45:00:eb luna.ip=10.141.0.1/16 luna.url=http://10.141.255.254:7050/luna luna.node=node001 luna.hostname=node001.cluster luna.service=0 initrd=initrd.img
imgfetch --name initrd.img http://10.141.255.254:7050/boot/compute-initramfs-4.18.0-372.26.1.el8_6.x86_64
imgexec kernel
Manual boot
Request
GET /boot/manual/hostname/node002/18:c0:4d:45:00:eb
Response
The controller will immediately change the hostname in the backend to reflect the change, removing the previous settings for the entry.
The response will allow booting from an alternative hostname. Note the changed
luna.node
and
luna.hostname
parameter.
#!ipxe
imgfetch -n kernel http://10.141.255.254:7050/boot/compute-vmlinuz-4.18.0-372.26.1.el8_6.x86_64
imgload kernel
imgargs kernel root=luna luna.bootproto=static luna.mac=18:c0:4d:45:00:eb luna.ip=10.141.0.1/16 luna.url=http://10.141.255.254:7050/luna luna.node=node002 luna.hostname=node002.cluster luna.service=0 initrd=initrd.img
imgfetch --name initrd.img http://10.141.255.254:7050/boot/compute-initramfs-4.18.0-372.26.1.el8_6.x86_64
imgexec kernel
iPXE boot menu (GET /boot)
This endpoint is requested by the node's iPXE bootloader and is served without a token.
Request
GET /boot
Response body A rendered iPXE script (the main boot menu) is returned. The Luna controller fills in the available nodes, groups and controller details before serving it.
#!ipxe
[...]
Response header
HTTP 200 OK
will be expected to be returned.
Shortened iPXE boot menu (GET /boot/short)
This endpoint is requested by the node's iPXE bootloader and is served without a token.
Request
GET /boot/short
Response body A rendered iPXE script is returned. This is a shortened variant of the main boot menu that omits the per-node and per-group listings.
#!ipxe
[...]
Response header
HTTP 200 OK
will be expected to be returned.
Boot from local disk (GET /boot/disk)
This endpoint is requested by the node's iPXE bootloader and is served without a token.
Request
GET /boot/disk
Response body A rendered iPXE script that instructs the node to boot from its local disk is returned.
#!ipxe
[...]
sanboot --no-describe --drive 0x80
[...]
Response header
HTTP 200 OK
will be expected to be returned.
Boot lookup by MAC address (GET /boot/search/mac/{macaddress})
This endpoint is requested by the node's iPXE bootloader and is served without a token.
Request
GET /boot/search/mac/aa:bb:cc:dd:ee:ff
Response body The server performs discovery on the supplied MAC address (looking the MAC up via SNMP port-detection if that has been enabled) and returns a rendered iPXE script populated with the matched node's image, kernel, initrd, kernel options and network details.
#!ipxe
[...]
Response header
HTTP 200 OK
will be expected to be returned.
Manual boot by group (GET /boot/manual/group/{groupname}/{macaddress})
This endpoint is requested by the node's iPXE bootloader and is served without a token.
Request
GET /boot/manual/group/compute/aa:bb:cc:dd:ee:ff
Response body The server picks the first available node in the chosen group (creating one if none is available), assigns the supplied MAC address to it, and returns a rendered iPXE script populated with that node's image, kernel, initrd, kernel options and network details.
#!ipxe
[...]
Response header
HTTP 200 OK
will be expected to be returned.
Manual boot by hostname (GET /boot/manual/hostname/{hostname}/{macaddress})
This endpoint is requested by the node's iPXE bootloader and is served without a token.
Request
GET /boot/manual/hostname/node001/aa:bb:cc:dd:ee:ff
Response body The server performs discovery on the supplied hostname (looking the MAC up via SNMP port-detection if that has been enabled), assigns the supplied MAC address to the matched node, and returns a rendered iPXE script populated with that node's image, kernel, initrd, kernel options and network details.
#!ipxe
[...]
Response header
HTTP 200 OK
will be expected to be returned.
Boot role (GET /boot/roles/{role})
Request
GET /boot/roles/<role>
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body Unlike the other boot endpoints, this returns a JSON payload containing the role's target and its base64-encoded script data.
{
"target": "[...]",
"script": "[...]"
}
Response header
HTTP 200 OK
will be expected to be returned.
Boot script (GET /boot/scripts/{script})
Request
GET /boot/scripts/<script>
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body Like the role endpoint, this returns a JSON payload containing the script's target and its base64-encoded script data.
{
"target": "[...]",
"script": "[...]"
}
Response header
HTTP 200 OK
will be expected to be returned.
Boot profile (GET /boot/profiles/{profile})
Returns what the installer needs to apply one profile: its files with content, path, owner and mode, and its service with the action. Called by the node during installation.
Token is required: a node's provision token (for any profile), or the token of the controller account or an admin user. Unset owners and modes are filled in with root:root and 644, and resolved_owner carries the owner as numeric ids, resolved on the controller. File content is base64 encoded.
Request
GET /boot/profiles/sysctl-hpc
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"profile": {
"sysctl-hpc": {
"scope": "static",
"service": "systemd-sysctl",
"action": "restart",
"enabled": true,
"files": [
{
"name": "90-hpc.conf",
"content": "dm0uc3dhcHBpbmVzcyA9IDEK",
"path": "/etc/sysctl.d/90-hpc.conf",
"owner": "root:root",
"mode": "644",
"resolved_owner": "0:0"
}
]
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the token belongs to a user other than the controller account or an admin user.
HTTP 404 Not found
is returned when the profile does not exist.
Kickstart installation template (GET /kickstart/install/{node})
This endpoint is requested by the node during provisioning and is served without a token.
Request
GET /kickstart/install/node001
Response body A rendered kickstart installation template for the named node is returned, populated with the node's group, OS image, distribution, partitioning, BMC setup, interfaces, pre/part/post scripts, provisioning method and related values.
[...]
%post
[...]
%end
Response header
HTTP 200 OK
will be expected to be returned.
Switch ZTP recipe (GET /boot/switch/{name})
This endpoint is requested by the switch during zero-touch provisioning (ZTP) and is served without a token.
Returns the ZTP recipe for the switch as JSON (Content-Type: application/json). The image step is present only when the switch has a default_url. The second step points at the switch's command list; it is a startup file when the switch carries its own ZTP configuration in YAML format, otherwise a command list. URLs use the controller's API endpoint, or the web server's protocol and port when the switch's url_protocol is plain; the switch's url_server replaces the controller address when set.
Request
GET /boot/switch/switch01
Response body A ZTP recipe in JSON is returned:
{
"ztp": {
"01-image": {
"image": {
"install": {
"url": "https://10.141.255.254:7050/files/switch-os.bin",
"skip-reboot": false
}
},
"halt-on-failure": true,
"description": "switch01: ensure correct OS version, reboot, then continue"
},
"02-commands-list": {
"url": "https://10.141.255.254:7050/boot/switch/switch01/commands",
"clear-config": "true",
"save-config": "true",
"halt-on-failure": true,
"description": "switch01: apply identity + services, persist, disable ZTP"
},
"03-connectivity-check": {
"connectivity-check": {
"ping-hosts": [
"10.141.255.254"
],
"ping-count": 5,
"ignore-result": true
},
"description": "switch01: sanity-check mgmt reachability"
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 404 Not found
is returned when the switch does not exist or the ZTP template is missing. The body is JSON with the reason in message:
{
"message": "switch switch01 does not exist",
"ipaddress": "10.141.255.254",
"webserver_protocol": "https",
"webserver_port": "7050",
"template": "templ_boot_failed.cfg"
}
Switch ZTP command list (GET /boot/switch/{name}/commands)
This endpoint is requested by the switch during zero-touch provisioning and is served without a token.
Returns plain text (Content-Type: text/plain): the switch's own ZTP configuration (ztpconfig, stored base64 encoded and served decoded) when one is set, otherwise a minimal default that sets the host name and enables SSH.
Request
GET /boot/switch/switch01/commands
Response body The default command list is returned when the switch has no ZTP configuration of its own:
# generated by Luna for switch01
nv set system hostname switch01
nv set system ssh-server state enabled
nv config apply -y
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 404 Not found
is returned when the switch does not exist. The body is JSON with the reason in message.
Luna installation template (GET boot/install/{node})
The
luna.node
and
luna.hostname
are passed through the boot parameters and are used to retrieve the installation template. Note that the API must verify that the request is originating from the node itself by checking the IP address (i.e. 10.141.0.1 can only request a template belonging to node001).
Request
GET /boot/install/node001
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response
The response would be a tailored installation script for this node (See #pre, #part, #postscripts) in plain text.
export LUNA_IMAGEFILE=''
export LUNA_OSIMAGE=''
export LUNA_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MCwiZXhwIjoxNzM5MjcxNzA2fQ.2HUmy8sL5oFtzayjWBfUeK0huezEk6rA9qt41_VixCU"
export DECODE=""
## ----------- useful variable exports -----------
export _HOSTNAME="node001"
export _SYSTEMROOT="/sysroot"
export _BOOTIF=${LUNA_BOOTIF}
## -----------------------------------------------
export INSECURE='--insecure'
if [ -n "${LUNA_BOOTIF}" ]; then
export INTERFACE="--interface ${LUNA_BOOTIF}"
fi
if [ "$(echo LUNA_API_PROTOCOL | grep ':')" ]; then
export LUNA_URL="http://[10.141.255.254]:7050"
else
export LUNA_URL="http://10.141.255.254:7050"
fi
base64 --help &> /dev/null
if [ "$?" == "0" ]; then
DECODE=1
fi
if [ ! "$DECODE" ]; then
echo "Luna2: --WARNING-- base64 decoder not available. This will impair the installer"
fi
function update_status {
json='{"monitor": { "status": { "node001": { "state": "'$1'" } } } }'
curl $INTERFACE $INSECURE -X POST -H "x-access-tokens: $LUNA_TOKEN" -H "Content-Type: application/json" -d "$json" -s "${LUNA_URL}/monitor/node/node001"
}
function update_system_info {
dmidecode --help &> /dev/null
ret=$?
if [ "$ret" == "0" ]; then
vendor=$(dmidecode -s system-manufacturer)
assettag=$(dmidecode -s system-serial-number)
json='{"config": {"node": { "node001": { "vendor": "'$vendor'", "assettag": "'$assettag'" } } } }'
curl $INTERFACE $INSECURE -X POST -H "x-access-tokens: $LUNA_TOKEN" -H "Content-Type: application/json" -d "$json" -s "${LUNA_URL}/config/node/node001"
else
echo "Luna2: dmidecode not found and could therefor not update system information"
fi
}
function update_node_ip {
json='{"config": {"node": {"node001": {"name": "node001", "interfaces": [{"interface": "BOOTIF", "force": true, "ipaddress": "'$1'"}]}}}}'
curl $INTERFACE $INSECURE -X POST -H "x-access-tokens: $LUNA_TOKEN" -H "Content-Type: application/json" -d "$json" -s "${LUNA_URL}/config/node/node001"
}
function lunainit {
if [ ! -d /lunatmp ]; then
mkdir /lunatmp
fi
if [ ! -d //sysroot ]; then
echo "Luna2: Warning! /sysroot did not exist! it's unexpected. I will create it and try to continue"
mkdir //sysroot
fi
}
function dynamic_ip_check {
if [ "${LUNA_BOOTPROTO}" == "dhcp" ]; then
echo "Luna2: I need to update luna to reflect my dynamic IP address"
if [ "${LUNA_BOOTIF}" ]; then
MY_IP=$(ip a show dev ${LUNA_BOOTIF}|grep -oE "inet [0-9\.]+"|grep -oE "[0-9\.]+")
if [ "${MY_IP}" ]; then
update_node_ip $MY_IP
else
echo "Luna2: Could not figure out my IP address"
fi
else
echo "Luna2: BOOTIF is not defined"
fi
fi
}
...
...
...
Group configuration
Get a list of groups (GET /config/group)
Request
GET /config/group
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"group": {
"compute": {
"bmcsetup": true,
"bmcsetupname": "gigabyte",
"domain": "cluster",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
},
{
"interface": "BMC",
"network": "ipmi"
},
{
"interface": "ib0",
"network": "ib"
}
],
"osimage": "compute",
"osimagetag": "versionx",
"partscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"postscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"prescript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"provision_interface": null,
"netboot": true,
"bootmenu": false,
"comment": "Default group",
"provision_method": "torrent",
"provision_fallback": "http"
},
"compute-ib": {
"bmcsetup": true,
"bmcsetupname": "gigabyte",
"domain": "cluster",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
},
{
"interface": "BMC",
"network": "ipmi"
},
{
"interface": "ib0",
"network": "ib"
}
],
"osimage": "compute",
"partscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"postscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"prescript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"provision_interface": null,
"netboot": true,
"bootmenu": false,
"comment": "Default group",
"provision_method": "torrent",
"provision_fallback": "http",
"_override": false
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get group information (GET /config/group/{group})
Request
GET /config/group/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"group": {
"compute": {
"bmcsetup": true,
"bmcsetupname": "gigabyte",
"domain": "cluster",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
},
{
"interface": "BMC",
"network": "ipmi"
},
{
"interface": "ib0",
"network": "ib"
}
],
"osimage": "compute",
"osimagetag": "versionx",
"partscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"postscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"prescript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"provision_interface": null,
"netboot": true,
"bootmenu": false,
"comment": "Default group",
"provision_method": "torrent",
"provision_fallback": "http",
"_override": false
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get a list members of the groups (GET /config/group/{group}/_member)
Request
GET /config/group/{group}/_member
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"group": {
"compute": {
"members": [
"node001",
"node002",
"node003",
"node004"
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update & Rename(By newgroupname) group information (POST /config/group/{group})
Request
POST /config/group/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"group": {
"compute": {
"newgroupname": "compute-gpu",
"bmcsetup": true,
"bmcsetupname": "gigabyte",
"domain": "cluster",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
},
{
"interface": "BMC",
"network": "ipmi"
},
{
"interface": "ib0",
"network": "ib"
}
],
"osimage": "compute",
"osimagetag": "versionx",
"partscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"postscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"prescript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"provision_interface": null,
"netboot": true,
"bootmenu": false,
"comment": "Default group",
"provision_method": "torrent",
"provision_fallback": "http",
"_override": false
}
}
}
}
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 201 Created
will be expected to be returned when a new object is created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Clone (By newgroupname) a group (POST /config/group/{group}/_clone) 
Request
POST /config/group/compute/_clone
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"group": {
"compute": {
"newgroupname": "compute-gpu",
"bmcsetup": true,
"bmcsetupname": "gigabyte",
"domain": "cluster",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
},
{
"interface": "BMC",
"network": "ipmi"
},
{
"interface": "ib0",
"network": "ib"
}
],
"osimage": "compute",
"osimagetag": "versionx",
"partscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"postscript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"prescript": "IyEvYmluL2Jhc2gKZXhpdCAw",
"provision_interface": null,
"netboot": true,
"bootmenu": false,
"comment": "Default group",
"provision_method": "torrent",
"provision_fallback": "http"
}
}
}
}
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 201 Created
will be expected to be returned when a new object is created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Deleting a group (GET /config/group/{group}/_delete)
Request
GET /config/group/compute/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get group interface information (GET /config/group/{group}/interfaces)
Request
GET /config/group/compute/interfaces
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"group": {
"compute": {
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
},
{
"interface": "BMC",
"network": "ipmi"
},
{
"interface": "ib0",
"network": "ib"
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update group interface information (POST /config/group/{group}/interfaces)
The interfaces can accept updates to one or more interfaces.
Request
POST /config/group/compute/interfaces
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
},
{
"interface": "BMC",
"network": "ipmi"
},
{
"interface": "ib0",
"network": "ib"
}
]
}
}
}
}
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 201 Created
will be expected to be returned when created
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist (group)
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Retrieve group interface information (GET /config/group/{group}/interfaces/{interface})
Request
GET /config/group/compute/interfaces/BOOTIF
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
}
]
}
}
}
}
Response body
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist (group)
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete group interface (GET /config/group/{group}/interfaces/{interface}/_delete)
Request
GET /config/group/compute/interfaces/BOOTIF/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist (group)
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Push the osimage to all nodes in the group (POST /config/group/{name}/_ospush)
Request
POST /config/group/compute/_ospush
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"osimage": "compute-image"
}
}
}
}
Response body
This is an asynchronous operation. The push is queued and a request_id is returned that can be polled for progress (see Tracking asynchronous requests).
{
"message": "queued",
"request_id": "1781082941.3238328347230542"
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when the push could not be started.
Get the group disk layout (GET /config/group/{name}/disklayout)
Returns only the disk layout of the group, in the same shape the full group information uses. The value is base64-encoded JSON; _disklayout_source says where it comes from: group or default (empty).
Request
GET /config/group/compute/disklayout
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"group": {
"compute": {
"disklayout": "eyJ2ZXJzaW9uIjogMiwgInNldHMiOiBbLi4uXX0=",
"_disklayout_source": "group"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not Found
is returned when the group does not exist or is not visible to the token's user.
Get the group mounts document (GET /config/group/{name}/mounts)
Returns only the resolved network mounts document of the group (cluster, group; the most specific level that holds a document wins outright). The value is base64-encoded JSON; _mounts_source says where it comes from: group, cluster or default (empty).
Request
GET /config/group/compute/mounts
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"group": {
"compute": {
"mounts": "eyJ2ZXJzaW9uIjogMSwgIm1vdW50cyI6IFt7InBhdGgiOiAiL2RhdGEiLCAidHlwZSI6ICJuZnMiLCAic2VydmVyIjogImNvbnRyb2xsZXIiLCAic291cmNlIjogIi9leHBvcnQvZGF0YSIsICJvcHRpb25zIjogInJ3LGhhcmQifV19",
"_mounts_source": "cluster"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not Found
is returned when the group does not exist or is not visible to the token's user.
Add or update a group mount (POST /config/group/{name}/mounts)
Adds one entry to the group's network mounts document, or updates the entry with the same path: the fields given replace those stored, the others stay. mount is a single entry as base64-encoded JSON, with the fields described under Add or update a cluster mount. A group without a document of its own first receives a copy of the document it currently resolves to, and the message then says so; from then on the group keeps its own document.
Request
POST /config/group/compute/mounts
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"mount": "eyJwYXRoIjogIi9kYXRhIiwgInR5cGUiOiAibmZzIiwgInNlcnZlciI6ICJjb250cm9sbGVyIiwgInNvdXJjZSI6ICIvZXhwb3J0L2RhdGEiLCAib3B0aW9ucyI6ICJydyxoYXJkIn0="
}
}
}
}
Response body
{
"message": "Mount /data added to group compute."
}
Response header
HTTP 201 Created
will be expected to be returned when the entry was added or updated, or the document was already as requested.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no mount is given, the entry has no path, or the resulting document is invalid.
HTTP 403 Forbidden
is returned when the token's user may not change the group, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the group does not exist or the token's user may not read it, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Remove a group mount (POST /config/group/{name}/mounts/_remove)
Removes the entry with the given path from the group's network mounts document. A group without a document of its own first receives a copy of the document it resolves to, so the entry is removed for this group only. An emptied document stays in place and still overrides the levels above it.
Request
POST /config/group/compute/mounts/_remove
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"path": "/data"
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no path is given or the document the group sees holds no entry at that path.
HTTP 403 Forbidden
is returned when the token's user may not change the group, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the group does not exist or the token's user may not read it, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Assign a profile to a group (POST /config/group/{name}/profiles)
Adds one profile to the group's own profile assignments, beside the ones it already has. Profiles assigned at a higher level are not touched.
Request
POST /config/group/compute/profiles
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"profile": "gpu"
}
}
}
}
Response body
{
"message": "Profile gpu assigned to group compute."
}
Response header
HTTP 201 Created
will be expected to be returned when the profile was assigned, or was already assigned to the group.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no profile is given or the profile does not exist.
HTTP 403 Forbidden
is returned when the token's user may not change the group, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the group does not exist or the token's user may not read it, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Unassign a profile from a group (POST /config/group/{name}/profiles/_unassign)
Removes one profile from the group's own profile assignments.
Request
POST /config/group/compute/profiles/_unassign
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"profile": "gpu"
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no profile is given or the profile is not assigned to the group.
HTTP 403 Forbidden
is returned when the token's user may not change the group, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the group does not exist or the token's user may not read it, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Preview a firmware push to a group (GET /config/group/{name}/firmware/_preview)
Answers what a firmware push to the group would do, per node, without doing any of it. No BMC is contacted: the answer comes from the stored inventory and the firmware catalogue, so it also works for powered-off nodes. Nodes that would be updated or are already up to date are listed under ready; nodes that cannot be updated are grouped by reason under skipped; summary gives the counts.
Request
GET /config/group/compute/firmware/_preview
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"firmware": {
"preview": {
"ready": [
{
"node": "node001",
"hardware": [
"Supermicro",
"X12DPT-B6"
],
"components": [
{
"component": "BMC",
"entry": "x12-bmc",
"wanted": "01.04.08",
"running": "01.03.12",
"updateable": true,
"imagefile": "x12-bmc-010408.bin"
}
],
"differs": [
{
"component": "BMC",
"entry": "x12-bmc",
"wanted": "01.04.08",
"running": "01.03.12",
"updateable": true,
"imagefile": "x12-bmc-010408.bin"
}
]
}
],
"skipped": {
"no inventory; has this node booted?": [
"node004"
]
},
"summary": [
"1 node(s) would change, 0 already as the catalogue asks",
"1 skipped: no inventory; has this node booted?"
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not Found
is returned when the group does not exist, the token's user may not read it, or it has no nodes.
Push firmware to all nodes in the group (POST /config/group/{name}/_firmwarepush)
Queues a firmware update for every node of the group whose running versions differ from the firmware catalogue. Members are read when the request is made. Nodes already on the catalogue version, and nodes that cannot be updated (for example without inventory), are counted in the message rather than queued. The optional component limits the push to one component. This is an asynchronous operation: poll the returned request_id with GET /config/status/{request_id}; the outcome per node is also available from the firmware catalogue status.
Request
POST /config/group/compute/_firmwarepush
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"component": "BMC"
}
}
}
}
Response body
{
"message": "firmware update queued for 3 node(s), 1 skipped: no inventory; has this node booted?",
"request_id": "1761738420.5531207630414211"
}
Response header
HTTP 200 OK
will be expected to be returned with the request_id in the body.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when the name or the request body is malformed.
HTTP 403 Forbidden
is returned when the token's user may not operate the group or change a catalogue entry the push would apply.
HTTP 404 Not Found
is returned when the group does not exist or has no nodes, or no node has anything to update.
Push a BIOS configuration to all nodes in the group (POST /config/group/{name}/_biospush)
Queues a stored BIOS configuration to be applied to every node of the group; members are read when the request is made. biosconfig names the configuration; when it is left out, the group must have one assigned, and each node then receives its own assignment, else the group's. version_match is optional and sets how a BIOS version difference between the configuration and a node is handled: strict refuses, warn proceeds and reports it, ignore does not compare; the default comes from the daemon configuration (warn). This is an asynchronous operation: poll the returned request_id with GET /config/status/{request_id}.
Request
POST /config/group/compute/_biospush
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"group": {
"compute": {
"biosconfig": "compute-bios",
"version_match": "warn"
}
}
}
}
Response body
{
"message": "BIOS configuration compute-bios queued for 4 node(s)",
"request_id": "1761738480.2209861712514211"
}
Response header
HTTP 200 OK
will be expected to be returned with the request_id in the body.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no biosconfig is named and the group has none assigned, or the body is malformed.
HTTP 403 Forbidden
is returned when the token's user may not operate the group or change the BIOS configuration.
HTTP 404 Not Found
is returned when the group does not exist or has no nodes, or the configuration does not exist or holds no settings.
Node configuration
Get a list of nodes (GET /config/node)
Request
GET /config/node
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"node": {
"node001": {
"group": "compute",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet",
"ipaddress": "10.141.0.1"
},
{
"interface": "BMC",
"network": "ipmi",
"ipaddress": "10.148.0.1"
},
{
"interface": "ib0",
"network": "ib",
"ipaddress": "10.149.0.1"
}
],
"switch": "switch01",
"switchport": 1,
"service": false,
"setupbmc": true,
"status": "installer.completed",
"comment": null,
"osimage": null,
"osimagetag": null,
"prescript": null,
"postscript": null,
"partscript": null,
"netboot": true,
"bootmenu": false,
"provision_interface": null,
"provision_method": null,
"provision_fallback": null,
"tpm_uuid": null,
"tpm_pubkey": null,
"tpm_sha256": null,
"_override": false
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get node information (GET /config/node/{node})
Request
GET /config/node/node001
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"node": {
"node001": {
"group": "compute",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet",
"ipaddress": "10.141.0.1"
},
{
"interface": "BMC",
"network": "ipmi",
"ipaddress": "10.148.0.1"
},
{
"interface": "ib0",
"network": "ib",
"ipaddress": "10.149.0.1"
}
],
"switch": "switch01",
"switchport": 1,
"service": false,
"setupbmc": true,
"status": "installer.completed",
"comment": null,
"osimage": null,
"osimagetag": null,
"prescript": null,
"postscript": null,
"partscript": null,
"netboot": true,
"bootmenu": false,
"provision_interface": null,
"provision_method": null,
"provision_fallback": null,
"tpm_uuid": null,
"tpm_pubkey": null,
"tpm_sha256": null,
"_override": false
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update node information (POST /config/node/{node})
Renaming a node is done by setting the
newhostname
field
Interfaces can be updated in bulk via the {node}, or single items via the {node}/interfaces
Request
POST /config/node/{node}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"group": "compute",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet",
"ipaddress": "10.141.0.1"
},
{
"interface": "BMC",
"network": "ipmi",
"ipaddress": "10.148.0.1"
},
{
"interface": "ib0",
"network": "ib",
"ipaddress": "10.149.0.1"
}
],
"switch": "switch01",
"switchport": 1,
"service": false,
"setupbmc": true,
"status": "installer.completed",
"comment": null,
"osimage": null,
"osimagetag": null,
"prescript": null,
"postscript": null,
"partscript": null,
"netboot": true,
"bootmenu": false,
"provision_interface": null,
"provision_method": null,
"provision_fallback": null,
"tpm_uuid": null,
"tpm_pubkey": null,
"tpm_sha256": null
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 201 Created
will be expected to be returned when a new object has been created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Clone a node (POST /config/node/{node}/_clone) 
Renaming a node is done by setting the
newhostname
field
Interfaces can be updated in bulk via the {node}, or single items via the {node}/interfaces
Request
POST /config/node/{node}/_clone
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"group": "compute",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet",
"ipaddress": "10.141.0.1"
},
{
"interface": "BMC",
"network": "ipmi",
"ipaddress": "10.148.0.1"
},
{
"interface": "ib0",
"network": "ib",
"ipaddress": "10.149.0.1"
}
],
"switch": "switch01",
"switchport": 1,
"service": false,
"setupbmc": true,
"status": "installer.completed",
"comment": null,
"osimage": null,
"osimagetag": null,
"prescript": null,
"postscript": null,
"partscript": null,
"netboot": true,
"bootmenu": false,
"provision_interface": null,
"provision_method": null,
"provision_fallback": null,
"tpm_uuid": null,
"tpm_pubkey": null,
"tpm_sha256": null
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 201 Created
will be expected to be returned when a new object has been created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Deleting a node (GET /config/node/{node}/_delete)
Request
GET /config/node/node001/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 401 Not Found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Listing node interfaces (GET /config/node/{node}/interfaces)
Request
GET /config/node/node001/interfaces
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"node": {
"node001": {
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet",
"ipaddress": "10.141.0.1"
},
{
"interface": "BMC",
"network": "ipmi",
"ipaddress": "10.148.0.1"
},
{
"interface": "ib0",
"network": "ib",
"ipaddress": "10.149.0.1"
}
]
}
}
}
}
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 401 Not Found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Updating node interfaces (POST /config/node/{node}/interfaces)
Request
POST /config/node/node001/interfaces
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet",
"ipaddress": "10.141.0.1"
},
{
"interface": "BMC",
"network": "ipmi",
"ipaddress": "10.148.0.1"
},
{
"interface": "ib0",
"network": "ib",
"ipaddress": "10.149.0.1"
}
]
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Showing node interfaces (GET /config/node/{node}/interfaces/{interface})
Request
GET /config/node/node001/interfaces/BOOTIF
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"node": {
"node001": {
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet",
"ipaddress": "10.141.0.1"
}
]
}
}
}
}
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete node interfaces (GET /config/node/{node}/interfaces/{interface}/_delete)
Request
GET /config/node/node001/interfaces/BOOTIF/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Grab an osimage from a node (POST /config/node/{name}/_osgrab)
Request
POST /config/node/node001/_osgrab
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"osimage": "compute-image",
"dryrun": false
}
}
}
}
Response body
This is an asynchronous operation. The grab is queued and a request_id is returned that can be polled for progress (see Tracking asynchronous requests). On a high-availability setup where this controller is not the master, the request is forwarded and the message reflects that.
{
"message": "queued",
"request_id": "1781083867.650934521872381"
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when the grab could not be started.
Push an osimage to a node (POST /config/node/{name}/_ospush)
Request
POST /config/node/node001/_ospush
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"osimage": "compute-image"
}
}
}
}
Response body
This is an asynchronous operation. The push is queued and a request_id is returned that can be polled for progress (see Tracking asynchronous requests).
{
"message": "queued",
"request_id": "1781084659.3656888195114211"
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when the push could not be started.
Get the node disk layout (GET /config/node/{name}/disklayout)
Returns only the resolved disk layout of the node, in the same shape the full node information uses, so a booting node can read the layout it is about to apply. The value is base64-encoded JSON; _disklayout_source says where it comes from: node, group or default (empty).
Request
GET /config/node/node001/disklayout
Request header
An administrator token, or the node's own node token (see Obtain a node token via TPM attestation), is accepted.
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"node": {
"node001": {
"disklayout": "eyJ2ZXJzaW9uIjogMiwgInNldHMiOiBbLi4uXX0=",
"_disklayout_source": "group"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used for another node.
HTTP 404 Not Found
is returned when the node does not exist or is not visible to the token's user.
Get the node mounts document (GET /config/node/{name}/mounts)
Returns only the resolved network mounts document of the node (cluster, group and node; the most specific level that holds a document wins outright). The value is base64-encoded JSON; _mounts_source says where it comes from: node, group, cluster or default (empty).
Request
GET /config/node/node001/mounts
Request header
An administrator token, or the node's own node token (see Obtain a node token via TPM attestation), is accepted.
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"node": {
"node001": {
"mounts": "eyJ2ZXJzaW9uIjogMSwgIm1vdW50cyI6IFt7InBhdGgiOiAiL2RhdGEiLCAidHlwZSI6ICJuZnMiLCAic2VydmVyIjogImNvbnRyb2xsZXIiLCAic291cmNlIjogIi9leHBvcnQvZGF0YSIsICJvcHRpb25zIjogInJ3LGhhcmQifV19",
"_mounts_source": "cluster"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used for another node.
HTTP 404 Not Found
is returned when the node does not exist or is not visible to the token's user.
Add or update a node mount (POST /config/node/{name}/mounts)
Adds one entry to the node's network mounts document, or updates the entry with the same path: the fields given replace those stored, the others stay. mount is a single entry as base64-encoded JSON, with the fields described under Add or update a cluster mount. A node without a document of its own first receives a copy of the document it currently resolves to, and the message then says so; from then on the node keeps its own document.
Request
POST /config/node/node001/mounts
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"mount": "eyJwYXRoIjogIi9kYXRhIiwgInR5cGUiOiAibmZzIiwgInNlcnZlciI6ICJjb250cm9sbGVyIiwgInNvdXJjZSI6ICIvZXhwb3J0L2RhdGEiLCAib3B0aW9ucyI6ICJydyxoYXJkIn0="
}
}
}
}
Response body
{
"message": "Mount /data added to node node001."
}
Response header
HTTP 201 Created
will be expected to be returned when the entry was added or updated, or the document was already as requested.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no mount is given, the entry has no path, or the resulting document is invalid.
HTTP 403 Forbidden
is returned when the token's user may not change the node, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the node does not exist or the token's user may not read it, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Remove a node mount (POST /config/node/{name}/mounts/_remove)
Removes the entry with the given path from the node's network mounts document. A node without a document of its own first receives a copy of the document it resolves to, so the entry is removed for this node only. An emptied document stays in place and still overrides the levels above it.
Request
POST /config/node/node001/mounts/_remove
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"path": "/data"
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no path is given or the document the node sees holds no entry at that path.
HTTP 403 Forbidden
is returned when the token's user may not change the node, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the node does not exist or the token's user may not read it, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Assign a profile to a node (POST /config/node/{name}/profiles)
Adds one profile to the node's own profile assignments, beside the ones it already has. Profiles assigned at a higher level are not touched.
Request
POST /config/node/node001/profiles
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"profile": "gpu"
}
}
}
}
Response body
{
"message": "Profile gpu assigned to node node001."
}
Response header
HTTP 201 Created
will be expected to be returned when the profile was assigned, or was already assigned to the node.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no profile is given or the profile does not exist.
HTTP 403 Forbidden
is returned when the token's user may not change the node, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the node does not exist or the token's user may not read it, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Unassign a profile from a node (POST /config/node/{name}/profiles/_unassign)
Removes one profile from the node's own profile assignments.
Request
POST /config/node/node001/profiles/_unassign
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"profile": "gpu"
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no profile is given or the profile is not assigned to the node.
HTTP 403 Forbidden
is returned when the token's user may not change the node, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the node does not exist or the token's user may not read it, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Get the inventory summary of all nodes (GET /config/node/inventory)
Returns one summary line of hardware inventory per node that has inventory and that the token's user may read. Where a node has both an in-band snapshot (collected during installation) and a Redfish snapshot, the in-band one is shown.
Request
GET /config/node/inventory
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"node": {
"node001": {
"source": "inband",
"product": "SYS-120U-TNR",
"serial": "S41234567890123",
"cpu_count": 2,
"memory_mb": 262144,
"disk_count": 2,
"disk_total_gb": 960,
"gpu_count": 0,
"nic_count": 2,
"updated": "2026-10-20 09:14:02"
},
"node002": {
"source": "redfish",
"product": "SYS-120U-TNR",
"serial": "S41234567890124",
"cpu_count": 2,
"memory_mb": 262144,
"disk_count": 2,
"disk_total_gb": 960,
"gpu_count": 0,
"nic_count": 2,
"updated": "2026-10-21 11:02:45"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when no node has inventory.
Get node inventory (GET /config/node/{name}/inventory)
Returns the stored hardware inventory of the node: one snapshot per source (inband from installation, redfish from an out-of-band collection), each with its disks, GPUs, network interfaces and firmware components.
Request
GET /config/node/node001/inventory
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"node": {
"node001": {
"inventory": [
{
"source": "inband",
"manufacturer": "Supermicro",
"product": "SYS-120U-TNR",
"serial": "S41234567890123",
"cpu_model": "Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz",
"cpu_count": 2,
"memory_mb": 262144,
"bios_version": "1.4",
"bios_digest": null,
"bios_config": null,
"bios_config_digest": null,
"bios_config_content": null,
"bios_writable": null,
"disk_count": 1,
"disk_total_gb": 480,
"gpu_count": 0,
"nic_count": 1,
"updated": "2026-10-20 09:14:02",
"disks": [
{
"name": "sda",
"size_gb": 480,
"type": "SSD",
"model": "SAMSUNG MZ7L3480",
"serial": "S6KMNA0R123456"
}
],
"gpus": [],
"nics": [
{
"name": "eno1",
"mac": "3c:ec:ef:00:00:01",
"speed_mbps": 25000,
"capabilities": ""
}
],
"firmware": []
},
{
"source": "redfish",
"manufacturer": "Supermicro",
"product": "SYS-120U-TNR",
"serial": "S41234567890123",
"cpu_model": "Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz",
"cpu_count": 2,
"memory_mb": 262144,
"bios_version": "1.4",
"bios_digest": "5d41402abc4b2a76b9719d911017c592a6b0f1e2c3d4e5f60718293a4b5c6d7e",
"bios_config": null,
"bios_config_digest": null,
"bios_config_content": null,
"bios_writable": "1",
"disk_count": 1,
"disk_total_gb": 480,
"gpu_count": 0,
"nic_count": 1,
"updated": "2026-10-21 11:02:45",
"disks": [
{
"name": "sda",
"size_gb": 480,
"type": "SSD",
"model": "SAMSUNG MZ7L3480",
"serial": "S6KMNA0R123456"
}
],
"gpus": [],
"nics": [
{
"name": "eno1",
"mac": "3c:ec:ef:00:00:01",
"speed_mbps": 25000,
"capabilities": ""
}
],
"firmware": [
{
"name": "bmc",
"component": "X12DPT-B6",
"version": "01.03.12",
"updateable": 1,
"manufacturer": "Supermicro",
"release_date": "",
"software_id": "",
"related_item": "/redfish/v1/Managers/1"
}
]
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not Found
is returned when the node does not exist, the token's user may not read it, or it has no inventory.
Store a node inventory snapshot (POST /config/node/{name}/inventory)
Stores a hardware inventory snapshot for the node, replacing the previous snapshot from the same source (default inband). Counts and totals are calculated from the lists sent. The node's vendor and asset tag are updated from the snapshot, the Redfish snapshot taking precedence. This is normally called by the node during installation.
Request
POST /config/node/node001/inventory
Request header
An administrator token, or the node's own node token (see Obtain a node token via TPM attestation), is accepted.
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"inventory": {
"source": "inband",
"manufacturer": "Supermicro",
"product": "SYS-120U-TNR",
"serial": "S41234567890123",
"cpu_model": "Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz",
"cpu_count": 2,
"memory_mb": 262144,
"bios_version": "1.4",
"disks": [
{
"name": "sda",
"size_gb": 480,
"type": "SSD",
"model": "SAMSUNG MZ7L3480",
"serial": "S6KMNA0R123456"
}
],
"gpus": [],
"nics": [
{
"name": "eno1",
"mac": "3c:ec:ef:00:00:01",
"speed_mbps": 25000,
"capabilities": ""
}
],
"firmware": []
}
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when the body carries no inventory or is malformed.
HTTP 403 Forbidden
is returned when a node token is used for another node, or the token's user may not change the node.
HTTP 404 Not Found
is returned when the node does not exist, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Collect node inventory over Redfish (GET /config/node/{name}/inventory/_redfish)
Reads the node's hardware inventory from its BMC over Redfish and stores it as the node's redfish snapshot, beside the in-band one. The node needs a BMC interface with an address and a Redfish setup; it does not need to be provisioned or powered on. The request waits for the collection.
Request
GET /config/node/node001/inventory/_redfish
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the token's user may not operate the node.
HTTP 404 Not Found
is returned when the node does not exist, has no BMC address or Redfish setup, or the BMC could not be read, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Collect inventory over Redfish for several nodes (POST /config/node/inventory/_redfish)
Collects and stores Redfish inventory for a hostlist or for every node of a group; give one of the two. The request returns as soon as the work is scheduled, with the number of nodes queued. Collection runs in bounded batches, and the outcome per node is reported on the returned request_id, polled with GET /control/status/{request_id}.
Request
POST /config/node/inventory/_redfish
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
A group such as "compute" may be given instead of hostlist.
{
"config": {
"node": {
"hostlist": "node[001-004]"
}
}
}
Response body
{
"request_id": "1761730200.1234567812314211",
"config": {
"node": {
"inventory": {
"queued": 4
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when neither a hostlist nor a group is given, or the hostlist is invalid.
HTTP 403 Forbidden
is returned when the token's user may not operate one or more of the nodes.
HTTP 404 Not Found
is returned when the group does not exist or has no nodes.
Provision Redfish accounts for several nodes (POST /config/node/redfishaccounts/_provision)
Makes the Redfish accounts on the BMCs of a hostlist, or of every node of a group, match their Redfish setup, on demand rather than at the next installation. The request returns as soon as the work is scheduled. The outcome per node is reported on the returned request_id, polled with GET /control/status/{request_id}.
Request
POST /config/node/redfishaccounts/_provision
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
A hostlist such as "node[001-004]" may be given instead of group.
{
"config": {
"node": {
"group": "compute"
}
}
}
Response body
{
"request_id": "1761730260.4567890112314211",
"config": {
"node": {
"accounts": {
"queued": 4
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when neither a hostlist nor a group is given, or the hostlist is invalid.
HTTP 403 Forbidden
is returned when the token's user may not operate one or more of the nodes.
HTTP 404 Not Found
is returned when the group does not exist or has no nodes.
Grab a BIOS configuration from a node (POST /config/node/{name}/_biosgrab)
Reads the node's BIOS settings over Redfish and stores them as the named BIOS configuration, creating it when it does not exist. Only settings the machine's attribute registry marks as portable are kept, and the configuration's exclude list is applied; the message reports how many settings were stored and how many were not carried. The request waits for the BMC.
Request
POST /config/node/node001/_biosgrab
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"biosconfig": "compute-bios"
}
}
}
}
Response body
{
"message": "BIOS configuration compute-bios grabbed from node001: 412 setting(s) stored, 37 not carried"
}
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no biosconfig is given or the body is malformed.
HTTP 403 Forbidden
is returned when the token's user may not operate the node, or may not change or create the BIOS configuration.
HTTP 404 Not Found
is returned when the node or its BMC cannot be reached or read, the machine publishes no usable BIOS attributes or registry, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Push a BIOS configuration to a node (POST /config/node/{name}/_biospush)
Queues a stored BIOS configuration to be applied to the node. biosconfig names the configuration; when it is left out, the node must have a configuration assigned to it directly (an assignment inherited from its group is not enough), and that one is used. version_match is optional, as for the group push. This is an asynchronous operation: poll the returned request_id with GET /config/status/{request_id}.
Request
POST /config/node/node001/_biospush
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"biosconfig": "compute-bios",
"version_match": "warn"
}
}
}
}
Response body
{
"message": "BIOS configuration compute-bios queued for 1 node(s)",
"request_id": "1761738510.9047712345614211"
}
Response header
HTTP 200 OK
will be expected to be returned with the request_id in the body.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no biosconfig is named and the node has none assigned directly, or the body is malformed.
HTTP 403 Forbidden
is returned when the token's user may not operate the node or change the BIOS configuration.
HTTP 404 Not Found
is returned when the node does not exist, or the configuration does not exist or holds no settings.
Preview a firmware push to a node (GET /config/node/{name}/firmware/_preview)
Answers what a firmware push to the node would do, without doing any of it. No BMC is contacted: the answer comes from the stored inventory and the firmware catalogue, so it also works for a powered-off node. The response has the same shape as the group preview.
Request
GET /config/node/node001/firmware/_preview
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"firmware": {
"preview": {
"ready": [
{
"node": "node001",
"hardware": [
"Supermicro",
"X12DPT-B6"
],
"components": [
{
"component": "BMC",
"entry": "x12-bmc",
"wanted": "01.04.08",
"running": "01.03.12",
"updateable": true,
"imagefile": "x12-bmc-010408.bin"
}
],
"differs": [
{
"component": "BMC",
"entry": "x12-bmc",
"wanted": "01.04.08",
"running": "01.03.12",
"updateable": true,
"imagefile": "x12-bmc-010408.bin"
}
]
}
],
"skipped": {},
"summary": [
"1 node(s) would change, 0 already as the catalogue asks"
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not Found
is returned when the node does not exist or the token's user may not read it.
Push firmware to a node (POST /config/node/{name}/_firmwarepush)
Queues a firmware update for the node when its running versions differ from the firmware catalogue. The optional component limits the push to one component. This is an asynchronous operation: poll the returned request_id with GET /config/status/{request_id}.
Request
POST /config/node/node001/_firmwarepush
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"component": "BMC"
}
}
}
}
Response body
{
"message": "firmware update queued for 1 node(s)",
"request_id": "1761738540.3318046927714211"
}
Response header
HTTP 200 OK
will be expected to be returned with the request_id in the body.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when the name or the request body is malformed.
HTTP 403 Forbidden
is returned when the token's user may not operate the node or change a catalogue entry the push would apply.
HTTP 404 Not Found
is returned when the node does not exist or has nothing to update.
Cluster information
The cluster endpoint mostly read-only, and can not be used to modify the configuration. All the configuration is done via the ini and will require restarting the daemon.
Only configurable items are:
-
ntp_server
-
technical_contacts
-
provisioning_method
-
provision_fallback
-
debug
Get cluster information (GET /config/cluster)
Request
GET /config/cluster
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"cluster": {
"controller1": {
"status": "primary",
"ipaddr": "10.141.255.254",
"serverport": 7050,
"luna_config": "/trinity/local/luna/config/luna-daemon.ini"
},
"controller2": {
"status": "standby",
"ipaddr": "10.141.255.253",
"serverport": 7050,
"luna_config": "/trinity/local/luna/config/luna-daemon.ini"
},
"ntp_server": "10.141.255.252",
"debug": false,
"technical_contacts": "root@localhost",
"provision_method": "torrent",
"provision_fallback": "http"
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Update cluster information (POST /config/cluster)
Request
POST /config/cluster
Request body
{
"config": {
"cluster": {
"ntp_server": "10.141.255.252",
"debug": false,
"technical_contacts": "root@localhost",
"provision_method": "torrent",
"provision_fallback": "http"
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 400 Bad request
is mandatory if the controller objects are attempted to be modified
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Export the cluster configuration (GET /config/cluster/export)
Request
GET /config/cluster/export
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"cluster": { "...": "..." },
"network": { "...": "..." },
"group": { "...": "..." },
"node": { "...": "..." },
"osimage": { "...": "..." },
"[...]": "[...]"
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when the configuration could not be exported.
Import a cluster configuration (POST /config/cluster/import)
Request
POST /config/cluster/import
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"cluster": { "...": "..." },
"network": { "...": "..." },
"group": { "...": "..." },
"node": { "...": "..." },
"[...]": "[...]"
}
}
Response body
{
"message": "Configuration imported"
}
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when the configuration could not be imported.
Get the cluster mounts document (GET /config/cluster/mounts)
Returns only the cluster's network mounts document, the top of the cluster, group and node chain, in the same shape the full cluster information uses. The value is base64-encoded JSON; _mounts_source is cluster when a document is stored and default when none is.
Request
GET /config/cluster/mounts
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"cluster": {
"mounts": "eyJ2ZXJzaW9uIjogMSwgIm1vdW50cyI6IFt7InBhdGgiOiAiL2RhdGEiLCAidHlwZSI6ICJuZnMiLCAic2VydmVyIjogImNvbnRyb2xsZXIiLCAic291cmNlIjogIi9leHBvcnQvZGF0YSIsICJvcHRpb25zIjogInJ3LGhhcmQifV19",
"_mounts_source": "cluster"
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not Found
is returned when the cluster information is not available.
Add or update a cluster mount (POST /config/cluster/mounts)
Adds one entry to the cluster's network mounts document, or updates the entry with the same path: the fields given replace those stored, the others stay. mount is a single entry as base64-encoded JSON, for example {"path": "/data", "type": "nfs", "server": "controller", "source": "/export/data", "options": "rw,hard"}. path is required and absolute; type is one of nfs (default), lustre, beegfs, gpfs, mmfs, panfs or manual; state is one of mounted, present or absent. The resulting document is validated as a whole before it is stored.
Request
POST /config/cluster/mounts
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"cluster": {
"mount": "eyJwYXRoIjogIi9kYXRhIiwgInR5cGUiOiAibmZzIiwgInNlcnZlciI6ICJjb250cm9sbGVyIiwgInNvdXJjZSI6ICIvZXhwb3J0L2RhdGEiLCAib3B0aW9ucyI6ICJydyxoYXJkIn0="
}
}
}
Response body
{
"message": "Mount /data added to the cluster."
}
Response header
HTTP 201 Created
will be expected to be returned when the entry was added or updated, or the document was already as requested.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no mount is given, the entry has no path, or the resulting document is invalid.
HTTP 403 Forbidden
is returned when the token's user may not change the cluster, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the change could not be stored, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Remove a cluster mount (POST /config/cluster/mounts/_remove)
Removes the entry with the given path from the cluster's network mounts document.
Request
POST /config/cluster/mounts/_remove
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"cluster": {
"path": "/data"
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad Request
is returned when no path is given or the document holds no entry at that path.
HTTP 403 Forbidden
is returned when the token's user may not change the cluster, and when a node's provision token is used.
HTTP 404 Not Found
is returned when the change could not be stored, or, on a high-availability setup, when this controller is not yet in sync with its peer.
Network Management
Network management covers the network configuration section of the configuration management database. It does not configure the network equipment.
Get the list of networks (GET /config/network)
Request
GET /config/network
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"network": {
"cluster": {
"network": "10.141.0.0/16",
"nameserver_ip": "10.141.255.254",
"ntp_server": "10.141.255.254",
"gateway": "10.141.255.254",
"comment": "Default cluster network",
"dhcp": true,
"dhcp_range_begin": "10.141.0.200",
"dhcp_range_end": "10.141.0.253"
},
"ipmi": {
"network": "10.148.0.0/16",
"nameserver_ip": "10.148.255.254",
"ntp_server": "10.148.255.254",
"gateway": "10.148.255.254",
"comment": "Default OOB network",
"dhcp": false
},
"ib": {
"network": "10.149.0.0/16",
"nameserver_ip": "10.149.255.254",
"ntp_server": "10.149.255.254",
"gateway": "10.149.255.254",
"comment": "Default highspeed interconnect network",
"dhcp": false
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get network information (GET /config/network/{networkname})
Request
GET /config/network/cluster
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"network": {
"cluster": {
"name": "cluster",
"network": "10.141.0.0/16",
"gateway": "10.141.255.254",
"nameserver_ip": "10.141.255.254",
"ntp_server": "10.141.255.254",
"comment": "Default cluster network",
"dhcp": true,
"dhcp_range_begin": "10.141.0.200",
"dhcp_range_end": "10.141.0.253"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Update network information (POST /config/network/{networkname})
Request
POST /config/network/cluster
Request body
{
"config": {
"network": {
"cluster": {
"newnetname": "cluster2",
"network": "10.141.0.0/16",
"gateway": "10.141.255.254",
"nameserver_ip": "10.141.255.254",
"ntp_server": "10.141.255.254",
"comment": "Default cluster network",
"dhcp": true,
"dhcp_range_begin": "10.141.0.200",
"dhcp_range_end": "10.141.0.253"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 201 Created
will be expected to be returned when a new object is created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Deleting network information (GET /config/network/{networkname}/_delete)
Request
GET /config/network/cluster/_delete
Request body
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 201 Created
will be expected to be returned when a new object is created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get IP Address information (GET /config/network/{ipaddr})
Request
GET /config/network/cluster/10.141.0.3
Request header
Response body
{
"config": {
"network": {
"10.141.0.1": {
"status": "free"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned when the query executes. The client is responsible for handling the response
HTTP 404 Not found
when the IP is not in the network range (out-of-scope)
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get all taken IP address with device name (GET /config/network/{networkname}/_member)
This API will fetch all the taken IP address with there device names.
Request
GET /config/network/cluster/_member
Request header
Response body
{
"config": {
"network": {
"cluster": {
"taken": [
{"ipaddress": "10.141.255.254", "device": "controller"},
{"ipaddress": "10.141.0.1", "device": "node001"},
{"ipaddress": "10.141.0.2", "device": "node003"},
{"ipaddress": "10.141.0.3", "device": "switch001"},
{"ipaddress": "10.141.0.4", "device": "otherdevice003"}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned when the query executes. The client is responsible for handling the response
HTTP 404 Not found
when the IP is not in the network range (out-of-scope)
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get next available IP address (GET /config/network/{networkname}/_nextfreeip)
The Next IP will search the database for the next available IP address:
-
check database for occupied nodes, otherdev addresses,
-
removing the gateway and network addresses
-
returning the first available address in the range
The client is responsible for processing this, no reservation is made.
Request
GET /config/network/cluster/_nextfreeip
Request header
Response body
{
"config": {
"network": {
"cluster": {
"nextip": "10.141.0.2"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned when the query executes. The client is responsible for handling the response
HTTP 404 Not found
when the IP is not in the network range (out-of-scope)
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get the status of a single IP address (GET /config/network/{name}/{ipaddress})
Request
GET /config/network/cluster/10.141.0.10
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"network": {
"10.141.0.10": {
"status": "taken"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned. The reported status is either taken or free.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when the network does not exist or the IP address is not within its range.
Get the list of static routes (GET /config/route)
Static routes are kept in a catalogue and coupled to networks, groups and nodes. assigned lists what each route is coupled to as type/name. Only the routes the caller may read are listed.
Token is required.
Request
GET /config/route
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"route": {
"storage": {
"name": "storage",
"destination": "10.149.0.0/16",
"gateway": "10.141.255.250",
"metric": 100,
"device": "",
"comment": "storage network",
"assigned": "network/cluster,group/compute",
"owners": "rootus",
"usergroups": "",
"access": "rw-r--r--"
},
"default": {
"name": "default",
"destination": "0.0.0.0/0",
"gateway": "10.141.255.254",
"metric": null,
"device": "BOOTIF",
"comment": null,
"assigned": "",
"owners": "rootus",
"usergroups": "",
"access": "rw-r--r--"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when no routes are available.
Get static route information (GET /config/route/{name})
Token is required.
Request
GET /config/route/storage
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"route": {
"storage": {
"name": "storage",
"destination": "10.149.0.0/16",
"gateway": "10.141.255.250",
"metric": 100,
"device": "",
"comment": "storage network",
"assigned": "network/cluster,group/compute",
"owners": "rootus",
"usergroups": "",
"access": "rw-r--r--"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when the route does not exist or the caller may not read it.
Create, update or rename a static route (POST /config/route/{name})
Token is required. Fields: destination (a network in CIDR notation or a host, IPv4 or IPv6), gateway (the next-hop address, same family as the destination), device (an interface name; BOOTIF means the node's provisioning interface), metric (a number) and comment. A route needs a gateway, a device or both. An update carries only the fields that change. Renaming is done by passing the newname field.
Creating a route is for the controller account and admin users.
Request
POST /config/route/storage
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"route": {
"storage": {
"destination": "10.149.0.0/16",
"gateway": "10.141.255.250",
"metric": 100,
"comment": "storage network"
}
}
}
}
Response body
{
"message": "Route storage created"
}
Response header
HTTP 201 Created
will be expected to be returned when the route is created or renamed.
HTTP 204 No content
will be expected to be returned when the route is updated.
HTTP 400 Bad request
is returned when the destination is missing or invalid, neither gateway nor device is given, the gateway is not a valid address of the destination's family, the metric is not a number, the new name already exists, or the body is not valid.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not create or change the route.
HTTP 404 Not found
is returned when the caller may not read the route.
Delete a static route (GET /config/route/{name}/_delete)
Token is required. A route that is still coupled to a network, group or node cannot be deleted; decouple it first. Deleting a route is for the controller account and admin users.
Request
GET /config/route/storage/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 400 Bad request
is returned when the route is still coupled; the message names what it is coupled to.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller is not the controller account or an admin user.
HTTP 404 Not found
is returned when the route does not exist.
Couple a static route (GET /config/route/{name}/{tableref}/{target}/_couple)
Token is required. Couples the route to a network, group or node: tableref is network, group or node, target its name. A node receives the routes of the most specific level that has any coupled: its own replace its group's, and its group's replace those of its networks. The caller needs read access to the route and change access to the target.
Request
GET /config/route/storage/group/compute/_couple
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "Route storage coupled to group compute"
}
Response header
HTTP 201 Created
will be expected to be returned, also when the route was already coupled.
HTTP 400 Bad request
is returned when tableref is not network, group or node.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not change the target.
HTTP 404 Not found
is returned when the route or the target does not exist.
Decouple a static route (GET /config/route/{name}/{tableref}/{target}/_decouple)
Token is required. Removes the coupling of the route to a network, group or node; the route itself stays in the catalogue.
Request
GET /config/route/storage/group/compute/_decouple
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "Route storage decoupled from group compute"
}
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 400 Bad request
is returned when tableref is not network, group or node.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not change the target.
HTTP 404 Not found
is returned when the route or the target does not exist, or the route is not coupled to the target.
BMC Management
BMC management entails the ipmi settings. The actual trigger to setup the BMC is done in the group or node configuration using the
setupbmc
boolean.
Get the list of BMC settings (GET /config/bmcsetup)
Request
GET /config/bmcsetup
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"bmcsetup": {
"dell": {
"mgmtchannel": 1,
"netchannel": 1,
"password": "calvin",
"username": "root",
"userid": 2,
"comment": "Default DELL"
},
"gigabyte": {
"mgmtchannel": 1,
"netchannel": 1,
"password": "password",
"username": "admin",
"userid": 2,
"comment": "Default Gigabyte"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get the list of nodes in BMC setup (GET /config/bmcsetup/{name}/_member)
Request
GET /config/bmcsetup/dell/_member
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"bmcsetup": {
"ipmi": {
"members": [
"node001",
"node002",
"node003",
"node004"
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Show BMC setup (GET /config/bmcsetup/{bmcname})
Request
GET /config/bmcsetup/dell
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"bmcsetup": {
"dell": {
"mgmtchannel": 1,
"netchannel": 1,
"password": "calvin",
"username": "root",
"userid": 2,
"comment": "Default DELL"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create, configure or rename BMC setup (POST /config/bmcsetup/{bmcname})
Renaming is done by setting the newbmcname field.
Request
POST /config/bmcsetup/dell
Request body
{
"config": {
"bmcsetup": {
"dell": {
"newbmcname": "dell2",
"mgmtchannel": 1,
"netchannel": 1,
"password": "calvin",
"username": "root",
"userid": 2,
"comment": "Default DELL"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 200 OK
will be expected to be returned when updating fields
HTTP 201 Created
will be expected when the BMC setup is created
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Clone BMC setup (POST /config/bmcsetup/{bmcname}/_clone)
Cloning is done by setting the newbmcname field. In this example the
dell
bmcsetup is cloned to
dell2
.
Request
POST /config/bmcsetup/dell/_clone
Request body
{
"config": {
"bmcsetup": {
"dell": {
"newbmcname": "dell2",
"mgmtchannel": 1,
"netchannel": 1,
"password": "calvin",
"username": "root",
"userid": 2,
"comment": "Default DELL"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 201 Created
will be expected when the BMC setup is created
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete BMC setup (GET /config/bmcsetup/{bmcname}/_delete)
Removing an object is done by calling the _delete on the object.
Request
GET /config/bmcsetup/dell/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected when the object is successfully deleted
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Redfish management
A Redfish setup describes how Luna reaches a BMC over Redfish (scheme, port, certificate verification) and which accounts it logs in with. It is assigned to a group or a node with the
redfishsetup
field, the same way a BMC setup is. A node without a Redfish setup is not contacted over Redfish.
Get the list of Redfish setups (GET /config/redfishsetup)
Request
GET /config/redfishsetup
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Only the Redfish setups the user may read are listed.
{
"config": {
"redfishsetup": {
"datacentre": {
"name": "datacentre",
"scheme": "https",
"port": 443,
"verify": false,
"comment": "Compute racks",
"owners": "rootus",
"usergroups": "",
"access": "rwxrwx---",
"accounts": [
{
"name": "monitor",
"username": "monitor",
"password": "<password>",
"role": "ReadOnly",
"comment": null
},
{
"name": "admin",
"username": "rfadmin",
"password": "<password>",
"role": "Administrator",
"comment": null
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when no Redfish setup is available.
Show Redfish setup (GET /config/redfishsetup/{name})
Request
GET /config/redfishsetup/datacentre
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"redfishsetup": {
"datacentre": {
"name": "datacentre",
"scheme": "https",
"port": 443,
"verify": false,
"comment": "Compute racks",
"owners": "rootus",
"usergroups": "",
"access": "rwxrwx---",
"accounts": [
{
"name": "monitor",
"username": "monitor",
"password": "<password>",
"role": "ReadOnly",
"comment": null
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist or the user may not read it.
Get the list of members of a Redfish setup (GET /config/redfishsetup/{name}/_member)
Lists the nodes and groups that have this Redfish setup assigned directly. A node that only inherits it from its group is listed through its group.
Request
GET /config/redfishsetup/datacentre/_member
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Only the members the user may read are listed.
{
"config": {
"redfishsetup": {
"datacentre": {
"members": [
"node node001",
"group compute"
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the Redfish setup does not exist or has no members.
Create, configure or rename Redfish setup (POST /config/redfishsetup/{name})
Creates the Redfish setup when it does not exist, otherwise changes it. Renaming is done by setting the
newredfishsetupname
field; nodes and groups that use the setup keep using it under the new name.
schemeishttpsorhttp, and defaults tohttpson creation.portis a number between 1 and 65535.verifysets whether the BMC certificate is verified, and defaults to no on creation.accountscreates or changes accounts byname. A new account needsusernameandpassword; a change carries only the fields that change. Accounts not named are left as they are; an account is removed with the account delete call.
Request
POST /config/redfishsetup/datacentre
Request body
{
"config": {
"redfishsetup": {
"datacentre": {
"scheme": "https",
"port": 443,
"verify": false,
"comment": "Compute racks",
"accounts": [
{
"name": "monitor",
"username": "monitor",
"password": "<password>",
"role": "ReadOnly"
},
{
"name": "operator",
"username": "operator",
"password": "<password>",
"role": "Operator"
}
]
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Empty when the Redfish setup is changed. On creation:
{
"message": "Redfish Setup datacentre created"
}
Response header
HTTP 201 Created
will be expected when the Redfish setup is created
HTTP 204 No content
will be expected to be returned when updating fields or renaming
HTTP 400 Bad request
is returned when the body is not valid JSON or not in this structure, a field is unknown or invalid, the port is out of range, the new name is already in use, or a new account lacks a name, username or password. When an account is refused, the Redfish setup itself, and the accounts listed before the refused one, have already been created or changed
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not change or create the Redfish setup
HTTP 404 Not found
is returned when a Redfish setup that does not exist is renamed
HTTP 500 Internal Server error
is returned when the Redfish setup could not be created.
Clone Redfish setup (POST /config/redfishsetup/{name}/_clone)
Cloning is done by setting the
newredfishsetupname
field. The clone gets the settings and all accounts of the original. In this example the
datacentre
Redfish setup is cloned to
datacentre-gpu
.
Request
POST /config/redfishsetup/datacentre/_clone
Request body
{
"config": {
"redfishsetup": {
"datacentre": {
"newredfishsetupname": "datacentre-gpu"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "Redfish Setup datacentre cloned to datacentre-gpu"
}
Response header
HTTP 201 Created
will be expected when the Redfish setup is cloned
HTTP 400 Bad request
is returned when the new name is missing or already in use, or the body is not in this structure
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not create a Redfish setup
HTTP 404 Not found
is mandatory if the object does not exist
Delete Redfish setup (GET /config/redfishsetup/{name}/_delete)
Removes the Redfish setup and its accounts. A Redfish setup that is assigned to a node or a group is not removed.
Request
GET /config/redfishsetup/datacentre/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected when the object is successfully deleted
HTTP 400 Bad request
is returned when the Redfish setup is still in use; the message names the nodes and groups using it
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not remove the Redfish setup
HTTP 404 Not found
is mandatory if the object does not exist
Delete an account from a Redfish setup (GET /config/redfishsetup/{name}/{account}/_delete)
Removes one account from the Redfish setup in Luna. The account on the BMC itself is not touched.
Request
GET /config/redfishsetup/datacentre/monitor/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected when the account is successfully deleted
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not change the Redfish setup
HTTP 404 Not found
is returned when the Redfish setup or the account does not exist
BIOS configuration
A BIOS configuration is grabbed from a node over Redfish, stored under a name and pushed to other nodes of the same board type. It is created by the grab, not by a POST on the configuration itself. It is assigned to a group or a node with the
biosconfig
field.
Get the list of BIOS configurations (GET /config/biosconfig)
Request
GET /config/biosconfig
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Only the BIOS configurations the user may read are listed.
settings
is the number of stored attributes,
grabbedfrom
the node the configuration was grabbed from, and
grab_exclude
is returned base64 encoded, as it is stored.
{
"config": {
"biosconfig": {
"hpc-tuned": {
"name": "hpc-tuned",
"manufacturer": "Supermicro",
"model": "X12DPG-QT6",
"biosversion": "1.4a",
"grabbedfrom": "node001",
"settings": 412,
"grab_exclude": "KkFzc2V0VGFnKiwgKlNlcmlhbE51bWJlcio=",
"updated": "2026-10-20 09:14:52",
"comment": "Golden node",
"owners": "rootus",
"usergroups": "",
"access": "rwxrwxr--"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when no BIOS configuration is available.
Show BIOS configuration (GET /config/biosconfig/{name})
Returns the summary, every stored attribute with its value, and the setting name the board gives each attribute where it gives one.
Request
GET /config/biosconfig/hpc-tuned
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"biosconfig": {
"hpc-tuned": {
"name": "hpc-tuned",
"manufacturer": "Supermicro",
"model": "X12DPG-QT6",
"biosversion": "1.4a",
"grabbedfrom": "node001",
"settings": 412,
"grab_exclude": "KkFzc2V0VGFnKiwgKlNlcmlhbE51bWJlcio=",
"updated": "2026-10-20 09:14:52",
"comment": "Golden node",
"owners": "rootus",
"usergroups": "",
"access": "rwxrwxr--",
"attributes": {
"ProcessorHyperThreading": "Disabled",
"SRIOVEnable": "Enabled"
},
"labels": {
"ProcessorHyperThreading": "Hyper-Threading",
"SRIOVEnable": "SR-IOV Support"
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist or the user may not read it.
Change or rename BIOS configuration (POST /config/biosconfig/{name})
Changes an existing BIOS configuration; it does not create one. The fields that can be set are
comment
,
grab_exclude
(comma separated patterns, sent base64 encoded),
newbiosname
to rename, and
set
to change individual entries. An entry under
set
is named by a concept (such as hyperthreading), by the attribute name the board publishes, or by the setting name the board gives it. Entries are checked against the attribute registry of the configuration's board type, read live from a node of that type, so a BMC of that type has to be reachable. The change is all or nothing: one entry the board type cannot express refuses the whole change.
Request
POST /config/biosconfig/hpc-tuned
Request body
{
"config": {
"biosconfig": {
"hpc-tuned": {
"set": {
"hyperthreading": "off",
"SRIOVEnable": "Enabled"
}
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned when the configuration is changed
HTTP 400 Bad request
is returned when the body is not valid JSON or not in this structure, or
set
carries no entries
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not change the BIOS configuration
HTTP 404 Not found
is returned when the BIOS configuration does not exist, or the change is refused: a field that cannot be set, a new name that is already in use, nothing to change, an entry the board type cannot express, or no node of the board type whose registry can be read. The message says which.
Clone BIOS configuration (POST /config/biosconfig/{name}/_clone)
Cloning is done by setting the
newbiosname
field. The clone keeps everything the original holds, including the node it was grabbed from;
comment
can be set on the clone in the same request.
Request
POST /config/biosconfig/hpc-tuned/_clone
Request body
{
"config": {
"biosconfig": {
"hpc-tuned": {
"newbiosname": "hpc-tuned-gpu",
"comment": "GPU nodes"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "BIOS configuration hpc-tuned cloned to hpc-tuned-gpu"
}
Response header
HTTP 201 Created
will be expected when the BIOS configuration is cloned
HTTP 400 Bad request
is returned when the new name is missing or the body is not in this structure
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not create a BIOS configuration
HTTP 404 Not found
is returned when the BIOS configuration does not exist, or the new name is already in use
Delete BIOS configuration (GET /config/biosconfig/{name}/_delete)
A BIOS configuration that is assigned to a node or a group is not removed.
Request
GET /config/biosconfig/hpc-tuned/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected when the object is successfully deleted
HTTP 400 Bad request
is returned when the BIOS configuration is still assigned; the message names the nodes and groups it is assigned to
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not remove the BIOS configuration
HTTP 404 Not found
is mandatory if the object does not exist
Get the BIOS status of all nodes (GET /config/biosconfig/status)
Returns, per node, what it was last seen holding, read from the stored inventory. No BMC is contacted, so nodes that are switched off are reported too. Only nodes the user may read are listed.
Each node has a
state
:
matched: the last read found the node holding its configurationpending: the node is assigned a configuration it was not last found holdingstale: the node holds its configuration as it was when pushed, and entries have been changed on the configuration sincedrifted: the node matched once and its BIOS has changed sincecollected: the BIOS has been read and matches no stored configurationunknown: no Redfish inventory has been taken from the node yet
config
is the configuration the node was last found holding,
assigned
the one it is assigned through the node or its group, and
since
when the inventory was last updated.
summary
counts the nodes per state.
Request
GET /config/biosconfig/status
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"biosconfig": {
"status": {
"node001": {
"config": "hpc-tuned",
"digest": "3f9a1c0be27d",
"state": "matched",
"assigned": "hpc-tuned",
"bios_version": "1.4a",
"since": "2026-10-21 14:02:11",
"group": "compute"
},
"node002": {
"config": "",
"digest": "",
"state": "unknown",
"assigned": "hpc-tuned",
"bios_version": "",
"since": "",
"group": "compute"
}
},
"summary": {
"matched": 1,
"unknown": 1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when there are no nodes.
Get the BIOS status of a node (GET /config/biosconfig/status/{name})
The same as the status of all nodes, for one node.
Request
GET /config/biosconfig/status/node001
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"biosconfig": {
"status": {
"node001": {
"config": "hpc-tuned",
"digest": "3f9a1c0be27d",
"state": "drifted",
"assigned": "hpc-tuned",
"bios_version": "1.4a",
"since": "2026-10-21 14:02:11",
"group": "compute"
}
},
"summary": {
"drifted": 1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the node does not exist or the user may not read it.
Get the BIOS status of a group (GET /config/biosconfig/status/group/{name})
The same as the status of all nodes, for the nodes of one group.
Request
GET /config/biosconfig/status/group/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"biosconfig": {
"status": {
"node001": {
"config": "hpc-tuned",
"digest": "3f9a1c0be27d",
"state": "matched",
"assigned": "hpc-tuned",
"bios_version": "1.4a",
"since": "2026-10-21 14:02:11",
"group": "compute"
},
"node002": {
"config": "hpc-tuned",
"digest": "3f9a1c0be27d",
"state": "stale",
"assigned": "hpc-tuned",
"bios_version": "1.4a",
"since": "2026-10-21 14:05:37",
"group": "compute"
}
},
"summary": {
"matched": 1,
"stale": 1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the group does not exist or has no nodes the user may read.
Firmware catalogue
An entry in the firmware catalogue names the hardware (manufacturer and model, as the board reports them), the component (as the board's firmware inventory names it), the version that hardware should run, and the image file. The image file is a bare file name in Luna's files directory on the active controller.
Get the firmware catalogue (GET /config/firmwarecatalog)
Request
GET /config/firmwarecatalog
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Only the entries the user may read are listed.
{
"config": {
"firmwarecatalog": {
"r181-bmc": {
"name": "r181-bmc",
"manufacturer": "GIGABYTE",
"model": "R181-Z91-00",
"component": "BMC",
"version": "12.61.25",
"imagefile": "rom_v12.61.25.ima_enc",
"updated": null,
"comment": null,
"owners": "rootus",
"usergroups": "",
"access": "rwxrwxr--"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the catalogue is empty, or the user may read none of its entries.
Show firmware catalogue entry (GET /config/firmwarecatalog/{name})
Request
GET /config/firmwarecatalog/r181-bmc
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"firmwarecatalog": {
"r181-bmc": {
"name": "r181-bmc",
"manufacturer": "GIGABYTE",
"model": "R181-Z91-00",
"component": "BMC",
"version": "12.61.25",
"imagefile": "rom_v12.61.25.ima_enc",
"updated": null,
"comment": null,
"owners": "rootus",
"usergroups": "",
"access": "rwxrwxr--"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist or the user may not read it.
Create, change or rename firmware catalogue entry (POST /config/firmwarecatalog/{name})
Creates the entry when it does not exist, otherwise changes it. A new entry needs
manufacturer
,
model
,
component
and
version
. Renaming is done by setting the
newfirmwarename
field.
imagefile
must be a bare file name, and not of a type the file server only hands out with a token, as a BMC cannot present one. Whether the file is staged is checked at push time, not here.
Request
POST /config/firmwarecatalog/r181-bmc
Request body
{
"config": {
"firmwarecatalog": {
"r181-bmc": {
"manufacturer": "GIGABYTE",
"model": "R181-Z91-00",
"component": "BMC",
"version": "12.61.25",
"imagefile": "rom_v12.61.25.ima_enc"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
When the request names an image file, the message carries a note on where to stage it. A change that names no image file returns an empty body.
{
"message": "Firmware catalogue entry r181-bmc created; note: stage rom_v12.61.25.ima_enc in /trinity/local/luna/files on the active controller. BMCs fetch it from the controller over port 7051, so the interface facing the BMC network must be in the firewall's trusted zone"
}
Response header
HTTP 201 Created
will be expected when the entry is created, or changed with an image file named
HTTP 204 No content
will be expected to be returned when updating fields without an image file
HTTP 400 Bad request
is returned when the body is not valid JSON or not in this structure, a new entry lacks one of the required fields, a change names an unknown field, the image file name is not usable, or the new name is already in use
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not change or create the entry
HTTP 404 Not found
is returned when an entry that does not exist is renamed, or a change carries no fields
HTTP 500 Internal Server error
is returned when the entry could not be created, for instance because the request names an unknown field.
Delete firmware catalogue entry (GET /config/firmwarecatalog/{name}/_delete)
Request
GET /config/firmwarecatalog/r181-bmc/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected when the object is successfully deleted
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the user may not remove the entry
HTTP 404 Not found
is mandatory if the object does not exist
Get the firmware update status of all nodes (GET /config/firmwarecatalog/status)
Returns the newest firmware update request per node and what became of it. This reports what was asked and its outcome, not what a node runs now. Only nodes the user may read are listed.
state
is
queued
,
in progress
,
done
or
failed
.
restore
is
pending
while the node still owes a restore of its BMC settings after a flash reset its BMC; once the restore has run it holds its outcome, starting with
done:
or
failed:
followed by the message.
summary
counts the nodes per state. When requests exist but the user may read none of their nodes, the answer is 200 with an empty
status
and
summary
.
Request
GET /config/firmwarecatalog/status
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"firmwarecatalog": {
"status": {
"node001": {
"group": "compute",
"component": "BMC",
"request_id": "1761736212.4825933482120113",
"state": "done",
"message": "node001: BMC now at the catalogue version; BMC configuration retained",
"restore": "",
"since": "2026-10-22 10:41:07"
},
"node002": {
"group": "compute",
"component": "BMC",
"request_id": "1761736212.4825933482120113",
"state": "in progress",
"message": "",
"restore": "",
"since": "2026-10-22 10:35:12"
}
},
"summary": {
"done": 1,
"in progress": 1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when no firmware update has been requested.
Get the firmware update status of a node (GET /config/firmwarecatalog/status/{name})
The same as the status of all nodes, for one node.
Request
GET /config/firmwarecatalog/status/node001
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"firmwarecatalog": {
"status": {
"node001": {
"group": "compute",
"component": "BMC",
"request_id": "1761736212.4825933482120113",
"state": "done",
"message": "node001: BMC now at the catalogue version; BMC configuration retained; 2 BIOS setting(s) differ from the recorded configuration compute-bios - re-applied when the node next installs through Luna",
"restore": "pending",
"since": "2026-10-22 10:41:07"
}
},
"summary": {
"done": 1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when no firmware update has been requested for the node, or the node does not exist.
Get the firmware update status of a group (GET /config/firmwarecatalog/status/group/{name})
The same as the status of all nodes, for the nodes of one group.
Request
GET /config/firmwarecatalog/status/group/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"firmwarecatalog": {
"status": {
"node001": {
"group": "compute",
"component": "BMC",
"request_id": "1761736212.4825933482120113",
"state": "failed",
"message": "image rom_v12.61.25.ima_enc is not staged on this controller",
"restore": "",
"since": "2026-10-22 10:36:40"
}
},
"summary": {
"failed": 1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the group does not exist, or no firmware update has been requested for its nodes.
Image management
Image management is mostly token based, as it made introduce breaking changes to the system.
Get a list of images (GET /config/osimage):
Request
GET /config/osimage
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osimage": {
"compute": {
"grab_exclude": [
"/dev",
"/proc",
"/sys"
],
"grab_filesystems": [
"/",
"/boot"
],
"initrdfile": "compute-initramfs-`uname -r`",
"kernelfile": "compute-kernel-`uname -r`",
"kernelmodules": "ipmi_devinft, ipmi_si, ipmi_msghandler",
"kerneloptions": "mitigations=off nosmt noht",
"kernelversion": "`uname -r`",
"path": "/trinity/images/compute",
"imagefile": "compute.tar.bz2",
"comment": "Default image"
},
"compute-ib": {
"grab_exclude": [
"/dev",
"/proc",
"/sys"
],
"grab_filesystems": [
"/",
"/boot"
],
"initrdfile": "compute-initramfs-`uname -r`",
"kernelfile": "compute-kernel-`uname -r`",
"kernelmodules": "ipmi_devinft, ipmi_si, ipmi_msghandler",
"kerneloptions": "mitigations=off nosmt noht",
"kernelversion": "`uname -r`",
"path": "/trinity/images/compute-ib",
"imagefile": "compute.tar.bz2",
"comment": "Default image with updated drivers"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get a list members of the osimage (GET /config/osimage/{osimage}/_member)
Request
GET /config/osimage/{osimage}/_member
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osimage": {
"compute-b": {
"members": [
"node001",
"node002",
"node003",
"node004"
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get osimage information (GET /config/osimage/{osimage})
Request
GET /config/osimage/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osimage": {
"compute": {
"grab_exclude": [
"/dev",
"/proc",
"/sys"
],
"grab_filesystems": [
"/",
"/boot"
],
"initrdfile": "compute-initramfs-`uname -r`",
"kernelfile": "compute-kernel-`uname -r`",
"kernelmodules": "ipmi_devinft, ipmi_si, ipmi_msghandler",
"kerneloptions": "mitigations=off nosmt noht",
"kernelversion": "`uname -r`",
"path": "/trinity/images/compute",
"imagefile": "compute.tar.bz2",
"comment": "Default image"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Updating or creating osimage information (POST /config/osimage/{osimage})
Note that when posting to a non-existing osimage name, it will create the image with the settings submitted.
Request
POST /config/osimage/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"osimage": {
"compute": {
"comment": "Default image",
"distribution": "redhat",
"grab_exclude": [
"/dev",
"/proc",
"/sys"
],
"grab_filesystems": [
"/",
"/boot"
],
"initrdfile": "compute-initramfs-`uname -r`",
"kernelfile": "compute-kernel-`uname -r`",
"kernelmodules": "ipmi_devinft, ipmi_si, ipmi_msghandler",
"kerneloptions": "mitigations=off nosmt noht",
"kernelversion": "`uname -r`",
"path": "/trinity/images/compute",
"imagefile": "compute.tar.bz2"
}
}
}
}
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 201 Created
will be expected when a new object is created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete osimage (GET /config/osimage/{osimage}/_delete)
Request
GET /config/osimage/compute/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Renaming osimage (POST /config/osimage/{osimage})
This example will rename the image compute to compute-ib.
Request
POST /config/osimage/compute/
Request body
{
"config": {
"osimage": {
"compute": {
"newosimage": "compute-ib"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the newosimage field is not set.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Cloning osimage (POST /config/osimage/{osimage}/_clone)
This example will clone the image compute to compute-ib.
Request
POST /config/osimage/compute/_clone
Request body
{
"config": {
"osimage": {
"compute": {
"newosimage": "compute-ib"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the newosimage field is not set.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Packing osimage (GET /config/osimage/{osimage}/_pack)
This example will pack the osimage compute.
Request
GET /config/osimage/compute/_pack
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Cancel an osimage pack (GET /config/osimage/{name}/_cancel)
Cancels a pack of the osimage that is in progress on this controller: the pack worker is stopped (and, if it ignores the request to stop, killed and the mounts below the image cleaned up), the remaining queued tasks of the same request are removed and the request is closed. The cancel acts only on the controller that runs the pack and is not replicated.
Request
GET /config/osimage/compute-image/_cancel
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "cancelled pack for osimage compute-image (worker stopped)"
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the token's user may not change the osimage.
HTTP 404 Not Found
is returned when no pack of the osimage is in progress, or the worker was killed but the mount cleanup failed.
Changing kernel version in osimage (incl. pack) (POST /config/osimage/{osimage}/kernel)
This example will pack the osimage compute, as well as triggering a pack afterwards.
Request
POST /config/osimage/compute/kernel
Request body
{
"config": {
"osimage": {
"compute": {
"initrdfile": "compute-initramfs-`uname -r`",
"kernelfile": "compute-kernel-`uname -r`",
"kernelversion": "`uname -r`"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Update the CA certificates in an osimage (GET /config/osimage/{name}/_updatecerts)
Copies the controller's RHSM CA certificates (/etc/rhsm/ca/) into the osimage, so that package management inside the image keeps working after the Satellite or Red Hat CA keys are rotated. This is an asynchronous operation: the task is queued and a request_id is returned that can be polled with GET /config/status/{request_id}. When an equal task is already queued, its request_id is returned instead. On a high-availability setup where this controller is not the master, the request is forwarded to the master and the message reflects that.
Request
GET /config/osimage/compute-image/_updatecerts
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "osimage certificate update for compute-image queued",
"request_id": "1761738600.7712093518814211"
}
Response header
HTTP 200 OK
will be expected to be returned with the request_id in the body.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the token's user may not change the osimage.
HTTP 404 Not Found
is returned when the osimage does not exist or the task could not be queued.
Get osimage+osimage tag information (GET /config/osimagetag)
Request
GET /config/osimagetag
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osimagetag": {
"versionx": {
"name": "versionx",
"osimage": "compute",
"kernelfile": "compute-kernel-`uname -r`",
"initrdfile": "compute-initramfs-`uname -r`",
"imagefile": "uuid",
"path": "/trinity/images/compute"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get osimage+osimage tag information (GET /config/osimagetag/{osimage})
Request
GET /config/osimagetag/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osimagetag": {
"versionx": {
"name": "versionx",
"osimage": "compute",
"kernelfile": "compute-kernel-`uname -r`",
"initrdfile": "compute-initramfs-`uname -r`",
"imagefile": "uuid",
"path": "/trinity/images/compute"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Changing/creating tag in osimage (POST /config/osimage/{osimage}/tag)
Request
POST /config/osimage/compute/tag
Request body
{
"config": {
"osimage": {
"compute": {
"tag": "version1"
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned for change, create or update.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete osimagetag (GET /config/osimage/{osimage}/osimagetag/{tagname}/_delete)
Request
GET /config/osimage/compute/osimagetag/versionx/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Secret management
Secrets (encrypted data) may not be revealed without a valid token. The secrets endpoint is token only.
Secrets are stored on node and group level, proper resolving of the hierarchy is the responsibility of the API.
Secrets can be requested on different levels:
-
Global (list)
-
Overview of node (incl. group)
-
Overview of group
-
Single item from node
-
Single item from group
Get a list of secrets (GET /config/secrets):
Request
GET /config/secrets
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"secrets": {
"node": {
"node001": [
{
"secretname": "shared secret",
"content": "<ENC>",
"path": "/etc/keys.crt"
},
{
"secretname": "software license",
"content": "<ENC>",
"path": "/etc/app/license.lic"
},
{
"secretname": "shared secret",
"content": "<ENC>",
"path": "/etc/keys.crt"
}
],
"node002": [
{
"secretname": "software license",
"content": "<ENC>",
"path": "/etc/app/license.lic"
}
]
},
"group": {
"compute": [
{
"secretname": "Proprietary key",
"content": "<ENC>",
"path": "/var/lib/key.pem"
}
],
"compute-ib": [
{
"secretname": "Infiniband",
"content": "<ENC>",
"path": "/etc/rdma/license.lic"
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Retrieve all secrets for a node (GET /config/secrets/node/{node})
Token is required. Note that the secrets from the group membership must also be resolved and provided.
Request
GET /config/secrets/node/node002
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"secrets": {
"node": {
"node002": [
{
"secretname": "software license",
"content": "<ENC>",
"path": "/etc/app/license.lic"
}
]
},
"group": {
"compute-ib": [
{
"secretname": "Infiniband",
"content": "<ENC>",
"path": "/etc/rdma/license.lic"
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Update all secrets for a node (POST /config/secrets/node/{node})
Request
POST /config/secrets/node/node001
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"secrets": {
"node": {
"node001": [
{
"secretname": "shared secret",
"content": "<ENC>",
"path": "/etc/keys.crt"
},
{
"secretname": "software license",
"content": "<ENC>",
"path": "/etc/app/license.lic"
},
{
"secretname": "shared secret",
"content": "<ENC>",
"path": "/etc/keys.crt"
}
]
}
}
}
}
Response body
Response header
HTTP 200 OK
will be expected to be returned when no updates have occurred
HTTP 201 Created
is expected when one or more creations have occurred
HTTP 204 No content
is expected when one or more updates have occurred
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Retrieve a single secret from a node (GET /config/secrets/node/{node}/{secret})
Token is required.
Request
GET /config/secrets/node/node002/software%20license
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"secrets": {
"node": {
"node002": [
{
"secretname": "software license",
"content": "<ENC>",
"path": "/etc/app/license.lic"
}
]
}
}
}
}
Response header
HTTP 204 No content
will be expected to be returned when the query executed successfully.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Updating a single secret from a node (POST /config/secrets/node/{node}/{secret})
In this example, a node and secret name must be specified.
Request
POST /config/secrets/node/node002/software%20license
Request body
{
"config": {
"secrets": {
"node": {
"node001": [
{
"secretname:": "software license",
"content": "<ENC>",
"path": "/etc/app/license.lic"
}
]
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
A
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 404 Not Found
is mandatory if the object is not found
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Cloning a secret from a node (POST /config/secrets/node/{node}/{secret}/_clone)
In this example, a nodeand secret name must be specified.
Token is required.
Request
POST /config/secrets/node/node001/software%20license/_clone
Request body
{
"config": {
"secrets": {
"node": {
"node001": [
{
"secretname": "software license",
"newsecretname": "software license2",
"content": "<ENC>",
"path": "/etc/app/license.lic"
}
]
}
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the newsecret field is not set.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Deleting a secret from a node (GET /config/secrets/node/{node}/{secret}/_delete)
In this example, a node and secret name must be specified.
Token is required.
Request
GET /config/secrets/node/node002/software%20license/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
A
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 404 Not Found
is mandatory if the object is not found
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Retrieve all secrets for a group (GET /config/secrets/group/{group})
Token is required.
Request
GET /config/secrets/group/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"secrets": {
"group": {
"compute": [
{
"secretname": "Proprietary key",
"content": "<ENC>",
"path": "/var/lib/key.pem"
}
]
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Updating all secrets for a group (POST /config/secrets/group/{group})
Request
POST /config/secrets/group/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"secrets": {
"group": {
"compute": [
{
"secretname": "Proprietary key",
"content": "<ENC>",
"path": "/var/lib/key.pem"
}
]
}
}
}
}
Response body
Response header
HTTP 200 OK
will be expected to be returned when no updates have occurred
HTTP 201 Created
is expected when one or more creations have occurred
HTTP 204 No content
is expected when one or more updates have occurred
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Retrieve a single secret from a group (GET /config/secrets/group/{group}/{secret})
Token is required.
Request
GET /config/secrets/group/compute-ib/Infiniband
Request body
{
"secrets": {
"group": {
"compute": null,
"compute-ib": [
{
"secretname": "Infiniband",
"content": "<ENC>",
"path": "/etc/rdma/license.lic"
}
]
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned when the query executed successfully.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Updating a single secret from a group (POST /config/secrets/group/{group}/{secret})
In this example, a group and secret name must be specified.
Request
POST /config/secrets/group/compute-ib/Infiniband
{
"secrets": {
"group": {
"compute-ib": [
{
"secretname": "Infiniband",
"content": "<ENC>",
"path": "/etc/rdma/license.lic"
}
]
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
A
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 404 Not Found
is mandatory if the object is not found
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Cloning a secret from a group (POST /config/secrets/group/{group}/{secret}/_clone)
In this example, a group and secret name must be specified.
Token is required.
Request
POST /config/secrets/group/compute-ib/Infiniband/_clone
Request body
{
"secrets": {
"group": {
"compute-ib": [
{
"secretname": "Infiniband",
"newsecretname": "Infiniband2",
"content": "<ENC>",
"path": "/etc/rdma/license.lic"
}
]
}
}
}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the newsecret field is not set.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Deleting a secret from a group (GET /config/secrets/group/{group}/{secret}/_delete)
In this example, a group and secret name must be specified.
Token is required.
Request
GET /config/secrets/group/compute-ib/Infiniband/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
A
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 404 Not Found
is mandatory if the object is not found
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Retrieve all cluster secrets (GET /config/secrets/cluster)
Token is required. Cluster secrets apply to every node, on top of its group and node secrets. They are for the controller account and admin users only. content is base64 encoded and returned decrypted; an unset owner and mode read as root:root and 600, and resolved_owner carries the owner as numeric ids.
Request
GET /config/secrets/cluster
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"secrets": {
"cluster": [
{
"name": "software license",
"content": "<base64 content>",
"path": "/etc/app/license.lic",
"owner": "root:root",
"mode": "600",
"resolved_owner": "0:0"
},
{
"name": "site key",
"content": "<base64 content>",
"path": "/etc/pki/site.key",
"owner": "root:root",
"mode": "400",
"resolved_owner": "0:0"
}
]
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller is not the controller account or an admin user.
HTTP 404 Not found
is returned when no cluster secrets are available.
Update all cluster secrets (POST /config/secrets/cluster)
Token is required. Creates or updates the cluster secrets in the list. Every entry needs name and content; path, owner (user or user:group, names or numeric ids) and mode (octal) are optional.
Request
POST /config/secrets/cluster
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"secrets": {
"cluster": [
{
"name": "software license",
"content": "<base64 content>",
"path": "/etc/app/license.lic",
"owner": "root:root",
"mode": "600"
}
]
}
}
}
Response body
{
"message": "Cluster Secret created"
}
Response header
HTTP 201 Created
will be expected to be returned when secrets are created only, or when the message carries a warning that an owner cannot currently be resolved.
HTTP 204 No content
will be expected to be returned when existing secrets are updated.
HTTP 400 Bad request
is returned when the entries are not a list of objects, or an entry lacks name or content.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller is not the controller account or an admin user.
Retrieve a single cluster secret (GET /config/secrets/cluster/{secret})
Token is required.
Request
GET /config/secrets/cluster/software%20license
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"secrets": {
"cluster": [
{
"name": "software license",
"content": "<base64 content>",
"path": "/etc/app/license.lic",
"owner": "root:root",
"mode": "600",
"resolved_owner": "0:0"
}
]
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller is not the controller account or an admin user.
HTTP 404 Not found
is returned when the secret does not exist.
Updating a single cluster secret (POST /config/secrets/cluster/{secret})
Token is required. The body carries one entry; its name identifies the secret that is updated, or created when it does not exist. The name in the path is not compared with it and only appears in the response message. An existing secret is updated with only the fields sent; a new one needs content.
Request
POST /config/secrets/cluster/software%20license
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"secrets": {
"cluster": [
{
"name": "software license",
"mode": "640",
"owner": "root:app"
}
]
}
}
}
Response body
Response header
HTTP 201 Created
will be expected to be returned when the secret is created, or when the message carries a warning that the owner cannot currently be resolved.
HTTP 204 No content
will be expected to be returned when the secret is updated.
HTTP 400 Bad request
is returned when the entries are not a list of objects, a field is not a secret field, or a new secret has no content.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller is not the controller account or an admin user.
HTTP 500 Internal server error
is returned when the secret could not be written.
Cloning a cluster secret (POST /config/secrets/cluster/{secret}/_clone)
Token is required. The entry names the source secret in name and the copy in newsecretname. The source is taken from name; the name in the path is not compared with it and only appears in the response message. content, path, owner and mode are copied from the source unless given.
Request
POST /config/secrets/cluster/software%20license/_clone
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"secrets": {
"cluster": [
{
"name": "software license",
"newsecretname": "software license2",
"path": "/etc/app/license2.lic"
}
]
}
}
}
Response body
{
"message": "Cluster Secret software license Cloned to software license2."
}
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 400 Bad request
is returned when newsecretname is missing or already exists, or the entries are not a list of objects.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller is not the controller account or an admin user.
HTTP 404 Not found
is returned when the source secret does not exist.
Deleting a cluster secret (GET /config/secrets/cluster/{secret}/_delete)
Token is required.
Request
GET /config/secrets/cluster/software%20license/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller is not the controller account or an admin user.
HTTP 404 Not found
is returned when the secret does not exist.
Profile management
A profile is a named set of files, with their path, owner and mode on the node, and optionally a service on the node to act on once the files are in place. Profiles are assigned to groups and nodes and stack: a node applies its group's profiles and its own. File content is base64 encoded. See Luna profiles for how profiles are assigned and delivered.
Profiles are subject to access control: a profile the caller may not read answers 404, a missing permission answers 403.
Get a list of profiles (GET /config/profiles)
Token is required. Only the profiles the caller may read are listed.
Request
GET /config/profiles
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"profiles": {
"motd": {
"scope": "static",
"service": null,
"action": "none",
"enabled": true,
"files": [
{
"name": "motd",
"content": "V2VsY29tZSB0byB0aGUgY29tcHV0ZSBjbHVzdGVyCg==",
"path": "/etc/motd",
"owner": "root:root",
"mode": "644"
}
],
"owners": "rootus",
"usergroups": "",
"access": "rwxrwx---"
},
"sysctl-hpc": {
"scope": "static",
"service": "systemd-sysctl",
"action": "restart",
"enabled": true,
"files": [
{
"name": "90-hpc.conf",
"content": "dm0uc3dhcHBpbmVzcyA9IDEK",
"path": "/etc/sysctl.d/90-hpc.conf",
"owner": null,
"mode": null
}
],
"owners": "rootus",
"usergroups": "",
"access": "rwxrwx---"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when no profiles are available.
Get profile information (GET /config/profiles/{name})
Token is required.
Request
GET /config/profiles/sysctl-hpc
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"profiles": {
"sysctl-hpc": {
"scope": "static",
"service": "systemd-sysctl",
"action": "restart",
"enabled": true,
"files": [
{
"name": "90-hpc.conf",
"content": "dm0uc3dhcHBpbmVzcyA9IDEK",
"path": "/etc/sysctl.d/90-hpc.conf",
"owner": null,
"mode": null
}
],
"owners": "rootus",
"usergroups": "",
"access": "rwxrwx---"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when the profile does not exist or the caller may not read it.
Get the members of a profile (GET /config/profiles/{name}/_member)
Token is required. Lists the groups that apply the profile and the nodes that apply it themselves; a node that has it only through its group is not listed. Only groups and nodes the caller may read are listed.
Request
GET /config/profiles/sysctl-hpc/_member
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"profiles": {
"sysctl-hpc": {
"members": {
"groups": [
"compute"
],
"nodes": [
"node001"
]
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when the profile does not exist or the caller may not read it.
Create, update or rename a profile (POST /config/profiles/{name})
Token is required. Profile names are lower case: a-z, 0-9, - and .. Fields: service (a systemd unit on the node), action (restart, reload, start, stop or none), enabled (false freezes the profile on the nodes), scope (static or dynamic) and files. A file is identified by name; a new file needs content and path, a change carries only what changes. owner is user or user:group, names or numeric ids (default root:root); mode is octal (default 644). Files not named in the request are left as they are. A new profile needs a service or at least one file. Renaming is done by passing the newprofilename field. A change is delivered to the running nodes that apply the profile.
Request
POST /config/profiles/sysctl-hpc
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"profiles": {
"sysctl-hpc": {
"service": "systemd-sysctl",
"action": "restart",
"files": [
{
"name": "90-hpc.conf",
"content": "dm0uc3dhcHBpbmVzcyA9IDEK",
"path": "/etc/sysctl.d/90-hpc.conf",
"owner": "root:root",
"mode": "644"
}
]
}
}
}
}
Response body
{
"message": "Profile sysctl-hpc created"
}
Response header
HTTP 201 Created
will be expected to be returned when the profile is created or renamed, or when the message carries a warning that a file owner cannot currently be resolved.
HTTP 204 No content
will be expected to be returned when the profile is updated.
HTTP 400 Bad request
is returned when a field is not a profile or file field, action or enabled has an invalid value, the profile would have neither a service nor a file, a new file lacks name, content or path, the new name already exists, or the body is not valid.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not create or change the profile, or when a caller that is not rootus or an admin user sets owners, usergroups or access in the body.
HTTP 404 Not found
is returned when a profile to be renamed does not exist, or the caller may not read it.
HTTP 500 Internal server error
is returned when the profile could not be created.
Clone a profile (POST /config/profiles/{name}/_clone)
Token is required. Cloning is done by passing the newprofilename field; the copy includes all files.
Request
POST /config/profiles/sysctl-hpc/_clone
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"profiles": {
"sysctl-hpc": {
"newprofilename": "sysctl-gpu"
}
}
}
}
Response body
{
"message": "Profile sysctl-hpc cloned to sysctl-gpu"
}
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 400 Bad request
is returned when newprofilename is missing or already exists, or the body is not valid.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not create profiles, or when a caller that is not rootus or an admin user sets owners, usergroups or access in the body.
HTTP 404 Not found
is returned when the profile does not exist or the caller may not read it.
Delete a profile (GET /config/profiles/{name}/_delete)
Token is required. A profile that is still assigned to a group or node cannot be deleted; unassign it first, which reverts its files on the nodes.
Request
GET /config/profiles/sysctl-hpc/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 400 Bad request
is returned when the profile is still assigned; the message names the groups and nodes.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not change the profile.
HTTP 404 Not found
is returned when the profile does not exist or the caller may not read it.
Delete a file from a profile (GET /config/profiles/{name}/{filename}/_delete)
Token is required. The file is reverted on the running nodes that apply the profile. The last file of a profile without a service cannot be deleted; delete the profile, or give it a service first.
Request
GET /config/profiles/sysctl-hpc/90-hpc.conf/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 400 Bad request
is returned when it is the last file of a profile without a service.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not change the profile.
HTTP 404 Not found
is returned when the profile or the file does not exist.
Get the profiles of a node (GET /config/profiles/node/{name})
Returns every profile the node applies, enabled or not, its group's first and then its own, in the same apply-ready form as Boot profile.
Token is required: the node's own provision token, or a user token with read access to the node.
Request
GET /config/profiles/node/node001
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"profiles": {
"motd": {
"scope": "static",
"service": "",
"action": "none",
"enabled": true,
"files": [
{
"name": "motd",
"content": "V2VsY29tZSB0byB0aGUgY29tcHV0ZSBjbHVzdGVyCg==",
"path": "/etc/motd",
"owner": "root:root",
"mode": "644",
"resolved_owner": "0:0"
}
]
},
"sysctl-hpc": {
"scope": "static",
"service": "systemd-sysctl",
"action": "restart",
"enabled": true,
"files": [
{
"name": "90-hpc.conf",
"content": "dm0uc3dhcHBpbmVzcyA9IDEK",
"path": "/etc/sysctl.d/90-hpc.conf",
"owner": "root:root",
"mode": "644",
"resolved_owner": "0:0"
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a provision token of another node is used.
HTTP 404 Not found
is returned when the node does not exist, the caller may not read it, or it applies no profiles.
Get the profile status of all nodes (GET /config/profiles/status)
Token is required. Reports per node what it should hold, what it last accepted and what happened at the last delivery, with a count per state in summary. Only the nodes the caller may read are listed. state is one of in sync, behind (a delivery is due or under way; detail says why it waits), failed (the last delivery failed and is retried), given up (the retries are exhausted), frozen (in sync, with a disabled profile, named in frozen) and not applied (nothing assigned, nothing delivered). attempts counts the failed deliveries in a row.
Request
GET /config/profiles/status
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"profiles": {
"status": {
"node001": {
"profiles": "motd,sysctl-hpc",
"state": "in sync",
"frozen": "",
"detail": "",
"since": "2026-10-28 09:12:44",
"attempts": 0
},
"node002": {
"profiles": "motd,sysctl-hpc",
"state": "failed",
"frozen": "",
"detail": "<reason of the last failure>",
"since": "2026-10-28 09:14:02",
"attempts": 3
},
"node003": {
"profiles": "",
"state": "not applied",
"frozen": "",
"detail": "",
"since": "",
"attempts": 0
}
},
"summary": {
"in sync": 1,
"failed": 1,
"not applied": 1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when no nodes are available.
Get the profile status of a node (GET /config/profiles/status/{name})
Token is required. The same report for one node.
Request
GET /config/profiles/status/node002
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"profiles": {
"status": {
"node002": {
"profiles": "motd,sysctl-hpc",
"state": "failed",
"frozen": "",
"detail": "<reason of the last failure>",
"since": "2026-10-28 09:14:02",
"attempts": 3
}
},
"summary": {
"failed": 1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when the node does not exist.
Switch management
Switches are used for identifying nodes. Also creating them and assigning them an IP address will create an entry into the CMDB.
Get a list of switches (GET /config/switch):
Request
GET /config/switch
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"switch": {
"switch01": {
"network": "cluster",
"ipaddress": "10.141.253.1",
"oid": ".1.3.6.1.2.1.17.7.1.2.2.1.2",
"read": "public",
"rw": "private",
"comments": "Bootswitch"
},
"switch02": {
"network": "ipmi",
"ipaddress": "10.148.253.1",
"oid": ".1.3.6.1.2.1.17.7.1.2.2.1.2",
"read": "public",
"rw": "private",
"comments": "Bootswitch"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get switch information (GET /config/switch/{switch}):
Request
GET /config/switch/switch01
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"switch": {
"switch01": {
"network": "cluster",
"ipaddress": "10.141.253.1",
"oid": ".1.3.6.1.2.1.17.7.1.2.2.1.2",
"read": "public",
"rw": "private",
"comments": "Bootswitch"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 404 Not found
is mandatory if object doesn’t exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update switch information (POST /config/switch/{switch}):
Renaming the switch is done by passing the
newswitchname
field.
Note that a switch with the
network
and
ipaddress
configured will create an entry in the CMDB.
Request
POST /config/switch/switch01
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"switch": {
"switch01": {
"network": "cluster",
"ipaddress": "10.141.253.1",
"oid": ".1.3.6.1.2.1.17.7.1.2.2.1.2",
"read": "public",
"rw": "private",
"comments": "Bootswitch"
}
}
}
}
Response body
Response header
HTTP 201 Created
will be expected to be returned when a switch is created
HTTP 204 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Clone switch (POST /config/switch/{switch}/_clone):
Token is required. Cloning is done by passing the newswitchname field. Fields not given are copied from the source switch. When no ipaddress is given, the clone gets the next free address in the given network; DHCP and DNS are reloaded afterwards. Without network the clone is created without an address, with the message Switch cloned without network or ipaddress. The interfaces of the source switch are not copied. Creating a switch is for the controller account and admin users.
Request
POST /config/switch/switch01/_clone
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"switch": {
"switch01": {
"newswitchname": "switch02",
"network": "cluster",
"ipaddress": "10.141.253.2",
"comment": "Bootswitch"
}
}
}
}
Response body
{
"message": "Switch cloned"
}
Response header
HTTP 201 Created
will be expected to be returned, also when the switch is cloned without a network or address.
HTTP 400 Bad request
is returned when newswitchname is missing or already exists, a field is not a switch field, the address cannot be assigned, or the body is not valid.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not create switches.
HTTP 404 Not found
is returned when the source switch does not exist or the caller may not read it.
HTTP 500 Internal server error
is returned when the clone clashes with an existing configuration.
Delete switch (GET /config/switch/{switch}/_delete):
Request
GET /config/switch/switch01/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get switch interfaces (GET /config/switch/{name}/interfaces)
Token is required. Lists the interfaces of the switch that have an IP address. Empty fields are left out; the management interface carries "mgmt": 1.
Request
GET /config/switch/switch01/interfaces
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"switch": {
"switch01": {
"interfaces": [
{
"interface": "eth0",
"macaddress": "aa:bb:cc:dd:ee:01",
"mgmt": 1,
"ipaddress": "10.141.253.1",
"network": "cluster"
},
{
"interface": "eth1",
"macaddress": "aa:bb:cc:dd:ee:02",
"ipaddress": "10.148.253.1",
"network": "ipmi"
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when the switch does not exist, has no interface configured, or the caller may not read it.
Get a single switch interface (GET /config/switch/{name}/interfaces/{interface})
Token is required.
Request
GET /config/switch/switch01/interfaces/eth1
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"switch": {
"switch01": {
"interfaces": [
{
"interface": "eth1",
"macaddress": "aa:bb:cc:dd:ee:02",
"ipaddress": "10.148.253.1",
"network": "ipmi"
}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when a node's provision token is used; this endpoint takes a user token.
HTTP 404 Not found
is returned when the switch or the interface does not exist, or the caller may not read the switch.
Create or update switch interfaces (POST /config/switch/{name}/interfaces)
Token is required. Each entry needs interface; macaddress, network, ipaddress, mgmt and newinterfacename (to rename) are optional. An empty ipaddress clears the interface's addresses. A switch has one management interface: "mgmt": true moves it to this interface, and the only management interface cannot be cleared. DHCP and DNS are reloaded afterwards.
Request
POST /config/switch/switch01/interfaces
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"switch": {
"switch01": {
"interfaces": [
{
"interface": "eth1",
"macaddress": "aa:bb:cc:dd:ee:02",
"network": "ipmi",
"ipaddress": "10.148.253.1"
}
]
}
}
}
}
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 400 Bad request
is returned when no interfaces are given, an entry lacks interface, the new interface name already exists, the only management interface would be cleared, or the body is not valid.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller may not change the switch.
HTTP 404 Not found
is returned when the switch or the interface to rename does not exist, or the IP address cannot be assigned (no network given, or not valid in the network).
Delete a switch interface (GET /config/switch/{name}/interfaces/{interface}/_delete)
Token is required. The interface's addresses are removed with it and DHCP and DNS are reloaded. The only management interface cannot be deleted; flag another interface as management first, or delete the switch.
Request
GET /config/switch/switch01/interfaces/eth1/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 400 Bad request
is returned when it is the only management interface.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the caller is not the controller account or an admin user and either lacks change access on the switch (with the default mode only its owners have it) or is not an admin or manager of a usergroup with the hardware flag that is listed on the switch.
HTTP 404 Not found
is returned when the switch or the interface does not exist, or the caller may not read the switch.
Other devices management
The otherdev section is used to create entries in the CMDB, for non-bootable devices and switches. These objects are usually PDU, UPS or other externally managed devices.
Get a list of otherdev devices (GET /config/otherdev):
Request
GET /config/otherdev
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"otherdev": {
"apc01": {
"network": "cluster",
"ipaddress": "10.141.250.1",
"comments": "APC for rack01a"
},
"ups01": {
"network": "ipmi",
"ipaddress": "10.148.250.1",
"comments": "UPS for the head node"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get otherdev information (GET /config/otherdev/{device}):
Request
GET /config/otherdev/apc01
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"otherdev": {
"apc01": {
"network": "cluster",
"ipaddress": "10.141.250.1",
"comments": "APC for rack01a"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 404 Not found
is mandatory if object doesn’t exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update otherdev information (POST/config/otherdev/{device}):
Renaming is done by passing the
newotherdevname
field.
Request
POST /config/otherdev/apc01
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"otherdev": {
"apc01": {
"network": "cluster",
"ipaddress": "10.141.250.1",
"comments": "APC for rack01a"
}
}
}
}
Response body
Response header
HTTP 201 Created
will be expected to be returned when a new device is created
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Clone otherdev information (POST/config/otherdev/{device}/_clone):
Cloning is done by passing the
newotherdevname
field.
Request
POST /config/otherdev/apc01/_clone
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"otherdev": {
"apc01": {
"network": "cluster",
"newotherdevname": "apc01b",
"ipaddress": "10.141.250.1",
"comments": "APC for rack01a"
}
}
}
}
Response body
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Deleting otherdev device (GET /config/otherdev/{device}/_delete):
Request
GET /config/otherdev/apc01/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Service management
Reload DNS
Note that Luna2 will automatically schedule a reload once changes have been made to objects which have changed the
network
and/or
ipaddress
field.
Request
GET /service/dns/reload
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 204 No Content
will be returned when the service is in cooldown
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Reload DHCP
Request
GET /service/dhcp/reload
Request body
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 204 No Content
will be returned when the service is in cooldown
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Reload Luna2
This is required when templates on the filesystem have manually changed.
Request
GET /service/luna2/reload
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 204 No Content
will be returned when the service is in cooldown
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Poll the result of a service action (GET /service/status/{request_id})
Request
GET /service/status/1781092799.0698555248730542
Response body
{
"message": "2026-06-10 12:00:00 :: restarting dhcp;;2026-06-10 12:00:02 :: dhcp restarted",
"status": 200
}
Response header
HTTP 200 OK
will be expected to be returned while results are available. Poll again until the request is complete.
HTTP 404 Not Found
is returned when there is no data for this request id.
Monitoring handles
Monitoring DNS service
Request
GET /monitor/service/dns
Request header
Response body
{
"monitor": {
"service": {
"dns": "OK, running"
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 204 No Content
will be returned when the service is in cooldown
HTTP 500 Internal Server Error
is returned when the service is unavailable.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Monitoring DHCP service
Request
GET /monitor/service/dhcp
Request header
Response body
{
"monitor": {
"service": {
"dns": "OK, reloaded"
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 204 No Content
will be returned when the service is in cooldown
HTTP 500 Internal Server Error
is returned when the service is unavailable.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Monitoring Luna2 service
Request
GET /monitor/service/luna2
Request header
Response body
{
"monitor": {
"service": {
"luna2": "OK"
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 204 No Content
will be returned when the service is in cooldown
HTTP 500 Internal Server Error
is returned when the service is unavailable.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Node monitoring (GET /monitor/node/{node})
Request
GET /monitor/node/node001
Request header
Response body
{
"monitor": {
"status": {
"node001": {
"status": "Luna installer: No errors",
"state": "installer.ok"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned when the node is OK
HTTP 500 Internal Server Error
is when the node is not OK
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Node monitoring (POST /monitor/node/{node})
Meant to be called from the LUNA installer only. Once the node is only, a monitoring stack will be available.
Request
POST /monitor/node/node001
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"monitor": {
"status": {
"node001": {
"status": "Luna installer: No errors",
"state": "installer.ok"
}
}
}
}
Response body
Response header
HTTP 204 No Content
will be expected when the node contents have been successfully updated
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 404 Not Found
is to be returned when the node does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Cluster monitoring status (GET /monitor/status)
Request
GET /monitor/status
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": [
{
"request_id": "1781082942.0591104302914211",
"username_initiator": "admin",
"created": "2026-06-10 09:15:42",
"read": 0,
"message": "osimage compute build started"
}
]
}
}
The handler returns every message still held in the status table, ordered by creation time; each entry carries request_id, username_initiator, created, read and message. When the table is empty the list is returned empty.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Push cluster monitoring status (POST /monitor/status)
Request
POST /monitor/status
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"monitor": {
"status": {
"request_id": "1781082942.0591104302914211",
"messages": [
{ "message": "osimage compute sync finished" }
]
}
}
}
This route receives remote status messages and appends them to the local status table; it is not tied to a node. The payload must contain monitor.status.request_id. Either a list of messages (each with a message, and optionally remote_request_id/remote_host) or a single remote reference (remote_request_id plus remote_host) is accepted.
Response body
{
"message": "success"
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Node monitoring state (GET /monitor/node)
Request
GET /monitor/node
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"node": {
"node001": {
"state": "node001 ok",
"status": "ready"
}
}
}
}
}
Each node is keyed by name and reports a state string (the node name followed by its state) and an interpreted status.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
HA monitoring summary (GET /monitor/ha)
Request
GET /monitor/ha
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"ha": {
"controller": {
"state": "controller ok",
"status": "active"
}
}
}
}
}
Every HA reference entry is returned, keyed by its name, with a state string and a status.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
HA monitoring for one controller (GET /monitor/ha/{name})
Request
GET /monitor/ha/controller
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"controller": {
"status": "active",
"state": "controller ok"
}
}
}
}
The single HA entry is keyed by the requested name; if no monitor row exists for it the endpoint responds with HTTP 404 Not Found.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Mother monitoring summary (GET /monitor/mother)
Request
GET /monitor/mother
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"mother": {
"controller": {
"state": "controller ok",
"status": "running"
}
}
}
}
}
Every mother/core reference entry is returned, keyed by its name, with a state string and a status.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Mother monitoring for one entry (GET /monitor/mother/{name})
Request
GET /monitor/mother/controller
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"controller": {
"status": "running",
"state": "controller ok"
}
}
}
}
The single mother entry is keyed by the requested name; if no monitor row exists for it the endpoint responds with HTTP 404 Not Found.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
OS image monitoring summary (GET /monitor/osimage)
Request
GET /monitor/osimage
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"osimage": {
"compute": {
"state": "compute ok",
"status": "built"
}
}
}
}
}
Every OS image is returned, keyed by image name, with its build/sync state string and a status.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
OS image monitoring for one image (GET /monitor/osimage/{name})
Request
GET /monitor/osimage/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"compute": {
"status": "built",
"state": "compute ok"
}
}
}
}
The single image is keyed by the requested name and reports the recorded status and state; if no monitor row exists for it the endpoint responds with HTTP 404 Not Found.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Task queue status (GET /monitor/queue)
Request
GET /monitor/queue
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"queue": [
{
"level": "maintask",
"queue_id": 12,
"request_id": "1781082942.0591104302914211",
"username_initiator": "admin",
"created": "2026-06-10 09:15:42",
"subsystem": "osimage",
"task": "pack_n_build compute",
"status": "queued"
}
]
}
}
Each queued task is reported with a level of maintask or subtask, a queue_id, and its request_id, username_initiator, created, subsystem, task (with any parameter appended) and status.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Sync monitoring summary (GET /monitor/sync)
Request
GET /monitor/sync
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"sync": {
"compute": {
"state": "compute ok",
"status": "synced"
}
}
}
}
}
Sync state is derived from the OS image entries; each is keyed by image name and reports a state string and a status.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Sync monitoring for one entry (GET /monitor/sync/{name})
Request
GET /monitor/sync/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"monitor": {
"status": {
"compute": {
"status": "synced",
"state": "compute ok"
}
}
}
}
The single sync entry is keyed by the requested name and reports the recorded status and state; if no monitor row exists for it the endpoint responds with HTTP 404 Not Found.
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Control API
The control API is used by the Luna tools such as lpower or any scripts to control nodes: power, chassis identification, the system event log, a one-time boot into the BIOS setup and Redfish actions. The calls below list the subsystems and actions they take.
Control a single node (GET /control/action/{subsystem}/{hostname}/_{action})
Runs one action on the BMC of one node and waits for the answer. The node needs a BMC interface and a BMC setup, assigned to the node or its group.
| Subsystem | Actions |
|---|---|
| power | on, off, reset, cycle, status |
| chassis | identify, noidentify |
| sel | list, clear |
| nextboot | bios, status, clear |
nextboot
sets a one-time boot into the BIOS setup and needs Redfish. The
redfish
subsystem needs a request body and is only available through the POST call.
Request
GET /control/action/power/node001/_on
GET /control/action/power/node001/_status
GET /control/action/chassis/node001/_identify
GET /control/action/sel/node001/_list
GET /control/action/nextboot/node001/_bios
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
No body is returned for an action that changes something. A
status
or
list
action returns the answer under the subsystem; for
sel list
the lines are separated by
;;
.
{
"control": {
"power": "on"
}
}
When the BMC refuses or fails the action, the reason is returned under the subsystem:
{
"control": {
"nextboot": "this system exposes no boot override"
}
}
Response header
HTTP 200 OK
will be expected for a status or list action
HTTP 204 No Content
will be expected when any other action is carried out
HTTP 400 Bad request
is returned when the hostname is not a valid name
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 403 Forbidden
is returned when the user may read the node but not operate it (a status action needs read only)
HTTP 404 Not Found
is returned when the node does not exist, the user may not read it, it has no BMC interface, or it has no usable BMC setup
HTTP 501 Not Implemented
is returned when the action failed on the BMC or is not implemented
Control a list of nodes (POST /control/action/{subsystem}/_{action})
Runs one action on the BMCs of a list of nodes, given as a hostlist. The subsystems and actions are those of the single-node call, plus
redfish
with the actions
setting
and
upload
. The subsystem and action that run are taken from the request body; the path should name the same, as the access check reads the action from the path.
The work runs in the background in batches. The call waits up to about three seconds and returns the results available by then, with a
request_id
. Poll the remaining results with
GET /control/status/{request_id}
until the request is complete.
Request
POST /control/action/power/_on
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"control": {
"power": {
"on": {
"hostlist": "node[001-004]"
}
}
}
}
A
redfish
action also carries the
uri
to work on and the
content
to send, as base64 encoded JSON:
{
"control": {
"redfish": {
"setting": {
"hostlist": "node[001-004]",
"uri": "/redfish/v1/Systems/1/Bios/Settings",
"content": "eyJBdHRyaWJ1dGVzIjogeyJQcm9jZXNzb3JIeXBlclRocmVhZGluZyI6ICJEaXNhYmxlZCJ9fQ=="
}
}
}
}
Response body
ok
lists the nodes where the action succeeded (for
redfish
, with what the BMC reports it did),
on
and
off
list the answers to
power status
, and
failed
lists the nodes that failed with the reason. In this example node002 has failed and node004 has not answered yet; its result is returned when polling:
{
"request_id": "1761736212.4825933482120113",
"control": {
"power": {
"ok": {
"node001": "power on",
"node003": "power on"
},
"on": {},
"off": {}
},
"failed": {
"node002": "host does not exist or has no BMC interface configured"
}
}
}
When no node has answered yet, the same shape is returned with every list empty:
{
"request_id": "1761736212.4825933482120113",
"control": {
"power": {
"ok": {},
"on": {},
"off": {}
},
"failed": {}
}
}
Response header
HTTP 200 OK
will be expected when the action has been started (incl. failed results)
HTTP 400 Bad request
is returned when the body is not valid JSON or not in this structure
HTTP 401 Unauthorized
is mandatory if there is no valid token
HTTP 403 Forbidden
is returned when the user may not read or may not operate one or more of the nodes (a status action needs read only); the message names them
HTTP 404 Not Found
is returned when the body has no hostlist, the hostlist is invalid, or a
redfish
action lacks a uri or content, or its content is not base64 encoded JSON
Poll the result of a control action (GET /control/status/{request_id})
Request
GET /control/status/1781085753.0374956810530542
Response body
{
"request_id": "1781085753.0374956810530542",
"control": {
"power": {
"ok": {
"node001": "power on"
},
"on": {},
"off": {}
},
"failed": {}
}
}
Response header
HTTP 200 OK
will be expected to be returned while results are available. Poll again until the request is complete.
HTTP 404 Not Found
is returned when there is no data for this request id.
Rack View
Get all the racks in detailed view
Request
GET /config/rack
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"rack": {
"rack001": {
"size": 52,
"order": "ascending",
"room": "Basement",
"site": "ClusterVision Amsterdam",
"name": "rack001",
"devices": [
{"name": "controller", "type": "controller", "vendor": "Supermicro", "orientation": "front", "height": 1, "position": 5},
{"name": "node001", "type": "node", "vendor": "Dell", "orientation": "front", "height": 2, "position": 8}
]
},
"rack002": {
"size": 52,
"order": "descending",
"room": "Basement",
"site": "ClusterVision Amsterdam",
"name": "rack002",
"devices": [
{"name": "node002", "type": "node", "vendor": "GigaByte", "orientation": "front", "height": 4, "position": 27}
]
},
"rack006": {
"size": 42,
"order": "descending",
"room": "1st Floor",
"site": "ClusterVision Schiphol",
"name": "rack006",
"devices": []
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get a single rack with detailed view
Request
GET /config/rack/{RACK-NAME}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"rack": {
"rack001": {
"size": 52,
"order": "ascending",
"room": "Basement",
"site": "ClusterVision Amsterdam",
"name": "rack001",
"devices": [
{"name": "node001", "type": "node", "vendor": "HP", "orientation": "front", "height": 1, "position": 5},
{"name": "node002", "type": "node", "vendor": "Lenovo", "orientation": "front", "height": 2, "position": 8}
]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create a new or update a rack
Request
POST /config/rack/{RACK-NAME}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"rack": {
"rack001": {
"size": 52,
"order": "ascending",
"room": "Basement",
"site": "ClusterVision Amsterdam",
"name": "rack001",
"devices": [
{"name": "node001", "type": "node", "vendor": "HP", "orientation": "front", "height": 1, "position": 5},
{"name": "node002", "type": "node", "vendor": "Lenovo", "orientation": "front", "height": 2, "position": 8}
]
}
}
}
}
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 201 Created
will be expected when a new object is created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get all the inventories in detailed view
Request
GET /config/rack/inventory
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"rack": {
"inventory": [
{"name": "node001", "type": "node", "vendor": "Dell", "height": 1, "orientation": "front"},
{"name": "node002", "type": "node", "vendor": "Dell", "height": 2, "orientation": "front"}
]
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get all the configured or unconfigured inventories in detailed view
Request
GET /config/rack/inventory/{SUBSET}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"rack": {
"inventory": [
{"name": "node001", "type": "node", "vendor": "Dell", "height": 1, "orientation": "front"},
{"name": "node002", "type": "node", "vendor": "Dell", "height": 2, "orientation": "front"}
]
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Update a Inventory
Request
POST /config/rack/inventory
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"rack": {
"inventory": [
{"name": "node001", "type": "node", "vendor": "Dell", "height": 1, "orientation": "front"},
{"name": "node002", "type": "node", "vendor": "Dell", "height": 2, "orientation": "front"}
]
}
}
}
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 201 Created
will be expected when a new object is created.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete a Rack
Request
GET /config/rack/{RACK-NAME}/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete a Inventory [Remove it from the Rack]
Request
GET /config/rack/inventory/{DEVICE_NAME}/type/{DEVICE_TYPE}/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "Inventory cleared"
}
Response header
HTTP 201 With content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Journal
The journal carries the changes of one controller of an HA pair to the other. These calls are made by the Luna daemons themselves and need the rootus account; a pull removes the entries it returns. They are not meant for administrators or tools.
Get all the journal entries for a controller
Request
GET /journal/{controller}
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"journal": [
{"function": "Node.update_node", "object": "node001", "param": null, "payload": "IyBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB3Zy1xdWljayg4KSBmb3IgdXNlIHdpdGgKIyB0", "masteronly": 0, "remoteonly": 0, "misc": null, "sendfor": "controller2", "sendto": null, "sendby": "controller1", "tries": 0, "created": "1713520340"},
{"function": "OSImage.pack", "object": "compute", "param": null, "payload": null, "masteronly": 1, "remoteonly": 0, "misc": "1703678426.721102268962463531", "sendfor": "controller2", "sendto": null, "sendby": "controller1", "tries": 0, "created": "1713520344"}
]
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is mandatory if the object does not exist
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Update journal with entries on controller
Request
POST /journal
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"journal": [
{"function": "Node.update_node", "object": "node001", "param": null, "payload": "IyBUaGlzIGZpbGUgd2FzIGdlbmVyYXRlZCBieSB3Zy1xdWljayg4KSBmb3IgdXNlIHdpdGgKIyB0", "masteronly": 0, "remoteonly": 0, "misc": null, "sendfor": "controller2", "sendto": null, "sendby": "controller1", "tries": 0, "created": "1713520340"},
{"function": "OSImage.pack", "object": "compute", "param": null, "payload": null, "masteronly": 1, "remoteonly": 0, "misc": "1703678426.721102268962463531", "sendfor": "controller2", "sendto": null, "sendby": "controller1", "tries": 0, "created": "1713520344"}
]
}
Response body
{
"message": "success"
}
Response header
HTTP 201 Created
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 400 Bad request
is returned when the request carries no journal entries or an entry has the wrong fields.
HTTP 404 Not found
is returned when an entry could not be added to the journal.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get the journal for the calling controller (GET /journal)
Returns the pending journal entries addressed to the controller that makes the request, which is recognised by its source address. This is how a controller in a high-availability setup fetches the changes its peer recorded for it. The returned entries are removed from the journal, so each entry is delivered once. When the source address is not that of a known controller, every entry in the journal is returned, and removed. Only rootus and admin users may call it.
Request
GET /journal
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"journal": [
{
"function": "Node.update_mount",
"object": "node001",
"param": null,
"payload": "eyJjb25maWciOiB7Im5vZGUiOiB7Im5vZGUwMDEiOiB7Im1vdW50IjogIi4uLiJ9fX19",
"masteronly": 0,
"remoteonly": 0,
"misc": null,
"sendfor": "controller2",
"sendto": null,
"sendby": "controller1",
"tries": 0,
"created": "1761730320"
}
]
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 403 Forbidden
is returned when the token's user is not rootus or an admin user.
Get journal entries for a host (GET /journal/{name})
Request
GET /journal/controller
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"journal": [
{
"function": "Node.update_node",
"object": "node001",
"payload": "[...]"
},
{ "...": "..." }
]
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when there are no journal entries for the host.
Clear journal entries for a host (GET /journal/{name}/_delete)
Request
GET /journal/controller/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No Content
will be expected to be returned when the host's journal entries are deleted.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when there are no journal entries to delete.
Cloud management
Get a list of clouds (GET /config/cloud)
Request
GET /config/cloud
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"cloud": {
"aws1": {
"name": "aws1",
"type": "aws",
"comment": "Production AWS account"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get a cloud (GET /config/cloud/{name})
Request
GET /config/cloud/aws1
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"cloud": {
"aws1": {
"name": "aws1",
"type": "aws",
"comment": "Production AWS account"
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the requested cloud does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update a cloud (POST /config/cloud/{name})
Request
POST /config/cloud/aws1
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"cloud": {
"aws1": {
"type": "aws",
"comment": "Production AWS account"
}
}
}
}
To rename an existing cloud, include the newcloudname field in the body. The cloud addressed by the URI is then renamed to this value:
{
"config": {
"cloud": {
"aws1": {
"newcloudname": "aws-prod",
"type": "aws",
"comment": "Production AWS account"
}
}
}
}
Response body
{
"message": "Cloud aws1 created successfully"
}
Response header
HTTP 201 Created
is returned when a new cloud is created.
HTTP 204 No Content
is returned when an existing cloud is updated.
HTTP 400 Bad Request
is returned when the request contains no data or unknown columns.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete a cloud (GET /config/cloud/{name}/_delete)
Request
GET /config/cloud/aws1/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "Cloud aws1 removed successfully"
}
Response header
HTTP 204 No Content
is returned when the cloud is removed.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the requested cloud does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
DNS management
Get DNS record(s) for a network (GET /config/dns/{name})
The {name} URI parameter is the name of the network. All additional DNS host entries belonging to that network are returned.
Request
GET /config/dns/cluster
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"dns": {
"cluster": [
{
"host": "mirror",
"ipaddress": "10.141.0.5"
},
{
"host": "license",
"ipaddress": "10.141.0.6"
}
]
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the network does not exist or has no additional DNS entries.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update DNS records for a network (POST /config/dns/{name})
The {name} URI parameter is the name of the network. The body carries a list of host entries; each entry must provide both a host and an ipaddress. Existing hosts on the network are updated, new hosts are inserted.
Request
POST /config/dns/cluster
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"dns": {
"cluster": [
{
"host": "mirror",
"ipaddress": "10.141.0.5"
},
{
"host": "license",
"ipaddress": "10.141.0.6"
}
]
}
}
}
Response body
{
"message": "DNS entries added or changed"
}
Response header
HTTP 201 Created
is returned when the DNS entries are added or changed.
HTTP 400 Bad Request
is returned when the request contains no data.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the network is not present in the database.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Delete a DNS record from a network (GET /config/dns/{network}/{name}/_delete)
The {network} URI parameter is the name of the network and {name} is the host entry to remove from it.
Request
GET /config/dns/cluster/mirror/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "Entry removed"
}
Response header
HTTP 204 No Content
is returned when the host entry is removed.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the host entry does not exist for the given network.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
OS user group management
Get a list of OS groups (GET /config/osgroup)
Request
GET /config/osgroup
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osgroup": {
"users": {
"gidNumber": 100,
"member": ["alice", "bob"]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get a single OS group (GET /config/osgroup/{name})
Request
GET /config/osgroup/users
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osgroup": {
"users": {
"gidNumber": 100,
"member": ["alice", "bob"]
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the requested OS group does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update an OS group (POST /config/osgroup/{name})
Request
POST /config/osgroup/users
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"osgroup": {
"users": {
"gidNumber": 100,
"member": ["alice", "bob"]
}
}
}
}
Response body
{
"message": "[obol: group users created]"
}
Response header
HTTP 201 Created
will be expected to be returned when a new OS group is created.
HTTP 204 No content
will be expected to be returned when an existing OS group is updated.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the request data is missing or the backend is unavailable.
Delete an OS group (GET /config/osgroup/{name}/_delete)
Request
GET /config/osgroup/users/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "[obol: group users deleted]"
}
Response header
HTTP 204 No content
will be expected to be returned when the OS group is deleted.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the requested OS group does not exist.
OS user management
Get a list of OS users (GET /config/osuser)
Request
GET /config/osuser
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osuser": {
"alice": {
"uidNumber": 1050,
"gidNumber": 100,
"cn": "Alice Anderson",
"sn": "Anderson",
"givenName": "Alice",
"mail": "alice@controller",
"telephoneNumber": "555-0100",
"loginShell": "/bin/bash",
"homeDirectory": "/home/alice",
"memberOf": ["users"],
"shadowExpire": -1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get a single OS user (GET /config/osuser/{name})
Request
GET /config/osuser/alice
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"osuser": {
"alice": {
"uidNumber": 1050,
"gidNumber": 100,
"cn": "Alice Anderson",
"sn": "Anderson",
"givenName": "Alice",
"mail": "alice@controller",
"telephoneNumber": "555-0100",
"loginShell": "/bin/bash",
"homeDirectory": "/home/alice",
"memberOf": ["users"],
"shadowExpire": -1
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the requested OS user does not exist.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Create or update an OS user (POST /config/osuser/{name})
Request
POST /config/osuser/alice
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"osuser": {
"alice": {
"uidNumber": 1050,
"gidNumber": 100,
"userPassword": "s3cr3t",
"cn": "Alice Anderson",
"sn": "Anderson",
"givenName": "Alice",
"mail": "alice@controller",
"telephoneNumber": "555-0100",
"loginShell": "/bin/bash",
"homeDirectory": "/home/alice",
"memberOf": ["users"],
"shadowExpire": -1
}
}
}
}
Response body
{
"message": "[obol: user alice created]"
}
Response header
HTTP 201 Created
will be expected to be returned when a new OS user is created.
HTTP 204 No content
will be expected to be returned when an existing OS user is updated.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the request data is missing or the backend is unavailable.
Delete an OS user (GET /config/osuser/{name}/_delete)
Request
GET /config/osuser/alice/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "[obol: user alice deleted]"
}
Response header
HTTP 204 No content
will be expected to be returned when the OS user is deleted.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not found
is returned when the requested OS user does not exist.
User management (Luna)
Luna users are the identities that obtain a token through POST /token. They are not the cluster's OS accounts, which are managed under OS user management. A user is authenticated by the sources configured for the daemon (local, pam and ldap are available); a user known to an external source is created at its first login. rootus, the account defined in the daemon's configuration file, is not stored as a Luna user and is not listed.
These endpoints are for rootus and admin users, except reading what a user may access, which users may also do for themselves. A password is never returned: password_set says whether one is stored.
Get a list of Luna users (GET /config/user)
Request
GET /config/user
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"user": {
"asmith": {
"name": "asmith",
"username": "asmith",
"source": "ldap",
"external_id": "asmith",
"password_set": false,
"lastlogin": "2026-10-27 14:05:51",
"created": "2026-10-01 09:12:44",
"createdby": "luna",
"enabled": true,
"admin": false,
"delegate": false,
"usergroups": {
"physics": "reader"
}
},
"jdoe": {
"name": "jdoe",
"username": "jdoe",
"source": "local",
"external_id": null,
"password_set": true,
"lastlogin": "2026-10-28 08:41:12",
"created": "2026-09-15 10:02:37",
"createdby": "luna",
"enabled": true,
"admin": false,
"delegate": false,
"usergroups": {
"physics": "manager"
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when no Luna users exist.
Get a Luna user (GET /config/user/{name})
Request
GET /config/user/jdoe
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"user": {
"jdoe": {
"name": "jdoe",
"username": "jdoe",
"source": "local",
"external_id": null,
"password_set": true,
"lastlogin": "2026-10-28 08:41:12",
"created": "2026-09-15 10:02:37",
"createdby": "luna",
"enabled": true,
"admin": false,
"delegate": false,
"usergroups": {
"physics": "manager"
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the user does not exist.
Get what a Luna user may access (GET /config/user/{name}/_access)
Lists, per kind of governed object, every object the user may read and the permission bits the user holds on it (r read, w change or remove, x operate). Objects the user may not read are absent. See Object access control. rootus and admin users may ask this for any user; any other user only for themselves.
Request
GET /config/user/jdoe/_access
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"user": {
"jdoe": {
"access": {
"group": {
"compute": "rwx"
},
"node": {
"node001": "rwx",
"node002": "rwx"
},
"osimage": {
"compute": "rwx",
"default": "r--"
},
"network": {
"cluster": "r--"
}
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled. It is also returned, to any caller including rootus, when the user asked about is disabled.
HTTP 403 Forbidden
is returned when a user that is not rootus or an admin user asks about another user, for the token of a delegate user, and for a node's provision token. It is also returned, to any caller including rootus, when the user asked about is a delegate user.
HTTP 404 Not found
is returned when the user does not exist.
Create or update a Luna user (POST /config/user/{name})
Creates the user when it does not exist, otherwise updates it. Fields that are left out keep their value; a new user defaults to source local, enabled true, admin false and delegate false, and the caller is recorded as createdby.
password: stored as a salted digest; an empty value removes the stored password, so the user can only authenticate through another source.source: the authentication source of the user; it cannot be changed once the user exists.external_id: the user's identity in an external source.admin: an admin user has every right rootus has.delegate: a program that obtains tokens on behalf of other users; its own token is refused on every other endpoint.newusername: renames an existing user.
Request
POST /config/user/jdoe
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"user": {
"jdoe": {
"password": "Secr3t-Passw0rd",
"enabled": true,
"admin": false
}
}
}
}
To rename an existing user, include the newusername field:
{
"config": {
"user": {
"jdoe": {
"newusername": "jdoe2"
}
}
}
}
Response body
{
"message": "User jdoe created."
}
An update answers with 204 and no body.
Response header
HTTP 201 Created
is returned when the user is created.
HTTP 204 No Content
is returned when an existing user is updated.
HTTP 400 Bad Request
is returned when the body is not valid JSON or not under config.user.{name}, holds an unknown field, changes source, sends newusername for a user that does not exist or names a user that already exists, or when a value contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the user could not be stored. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Delete a Luna user (GET /config/user/{name}/_delete)
Deletes the user and its usergroup memberships, and removes it from the owners of every object. An object whose last owner it was passes to an admin of a usergroup listed on the object, or to rootus when there is none.
Request
GET /config/user/jdoe/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No Content
is returned when the user is removed.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the user does not exist. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Usergroup management
Usergroups collect Luna users, each with a role, and are listed on governed objects to give their members access (see Object access control). They are neither node groups (Group configuration) nor OS groups (OS user group management). The role caps what the usergroup's permission bits grant to a member: admin and manager up to rwx, operator up to r-x, reader up to r--. Admins and managers of any usergroup may create groups, osimages and profiles; with the usergroup's hardware flag also nodes, BMC, Redfish, BIOS and firmware objects, and change the hardware fields of the nodes and groups the usergroup is listed on.
The usergroup map turns the groups a user has in an external authentication source into memberships: at every login through that source, the memberships it gave before are replaced by what the map says now. Memberships added by hand are left alone.
Listing, showing, changing and deleting usergroups and the map is for rootus and admin users. The members of a usergroup are managed by rootus, admin users and the members holding the admin role in that usergroup.
Get a list of usergroups (GET /config/usergroup)
Request
GET /config/usergroup
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"usergroup": {
"chemistry": {
"name": "chemistry",
"comment": "Chemistry department",
"hardware": false,
"members": {
"bkumar": "admin",
"jdoe": "reader"
}
},
"physics": {
"name": "physics",
"comment": "Physics department",
"hardware": true,
"members": {
"asmith": "reader",
"jdoe": "manager"
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when no usergroups exist.
Get a usergroup (GET /config/usergroup/{name})
Request
GET /config/usergroup/physics
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"usergroup": {
"physics": {
"name": "physics",
"comment": "Physics department",
"hardware": true,
"members": {
"asmith": "reader",
"jdoe": "manager"
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the usergroup does not exist.
Get what a usergroup may access (GET /config/usergroup/{name}/_access)
Lists, per kind of governed object, every object the usergroup is listed on and the permission bits each role in the usergroup holds there.
Request
GET /config/usergroup/physics/_access
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"usergroup": {
"physics": {
"access": {
"node": {
"node001": {
"admin": "rwx",
"manager": "rwx",
"operator": "r-x",
"reader": "r--"
}
},
"osimage": {
"compute": {
"admin": "rwx",
"manager": "rwx",
"operator": "r-x",
"reader": "r--"
}
}
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the usergroup does not exist.
Create or update a usergroup (POST /config/usergroup/{name})
Creates the usergroup when it does not exist, otherwise updates it. The fields are comment, hardware (default false) and, to rename an existing usergroup, newusergroupname. Members are not part of this body; they are added and removed one at a time through the members endpoints.
Request
POST /config/usergroup/physics
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"usergroup": {
"physics": {
"comment": "Physics department",
"hardware": true
}
}
}
}
Response body
{
"message": "Usergroup physics created."
}
An update answers with 204 and no body.
Response header
HTTP 201 Created
is returned when the usergroup is created.
HTTP 204 No Content
is returned when an existing usergroup is updated.
HTTP 400 Bad Request
is returned when the body is not valid JSON or not under config.usergroup.{name}, holds an unknown field, sends newusergroupname for a usergroup that does not exist or names a usergroup that already exists, or when a value contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the usergroup could not be stored. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Delete a usergroup (GET /config/usergroup/{name}/_delete)
Deletes the usergroup, its memberships and its map entries, and removes it from the usergroups of every object.
Request
GET /config/usergroup/physics/_delete
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
Response header
HTTP 204 No Content
is returned when the usergroup is removed.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the usergroup does not exist. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Get the members of a usergroup (GET /config/usergroup/{name}/members)
Request
GET /config/usergroup/physics/members
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"usergroup": {
"physics": {
"members": {
"asmith": "reader",
"jdoe": "manager"
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus, an admin user or a member with the admin role in this usergroup, for the token of a delegate user, and for a node's provision token.
HTTP 404 Not found
is returned when the usergroup does not exist.
Add a member to a usergroup or change its role (POST /config/usergroup/{name}/members)
Adds one existing Luna user to the usergroup with a role, or changes the role of a member. username and role (admin, manager, operator or reader) are required; source is optional and defaults to local.
Request
POST /config/usergroup/physics/members
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"usergroup": {
"physics": {
"username": "asmith",
"role": "operator"
}
}
}
}
Response body
{
"message": "Member asmith added to usergroup physics as operator."
}
Changing the role of an existing member answers with 204 and no body.
Response header
HTTP 201 Created
is returned when the user is added to the usergroup.
HTTP 204 No Content
is returned when the role of an existing member is changed.
HTTP 400 Bad Request
is returned when the body is not valid JSON or not under config.usergroup.{name}, username is missing or role is not one of the four roles.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus, an admin user or a member with the admin role in this usergroup, for the token of a delegate user, and for a node's provision token.
HTTP 404 Not found
is returned when the usergroup or the user does not exist. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Remove a member from a usergroup (POST /config/usergroup/{name}/members/_remove)
Request
POST /config/usergroup/physics/members/_remove
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"usergroup": {
"physics": {
"username": "asmith"
}
}
}
}
Response body
Response header
HTTP 204 No Content
is returned when the member is removed.
HTTP 400 Bad Request
is returned when the body is not valid JSON or not under config.usergroup.{name}, or username is missing.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus, an admin user or a member with the admin role in this usergroup, for the token of a delegate user, and for a node's provision token.
HTTP 404 Not found
is returned when the usergroup or the user does not exist, or the user is not a member of the usergroup. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Get the usergroup map (GET /config/usergroupmap)
Request
GET /config/usergroupmap
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"usergroupmap": [
{
"source": "ldap",
"external_group": "physics-staff",
"usergroup": "physics",
"role": "manager"
},
{
"source": "ldap",
"external_group": "physics-students",
"usergroup": "physics",
"role": "reader"
}
]
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the map has no entries.
Add or change a usergroup map entry (POST /config/usergroupmap)
An entry is identified by source and external_group. When it exists, its usergroup and role are changed; otherwise it is created. All four fields are required; role is admin, manager, operator or reader.
Request
POST /config/usergroupmap
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"usergroupmap": {
"source": "ldap",
"external_group": "physics-staff",
"usergroup": "physics",
"role": "manager"
}
}
}
Response body
{
"message": "Map entry ldap physics-staff created."
}
Changing an existing entry answers with 204 and no body.
Response header
HTTP 201 Created
is returned when the entry is created.
HTTP 204 No Content
is returned when an existing entry is changed.
HTTP 400 Bad Request
is returned when the body is not valid JSON or not under config.usergroupmap, source or external_group is missing, external_group contains a quote, or role is not one of the four roles.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the usergroup does not exist. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Remove a usergroup map entry (POST /config/usergroupmap/_remove)
Request
POST /config/usergroupmap/_remove
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"usergroupmap": {
"source": "ldap",
"external_group": "physics-staff"
}
}
}
Response body
Response header
HTTP 204 No Content
is returned when the entry is removed.
HTTP 400 Bad Request
is returned when the body is not valid JSON or not under config.usergroupmap, source or external_group is missing, or external_group contains a quote.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when the entry does not exist. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Object access control
Every governed object carries owners, usergroups and an access mode, much as a file does. What a caller may do with an object is decided in this order: rootus and admin users may do everything; an owner holds the owner bits; a member of a usergroup listed on the object holds the usergroup bits, capped by the highest role it has in those usergroups; anyone else holds the other bits. r is read, w change or remove, x operate (power, provisioning and similar actions). An object the caller may not read answers 404 Not found, as if it did not exist; a missing w or x answers 403 Forbidden. An object without owners is owned by rootus.
The governed entities and their default mode are: node, group, bmcsetup, redfishsetup and profile rwxrwx---; osimage, biosconfig and firmwarecatalog rwxrwxr--; cluster, network, route, cloud, switch, rack and otherdevices rw-r--r--. Listings and shows of these objects include owners, usergroups and access.
Owners, usergroups and the mode are changed with the three endpoints below only: a create or update body that names them is refused for anyone but rootus and admin users. {entity} is the entity name as listed above (for example profile and otherdevices), and the body carries the object under config.{entity}.{objectname}. The caller needs read access on the object.
Change the access mode of an object (POST /config/{entity}/{objectname}/_chmod)
Sets the mode as ls shows it, nine characters such as rwxr-x---, or as three octal digits such as 750. Allowed for rootus, admin users, the owners of the object and the members with the admin role in a usergroup listed on it.
Request
POST /config/node/node001/_chmod
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"access": "rwxr-x---"
}
}
}
}
Response body
Response header
HTTP 204 No Content
is returned when the mode is changed.
HTTP 400 Bad Request
is returned when the body is not valid JSON or has no config object, access is missing or is not a valid mode, or when {entity} is not a governed entity or a name in the path contains characters that are not allowed. For a caller that is not rootus or an admin user, an object it may not read and an {entity} that is not governed answer 404 before the body is checked.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the caller is not rootus, an admin user, an owner of the object or a usergroup admin on it, for the token of a delegate user, and for a node's provision token.
HTTP 404 Not found
is returned when the object does not exist or the caller may not read it. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Change the usergroups of an object (POST /config/{entity}/{objectname}/_chgrp)
usergroups is a list of usergroup names, or the same as one comma-separated string. Names without a prefix replace the current list; +name adds a usergroup and -name removes one. rootus and admin users may set any usergroup; owners of the object and usergroup admins on it may add only usergroups they are a member of themselves.
Request
POST /config/node/node001/_chgrp
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"usergroups": [
"+physics",
"-chemistry"
]
}
}
}
}
Response body
Response header
HTTP 204 No Content
is returned when the request is accepted, also when it leaves the list as it was, for example +name for a usergroup already listed.
HTTP 400 Bad Request
is returned when the body is not valid JSON or has no config object, usergroups is missing or empty, a usergroup does not exist, or when {entity} is not a governed entity or a name in the path contains characters that are not allowed. For a caller that is not rootus or an admin user, an object it may not read and an {entity} that is not governed answer 404 before the body is checked.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the request changes the list and the caller is not rootus, an admin user, an owner of the object or a usergroup admin on it, when it adds a usergroup it is not a member of, for the token of a delegate user, and for a node's provision token.
HTTP 404 Not found
is returned when the object does not exist or the caller may not read it. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
Change the owners of an object (POST /config/{entity}/{objectname}/_chown)
owners is a list of usernames, or the same as one comma-separated string, with the same +name and -name forms as _chgrp. rootus and admin users may set any owner; members with the admin role in a usergroup listed on the object may only make members of such a usergroup owner. An object left without owners is owned by rootus.
Request
POST /config/node/node001/_chown
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"config": {
"node": {
"node001": {
"owners": "jdoe,asmith"
}
}
}
}
Response body
Response header
HTTP 204 No Content
is returned when the owners are changed.
HTTP 400 Bad Request
is returned when the body is not valid JSON or has no config object, owners is missing or empty, a user does not exist, or when {entity} is not a governed entity or a name in the path contains characters that are not allowed. For a caller that is not rootus or an admin user, an object it may not read and an {entity} that is not governed answer 404 before the body is checked.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the caller is not rootus, an admin user or a usergroup admin on the object, when a new owner is not a member of a usergroup the caller administers on it, for the token of a delegate user, and for a node's provision token.
HTTP 404 Not found
is returned when the object does not exist or the caller may not read it. It is also returned by a controller of an HA pair that is not in sync yet; the change is not made.
High Availability
HA liveness check (GET /ping)
Request
GET /ping
This endpoint requires no token; it always replies with a small JSON acknowledgement and updates the controller's internal ping timestamp.
Response body
{
"message": "pong"
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
HA state (GET /ha/state)
Request
GET /ha/state
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Returns the full HA record of this controller. The boolean flags (master, syncimages, enabled, insync, overrule) are normalised to true/false; updated holds the timestamp of the last state change.
Response body
{
"ha": {
"enabled": true,
"syncimages": true,
"insync": true,
"sharedip": false,
"overrule": false,
"master": true,
"updated": "2025-01-01 00:00:00"
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when HA is not available; the body is then {"message": "HA not available"}.
HA master role (GET /ha/master)
Request
GET /ha/master
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Returns whether this controller currently holds the master role (the boolean value of the master flag).
Response body
{
"message": true
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when the controller does not hold the master role.
Become HA master (GET /ha/master/_set)
Request
GET /ha/master/_set
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Sets the current controller as master. It first forces the insync flag to true, then records the role-change request and sets the master role. The body is a single message describing the outcome.
Response body
{
"message": "current role set to master"
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the role could not be set to master (for example when insync could not be set, or the role change failed). The message then describes the reason.
Set HA overrule flag (GET /ha/overrule/_set)
Request
GET /ha/overrule/_set
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Sets the overrule flag, allowing this controller to proceed even when it is out of sync. Intended only for the case where all controllers are down and a single one is brought back up; use with caution. The body carries the boolean result of setting the flag.
Response body
{
"message": true
}
Response header
HTTP 204 No Content
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
List HA controllers (GET /ha/controllers)
Request
GET /ha/controllers
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Returns the HA state and configuration for every known controller. The local controller reports its own HA record directly; every other controller is queried over /ha/state. Each entry also carries a config block with its shadow/beacon settings, and an explanatory comment when a controller could not be reached.
Response body
{
"message": {
"controller": {
"ha": {
"enabled": true,
"master": true,
"insync": true,
"syncimages": true,
"sharedip": false,
"overrule": false,
"updated": "2025-01-01 00:00:00"
},
"config": {
"shadow": false,
"beacon": false
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when no controller data is available.
Sync image to controller (GET /ha/syncimage/{name})
Request
GET /ha/syncimage/image001
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
This endpoint is deprecated. Image synchronisation is now handled inline by the daemon, so the handler no longer triggers a sync and always reports that the operation is unavailable. The {name} path segment is validated as a name but is otherwise unused.
Response body
{
"message": "sync not available for images"
}
Response header
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned, as image sync is no longer offered through this endpoint.
File downloads
List downloadable files (GET /files)
Request
GET /files
Response body
[
"compute-image-20240101.tar.bz2",
"compute-image-20240101.torrent"
]
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 503 Service unavailable
is returned when no files are present or the backend is unavailable.
Download a file (GET /files/{filename})
This endpoint streams the requested file from the configured image-files directory. Authentication is enforced inside the handler only for image and torrent extensions (.gz, .tar, .bz, .bz2, .torrent); for those a valid token must be supplied in the x-access-tokens header. Other extensions are served without a token, since some files are fetched during early boot (PXE, kernel, ramdisk) before a token is available.
Request
GET /files/compute-image-20240101.tar.bz2
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
[... binary file stream ...]
Response header
HTTP 200 OK
will be expected to be returned, with the file delivered as a binary stream.
HTTP 401 Unauthorized
is returned for image/torrent files when the token is missing or invalid.
HTTP 503 Service unavailable
is returned when the file cannot be served.
Authenticated file-access check (GET /filesauth)
This endpoint performs an authentication subrequest (for example, an nginx auth_request). It inspects the X-Original-URI header to determine the requested file and enforces a token only for image and torrent extensions (.gz, .tar, .bz, .bz2, .torrent). For all other URIs it returns a "go" without a token. When authentication is required, a valid token must be present in the x-access-tokens header.
Request
GET /filesauth
Request header
X-Original-URI: /files/compute-image-20240101.tar.bz2
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"message": "Go"
}
Response header
HTTP 200 OK
will be expected to be returned when access is granted.
HTTP 401 Unauthorized
is returned when authentication is required but the token is missing or invalid.
Database tables
Get hashes of all tables (GET /table/hashes)
Request
GET /table/hashes
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"table": {
"hashes": {
"node": "8f14e45fceea167a5a36dedd4bea2543",
"group": "c9f0f895fb98ab9159f51fd0297e236d",
"...": "..."
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Get raw data for one table (GET /table/data/{name})
Request
GET /table/data/node
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"table": {
"data": {
"node": [
{
"id": 1,
"name": "node001",
"...": "..."
}
]
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 503 Service unavailable
is returned when the backend is unavailable.
Artefact checksums
The SHA-256 checksums of the artefacts a controller holds on disk: for an osimage, its image file, kernel and initramfs. A checksum is recorded where the artefact is built, or pulled from the other controller of an HA pair, which uses these endpoints to verify what it pulled. Checksums describe the files on the controller that answers and are not replicated. The endpoints are read-only and for rootus and admin users.
Get all artefact checksums (GET /hash)
Request
GET /hash
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"hash": {
"osimage": {
"compute": {
"compute-1760970728.tar.bz2": {
"hash": "9f2c4e1b7a3d5c8e0f6a2b4d6e8f0a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f",
"hashtype": "sha256",
"created": "2026-10-20 14:32:08"
},
"compute-1760970951-vmlinuz-5.14.0-570.el9.x86_64": {
"hash": "4b8d2f6a0c4e8b2d6f0a4c8e2b6d0f4a8c2e6b0d4f8a2c6e0b4d8f2a6c0e4b8d",
"hashtype": "sha256",
"created": "2026-10-20 14:35:51"
},
"compute-1760970951-initramfs-5.14.0-570.el9.x86_64": {
"hash": "e1c3a5b7d9f1e3c5a7b9d1f3e5c7a9b1d3f5e7c9a1b3d5f7e9c1a3b5d7f9e1c3",
"hashtype": "sha256",
"created": "2026-10-20 14:35:51"
}
},
"login": {
"login-1760971502.tar.bz2": {
"hash": "7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c",
"hashtype": "sha256",
"created": "2026-10-20 14:45:02"
}
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when this controller holds no checksums.
Get the checksums of an object (GET /hash/{object_type}/{name})
Request
GET /hash/osimage/compute
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"hash": {
"osimage": {
"compute": {
"compute-1760970728.tar.bz2": {
"hash": "9f2c4e1b7a3d5c8e0f6a2b4d6e8f0a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f",
"hashtype": "sha256",
"created": "2026-10-20 14:32:08"
},
"compute-1760970951-vmlinuz-5.14.0-570.el9.x86_64": {
"hash": "4b8d2f6a0c4e8b2d6f0a4c8e2b6d0f4a8c2e6b0d4f8a2c6e0b4d8f2a6c0e4b8d",
"hashtype": "sha256",
"created": "2026-10-20 14:35:51"
},
"compute-1760970951-initramfs-5.14.0-570.el9.x86_64": {
"hash": "e1c3a5b7d9f1e3c5a7b9d1f3e5c7a9b1d3f5e7c9a1b3d5f7e9c1a3b5d7f9e1c3",
"hashtype": "sha256",
"created": "2026-10-20 14:35:51"
}
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when this controller holds no checksums for the object.
Get the checksum of one artefact (GET /hash/{object_type}/{name}/{file})
Request
GET /hash/osimage/compute/compute-1760970728.tar.bz2
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Response body
{
"config": {
"hash": {
"osimage": {
"compute": {
"compute-1760970728.tar.bz2": {
"hash": "9f2c4e1b7a3d5c8e0f6a2b4d6e8f0a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f",
"hashtype": "sha256",
"created": "2026-10-20 14:32:08"
}
}
}
}
}
}
Response header
HTTP 200 OK
will be expected to be returned.
HTTP 400 Bad Request
is returned when a name in the path contains characters that are not allowed.
HTTP 401 Unauthorized
is mandatory if there is no valid token, or when the user of the token no longer exists or is disabled.
HTTP 403 Forbidden
is returned when the token does not belong to rootus or an admin user. The token of a delegate user and a node token are refused as well.
HTTP 404 Not found
is returned when this controller holds no checksum for the artefact, for example one packed before checksums were recorded.
Provisioning tracker
The provisioning tracker is the built-in BitTorrent tracker used for torrent-based image provisioning. It is queried by the aria2 clients running on nodes during deployment. These endpoints return a bencoded, plain-text (text/plain) tracker response, not JSON, and are unauthenticated (no token header is required).
BitTorrent announce (GET /announce)
The announce endpoint registers a peer for a torrent and returns the current peer list. The client passes the standard BitTorrent query parameters, including info_hash and peer_id.
Request
GET /announce?info_hash=%12%34...&peer_id=-aria2-...&port=6881&uploaded=0&downloaded=0&left=0&compact=1
Response body
d8:intervali1800e5:peers[... bencoded peer data ...]e
Response header
HTTP 200 OK
will be expected to be returned, with Content-Type: text/plain.
HTTP 400 Bad Request
is returned when info_hash or peer_id is missing or invalid.
HTTP 500 Internal Server Error
is returned when the response cannot be generated.
BitTorrent scrape (GET /scrape)
The scrape endpoint returns the state (seeders, leechers, completed) of the torrents the tracker manages. One or more info_hash parameters may be supplied; when none are given, all currently active torrents are reported.
Request
GET /scrape?info_hash=%12%34...
Response body
d5:filesd20:[... info_hash ...]d8:completei3e10:downloadedi0e10:incompletei1eeee
Response header
HTTP 200 OK
will be expected to be returned, with Content-Type: text/plain.
HTTP 500 Internal Server Error
is returned when the response cannot be generated.
Plugin import and export
Import data via an import plugin (POST /import/{name})
This endpoint forwards a request to the named import plugin (for example, prometheus rules). The request body is forwarded as-is to the plugin: if it is valid JSON it is parsed and passed as an object, otherwise the raw body is passed through unchanged.
Request
POST /import/prometheus
Request header
x-access-tokens: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjY4ODQyMTQwfQ"
Request body
{
"rules": [
{
"alert": "NodeDown",
"expr": "up == 0",
"...": "..."
}
]
}
Response body
[... plugin-defined response ...]
Response header
HTTP 200 OK
will be expected to be returned when the plugin accepts the data.
HTTP 401 Unauthorized
is mandatory if there is no valid token.
HTTP 404 Not Found
is returned when the plugin does not exist or rejects the request.
Export data via an export plugin (GET /export/{name})
This endpoint calls the named export plugin and returns its data as-is. Any query-string parameters are passed through to the plugin. This route is unauthenticated; no token header is required.
Request
GET /export/prometheus
Response body
[... plugin-defined response ...]
Response header
HTTP 200 OK
will be expected to be returned when the plugin produces data.
HTTP 404 Not Found
is returned when the plugin does not exist or has no data to return.
TPM authentication
Obtain a node token via TPM attestation (POST /tpm/{nodename})
This endpoint issues a node token after validating the supplied TPM attestation against the named node. When cluster security is enabled, the request body must contain the node's tpm_sha256 value, which is matched against the value stored for the node. When cluster security is not enabled, the TPM value is stored and a token is returned (a username/password pair may be supplied instead and is forwarded to the standard token flow). On success the response contains a JWT valid for the configured expiry time. This route is unauthenticated; no token header is required to call it.
Request
POST /tpm/node001
Request body
{
"tpm_sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
}
Response body
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MCwiZXhwIjoxNjY4ODQyMTQwfQ"
}
Response header
HTTP 200 OK
will be expected to be returned, with the node token in the body.
HTTP 401 Unauthorized
is returned when the TPM information is missing, the node is invalid, or the attestation does not match.
Asynchronous requests
Some operations do not complete within the lifetime of the HTTP request. When a state-changing POST operation is queued for background processing — for example pushing or grabbing an osimage, or a bulk control or service action — the daemon responds immediately with a request_id alongside the message:
{
"message": "queued",
"request_id": "1781082941.3238328347230542"
}
The result is then retrieved by polling the matching status endpoint until the operation finishes:
GET /config/status/{request_id}— for configuration operations such as osimage push and grab.GET /control/status/{request_id}— for control (power) actions.GET /service/status/{request_id}— for service (DHCP/DNS) actions.
Each poll returns the status messages collected so far and marks them as read, so successive calls return only new output. Continue polling until the operation is reported complete.
Poll the result of a configuration operation (GET /config/status/{request_id})
Request
GET /config/status/1781082941.3238328347230542
Response body
The status messages collected for the request so far are returned, keyed by the request id. Each poll marks the returned messages as read, so a subsequent call returns only newer output.
{
"1781082941.3238328347230542": [
{
"created": "2026-06-10 09:15:42",
"message": "osimage compute: packing started"
},
{
"created": "2026-06-10 09:18:10",
"message": "osimage compute: build finished"
}
]
}
Response header
HTTP 200 OK
will be expected to be returned while results are available. Poll again until the request is complete.
HTTP 404 Not Found
is returned when there is no data for this request id.
Error handling
Status code |
Description |
Content |
|---|---|---|
|
Indicates the request has succeeded |
Return response required, if just a confirmation, send a 204 |
|
Indicates the request has succeeded and a new resource has been created |
The new id |
|
The server has fulfilled the request but there is no response body |
None |
|
The request could not be understood. |
The faulty fields may be indicated by the server |
|
The request requires user authentication |
None |
|
The client does not have access rights to the content |
None |
|
The server can not find the resource |
The faulty fields may be indicated by the server |
|
The server encountered an unexpected condition. |
Send feedback |
|
The server is not ready to handle the request. |
Send feedback |
Note there are no 300 codes: Either the system is in fault (500), it doesn’t exist (400), but there is no (300) redirection to any other endpoint.
Full spec JSON
JSON
{
"config": {
"node": {
"node001": {
"newhostname": "gpu001",
"group": "compute",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet",
"ipaddress": "10.141.0.1"
},
{
"interface": "BMC",
"network": "ipmi",
"ipaddress": "10.148.0.1"
},
{
"interface": "ib0",
"network": "ib",
"ipaddress": "10.149.0.1"
}
],
"switch": "switch01",
"switchport": 1,
"service": false,
"setupbmc": true,
"status": "installer.completed",
"comment": null,
"osimage": "compute",
"prescript": "#!/bin/bash \n exit 0;",
"partscript": "#!/bin/bash \n exit 0;",
"postscript": "#!/bin/bash \n exit 0;",
"netboot": true,
"bootmenu": false,
"provision_interface": null,
"provision_method": null,
"provision_fallback": null,
"tpm_uuid": null,
"tpm_pubkey": null,
"tpm_sha256": null
}
},
"group": {
"compute": {
"newgroupname": "compute-gpu",
"bmcsetup": true,
"domain": "cluster",
"interfaces": [
{
"interface": "BOOTIF",
"network": "clusternet"
},
{
"interface": "BMC",
"network": "ipmi"
},
{
"interface": "ib0",
"network": "ib"
}
],
"osimage": "compute",
"partscript": "#!/bin/bash \n exit 0",
"postscript": "#!/bin/bash \n exit 0",
"prescript": "#!/bin/bash \n exit 0",
"provision_interface": null,
"netboot": true,
"bootmenu": false,
"comment": "Default group",
"provision_method": "torrent",
"provision_fallback": "http",
"members": [
"node001",
"node002",
"node003",
"node004"
]
}
},
"cluster": {
"controller1": {
"status": "primary",
"ipaddr": "10.141.255.254",
"serverport": 7050,
"luna_config": "/trinity/local/luna/config/luna-daemon.ini"
},
"controller2": {
"status": "standby",
"ipaddr": "10.141.255.253",
"serverport": 7050,
"luna_config": "/trinity/local/luna/config/luna-daemon.ini"
},
"ntp_server": "10.141.255.252",
"debug": false,
"technical_contacts": "root@localhost",
"provision_method": "torrent",
"provision_fallback": "http"
},
"network": {
"cluster": {
"newnetname": "cluster2",
"network": "10.141.0.0/16",
"nameserver_ip": "10.141.255.254",
"ntp_server": "10.141.255.254",
"gateway": "10.141.255.254",
"comment": "Default cluster network",
"dhcp": true,
"dhcp_range_begin": "10.141.0.200",
"dhcp_range_end": "10.141.0.253"
},
"ipmi": {
"newnetname": "ipmi2",
"network": "10.148.0.0/16",
"nameserver_ip": "10.148.255.254",
"ntp_server": "10.148.255.254",
"gateway": "10.148.255.254",
"comment": "Default OOB network",
"dhcp": false
},
"ib": {
"newnetname": "ib2",
"network": "10.149.0.0/16",
"nameserver_ip": "10.149.255.254",
"ntp_server": "10.149.255.254",
"gateway": "10.149.255.254",
"comment": "Default highspeed interconnect network",
"dhcp": false
}
},
"bmcsetup": {
"dell": {
"newbmcname": "newname",
"mgmtchannel": 1,
"netchannel": 1,
"password": "calvin",
"username": "root",
"userid": 2,
"comment": "Default DELL",
"unmanaged_bmc_users": "skip",
"members": [
"node003",
"node004"
]
},
"gigabyte": {
"newbmcname": "newname2",
"mgmtchannel": 1,
"netchannel": 1,
"password": "password",
"username": "admin",
"userid": 2,
"comment": "Default Gigabyte",
"unmanaged_bmc_users": "disable",
"members": [
"node001",
"node002"
]
}
},
"switch": {
"switch01": {
"network": "cluster",
"newswitchname": "mgmsw01",
"ipaddress": "10.141.253.1",
"oid": ".1.3.6.1.2.1.17.7.1.2.2.1.2",
"readcommunity": "public",
"rwcommunity": "private",
"comment": "Bootswitch"
},
"switch02": {
"network": "ipmi",
"newswitchname": "mgmsw02",
"ipaddress": "10.148.253.1",
"oid": ".1.3.6.1.2.1.17.7.1.2.2.1.2",
"readcommunity": "public",
"rwcommunity": "private",
"comment": "Bootswitch"
}
},
"otherdev": {
"apc01": {
"network": "cluster",
"newotherdevname": "apc01a",
"ipaddress": "10.141.250.1",
"comment": "APC for rack01a"
},
"ups01": {
"network": "ipmi",
"newotherdevname": "ups-01",
"ipaddress": "10.148.250.1",
"comment": "UPS for the head node"
}
},
"osimage": {
"compute": {
"grab_exclude": [
"/dev",
"/proc",
"/sys"
],
"grab_filesystems": [
"/",
"/boot"
],
"initrdfile": "compute-initramfs-`uname -r`",
"kernelfile": "compute-kernel-`uname -r`",
"kernelmodules": "ipmi_devinft, ipmi_si, ipmi_msghandler",
"kerneloptions": "mitigations=off nosmt noht",
"kernelversion": "`uname -r`",
"path": "/trinity/images/compute",
"imagefile": "compute.tar.bz2",
"comment": "Default image",
"members": [
"node003",
"node004"
]
},
"compute-ib": {
"grab_exclude": [
"/dev",
"/proc",
"/sys"
],
"grab_filesystems": [
"/",
"/boot"
],
"initrdfile": "compute-initramfs-`uname -r`",
"kernelfile": "compute-kernel-`uname -r`",
"kernelmodules": "ipmi_devinft, ipmi_si, ipmi_msghandler",
"kerneloptions": "mitigations=off nosmt noht",
"kernelversion": "`uname -r`",
"path": "/trinity/images/compute-ib",
"imagefile": "compute.tar.bz2",
"comment": "Default image with updated drivers",
"members": [
"node001",
"node002"
]
}
},
"secrets": {
"node": {
"node001": [
{
"secretname": "shared secret",
"content": "<ENC>",
"path": "/etc/keys.crt"
},
{
"secretname": "software license",
"content": "<ENC>",
"path": "/etc/app/license.lic"
},
{
"secretname": "shared secret",
"content": "<ENC>",
"path": "/etc/keys.crt"
}
],
"node002": [
{
"name": "software license",
"content": "<ENC>",
"path": "/etc/app/license.lic"
}
]
},
"group": {
"compute": [
{
"secretname": "Proprietary key",
"content": "<ENC>",
"path": "/var/lib/key.pem"
}
],
"compute-ib": [
{
"secretname": "Infiniband",
"content": "<ENC>",
"path": "/etc/rdma/license.lic"
}
]
}
}
},
"version": {
"luna": "2.0-001",
"api": 1,
"commit": "hex(commit)"
},
"monitor": {
"service": {
"dns": "OK, running",
"dhcp": "OK, reloaded",
"luna2": "OK"
},
"status": {
"node001": {
"status": "Luna installer: No errors",
"state": "installer.ok"
},
"node002": {
"status": "Luna installer: No errors",
"state": "installer.ok"
},
"beegfs01": {
"status": "Luna installer: No errors",
"state": "installer.ok"
},
"login01": {
"status": "Luna installer: Error in partscript",
"state": "installer.error"
}
}
},
"control": {
"power": {
"on": {
"hostlist": "node[001,node003-004]"
},
"fail": {
"hostlist": "node[002]"
}
}
}
}
YAML
---
config:
node:
node001:
newhostname: gpu001
group: compute
interfaces:
- interface: BOOTIF
network: clusternet
ipaddress: 10.141.0.1
- interface: BMC
network: ipmi
ipaddress: 10.148.0.1
- interface: ib0
network: ib
ipaddress: 10.149.0.1
macaddr: aa:bb:cc:dd:ee:ff
switch: switch01
switchport: 1
service: False
setupbmc: True
status: installer.completed
comment:
osimage: compute
prescript: "#!/bin/bash \n exit 0;"
partscript: "#!/bin/bash \n exit 0;"
postscript: "#!/bin/bash \n exit 0;"
netboot: True
bootmenu: False
provision_interface:
provision_method:
provision_fallback:
tpm_uuid:
tpm_pubkey:
tpm_sha256:
group:
compute:
newgroupname: compute-gpu
bmcsetup: True
domain: cluster
interfaces:
- interface: BOOTIF
network: clusternet
- interface: BMC
network: ipmi
- interface: ib0
network: ib
osimage: compute
partscript: "#!/bin/bash \n exit 0"
postscript: "#!/bin/bash \n exit 0"
prescript: "#!/bin/bash \n exit 0"
provision_interface:
netboot: True
bootmenu: False
comment: "Default group"
provision_method: torrent
provision_fallback: http
members:
- node001
- node002
- node003
- node004
cluster:
controller1:
status: primary
ipaddr: 10.141.255.254
serverport: 7050
luna_config: /trinity/local/luna/config/luna-daemon.ini
controller2:
status: standby
ipaddr: 10.141.255.253
serverport: 7050
luna_config: /trinity/local/luna/config/luna-daemon.ini
ntp_server: 10.141.255.252
debug: False
technical_contacts: root@localhost
provision_method: torrent
provision_fallback: http
network:
cluster:
newnetname: cluster2
network: 10.141.0.0/16
nameserver_ip: 10.141.255.254
ntp_server: 10.141.255.254
gateway: 10.141.255.254
comment: "Default cluster network"
dhcp: True
dhcp_range_begin: 10.141.0.200
dhcp_range_end: 10.141.0.253
ipmi:
newnetname: ipmi2
network: 10.148.0.0/16
nameserver_ip: 10.148.255.254
ntp_server: 10.148.255.254
gateway: 10.148.255.254
comment: "Default OOB network"
dhcp: False
ib:
newnetname: ib2
network: 10.149.0.0/16
nameserver_ip: 10.149.255.254
ntp_server: 10.149.255.254
gateway: 10.149.255.254
comment: "Default highspeed interconnect network"
dhcp: False
bmcsetup:
dell:
newbmcname: newname
mgmtchannel: 1
netchannel: 1
password: calvin
username: root
userid: 2
comment: "Default DELL"
unmanaged_bmc_users: "skip"
members:
- node003
- node004
gigabyte:
newbmcname: newname2
mgmtchannel: 1
netchannel: 1
password: password
username: admin
userid: 2
comment: "Default Gigabyte"
unmanaged_bmc_users: "disable"
members:
- node001
- node002
switch:
switch01:
network: cluster
newswitchname: mgmsw01
ipaddress: 10.141.253.1
oid: ".1.3.6.1.2.1.17.7.1.2.2.1.2"
readcommunity: public
rwcommunity: private
comment: Bootswitch
switch02:
network: ipmi
newswitchname: mgmsw02
ipaddress: 10.148.253.1
oid: ".1.3.6.1.2.1.17.7.1.2.2.1.2"
readcommunity: public
rwcommunity: private
comment: Bootswitch
otherdev:
apc01:
network: cluster
newotherdevname: apc01a
ipaddress: 10.141.250.1
comment: APC for rack01a
ups01:
network: ipmi
newotherdevname: ups-01
ipaddress: 10.148.250.1
comment: UPS for the head node
osimage:
compute:
grab_exclude:
- /dev
- /proc
- /sys
grab_filesystems:
- /
- /boot
initrdfile: "compute-initramfs-`uname -r`"
kernelfile: "compute-kernel-`uname -r`"
kernelmodules: "ipmi_devinft, ipmi_si, ipmi_msghandler"
kerneloptions: "mitigations=off nosmt noht"
kernelversion: "`uname -r`"
path: /trinity/images/compute
imagefile: compute.tar.bz2
comment: "Default image"
members:
- node003
- node004
compute-ib:
grab_exclude:
- /dev
- /proc
- /sys
grab_filesystems:
- /
- /boot
initrdfile: "compute-initramfs-`uname -r`"
kernelfile: "compute-kernel-`uname -r`"
kernelmodules: "ipmi_devinft, ipmi_si, ipmi_msghandler"
kerneloptions: "mitigations=off nosmt noht"
kernelversion: "`uname -r`"
path: /trinity/images/compute-ib
imagefile: compute.tar.bz2
comment: "Default image with updated drivers"
members:
- node001
- node002
secrets:
node:
node001:
- secretname: shared secret
content: <ENC>
path: /etc/keys.crt
- secretname: software license
content: <ENC>
path: /etc/app/license.lic
- secretname: shared secret
content: <ENC>
path: /etc/keys.crt
node002:
- name: software license
content: <ENC>
path: /etc/app/license.lic
group:
compute:
- secretname: Proprietary key
content: <ENC>
path: /var/lib/key.pem
compute-ib:
- secretname: Infiniband
content: <ENC>
path: /etc/rdma/license.lic
version:
luna: 2.0-001
api: 1.0
commit: hex(commit)
monitor:
service:
dns: "OK, running"
dhcp: "OK, reloaded"
luna2: "OK"
status:
node001:
status: "Luna installer: No errors"
state: "installer.ok"
node002:
status: "Luna installer: No errors"
state: "installer.ok"
beegfs01:
status: "Luna installer: No errors"
state: "installer.ok"
login01:
status: "Luna installer: Error in partscript"
state: "installer.error"
control:
power:
on:
hostlist: node[001,node003-004]
fail:
hostlist: node[002]