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 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 Generate a personal access token.
The token should be passed in the header as follow:
curl --header 'Authorization: Bearer <token>' https://csentry.esss.lu.se/api/v1/inventory/items
Status codes
The following status codes can be returned by the application:
Status code |
Description |
|---|---|
The GET or PATCH request was successfull. The resource is returned as JSON. |
|
The POST request was successful. The created resource is returned as JSON. |
|
The DELETE request was successful. No content is returned. |
|
Missing Authorization Header. |
|
The user doesn’t have the required permissions. |
|
A resource could not be accessed, e.g., the ID could not be found. |
|
The entity could not be processed. |
|
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 <token>' 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 <token>' https://csentry.esss.lu.se/api/v1/inventory/items?page=2
< HTTP/2 200
< content-type: application/json
< link: <https://csentry.esss.lu.se/api/v1/inventory/items?per_page=20&page=1>; rel="first", <https://csentry.esss.lu.se/api/v1/inventory/items?per_page=20&page=1>; rel="prev", <https://csentry.esss.lu.se/api/v1/inventory/items?per_page=20&page=3>; rel
="next", <https://csentry.esss.lu.se/api/v1/inventory/items?per_page=20&page=38>; 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”.
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==" } ]
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 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 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
Resource |
Operation |
Description |
|---|---|---|
Inventory |
Get actions |
|
Create new item |
||
Get items |
||
Get item by id or ICS id |
||
Update existing item |
||
Create comment on item |
||
Get item comments |
||
Delete an item |
||
Delete an item comment |
||
Create new location |
||
Get locations |
||
Delete a location |
||
Create new mac address |
||
Get mac addresses |
||
Create new manufacturer |
||
Get manufacturers |
||
DELETE /api/v1/inventory/manufacturers/(int:manufacturer_id) |
Delete a manufacturer |
|
Create new model |
||
Get models |
||
Delete a model |
||
Create new status |
||
Get statuses |
||
Delete a status |
||
Network |
Create new cname |
|
Get cnames |
||
Delete a cname |
||
Create new domain |
||
Get domains |
||
Delete a domain |
||
Create new Ansible group |
||
Get Ansible groups |
||
Delete an Ansible group |
||
Create new host |
||
Get hosts |
||
Delete a host |
||
Update an existing host |
||
Search hosts |
||
Create new interface |
||
Get interfaces |
||
Delete an interface |
||
Update an existing interface |
||
Create new network |
||
Get networks |
||
Delete a network |
||
Update an existing network |
||
Create new network scope |
||
Get network scopes |
||
Delete a network scope |
||
Update an existing network scope |
||
User |
Get a token |
|
Get current user profile |
||
Get users information |
User
- POST /api/v1/user/login
Return a JSON Web Token
- JSON Parameters
username – username to login
password – password
- GET /api/v1/user/profile
Return the current user profile
- GET /api/v1/user/users
Return users information
Inventory
- GET /api/v1/inventory/actions
Get actions
- POST /api/v1/inventory/items
Register a new item
- JSON Parameters
serial_number – serial number
ics_id – (optional) ICS id (temporary one generated if not present)
quantity – (optional) number of items [default: 1]
manufacturer – (optional) name of the manufacturer
model – (optional) name of the model
location – (optional) name of the location
status – (optional) name of the status
parent_id – (optional) parent id
host_id – (optional) host id
- GET /api/v1/inventory/items
Return items
- GET /api/v1/inventory/items/(id_)
Retrieve item by id or ICS id
- Parameters
id_ – ICS id or primary key of the item
- PATCH /api/v1/inventory/items/(id_)
Patch an existing item
- Parameters
id_ – ICS id or primary key of the item
- JSON Parameters
ics_id – ICS id - only allowed if the current one is temporary
manufacturer – Item’s manufacturer
model – Item’s model
location – Item’s location
status – Item’s status
parent – Item’s parent
- POST /api/v1/inventory/items/(id_)/comments
Create a comment on item
- Parameters
id_ – ICS id or primary key of the item
- JSON Parameters
body – comment body
- GET /api/v1/inventory/items/(id_)/comments
Get item comments
- Parameters
id_ – ICS id or primary key of the item
- DELETE /api/v1/inventory/items/(int: item_id)
Delete an item
- Parameters
item_id – item primary key
- DELETE /api/v1/inventory/items/comments/(int: comment_id)
Delete an item comment
- Parameters
comment_id – comment primary key
- POST /api/v1/inventory/locations
Create a new location
- JSON Parameters
name – location name
description – (optional) description
- GET /api/v1/inventory/locations
Get locations
- DELETE /api/v1/inventory/locations/(int: location_id)
Delete a location
- Parameters
location_id – location primary key
- POST /api/v1/inventory/macs
Create a new mac address
- JSON Parameters
address – MAC address
item_id – (optional) linked item primary key
- GET /api/v1/inventory/macs
Return mac addresses
- POST /api/v1/inventory/manufacturers
Create a new manufacturer
- JSON Parameters
name – manufacturer name
description – (optional) description
- GET /api/v1/inventory/manufacturers
Get manufacturers
- DELETE /api/v1/inventory/manufacturers/(int: manufacturer_id)
Delete a manufacturer
- Parameters
manufacturer_id – manufacturer primary key
- POST /api/v1/inventory/models
Create a new model
- JSON Parameters
name – model name
description – (optional) description
- GET /api/v1/inventory/models
Get models
- DELETE /api/v1/inventory/models/(int: model_id)
Delete a model
- Parameters
model_id – model primary key
- POST /api/v1/inventory/statuses
Create a new status
- JSON Parameters
name – status name
description – (optional) description
- GET /api/v1/inventory/statuses
Get statuses
- DELETE /api/v1/inventory/statuses/(int: status_id)
Delete a status
- Parameters
status_id – status primary key
Network
- POST /api/v1/network/cnames
Create a new cname
- JSON Parameters
name – full cname
interface_id – primary key of the associated interface
- GET /api/v1/network/cnames
Return cnames
- DELETE /api/v1/network/cnames/(int: cname_id)
Delete a cname
- Parameters
cname_id – cname primary key
- POST /api/v1/network/domains
Create a new domain
- JSON Parameters
name – domain name
- GET /api/v1/network/domains
Return domains
- DELETE /api/v1/network/domains/(int: domain_id)
Delete a domain
- Parameters
domain_id – domain primary key
- POST /api/v1/network/groups
Create a new Ansible group
- JSON Parameters
name – group name
vars – (optional) Ansible variables
- GET /api/v1/network/groups
Return ansible groups
- DELETE /api/v1/network/groups/(int: group_id)
Delete an Ansible group
- Parameters
group_id – Ansible group primary key
- POST /api/v1/network/hosts
Create a new host
- JSON Parameters
name – hostname
device_type – Physical|Virtual|…
is_ioc – True|False (optional)
description – (optional) description
items – (optional) list of items ICS id linked to the host
ansible_vars – (optional) Ansible variables
ansible_groups – (optional) list of Ansible groups names
- GET /api/v1/network/hosts
Return hosts
- DELETE /api/v1/network/hosts/(int: host_id)
Delete a host
- Parameters
host_id – host primary key
- PATCH /api/v1/network/hosts/(int: host_id)
Patch an existing host
- Parameters
host_id – host primary key
- JSON Parameters
device_type – Physical|Virtual|…
is_ioc – True|False
description – description
items – list of items ICS id linked to the host
ansible_vars – Ansible variables
ansible_groups – list of Ansible groups names
- GET /api/v1/network/hosts/search
Search hosts
- Query Parameters
q – the search query
- POST /api/v1/network/interfaces
Create a new interface
- JSON Parameters
network – network name
ip – (optional) interface IP - IP will be assigned automatically if not given
name – interface name
host – host name
mac – (optional) MAC address
- GET /api/v1/network/interfaces
Return interfaces
- DELETE /api/v1/network/interfaces/(int: interface_id)
Delete an interface
- Parameters
interface_id – interface primary key
- PATCH /api/v1/network/interfaces/(int: interface_id)
Patch an existing interface
- Parameters
interface_id – interface primary key
- JSON Parameters
ip – interface IP
name – interface name
network – network name
mac – MAC address
- POST /api/v1/network/networks
Create a new network
- JSON Parameters
vlan_name – vlan name
vlan_id – vlan id
address – vlan address
first_ip – first IP of the allowed range
last_ip – last IP of the allowed range
gateway – gateway IP
scope – network scope name
domain_id – (optional) primary key of the domain [default: scope domain]
admin_only – (optional) boolean to restrict the network to admin users [default: False]
sensitive – hide the network and all hosts if True (for non admin) [default: False]
description – (optional) description
- GET /api/v1/network/networks
Return networks
- DELETE /api/v1/network/networks/(int: network_id)
Delete a network
- Parameters
network_id – network primary key
- PATCH /api/v1/network/networks/(int: network_id)
Patch an existing network
- Parameters
network_id – network primary key
- JSON Parameters
vlan_name – vlan name
address – vlan address
first_ip – first IP of the allowed range
last_ip – last IP of the allowed range
gateway – gateway IP
domain – domain name
admin_only – boolean to restrict the network to admin users
sensitive – hide the network and all hosts if True (for non admin)
description – description
- POST /api/v1/network/scopes
Create a new network scope
- JSON Parameters
name – network scope name
first_vlan – network scope first vlan
last_vlan – network scope last vlan
supernet – network scope supernet
domain_id – primary key of the default domain
description – (optional) description
- GET /api/v1/network/scopes
Return network scopes
- DELETE /api/v1/network/scopes/(int: scope_id)
Delete a network scope
- Parameters
scope_id – network scope primary key
- PATCH /api/v1/network/scopes/(int: scope_id)
Patch an existing network scope
- Parameters
scope_id – network scope primary key
- JSON Parameters
name – network scope name
description – description
first_vlan – network scope first vlan
last_vlan – network scope last vlan
supernet – network scope supernet
domain – name of the default domain
Client
A Python client library is available to access CSEntry API: csentry-api