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