Designate/Blueprints/APIv2StructuredData

Overview
This blueprint proposes to define the structured data format for API v2 responses.

API Resource
A single example of both the structured and textual representations is provided here to illustrate the intent, using SRV records. We will default to the textual representation(?), and use a VND mime-type in the Accept/Content-Type headers to distinguish the supplied/requested request/response formats:

 Request: 

GET https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id}/records HTTP/1.1 Host: dns.provider.com Accept: application/vnd.openstack.designate-v2-structured+json X-Auth-Token: *****

 Response: 

HTTP/1.1 200 OK Vary: Accept Content-Type: application/vnd.openstack.designate-v2-structured+json

{   "records": [{ "id": " ... ", "data": { "weight": 0, "priority": 10, "port": 7778, "target": "xmpp1.example.org." }   }, {      "id": " ... ", "data": { "weight": 0, "priority": 20, "port": 7778, "target": "xmpp2.example.org." }   }]  }

 Request: 

GET https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id}/records HTTP/1.1 Host: dns.provider.com Accept: application/json X-Auth-Token: *****

 Response: 

HTTP/1.1 200 OK Vary: Accept Content-Type: application/json

{   "records": [{ "id": " ... ", "data": "0 10 7778 xmpp1.example.org." }, {     "id": " ... ", "data": "0 20 7778 xmpp2.example.org." }] }

Implementation
Each RRType (e.g. A, AAAA, SRV) will be implemented as a separate class, containing both the validations and converters to/from the textual and structured representations. These classes will be enumerated at startup via a plugin mechanism by the services that require them (e.g. the API service). For example:

class SRV(rrtype.RRType): """     SRV Resource Record Type      Defined in: RFC2782      """ __plugin_name__ = 'SRV' """ The RFC defined type code for the RRType """ TYPE = 33 """ A regular expression using named captures to extract the fields from a textual representation of the RData """ RE_TEXT = r"(?P \d+) (?P \d+) (?P \d+) (?P .+)" """ A formatting string used to reconstructed the textual representation of the RData from a set of named fields """ FM_TEXT = "%(priority)d %(weight)d %(port)d %(target)d" """ The Valdiation schema for this RRType, validates against the structured format """ SCHEMA = { "$schema": "http://json-schema.org/draft-04/hyper-schema", "additionalProperties": False, "required": ["priority", "weight", "port", "target"], "properties": { "priority": { "type": "integer", "min": 0, "max": 65535 },             "weight": { "type": "integer", "min": 0, "max": 65535 },             "port": { "type": "integer", "min": 0, "max": 65535 },             "target": { "type": "string", "format": "hostname" }         }      }      def __init__(self, priority=None, weight=None, port=None, target=None): super(SRV, self).__init__ self.priority = priority self.weight = weight self.port = port self.target = target @classmethod def from_text(self, t): """ Implemented in the base class, uses the RE_TEXT regex to construct a new object """ pass @classmethod def from_dict(self, d): """ Implemented in the base class, constructs a new object based on the supplied dict, using the classes constructor """ pass def to_text(self, t): """ Implemented in the base class, uses the FM_TEXT to construct the textual representation of this object """ pass def to_dict(self, d): """ Implemented in the base class, constructs a dict representation of this object """ pass

The API layer will convert all RData contained in a request to these classes, before sending the request to central. This allows the API layer to make use of the per-rrtype validations. Additionally, central (Storage?) will respond to all Record CRUD methods with these objects, allowing the API to choose the appropriate response format.

Database Schema
No changes will be made at this time.

In the future, we may choose to store the structured format in the database - either as a JSON/Pickle blob, or 1 well defined table per RRType. Details of this, and the decision over whether or not any change to the database schema is made is out of scope for this blueprint.

Review Comments
Ref: https://wiki.openstack.org/wiki/VersionDiscovery#media-types Should we consider adding a mime-type property to the VND (say version=1.0) just to make it easier to make changes to the types in the future, if that need arose, without breaking existing users? For example: application/vnd.openstack.designate-v2-structured+json becomes application/vnd.openstack.designate-v2-structured+json;version=1.0 This then allows us to do application/vnd.openstack.designate-v2-structured+json;version=2.0 if we need to without affecting users who do not want to move to the new structure. [eankutse]