OpenStack vendordata API - The API you never knew you needed.
OpenStack Nova Metadata Vendor API
Over the last month or so I have been looking for a solution on how to expose the rack location of bare metal machines to the running OS, this is to enable us to make more sensible scheduling decisions on our HPC clusters. If your OpenStack host aggregates and corresponding availability zones provide enough information on location you might be able to just make use of the standard metadata endpoint.
Most people who have worked with OpenStack are probably familiar with the metadata service that runs inside most OpenStack clouds. This is a API endpoint that can be called from inside the guest OS and returns some useful information, like the machine name, availability zone, SSH authorised keys and other user supplied user data. This API is normally consumed by cloud-init at startup.
If on the other hand you need more detail, or if your AZ’s and host aggs don’t provide enough clarity you might want to look at making use of the vendor data API endpoint.
Vendor data API
The metadata vendor data API, can be used to provide data into the metadata API which may not be known at run time. The API can operate in two ways, the first way, is that you can configure a static JSON file, which will then be exposed at the endpoint URL for all machines. The second, and personally more interesting way to make use of the API is to configure it to return dynamic data to the endpoint.
How does it work?
Firstly you need an endpoint that the metadata API will call when itself is called, this is what provides the dynamic data. Internally we have a tool called Central-API which acts as a go-between between our different services. As such we have configured the Vendor data API to speak to Central-API, Central-API in turn then talks to our CMDB to return Rack location information.
The flow
- A call is made to http://169.254.169.254/openstack/latest/vendor_data2.json
- The metadata service makes a call to Central-API sending the instancedata in JSON format
- Central-API receives the GET request
- Central-API makes a call to our CMDB API having munged the data into a format that works for the CMDB
- CMDB returns the info we are interested in to Central-API
- Central-API then munges the data into a format the metadata api is able to handle
In the end you get a response provided to the calling service in a simple JSON format.
Configuring the Vendor API
Its fairly easy to configure the vendor data service. Simply add the following to your nova.conf
[api]
vendordata_providers = DynamicJSON
vendordata_dynamic_targets = identifier@http://URL
In the vendordata_dynamic_targets
section, the identifier before the @
symbol is required, as this is what the top level JSON entry will be called in the JSON return.
For example vendordata_dynamic_targets = bob@http://URL
would return as
{
"bob": {}
}
You can configure as many dynamic targets that you want, they will all be returned anytime http://169.254.169.254/openstack/latest/vendor_data2.json` is called.
Authentication
One item of note, is that by default and in the current implementation the API endpoint that you are calling out too can only be protected by a Keystone integrated service, as there is currently no way of passing standard basic auth to the dynamic backends. If you don’t configure any of the items in auth section then no authorisation will be attempted on the remote endpoint. Having to intergrate the Kesytone Auth middleware increase the complexity of the design of the API endpoint you are calling, as it will need to know how to auth against OpenStack Keystone.
I am in the process of attempting to create a patch to allow basic auth, to make the integration of more simple API endpoints easier. I will update this article with the RFE/Bug once I get the patch in a state that its ready for review.
What can this be used for?
The ability to inject arbitrary data into instance is immensely powerful, especially as you can get this information from multiple internal system sources. Imagination and ingenuity really are the only limit.
Until next time, Steve.