xref: /openbmc/docs/rest-api.md (revision 309abc9187735439077138246f0e657aad902789)
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