1# OpenBMC REST API 2 3The OpenBMC REST API is disabled by default in bmcweb. Most of the functionality 4is available on Redfish. This document provides some basic structure and usage 5examples for the OpenBMC REST interface. 6 7The schema for the rest interface is directly defined by the OpenBMC D-Bus 8structure. Therefore, the objects, attributes and methods closely map to those 9in the D-Bus schema. 10 11For a quick explanation of HTTP verbs and how they relate to a RESTful API, see 12<http://www.restapitutorial.com/lessons/httpmethods.html>. 13 14## Authentication 15 16See the details on authentication at 17[REST-cheatsheet](https://github.com/openbmc/docs/blob/master/REST-cheatsheet.md#establish-rest-connection-session). 18 19This tutorial uses token based authentication method: 20 21```bash 22export bmc=xx.xx.xx.xx 23export token=`curl -k -H "Content-Type: application/json" -X POST https://${bmc}/login -d '{"username" : "root", "password" : "0penBmc"}' | grep token | awk '{print $2;}' | tr -d '"'` 24curl -k -H "X-Auth-Token: $token" https://${bmc}/xyz/openbmc_project/... 25``` 26 27## HTTP GET operations & URL structure 28 29There are a few conventions on the URL structure of the OpenBMC rest interface. 30They are: 31 32- To query the attributes of an object, perform a GET request on the object 33 name, with no trailing slash. For example: 34 35```bash 36curl -k -H "X-Auth-Token: $token" https://${bmc}/xyz/openbmc_project/inventory/system 37``` 38 39```json 40{ 41 "data": { 42 "AssetTag": "", 43 "BuildDate": "", 44 "Cached": true, 45 "FieldReplaceable": true, 46 "Manufacturer": "", 47 "Model": "", 48 "PartNumber": "", 49 "Present": true, 50 "PrettyName": "", 51 "SerialNumber": "" 52 }, 53 "message": "200 OK", 54 "status": "ok" 55} 56``` 57 58- To query a single attribute, use the `attr/<name>` path. Using the `system` 59 object from above, we can query just the `Name` value: 60 61```bash 62curl -k -H "X-Auth-Token: $token" https://${bmc}/xyz/openbmc_project/inventory/system/attr/Cached 63``` 64 65```json 66{ 67 "data": true, 68 "message": "200 OK", 69 "status": "ok" 70} 71``` 72 73- When a path has a trailing-slash, the response will list the sub objects of 74 the URL. For example, using the same object path as above, but adding a slash: 75 76```bash 77curl -k -H "X-Auth-Token: $token" https://${bmc}/xyz/openbmc_project/ 78``` 79 80```json 81{ 82 "data": [ 83 "/xyz/openbmc_project/Chassis", 84 "/xyz/openbmc_project/Hiomapd", 85 "/xyz/openbmc_project/Ipmi", 86 "/xyz/openbmc_project/certs", 87 "/xyz/openbmc_project/console", 88 "/xyz/openbmc_project/control", 89 "/xyz/openbmc_project/dump", 90 "/xyz/openbmc_project/events", 91 "/xyz/openbmc_project/inventory", 92 "/xyz/openbmc_project/ipmi", 93 "/xyz/openbmc_project/led", 94 "/xyz/openbmc_project/logging", 95 "/xyz/openbmc_project/network", 96 "/xyz/openbmc_project/object_mapper", 97 "/xyz/openbmc_project/sensors", 98 "/xyz/openbmc_project/software", 99 "/xyz/openbmc_project/state", 100 "/xyz/openbmc_project/time", 101 "/xyz/openbmc_project/user" 102 ], 103 "message": "200 OK", 104 "status": "ok" 105} 106``` 107 108This shows that there are 19 children of the `openbmc_project/` object: `dump`, 109`software`, `control`, `network`, `logging`,etc. This can be used with the base 110REST URL (ie., `http://${bmc}/`), to discover all objects in the hierarchy. 111 112- Performing the same query with `/list` will list the child objects 113 _recursively_. 114 115```bash 116curl -k -H "X-Auth-Token: $token" https://${bmc}/xyz/openbmc_project/network/list 117``` 118 119```json 120{ 121 "data": [ 122 "/xyz/openbmc_project/network/config", 123 "/xyz/openbmc_project/network/config/dhcp", 124 "/xyz/openbmc_project/network/eth0", 125 "/xyz/openbmc_project/network/eth0/ipv4", 126 "/xyz/openbmc_project/network/eth0/ipv4/3b9faa36", 127 "/xyz/openbmc_project/network/eth0/ipv6", 128 "/xyz/openbmc_project/network/eth0/ipv6/ff81b6d6", 129 "/xyz/openbmc_project/network/eth1", 130 "/xyz/openbmc_project/network/eth1/ipv4", 131 "/xyz/openbmc_project/network/eth1/ipv4/3b9faa36", 132 "/xyz/openbmc_project/network/eth1/ipv4/66e63348", 133 "/xyz/openbmc_project/network/eth1/ipv6", 134 "/xyz/openbmc_project/network/eth1/ipv6/ff81b6d6", 135 "/xyz/openbmc_project/network/host0", 136 "/xyz/openbmc_project/network/host0/intf", 137 "/xyz/openbmc_project/network/host0/intf/addr", 138 "/xyz/openbmc_project/network/sit0", 139 "/xyz/openbmc_project/network/snmp", 140 "/xyz/openbmc_project/network/snmp/manager" 141 ], 142 "message": "200 OK", 143 "status": "ok" 144} 145``` 146 147- Adding `/enumerate` instead of `/list` will also include the attributes of the 148 listed objects. 149 150```bash 151curl -k -H "X-Auth-Token: $token" https://${bmc}/xyz/openbmc_project/time/enumerate 152``` 153 154```json 155{ 156 "data": { 157 "/xyz/openbmc_project/time/bmc": { 158 "Elapsed": 1563209492098739 159 }, 160 "/xyz/openbmc_project/time/host": { 161 "Elapsed": 1563209492101678 162 }, 163 "/xyz/openbmc_project/time/owner": { 164 "TimeOwner": "xyz.openbmc_project.Time.Owner.Owners.BMC" 165 }, 166 "/xyz/openbmc_project/time/sync_method": { 167 "TimeSyncMethod": "xyz.openbmc_project.Time.Synchronization.Method.NTP" 168 } 169 }, 170 "message": "200 OK", 171 "status": "ok" 172} 173``` 174 175## HTTP PUT operations 176 177PUT operations are for updating an existing resource (an object or property), or 178for creating a new resource when the client already knows where to put it. These 179require a json formatted payload. To get an example of what that looks like: 180 181```bash 182curl -k -H "X-Auth-Token: $token" https://${bmc}/xyz/openbmc_project/state/host0 > host.json 183cat host.json 184``` 185 186```json 187{ 188 "data": { 189 "AttemptsLeft": 3, 190 "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified", 191 "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Off", 192 "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive", 193 "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.Off" 194 }, 195 "message": "200 OK", 196 "status": "ok" 197} 198``` 199 200or 201 202```bash 203curl -k -H "X-Auth-Token: $token" https://${bmc}/xyz/openbmc_project/state/host0/attr/RequestedHostTransition > requested_host.json 204cat requested_host.json 205``` 206 207```json 208{ 209 "data": "xyz.openbmc_project.State.Host.Transition.Off", 210 "message": "200 OK", 211 "status": "ok" 212} 213``` 214 215When turning around and sending these as requests, delete the message and status 216properties. 217 218To make curl use the correct content type header use the -H option to specify 219that we're sending JSON data: 220 221```bash 222curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X PUT -d <json> <url> 223``` 224 225A PUT operation on an object requires a complete object. For partial updates 226there is PATCH but that is not implemented yet. As a workaround individual 227attributes are PUTable. 228 229For example, make changes to the requested_host.json file and do a PUT (upload): 230 231```bash 232$ cat requested_host.json 233{"data": "xyz.openbmc_project.State.Host.Transition.Off"} 234$ curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X PUT -T requested_host.json https://${bmc}/xyz/openbmc_project/state/host0/attr/RequestedHostTransition 235``` 236 237Alternatively specify the json inline with -d: 238 239```bash 240curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X PUT -d '{"data": "xyz.openbmc_project.State.Host.Transition.On"}' https://${bmc}/xyz/openbmc_project/state/host0/attr/RequestedHostTransition 241``` 242 243When using '-d' just remember that json requires quoting. 244 245## HTTP POST operations 246 247POST operations are for calling methods, but also for creating new resources 248when the client doesn't know where to put it. OpenBMC does not support creating 249new resources via REST so any attempt to create a new resource will result in a 250HTTP 403 (Forbidden). These also require a json formatted payload. To delete 251logging entries: 252 253```bash 254curl -k -H "X-Auth-Token: $token" -H 'Content-Type: application/json' -X POST -d '{"data":[]}' https://${bmc}/xyz/openbmc_project/logging/action/DeleteAll 255``` 256 257To invoke a method without parameters (Factory Reset of BMC and Host): 258 259```bash 260curl -k -H "X-Auth-Token: $token" -H 'Content-Type: application/json' -X POST -d '{"data":[]}' https://${bmc}/xyz/openbmc_project/software/action/Reset 261``` 262 263## HTTP DELETE operations 264 265DELETE operations are for removing instances. Only D-Bus objects (instances) can 266be removed. If the underlying D-Bus object implements the 267`xyz.openbmc_project.Object.Delete` interface the REST server will call it. If 268`xyz.openbmc_project.Object.Delete` is not implemented, the REST server will 269return a HTTP 403 (Forbidden) error. 270 271For example, to delete a event record: 272 273Display logging entries: 274 275```bash 276curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X GET https://${bmc}/xyz/openbmc_project/logging/entry/enumerate 277``` 278 279Then delete the event record with ID 1: 280 281```bash 282curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X DELETE https://${bmc}/xyz/openbmc_project/logging/entry/1 283``` 284 285## Uploading images 286 287It is possible to upload software upgrade images (for example to upgrade the BMC 288or host software) via REST. The content-type should be set to 289"application/octet-stream". 290 291For example, to upload an image:(the `<file_to_upload>` must be a tar ball) 292 293```bash 294curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/octet-stream" -X POST -T <file_to_upload> https://${bmc}/upload/image 295``` 296 297In above example, the filename on the BMC will be chosen by the REST server. 298 299It is possible for the user to choose the uploaded file's remote name: 300 301```bash 302curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/octet-stream" -X PUT -T foo https://${bmc}/upload/image/bar 303``` 304 305In above example, the file foo will be saved with the name bar on the BMC. 306 307The operation will either return the version id (hash) of the uploaded file on 308success: 309 310```json 311{ 312 "data": "afb92384", 313 "message": "200 OK", 314 "status": "ok" 315} 316``` 317 318or an error message 319 320```json 321{ 322 "data": { 323 "description": "Version already exists or failed to be extracted" 324 }, 325 "message": "400 Bad Request", 326 "status": "error" 327} 328``` 329 330For more details on uploading and updating software, see: 331<https://github.com/openbmc/docs/tree/master/architecture/code-update> 332 333## Event subscription protocol 334 335It is possible to subscribe to events, of interest, occurring on the BMC. The 336implementation on the BMC uses WebSockets for this purpose, so that clients 337don't have do employ polling. Instead, the rest server on the BMC can push data 338to clients over a websocket. The BMC can push out information pertaining to 339D-Bus InterfacesAdded and PropertiesChanged signals. 340 341Following is a description of the event subscription protocol, with example JS 342code snippets denoting client-side code. 343 344a. The client needs to have logged on to the BMC. 345 346b. The client needs to open a secure websocket with the URL 347`<BMC IP>/subscribe`. 348 349```javascript 350var ws = new WebSocket("wss://<BMC IP>/subscribe"); 351``` 352 353c. The client needs to send, over the websocket, a JSON dictionary, comprising 354of key-value pairs. This dictionary serves as the "events filter". All the keys 355are optional, so the dictionary can be empty if no filtering is desired. The 356filters represented by each of the key-value pairs are ORed. 357 358One of the supported keys is "paths". The corresponding value is an array of 359D-Bus paths. The InterfacesAdded and PropertiesChanged D-Bus signals emanating 360from any of these path(s) alone, and not from any other paths, will be included 361in the event message going out of the BMC. 362 363The other supported key is "interfaces". The corresponding value is an array of 364D-Bus interfaces. The InterfacesAdded and PropertiesChanged D-Bus signal 365messages comprising of any of these interfaces will be included in the event 366message going out of the BMC. 367 368All of the following are valid: 369 370```javascript 371var data = JSON.stringify({ 372 paths: ["/xyz/openbmc_project/logging", "/xyz/openbmc_project/sensors"], 373 interfaces: [ 374 "xyz.openbmc_project.Logging.Entry", 375 "xyz.openbmc_project.Sensor.Value", 376 ], 377}); 378ws.onopen = function () { 379 ws.send(data); 380}; 381``` 382 383```javascript 384var data = JSON.stringify({ 385 paths: ["/xyz/openbmc_project/logging", "/xyz/openbmc_project/sensors"], 386}); 387ws.onopen = function () { 388 ws.send(data); 389}; 390``` 391 392```javascript 393var data = JSON.stringify({ 394 interfaces: [ 395 "xyz.openbmc_project.Logging.Entry", 396 "xyz.openbmc_project.Sensor.Value", 397 ], 398}); 399ws.onopen = function () { 400 ws.send(data); 401}; 402``` 403 404```javascript 405var data = JSON.stringify({}); 406ws.onopen = function () { 407 ws.send(data); 408}; 409``` 410 411d. The rest server on the BMC will respond over the websocket when a D-Bus event 412occurs, considering the client supplied filters. The rest servers notifies about 413InterfacesAdded and PropertiesChanged events. The response is a JSON dictionary 414as follows : 415 416InterfacesAdded 417 418```text 419"event": InterfacesAdded 420"path": <string : new D-Bus path that was created> 421"interfaces": <dict : a dictionary of interfaces> (similar to org.freedesktop.DBus.ObjectManager.InterfacesAdded ) 422``` 423 424PropertiesChanged 425 426```text 427"event": PropertiesChanged 428"path": <string : D-Bus path whose property changed> 429"interface": <string : D-Bus interface to which the changed property belongs> 430"properties": <dict : a dictionary of properties> (similar to org.freedesktop.DBus.Properties.PropertiesChanged) 431``` 432