.. _api: API === Concept ------- The root of the API is at `/api/v1`. Example of a valid API request using curl:: curl https://csentry.esss.lu.se/api/v1/inventory/items For POST requests, the arguments shall be passed as json data in the body. Authentication -------------- To access CSEntry API, a personal access token is required. A temporary token can be retrieved by sending a :http:post:`/api/v1/user/login` including the username and password. It will return a token valid for 12 hours. A token that never expires can be generated from the user profile page. See :ref:`token-generation`. The token should be passed in the header as follow:: curl --header 'Authorization: Bearer ' https://csentry.esss.lu.se/api/v1/inventory/items Status codes ------------ The following status codes can be returned by the application: ====================== =============================================================================== Status code Description ====================== =============================================================================== :http:statuscode:`200` The `GET` or `PATCH` request was successfull. The resource is returned as JSON. :http:statuscode:`201` The `POST` request was successful. The created resource is returned as JSON. :http:statuscode:`204` The `DELETE` request was successful. No content is returned. :http:statuscode:`401` Missing Authorization Header. :http:statuscode:`403` The user doesn't have the required permissions. :http:statuscode:`404` A resource could not be accessed, e.g., the ID could not be found. :http:statuscode:`422` The entity could not be processed. :http:statuscode:`500` An error occured while processing the request on the server. ====================== =============================================================================== Pagination ---------- When returning an array, the result is limited to 20 elements per page by default. You can pass the `page` (default: 1) and `per_page` (default:20, max: 100) parameters to access other elements. Note that you can't request more than 100 elements per page. You should follow the link headers to get more results. To list the 30 elements of the second page:: curl --header 'Authorization: Bearer ' https://csentry.esss.lu.se/api/v1/inventory/items?page=2&per_page=30 `Link headers `_ provide links to the previous, next, first and last page when it makes sense (there is no previous page for the first one). Here is a header example for the following query:: curl --header 'Authorization: Bearer ' https://csentry.esss.lu.se/api/v1/inventory/items?page=2 < HTTP/2 200 < content-type: application/json < link: ; rel="first", ; rel="prev", ; rel ="next", ; rel="last" < set-cookie: session=b966757d-1ca2-486f-8bff-b04073c483a8; Expires=Sun, 11-Mar-2018 14:10:12 GMT; HttpOnly; Path=/ < x-total-count: 751 < content-length: 16899 < date: Thu, 08 Feb 2018 14:10:12 GMT The `x-total-count` header is also sent back and set to the total number of elements returned by the query. Filtering --------- When sending a `GET` request, you can pass parameters in the query string to filter the results. If you want to retrieve all items with the status "Loaned". 1. Get the id of the "Loaned" status:: curl -H "Authorization: Bearer $TOKEN" $URL/api/v1/inventory/statuses?name=Loaned Example response:: [ { "description": null, "id": 4, "name": "Loaned", "qrcode": "iVBORw0KGgoAAAANSUhEUgAAAKUAAAClAQAAAAAVUAB3AAABYElEQVR4nO2XTW7bMBBG30gFqB19A/oisZp7KZUKB+ixKtUXkW9A7ShA1teF226a7DJBC4Qr4lvMw/yTJv4+a/WCCB/qv6MiZcAyqUAH0Kt40nppkmbtcUtSdqRVwM0aFjuuFWDV29l9XY1bCruD3VfUbxOX6/AOtFqFZWBt04B2T9qfmuxSmPI71OTvU9rc/7o5RnJ5OjIdngG48mMZXCOpgbBTS8pdovX0DSnXsyad52LSXMyzu++zpJyopSl3hDH65i3asbloYP0MrI/XwTdvG2GHVIhbCq41ee83jdSzdjrkGkkkbamcolTaDGH07O4Klk80l6tZA7B+eTO7L6tRs3Z6hZFeXLIvbTGzimfWituRh4MvjV4a45OF74d6xrIz7WYN1Foe81dDB0caUu4Ik7ZUiGdhzjsAgOU8BeWb8WCDr2/3N5dKqy1p8p7KgOUOTnFLxXV328ev479UfwKVEPNjwev1VAAAAABJRU5ErkJggg==" } ] 2. Get the items with status_id 4:: curl -H "Authorization: Bearer $TOKEN" $URL/api/v1/inventory/items?status_id=4 Example response:: [ { "children": [], "comments": [ "Will be sent to Freia with fan-out.\n", "delivered to BI temporarily ", "Imported from JIRA TAG-15" ], "created_at": "2014-04-22 08:39", "history": [ { "location": "ESS", "parent": null, "quantity": 1, "status": "Loaned", "updated_at": "2018-02-05 14:28" } ], "ics_id": "ZZA014", "id": 15, "location": "ESS", "macs": [], "manufacturer": "Schroff", "model": "Compact PCI Crate 2U 4 slot", "parent": null, "quantity": 1, "serial_number": "BGRR 2HE 24579 081 1291200686 BB", "status": "Loaned", "updated_at": "2018-02-05 14:28", "user": "Inigo Alonso" }, ... ] Searching --------- To search hosts, you can use a :http:get:`/api/v1/network/hosts/search` with your query passed using the ``q`` query parameter. - To search all hosts where the string "archiver" appears in any field, use ``q=archiver``:: curl -v -H "Authorization: Bearer $TOKEN" $URL/api/v1/network/hosts/search?q=archiver Example response:: < HTTP/1.0 200 OK < Content-Type: application/json < Content-Length: 6336 < X-Total-Count: 5 < Set-Cookie: session=9afbc88a-5177-4ece-bc55-7840a47290a1; Expires=Mon, 29-Apr-2019 15:27:37 GMT; HttpOnly; Path=/ < Server: Werkzeug/0.14.1 Python/3.7.1 < Date: Fri, 29 Mar 2019 15:27:37 GMT < [ { "ansible_groups": [ "aa_cluster_test", "archiver_appliance" ], "created_at": "2018-11-19 10:08", "description": "test archiver", "device_type": "VirtualMachine", "fqdn": "archiver-04.tn.esss.lu.se", "id": 401, ... "name": "archiver-04", "updated_at": "2018-11-20 07:43", "user": "benjaminbertrand" }, { ... "name": "archiver-01", "updated_at": "2018-11-28 09:29", "user": "benjaminbertrand" ... }, ... ] - To restrict the search to only the *name* field, use ``q=name:archiver``:: curl -v -H "Authorization: Bearer $TOKEN" $URL/api/v1/network/hosts/search?q=name:archiver < HTTP/1.0 200 OK < Content-Type: application/json < Content-Length: 5374 < X-Total-Count: 4 < Set-Cookie: session=1a637fca-c94b-4ab9-b290-10d18f35453e; Expires=Mon, 29-Apr-2019 15:37:37 GMT; HttpOnly; Path=/ < Server: Werkzeug/0.14.1 Python/3.7.1 < Date: Fri, 29 Mar 2019 15:37:37 GMT < ... The query string is passed directly to Elasticsearch. You can use exactly the same "mini-language" as when searching from the web user interface. Check the elasticsearch `query string syntax`_ for more details as well as the network :ref:`network-search` for the list of fields you can use. Note that if you pass ``q=name:arch``, this will not match *archiver* as elasticsearch uses keywords for string matching. In this case you'd need to use a wildcard: ``q=name:arch*``. Be aware that wildcard queries can use an enormous amount of memory and perform very badly. Resources --------- Summary +++++++ .. qrefflask:: wsgi:app :modules: app.api.user, app.api.inventory, app.api.network :order: path User ++++ .. autoflask:: wsgi:app :modules: app.api.user :order: path Inventory +++++++++ .. autoflask:: wsgi:app :modules: app.api.inventory :order: path Network +++++++ .. autoflask:: wsgi:app :modules: app.api.network :order: path Client ------ A Python client library is available to access CSEntry API: `csentry-api `_ .. _query string syntax: https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-dsl-query-string-query.html#query-string-syntax