Everyone is familiar with A, AAAA, CNAME, NS and other Rtypes.
However there are new record types being added all the time (possibly
too many). Each new record type requires special handling by
DNSControl.
If a record simply has a single "target", then there is little to
do because it is handled similarly to A, CNAME, and so on. However
if there are multiple fields within the record you have more work
to do.
Our general philosophy is:
* Internally the individual fields of a record are kept separate. If a particular provider combines them into one big string, that kind of thing is done in the provider code at the end of the food chain. For example, an MX record has a Target (`aspmx.l.google.com.`) and a preference (`10`). Some systems combine this into one string (`10 aspmx.l.google.com.`). We keep the two values separate in `RecordConfig` and leave it up to the individual providers to merge them when required. An earlier implementation kept everything combined and we found ourselves constantly parsing and re-parsing the target. It was inefficient and lead to many bugs.
* Anywhere we have a special case for a particular Rtype, we use a `switch` statement and have a `case` for every single record type, usually with a `default:` case that calls `panic()`. This way developers adding a new record type will quickly find where they need to add code (the panic will tell them where). Before we did this, missing implementation code would go unnoticed for months.
* Keep things alphabetical. If you are adding your record type to a case statement, function library, or whatever, please list it alphabetically along with the others when possible.
## Step 1: Update `RecordConfig` in `models/dns.go`
If the record has any unique fields, add them to `RecordConfig`.
The field name should be the record type, then the field name as
used in `github.com/miekg/dns/types.go`. For example, the `CAA`
record has a field called `Flag`, therefore the field name in
`RecordConfig` is CaaFlag (not `CaaFlags` or `CAAFlags`).
Here are some examples:
```
type RecordConfig struct {
...
MxPreference uint16 `json:"mxpreference,omitempty"` // FIXME(tlim): Rename to MxPreference
SrvPriority uint16 `json:"srvpriority,omitempty"`
SrvWeight uint16 `json:"srvweight,omitempty"`
SrvPort uint16 `json:"srvport,omitempty"`
CaaTag string `json:"caatag,omitempty"`
CaaFlag uint8 `json:"caaflag,omitempty"`
...
}
```
## Step 2: Add a capability for the record
You'll need to mark which providers support this record type. The
initial PR should implement this record for the `bind` provider at
a minimum.
* Add the capability to the file `dnscontrol/providers/providers.go` (look for `CanUseAlias` and add
it to the end of the list.)
* Mark the `bind` provider as supporting this record type by updating `dnscontrol/providers/bind/bindProvider.go` (look for `providers.CanUs` and you'll see what to do).
## Step 2: Add a helper function
Add a function to `pkg/js/helpers.js` for the new record type. This
is the Javascript file that defines `dnsconfig.js`'s functions like
`A()` and `MX()`. Look at the definition of A, MX and CAA for good