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