# creds.json file format change

**Feel free to skip to "How do I convert?" if you don't care about the details.**

Starting in v3.16 the "provider type identifier" (PTI) will be located in
`creds.json` instead of `dnsconfig.js`.  The PTI is the all caps string like
`ROUTE53` or `CLOUDFLAREAPI` used to identify a provider's type.

V3.16 will enable a syntax that is backwards and forwards compatible. The old
syntax will be removed in v4.0.  There's no planned release date for v4.0 but
it is expected to be after Dec 31, 2022.

The change was discussed
in [Request for Comments: Include the provider type in creds.json, remove it from dnsconfig.js](https://github.com/StackExchange/dnscontrol/issues/1457) where we decided "Plan A" would be selected.

# What does this mean to you?

In a nutshell, `NewRegistrar()` and `NewDnsProvider()` will lose the 2nd
parameter:

{% code title="dnscontrol.js" %}
```diff
var REG_GANDI = NewRegistrar(
-   "gandi",
-   "GANDI_V5"
+   "gandi"
);
var DSP_CF = NewDnsProvider(
-   "cloudflare_tal",
-   "CLOUDFLAREAPI"
+   "cloudflare_tal"
);
```
{% endcode %}

The second parameter (`GANDI_V5` and `CLOUDFLAREAPI` in the
above examples) has moved to `creds.json` instead.  It will be in a `TYPE`
field, which all providers have.  It can appear in both places for backwards compatibility for now.

{% code title="creds.json" %}
```diff
{
  "gandi": {
+   "TYPE": "GANDI_V5",
    "apikey": "reacted"
  },
  "cloudflare_tal": {
+   "TYPE": "CLOUDFLAREAPI",
    "apikey": "reacted",
    "apiuser": "reacted"
  }
}
```
{% endcode %}

In the past, a provider didn't need an entry in `creds.json` if there were no credentials to be stored.  Starting in v4.0 all providers must have an entry in `creds.json`.  To aid the transition, starting in v3.16 warnings will appear on stdout that direct you to convert to the new format.

Also to help in the conversion, if no provider named "none" or "bind" exist, ones will be added for you.  They look like this:

{% code title="creds.json" %}
```json
{
  "none": { "TYPE": "NONE" },
  "bind": { "TYPE": "BIND" }
}
```
{% endcode %}

# Command line tools

How does this affect command line tools?

The following subcommands require the PTI a parameter on the command line:

* `get-zone`
* `get-zones`
* `check-creds`

In 3.16, that parameter can be changed to `-` as a placeholder, or removed
entirely if it is the last parameter on the command line.  When you omit this
parameter, DNSControl will find the value in `creds.json` instead.

In 4.0, that parameter will be removed, though a `-` is permitted for backwards compatibility.

In other words, if you add the `TYPE` field to `creds.json`, you no longer need
to specify it on the command line.  You can specify `-` instead, or leave it
out entirely starting in v4.0.

For check-creds:

Starting in v3.16 these forms are valid:

```shell
dnscontrol check-creds myr53
dnscontrol check-creds myr53 -
dnscontrol check-creds myr53 ROUTE53
```

Starting in v4.0 this is the only valid form:

```shell
dnscontrol check-creds myr53
```

For backwards compatibility, these are valid until at least v5.0:

```shell
dnscontrol check-creds myr53 -
```

For get-zones/get-zone:

Starting in v3.16 these forms are valid:

```shell
dnscontrol get-zones gmain GANDI_V5 example.comn other.com
dnscontrol get-zones gmain - example.comn other.com
dnscontrol get-zones cfmain CLOUDFLAREAPI all
dnscontrol get-zones cfmain - all
dnscontrol get-zones --format=tsv bind BIND example.com
dnscontrol get-zones --format=tsv bind - example.com
dnscontrol get-zones --format=djs --out=draft.js glcoud GCLOUD example.com
dnscontrol get-zones --format=djs --out=draft.js glcoud - example.com
```

Starting in v4.0 these forms are valid:

```shell
dnscontrol get-zones gmain example.comn other.com
dnscontrol get-zones cfmain all
dnscontrol get-zones --format=tsv bind example.com
dnscontrol get-zones --format=djs --out=draft.js glcoud example.com
```

For backwards compatibility, these are valid until at least v5.0:

```shell
dnscontrol get-zones gmain - example.comn other.com
dnscontrol get-zones cfmain - all
dnscontrol get-zones --format=tsv bind - example.com
dnscontrol get-zones --format=djs --out=draft.js glcoud - example.com
```

# How do I convert?

## Step 1: Upgrade

Upgrade to v3.16 or later.  If DNSControl is installed in many places, do not
continue until they are all at v3.16 or later.

## Step 2:  Edit creds.json

Now that all uses of DNSControl are on v3.16 or later...

For each `creds.json` entry, add a field "TYPE" set to the provider type
identifier. This is the all-caps name such as `ROUTE53`, `GCLOUD`, or
`CLOUDFLAREAPI`.

For example, here is a new-style `creds.json` file with `TYPE` fields added:

{% code title="creds.json" %}
```diff
{
  "bind_inside": {
+   "TYPE": "BIND",
    "directory": "inzones"
  },
  "cloudflare_tal": {
+   "TYPE": "CLOUDFLAREAPI",
    "apikey": "redacted",
    "apiuser": "redacted"
  },
  "gandi": {
+   "TYPE": "GANDI_V5",
    "apikey": "redacted"
  }
}
```
{% endcode %}

## Step 3: Cross-check

Run `dnscontrol preview` as one normally would.  Fix any errors, warnings, or informational messages that appear on stdout.

Here are some examples:

If you see something like...

```text
WARNING: For future compatibility, update the "namedotcom_main" entry in `creds.json` by adding: "TYPE": "NAMEDOTCOM", (See https://docs.dnscontrol.org/commands/creds-json#missing)
```

...it means that the TYPE field is missing from that entry in `creds.json`.


If you see something like...

```text
ERROR: Mismatch found! creds.json entry "namedotcom_main" has "TYPE" set to "ROUTE53" but dnsconfig.js specifies New*("namedotcom_main", "NAMEDOTCOM") (See https://docs.dnscontrol.org/commands/creds-json#mismatch)
```

...it means your `dnsconfig.js` and `creds.json` specify mismatched values.  Fix one or the other.


After you correct some warnings, you may receive information messages like...

```text
INFO: In dnsconfig.js New*("namedotcom_main", "NAMEDOTCOM") can be simplified to New*("namedotcom_main") (See https://docs.dnscontrol.org/commands/creds-json#cleanup)
```

...which is a message that will disappear as you update `dnsconfig.js` in the next step.

## Step 4: Edit dnsconfig.js

Remove the 2nd parameter to any NewDnsProvider() or NewRegistrar() functions.

{% code title="dnsconfig.js" %}
```diff
var REG_NAMEDOTCOM_TAL = NewRegistrar(
-   "namedotcom_tal",
-   "NAMEDOTCOM"
+   "namedotcom_tal"
);
var DNS_GANDI_TAL = NewDnsProvider(
-   "gandi_v5_tal",
-   "GANDI_V5"
+   "gandi_v5_tal"
);
```
{% endcode %}

Again, run `dnscontrol preview` to verify you setup still works as expected.

## Step 5: Update any shell scripts

Any shell scripts or documentation that uses the subcommands `get-zone`,
`get-zones` or `check-creds` should be updated. The "provider type" parameter
should be changed to `-`.  If it is the last parameter on the command, it can
be removed.

It's unlikely you have scripts that use these commands. However you may have
documentation that refers to them and needs to be updated.

## Step 4: Test

Run `dnscontrol preview` as one normally would.  Fix any errors, warnings, or informational messages that appear on stdout.

## Step 5: Done

That's it!
