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

200 OK

The GET or PATCH request was successfull. The resource is returned as JSON.

201 Created

The POST request was successful. The created resource is returned as JSON.

204 No Content

The DELETE request was successful. No content is returned.

401 Unauthorized

Missing Authorization Header.

403 Forbidden

The user doesn’t have the required permissions.

404 Not Found

A resource could not be accessed, e.g., the ID could not be found.

422 Unprocessable Entity

The entity could not be processed.

500 Internal Server Error

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”.

  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=="
  }
]
  1. 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 /api/v1/inventory/actions

Get actions

POST /api/v1/inventory/items

Create new item

GET /api/v1/inventory/items

Get items

GET /api/v1/inventory/items/(id_)

Get item by id or ICS id

PATCH /api/v1/inventory/items/(id_)

Update existing item

POST /api/v1/inventory/items/(id_)/comments

Create comment on item

GET /api/v1/inventory/items/(id_)/comments

Get item comments

DELETE /api/v1/inventory/items/(int:item_id)

Delete an item

DELETE /api/v1/inventory/items/comments/(int:comment_id)

Delete an item comment

POST /api/v1/inventory/locations

Create new location

GET /api/v1/inventory/locations

Get locations

DELETE /api/v1/inventory/locations/(int:location_id)

Delete a location

POST /api/v1/inventory/macs

Create new mac address

GET /api/v1/inventory/macs

Get mac addresses

POST /api/v1/inventory/manufacturers

Create new manufacturer

GET /api/v1/inventory/manufacturers

Get manufacturers

DELETE /api/v1/inventory/manufacturers/(int:manufacturer_id)

Delete a manufacturer

POST /api/v1/inventory/models

Create new model

GET /api/v1/inventory/models

Get models

DELETE /api/v1/inventory/models/(int:model_id)

Delete a model

POST /api/v1/inventory/statuses

Create new status

GET /api/v1/inventory/statuses

Get statuses

DELETE /api/v1/inventory/statuses/(int:status_id)

Delete a status

Network

POST /api/v1/network/cnames

Create new cname

GET /api/v1/network/cnames

Get cnames

DELETE /api/v1/network/cnames/(int:cname_id)

Delete a cname

POST /api/v1/network/domains

Create new domain

GET /api/v1/network/domains

Get domains

DELETE /api/v1/network/domains/(int:domain_id)

Delete a domain

POST /api/v1/network/groups

Create new Ansible group

GET /api/v1/network/groups

Get Ansible groups

DELETE /api/v1/network/groups/(int:group_id)

Delete an Ansible group

POST /api/v1/network/hosts

Create new host

GET /api/v1/network/hosts

Get hosts

DELETE /api/v1/network/hosts/(int:host_id)

Delete a host

PATCH /api/v1/network/hosts/(int:host_id)

Update an existing host

GET /api/v1/network/hosts/search

Search hosts

POST /api/v1/network/interfaces

Create new interface

GET /api/v1/network/interfaces

Get interfaces

DELETE /api/v1/network/interfaces/(int:interface_id)

Delete an interface

PATCH /api/v1/network/interfaces/(int:interface_id)

Update an existing interface

POST /api/v1/network/networks

Create new network

GET /api/v1/network/networks

Get networks

DELETE /api/v1/network/networks/(int:network_id)

Delete a network

PATCH /api/v1/network/networks/(int:network_id)

Update an existing network

POST /api/v1/network/scopes

Create new network scope

GET /api/v1/network/scopes

Get network scopes

DELETE /api/v1/network/scopes/(int:scope_id)

Delete a network scope

PATCH /api/v1/network/scopes/(int:scope_id)

Update an existing network scope

User

POST /api/v1/user/login

Get a token

GET /api/v1/user/profile

Get current user profile

GET /api/v1/user/users

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

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