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