Designate/Blueprints/Search API

Overview
Right now, this spec is a VERY rough draft. It is mainly content from the Filtering API that has been moved into here because it didn't belong in the Filtering API.

Summary
Quick overview of the change

API Changes
Search, like filtering, will be implemented as a URL option. For

Additionally, where applicable, privileged users (support and admin) will be able to perform searching across all tenants by specifying an additional parameter, all_tenants=true, in their GET requests.

Searching by address is a special case and has undergone much discussion. This is primarily because a tenant may want to search for an address over all of their records (which could be distributed among several recordsets, in several zones), or over an individual recordset. In addition, admins need to be able to search for an address over all tenants' records. Several solutions have been proposed, and a tentative approach is discussed below:


 * Create a /records endpoint for admin use only, to search for addresses across all tenants. Use the original /zones/{id}/recordsets endpoint for individual tenants to search for an address within a single zone.  Having tenants search for an address across all of their zones, however, is not clear.  Perhaps the /records endpoint could be used for this, with an all_tenants option to differentiate between searching across one tenant and all tenants?

For illustration, below is a table showing a search for the IP address ADDR, constructed in the different ways posed above. All of these requests are GET requests.

List of changes to the HTTP API

Example of Call (HTTP Verb)
Request:

GET /v2/zones?name=example.com&match-type=exact&all_tenants=true HTTP/1.1 Host: dns.provider.com Accept: application/json X-Auth-Token: KeyStoneAuth_***** X-Tenant-ID:

Response: {  "zone": { "id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", "pool_id": "7d62d10d-3a16-4828-85dd-7b3fdc0ba989", "project_id": "4335d1f0-f793-11e2-b778-0800200c9a66", "name": "example.com.", "email": "joe@example.com.", "ttl": 7200, "serial": 1351800588, "status": "ACTIVE", "version": 1, "created_at": "...", "updated_at": null, "links": { "self": "https://dns.provider.com/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3" }  }  }

Privileged user searching in one tenant
Request:

GET /v2/zones?name=example.com&match-type=exact HTTP/1.1 Host: dns.provider.com Accept: application/json X-Auth-Token: KeyStoneAuth_***** X-Tenant-ID: 12345

Response:

(Empty - this particular tenant does not have domain example.com): {  "zone": { } }

A Customer searching across all tenants
Throw exception when policy check in API shows that tenant 1234 is not privileged to search across all tenants

A Customer searching in one tenant
Request:

GET /v2/zones?name=exp.com&match-type=exact HTTP/1.1 Host: dns.provider.com Accept: application/json X-Auth-Token: KeyStoneAuth_***** X-Tenant-ID: 12345

Response: {  "zone": { "id": "a66dba58-0043-4cc6-a1bb-69d5e86f3ca3", "pool_id": "6d62d10d-3a16-4828-85dd-7b3fdc0ba989", "project_id": "5335d1f0-f793-11e2-b778-0800200c9a66", "name": "exp.com.", "email": "jane@exp.com.", "ttl": 7200, "serial": 1351800588, "status": "ACTIVE", "version": 1, "created_at": "...", "updated_at": null, "links": { "self": "https://dns.provider.com/v2/zones/c86dba58-0043-4cc6-a1bb-69d5e86f3cc1" }  }  }

A Privileged user searching for records pointing to a specific IP Address across all tenants
Request:

GET /v2/zones/ipaddresses?address=172.192.112.82&match-type=exact&all_tenants=true HTTP/1.1 Host: dns.provider.com Accept: application/json X-Auth-Token: KeyStoneAuth_***** X-Tenant-ID:

Response: {    "records": [ {         "type": "A", "address": "172.192.112.82", “id”: “9e27811d-0320-4179-abb7-0e00e371e25b”, "zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", “name”: "www.example.org.", "links": { "self": "https://dns.provider.com/v2/zones/986dba58-0043-4cc6-a1bb-69d5e86f3ca9/recordsets/dedf6879-fd9a-41d6-a7c2-eeac316fa7b3" }    },         {         "type": "A", "address": "172.192.112.82", “id”: “4e27811d-0320-4179-abb7-0e00e371e25c”, "zone_id": "b46dba58-0043-4cc6-a1bb-69d5e86f3cc1", “name”: "exp.com.", "links": { "self": "https://dns.provider.com/v2/zones/436dba58-0043-4cc6-a1bb-69d5e86f3ca9/recordsets/dedf6879-fd9a-41d6-a7c2-eeac316fa7d2" }    }  ] }

A Privileged user searching for records pointing to a specific IP Address in a given tenant
Request:

GET /v2/zones/ipaddresses?address=172.192.112.82&match-type=exact HTTP/1.1 Host: dns.provider.com Accept: application/json X-Auth-Token: KeyStoneAuth_***** X-Tenant-ID: 31476

Response:

{    "records": [ {            "type": "A", "address": "172.192.112.82", “id”: “4e27811d-0320-4179-abb7-0e00e371e25c”, "zone_id": "b46dba58-0043-4cc6-a1bb-69d5e86f3cc1", “name”: "exp.com.", "links": { "self": https://dns.provider.com/v2/zones/436dba58-0043-4cc6-a1bb-69d5e86f3ca9/recordsets/dedf6879-fd9a-41d6-a7c2-eeac316fa7d2 }    }  ] }

A Customer searching for records pointing to a specific IP Address across all tenants
Exception - no customer can search across all tenants

A Customer searching for records pointing to a specific IP in the customer's own space
Request:

GET /v2/zones/ipaddresses?address=172.192.112.82&match-type=exact HTTP/1.1 Host: dns.provider.com Accept: application/json X-Auth-Token: KeyStoneAuth_***** X-Tenant-ID: 44441

Response:

{    "records": [ {            "type": "A", "address": "172.192.112.82", “id”: “9e27811d-0320-4179-abb7-0e00e371e25b”, "zone_id": "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3", “name”: "www.example.org.", "links": { "self": "https://dns.provider.com/v2/zones/986dba58-0043-4cc6-a1bb-69d5e86f3ca9/recordsets/dedf6879-fd9a-41d6-a7c2-eeac316fa7b3" }     }  ] }

Other Stuff
Verification step of all_tenants: 2. In middleware.py:KeystoneMiddleware::process_request, during the construction of DesignateContext
 * determined that all_tenants is set to True signaling intent to perform this operation on all tenants
 * perform policy check (in the API before we pass on to Central)
 * if confirmed that the user has this right to perform the operation across all tenants,
 * set context.all_tenants=True
 * let the request proceed to Central
 * if user cannot be confirmed to have the right to perform the operation across all tenants, reject the request with appropriate message

Database Changes
Description of Changes to DB schemas

eg -