Designate/Blueprints/RecordSets

This proposal is for the updated recordsets for designate v2.

= Proposal 1 =

We will have only records and no recordsets either explicitly(as it is currently in designate v2) or implicitly (as it is currently in designate v1). The checks for TTL are done when creates/updates are done.

/zones//records
Example request: POST /zones/89acac79-38e7-497d-807c-a011e1310438/records

Host: example.com Accept: application/json Content-Type: application/json

{     "name": "www.example.com.", "type": "A", "data": "192.0.2.3" "TTL": 200 }

When a create record is done, it would get records based on the domain_id, name and type. If none exist, it is created. If one or more exist, then all the TTLs should be the same. If not return an error. The error details would include the current records or the TTL of the current records.

When no records already exist and if 2 users concurrently try to create records with the same type and name, then the first record in will be added as is. The 2nd record is checked for TTL, if it is different then an error is returned. The error details would include the current records or the TTL of the current records.

/zones//records/
Example request: PATCH /zones/89acac79-38e7-497d-807c-a011e1310438/records/2e32e609-3a4f-45ba-bdef-e50eacd345ad Host: example.com Accept: application/json Content-Type: application/json

{     "name": "www.example.com.", "type": "A", "data": "192.0.2.5" "TTL":500 }

When a record is modified - the TTL value is checked with existing records based on the domain_id, new name and type. If the TTL is not the same, return an error. The error details would include the current records or the TTL of the current records.

To modify TTLs for all the records with the same name and type, we can have a new field in the json body call "modify-rrset". If it is set to TRUE, then all the records matching the old-name and old-type are modified. Alternatively we could have a parameter called ?modify-rrset. If it is set to TRUE, then modify all the records matching the old-name and old-type.

If we have 2 A records 2e32e609-3a4f-45ba-bdef-e50eacd345ad   www.example.com   A  192.0.2.5   200seconds 3e32e609-3a4f-45ba-bdef-e50eacd345ae   www.example.com   A  192.0.2.6   200seconds

To modify the TTL of these records we would send the following request to either of the records

Example request: PATCH /zones/89acac79-38e7-497d-807c-a011e1310438/records/2e32e609-3a4f-45ba-bdef-e50eacd345ad?modify-rrset=true Host: example.com Accept: application/json Content-Type: application/json

{     "ttl": 500 }

or alternatively the request could be as follows

Example request: PATCH /zones/89acac79-38e7-497d-807c-a011e1310438/records/2e32e609-3a4f-45ba-bdef-e50eacd345ad Host: example.com Accept: application/json Content-Type: application/json

{     "ttl": 500, "modify-rrset": true }

After this request is processed, the 2 A records would be as follows 2e32e609-3a4f-45ba-bdef-e50eacd345ad   www.example.com   A  192.0.2.5 500seconds 3e32e609-3a4f-45ba-bdef-e50eacd345ae   www.example.com   A  192.0.2.6 500seconds

= Proposal 2 =

Proposal - Handle TTLs Implicitly
This proposal would be to hide the concept of record sets from users completely and to handle the different TTLs in a recordset implicitly. Rather than do anything special, handle records in a recordset with different TTLs the way BIND does. BIND will send the recordset with the TTL of the lowest record. So, the change that is needed is to have mini-DNS handle it this way.

For example, a primary master in BIND has the following entries for a zone:

ttltest1	600	A	192.168.0.250 ttltest1	1200	A	192.168.0.251

The secondary slave will show:

$TTL 600       ; 10 minutes ttltest1               A       192.168.0.250 A      192.168.0.251

We will need to document this behavior for the user, but no additional API changes are needed.

= Proposal 3 =

Records/RecordSets Redesign Option 2
This proposal is to change the way RecordSets and Records are created in Designate v2. It is not a complete spec. It is only meant to demonstrate the concept.

There will only be one resource name, either Records or RecordSets. We can decide which one to keep. So, anywhere you see "records", it could be changed to "recordsets", if that is less confusing.

/zones//records
{     "name": "example.com.", "type": "A", "data": "192.0.2.3" }

When a record is created, it would check to see whether a record existed with the same, name and type. If none exists, the new record is created normally. If a match is found, then the record's data is added to the associated Data table. (See the table descriptions below for more info).

Return is displayed as: {       "name": "example.com", "type": "A:,       "ttl": 3600,        "data": {            "0.0.0.1"            "0.0.0.2"         },        "created_at": datestamp,        "updated_at": null    }

Modify a Record
A PUT and a PATCH would be needed.

/zones//records/
Example request:

PATCH /zones/89acac79-38e7-497d-807c-a011e1310438/records/2e32e609-3a4f-45ba-bdef-e50eacd345ad Host: example.com Accept: application/json Content-Type: application/json {     "data": "192.0.2.5" }

This would add the new IP address to the existing ones.

Example request: PUT /zones/89acac79-38e7-497d-807c-a011e1310438/records/2e32e609-3a4f-45ba-bdef-e50eacd345ad

Host: example.com Accept: application/json Content-Type: application/json {     "data": "192.0.2.5", "data": "192.0.2.6" }

This would replace all the existing data with the new data.

Delete a Record
The entire record, including all data, would be deleted.

= Proposal 4 =

POST /zones//recordsets
Request:

{   "name": "example.com.", "type": "A", "records": [ "192.0.2.1",     "192.0.2.2"    ]  }

Response:

{   "name": "example.com.", "type": "A", "records": [ "192.0.2.1",     "192.0.2.2"    ],    ....,    "created_at": datestamp, "updated_at": null }

PATCH /zones//recordsets/
Pre-existing RRSet has "192.0.2.1", "192.0.2.2"

Request (Standard):

{   "records": [ "192.0.2.1",     "192.0.2.2",      "192.0.2.3"    ]  }

Request (JSON Patch / RFC6902‎):

{   "op": "add", "path": "/records", "value": "192.0.2.3" }

Response:

{   "name": "example.com.", "type": "A", "records": [ "192.0.2.1",     "192.0.2.2",      "192.0.2.3"    ],    ....,    "created_at": datestamp, "updated_at": datestamp }

PATCH /zones//recordsets/
Pre-existing RRSet has "192.0.2.1", "192.0.2.2", "192.0.2.3"

Request (Standard):

{   "records": [ "192.0.2.1",     "192.0.2.2"    ]  }

Request (JSON Patch / RFC6902‎):

{   "op": "remove", "path": "/records", "value": "192.0.2.3" }

Response:

{   "name": "example.com.", "type": "A", "records": [ "192.0.2.1",     "192.0.2.2"    ],    ....,    "created_at": datestamp, "updated_at": datestamp }

DELETE /zones//recordsets/
Request:

EMPTY

Response:

EMPTY