While Openstack provides a python client(s) for interactions….
[root@diamond ~]# source keystonerc_tuxninja [root@diamond ~(keystone_tuxninja)]# openstack server list +--------------------------------------+-------+--------+----------------------------------------+ | ID | Name | Status | Networks | +--------------------------------------+-------+--------+----------------------------------------+ | e5b35d6a-a9ba-4714-a9e1-6361706bd047 | spin1 | ACTIVE | private_tuxlabs=10.0.0.8, 192.168.1.52 | +--------------------------------------+-------+--------+----------------------------------------+ [root@diamond ~(keystone_tuxninja)]#
I frequently, finding myself needing to get data out of it without the pain of awk/sed’ing out the ASCII art.
Thus to quickly access the raw data, we can directly query the API’s using curl & parsing JSON instead, which is much better 🙂
Authentication
Before we can interact with the other Openstack API’s we need to authenticate to Keystone openstack’s identity service. After authenticating we receive a token to use with our subequent API requests. So step 1 we are going to create a JSON object with the required authentication details.
Create a file called ‘token-request.json’ with an object that looks like this.
{ "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "domain": { "id": "default" }, "name": "tuxninja", "password": "put_your_openstack_pass" } } } } }
Btw, if you followed my tutorial on how to install Openstack Kilo, your authentication details for ‘admin’ is in your keystonerc_admin file.
Now we can use this file to authenticate like so:
export TOKEN=`curl -si -d @token-request.json -H "Content-type: application/json" http://localhost:35357/v3/auth/tokens | awk '/X-Subject-Token/ {print $2}'`
The token is actually returned in the header of the HTTP response, so this is why we need ‘-i’ when curling. Notice we are parsing out the token and returning the value to an environment variable $TOKEN.
Now we can include this $TOKEN and run whatever API commands we want (assuming admin privileges for the tenant/project)
Curl Commands (Numerous Examples!)
# list domains curl -si -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:35357/v3/domains # create a domain curl -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" -d '{"domain": {"description": "--optional--", "enabled": true, "name": "dom1"}}' http://localhost:35357/v3/domains # list users curl -si -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:35357/v3/users # To create a users, create file named create_user.json file like this: { "user": { "default_project_id": "18ed894bb8b84a5b9144c129fc754722", "description": "Description", "domain_id": "default", "email": "tuxninja@tuxlabs.com", "enabled": true, "name": "tuxninja", "password": "changeme" } } # then run curl -si -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:35357/v3/users -d @create_user.json # list images in nova <tenant_id> curl -s -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:8774/v2/18ed894bb8b84a5b9144c129fc754722/images | python -m json.tool # list servers (vms) curl -s -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:8774/v2/18ed894bb8b84a5b9144c129fc754722/servers | python -m json.tool # neutron networks curl -s -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:9696/v2.0/networks | python -m json.tool # neutron subnets curl -s -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:9696/v2.0/networks | python -m json.tool
I sometimes pipe the output to python -m json.tool, which provides formatting for JSON. Lets take a closer look at an example.
Listing servers (vm’s)
[root@diamond ~(keystone_tuxninja)]# curl -s -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:8774/v2/18ed894bb8b84a5b9144c129fc754722/servers | python -m json.tool { "servers": [ { "id": "e5b35d6a-a9ba-4714-a9e1-6361706bd047", "links": [ { "href": "http://localhost:8774/v2/18ed894bb8b84a5b9144c129fc754722/servers/e5b35d6a-a9ba-4714-a9e1-6361706bd047", "rel": "self" }, { "href": "http://localhost:8774/18ed894bb8b84a5b9144c129fc754722/servers/e5b35d6a-a9ba-4714-a9e1-6361706bd047", "rel": "bookmark" } ], "name": "spin1" } ] } [root@diamond ~(keystone_tuxninja)]#
I only have 1 VM currently called spin1, but for the tutorials sake, if I had ten’s or hundred’s of VM’s and all I cared about was the VM name or ID, I would still need to parse this JSON object to avoid getting all this other meta-data.
My favorite command line way to do that without going full Python is using the handy JQ tool.
Here is how to use it !
[root@diamond ~(keystone_tuxninja)]# curl -s -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:8774/v2/18ed894bb8b84a5b9144c129fc754722/servers | jq . { "servers": [ { "name": "spin1", "links": [ { "rel": "self", "href": "http://localhost:8774/v2/18ed894bb8b84a5b9144c129fc754722/servers/e5b35d6a-a9ba-4714-a9e1-6361706bd047" }, { "rel": "bookmark", "href": "http://localhost:8774/18ed894bb8b84a5b9144c129fc754722/servers/e5b35d6a-a9ba-4714-a9e1-6361706bd047" } ], "id": "e5b35d6a-a9ba-4714-a9e1-6361706bd047" } ] } [root@diamond ~(keystone_tuxninja)]# [root@diamond ~(keystone_tuxninja)]# curl -s -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:8774/v2/18ed894bb8b84a5b9144c129fc754722/servers | jq .servers[0].name -r spin1 [root@diamond ~(keystone_tuxninja)]#
The first command just takes whatever the STDOUT from curl is and indent’s and color’s the JSON making it pretty (colors gives it +1 vs. python -m json.tool).
The second example we actually parse what were after. As you can see it is pretty simple, but jq’s query language may not be 100% intuitive at first, but I promise it is pretty easy to understand if you have ever parsed JSON before. Read up more on JQ @ https://stedolan.github.io/jq/ & check out the Openstack docs for more API commands http://developer.openstack.org/api-ref.html
Hope you enjoyed this post ! Until next time.