diff --git a/docs/writing-providers.md b/docs/writing-providers.md index 59179d5a1..e0029b8bf 100644 --- a/docs/writing-providers.md +++ b/docs/writing-providers.md @@ -15,6 +15,64 @@ assigned bugs related to the provider in the future (unless you designate someone else as the maintainer). More details [here](provider-list.md). +## Overview + +I'll ignore all the small stuff and get to the point. + +A provider's `GetDomainCorrections()` function is the workhorse +of the provider. It is what gets called by `dnscontrol preview` +and `dnscontrol push`. + +How does a provider's `GetDomainCorrections()` function work? + +The goal of `GetDomainCorrections()` is to return a list of +corrections. Each correction is a text string describing the change +("Delete CNAME record foo") and a function that, if called, will +make the change (i.e. call the API and delete record foo). Preview +mode simply prints the text strings. `dnscontrol push` prints the +strings and calls the functions. Because of how Go's functions work, +the function will have everything it needs to make the change. +Pretty cool, eh? + +So how does `GetDomainCorrections()` work? + +First, some terminology: The DNS records specified in the dnsconfig.js +file are called the "desired" records. The DNS records stored at +the DNS service provider are called the "existing" records. + +Every provider does the same basic process. The function +`GetDomainCorrections()` is called with a list of the desired DNS +records (`dc.Records`). It then contacts the provider's API and +gathers the existing records. It converts the existing records into +a list of `*models.RecordConfig`. + +Now that it has the desired and existing records in the appropriate +format, `differ.IncrementalDiff(existingRecords)` is called and +does all the hard work of understanding the DNS records and figuring +out what changes need to be made. It generates lists of adds, +deletes, and changes. + +`GetDomainCorrections()` then generates the list of `models.Corrections()` +and returns. DNSControl takes care of the rest. + +So, what does all this mean? + +It basically means that writing a provider is as simple as writing +code that (1) downloads the existing records, (2) converts each +records into `models.RecordConfig`, (3) write functions that perform +adds, changes, and deletions. + +If you are new to Go, there are plenty of providers you can copy +from. In fact, many non-Go programmers +[have learned Go by contributing to DNSControl](https://everythingsysadmin.com/2017/08/go-get-up-to-speed.html). + +Oh, and what if the API simply requires that the entire zonefile be uploaded +every time? We still generate the text descriptions of the changes (so that +`dnscontrol preview` looks nice) but the functions are just no-ops, except +for one that uploads the new zonefile. + +Now that you understand the general process, here are the details. + ## Step 1: General advice A provider can be a DnsProvider, a Registrar, or both. We recommend @@ -24,8 +82,7 @@ Registrar if needed. If you have any questions, please dicuss them in the Github issue related to the request for this provider. Please let us know what was confusing so we can update this document with advice for future -authors (or even better, update [this -document](https://github.com/StackExchange/dnscontrol/blob/master/docs/writing-providers.md) +authors (or even better, update [this document](https://github.com/StackExchange/dnscontrol/blob/master/docs/writing-providers.md) yourself.) @@ -123,14 +180,21 @@ At this point you can submit a PR. Actually you can submit the PR even earlier if you just want feedback, input, or have questions. This is just a good stopping place to -submit a PR. At a minimum a new provider should pass all the -integration tests. Everything else is a bonus. +submit a PR if you haven't already. ## Step 7: Capabilities -The last step is to add any optional provider capabilities. You can -submit these as a separate PR once the main provider is working. +Some DNS providers have features that others do not. For example some +support the SRV record. A provider announces what it can do using +the capabilities system. + +If a provider doesn't advertise a particular capability, the integration +test system skips the appropriate tests. Therefore you might want +to initially develop the provider with no particular capabilities +advertised and code until all the integration tests work. Then +enable capabilities one at a time to finish off the project. + Don't feel obligated to implement everything at once. In fact, we'd prefer a few small PRs than one big one. Focus on getting the basic provider working well before adding these extras. @@ -146,7 +210,8 @@ at the very end. Enable optional capabilities in the nameProvider.go file and run the integration tests to see what works and what doesn't. Fix any -bugs and repeat. +bugs and repeat, repeat, repeat until you have all the capabilities +you want to implement. ## Vendoring Dependencies