Trove, OpenStack’s database-as-a-service, provides database provisioning and life cycle management capabilities. In part two of this three-part series, Tesora’s Amrith Kumar walks you through authentication.

Trove, the OpenStack database-as-a-service provides database provisioning and life cycle management capabilities for a number of databases. It exposes a single REST’ful API that can be used to access all the capabilities provided by the service. A command line interface and the Horizon web interface interact with Trove via this REST API.Trove allows interactions on this REST API to be secured using secured sockets layer (SSL.) This three-part article series describes how to configure and operate Trove using SSL on the REST API.

The previous tutorial describes SSL, what it is, and how it works. The second part describes interaction with the Trove REST API, how the OpenStack Keystone service catalog is used in discovering service end-points. The final (third) part will build on the first two and describes how to enable SSL in Trove and some useful troubleshooting tips.

Interacting with Trove API

We now describe briefly how one can interact with the Trove API. For the purposes of this illustration, we use the following configuration. Two machines, trove-controller (192.168.115.20) and trove-client (192.168.115.21) are used for this. On the trove-controller machine, we have a complete OpenStack controller setup including Keystone, Cinder, Swift, Nova, Glance, and Trove. Networking on this machine uses Nova Networking. For simplicity, only one hypervisor is setup and that hypervisor will launch VM’s on the machine trove-controller.

[email protected]:~$ openstack hypervisor list
+----+---------------------+
| ID | Hypervisor Hostname |
+----+---------------------+
|  1 | trove-controller    |
+----+---------------------+

The python-troveclient module is installed on the machine trove-client.
The trove CLI is able to communicate with the OpenStack setup on the machine trove-controller as shown below.

[email protected]:~$ trove --os-auth-url http://192.168.115.20:5000/v2.0 
> --os-tenant-name admin 
> --os-username admin 
> --os-password 3de4922d8b6ac5a1aad9 list
+----+------+-----------+-------------------+--------+-----------+------+
| ID | Name | Datastore | Datastore Version | Status | Flavor ID | Size |
+----+------+-----------+-------------------+--------+-----------+------+
+----+------+-----------+-------------------+--------+-----------+------+

How does the trove CLI know where Trove is running?

The Keystone project serves two vitally important functions in OpenStack. First, it is the Identity Management service in OpenStack. It can authenticate users against the list of users registered with an OpenStack installation, and when a user is authenticated, issue the user with a token that can be used with other OpenStack services. The second is that it is the OpenStack service catalog.
When the trove CLI shown above provided the Keystone end point (–os-auth-url http://192.168.115.20:5000/v2.0) with the user name, tenant name, and password, it was able to successfully authenticate with the system and obtain a token. It was then able to look up the ‘database’ service in the service catalog that it received and determine that Trove was running at http://192.168.115.20:8779/v1.0. It was therefore able to provide the Trove endpoint with the Keystone provided token and make the ‘list’ request.
You can enable –-debug on the trove CLI and see more of these interactions.

[email protected]:~$ trove --debug 
> --os-auth-url http://192.168.115.20:5000/v2.0 
> --os-tenant-name admin 
> --os-username admin 
> --os-password 3de4922d8b6ac5a1aad9 list
DEBUG (session:198) REQ: curl -g -i -X GET http://192.168.115.20:5000/v2.0 -H "Accept: application/json" -H "User-Agent: python-keystoneclient"
INFO (connectionpool:207) Starting new HTTP connection (1): 192.168.115.20
DEBUG (connectionpool:387) "GET /v2.0 HTTP/1.1" 200 340
DEBUG (session:216) RESP: [200] Content-Length: 340 Vary: X-Auth-Token Keep-Alive: timeout=5, max=100 Server: Apache/2.4.7 (Ubuntu) Connection: Keep-Alive Date: Mon, 07 Dec 2015 18:32:27 GMT Content-Type: application/json x-openstack-request-id: req-85d4509f-a49c-4bc6-a945-49207dcf6f0a
RESP BODY: {"version": {"status": "stable", "updated": "2014-04-17T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json"}], "id": "v2.0", "links": [{"href": "http://192.168.115.20:5000/v2.0/", "rel": "self"}, {"href": "http://docs.openstack.org/", "type": "text/html", "rel": "describedby"}]}}

DEBUG (v2:86) Making authentication request to http://192.168.115.20:5000/v2.0/tokens
DEBUG (connectionpool:387) "POST /v2.0/tokens HTTP/1.1" 200 4333
DEBUG (session:198) REQ: curl -g -i -X GET http://192.168.115.20:8779/v1.0/b0aea5682aea4074b6f215931eaebf56/instances -H "User-Agent: python-keystoneclient" -H "Accept: application/json" -H "X-Auth-Token: {SHA1}34fd8727ce50f0d3ed5ea5d35790ed7d5bcb99e5"
INFO (connectionpool:207) Starting new HTTP connection (1): 192.168.115.20
DEBUG (connectionpool:387) "GET /v1.0/b0aea5682aea4074b6f215931eaebf56/instances HTTP/1.1" 200 17
DEBUG (session:216) RESP: [200] Date: Mon, 07 Dec 2015 18:32:27 GMT Content-Length: 17 Content-Type: application/json Connection: keep-alive
RESP BODY: {"instances": []}

+----+------+-----------+-------------------+--------+-----------+------+
| ID | Name | Datastore | Datastore Version | Status | Flavor ID | Size |
+----+------+-----------+-------------------+--------+-----------+------+
+----+------+-----------+-------------------+--------+-----------+------+

The first step of the process is to establish credentials and obtain a service token and a service catalog as shown below.

The client provides the Keystone server with user id and password.
The Keystone server validates the user name and password and responds with a service catalog and a token.
Now, the client is able to inspect the service catalog and determine the endpoint for the ‘database’ service (Trove). It is then able to request the instance list from Trove as shown below.

In step one, the client passes the token it received from Keystone to the Trove server at the location identified in the service catalog and requests an instance list. The Trove server receives this request (step two) and proceeds to forward the token to Keystone for validation (step three). The Keystone server receives and validates the token (step four) and informs Trove of the validity. Since the token is valid, Trove can now generate the instance list (step five) and once generated, return that list to the client (steps six and seven).
You can inspect the Keystone service catalog as shown below.

[email protected]:~$ openstack endpoint list
+----------------------------------+-----------+--------------+----------------+
| ID                               | Region    | Service Name | Service Type   |
+----------------------------------+-----------+--------------+----------------+
| d0ad740c897d4366bb2416fd65ec98a4 | RegionOne | ec2          | ec2            |
| b4e1bab9a3ef431e9e40d26f2b0764ce | RegionOne | cinderv2     | volumev2       |
| 9b9fe6f1dfb84631bec592f7b0499bf8 | RegionOne | keystone     | identity       |
| 4e2459e7c3a1483ab5b5d32b5f54e0f3 | RegionOne | heat-cfn     | cloudformation |
| a6e63b4ea6a74a5ea444f5ade13c20a2 | RegionOne | swift        | object-store   |
| f364bc640b56422b9f758cfbcbc31051 | RegionOne | nova         | compute        |
| 13df1292df22409abfe733e1a7de42c3 | RegionOne | nova_legacy  | compute_legacy |
| 3db7eb7473c04a20b58218d23fb69e8a | RegionOne | trove        | database       |
| 8587393b6166406c868b4578e9b6919f | RegionOne | cinder       | volume         |
| 279e638d3e0942d894222871e402f26e | RegionOne | glance       | image          |
| 7164654e59674222929c5168e0adf0c9 | RegionOne | heat         | orchestration  |
+----------------------------------+-----------+--------------+----------------+

[email protected]:~$ openstack endpoint show database
+--------------+-----------------------------------------------+
| Field        | Value                                         |
+--------------+-----------------------------------------------+
| adminurl     | http://192.168.115.20:8779/v1.0/$(tenant_id)s |
| enabled      | True                                          |
| id           | 3db7eb7473c04a20b58218d23fb69e8a              |
| internalurl  | http://192.168.115.20:8779/v1.0/$(tenant_id)s |
| publicurl    | http://192.168.115.20:8779/v1.0/$(tenant_id)s |
| region       | RegionOne                                     |
| service_id   | 6417b68b2dc64c179088a7ae806cef88              |
| service_name | trove                                         |
| service_type | database                                      |
+--------------+-----------------------------------------------+

As you can see, the URL for the ‘database’ service is registered with a http:// service prefix indicating that it is not an SSL-enabled service.

Stay tuned for part three of the tutorial on enabling and troubleshooting coming soon.

Amrith Kumar, an active technical contributor and core reviewer of the OpenStack Trove project, as well as founder and CTO of Tesora Inc. He’s also the co-author of the “OpenStack Trove” book, available online.

Superuser is always interested in how-tos and other contributions, get in touch at [email protected]

Cover Photo // CC BY NC