mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-02-26 00:23:00 +08:00
Merge branch 'master' into dhcid
This commit is contained in:
commit
5761028cbe
9 changed files with 203 additions and 41 deletions
18
.github/workflows/build.yml
vendored
18
.github/workflows/build.yml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: restore_cache
|
||||
uses: actions/cache@v3.3.1
|
||||
uses: actions/cache@v3.3.2
|
||||
with:
|
||||
key: linux-go-${{ hashFiles('go.sum') }}-${{ env.cache-key }}
|
||||
restore-keys: linux-go-${{ hashFiles('go.sum') }}-${{ env.cache-key }}
|
||||
|
@ -28,7 +28,7 @@ jobs:
|
|||
gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES
|
||||
- name: Enforce Go Formatted Code
|
||||
run: "[ `go fmt ./... | wc -l` -eq 0 ]"
|
||||
- uses: actions/upload-artifact@v3.1.2
|
||||
- uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
path: "/tmp/test-results"
|
||||
|
||||
|
@ -178,7 +178,7 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
- run: mkdir -p "$TEST_RESULTS"
|
||||
- name: restore_cache
|
||||
uses: actions/cache@v3.3.1
|
||||
uses: actions/cache@v3.3.2
|
||||
with:
|
||||
key: linux-go-${{ hashFiles('go.sum') }}-${{ env.cache-key }}
|
||||
restore-keys: linux-go-${{ hashFiles('go.sum') }}-${{ env.cache-key }}
|
||||
|
@ -192,7 +192,7 @@ jobs:
|
|||
gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- -timeout 30m -v -verbose -provider ${{ matrix.provider }} -cfworkers=false
|
||||
fi
|
||||
working-directory: integrationTest
|
||||
- uses: actions/upload-artifact@v3.1.2
|
||||
- uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
path: "/tmp/test-results"
|
||||
integrtests-diff2:
|
||||
|
@ -285,7 +285,7 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
- run: mkdir -p "$TEST_RESULTS"
|
||||
- name: restore_cache
|
||||
uses: actions/cache@v3.3.1
|
||||
uses: actions/cache@v3.3.2
|
||||
with:
|
||||
key: linux-go-${{ hashFiles('go.sum') }}-${{ env.cache-key }}
|
||||
restore-keys: linux-go-${{ hashFiles('go.sum') }}-${{ env.cache-key }}
|
||||
|
@ -299,7 +299,7 @@ jobs:
|
|||
echo "Skip test for ${{ matrix.provider }} provider"
|
||||
fi
|
||||
working-directory: integrationTest
|
||||
- uses: actions/upload-artifact@v3.1.2
|
||||
- uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
path: "/tmp/test-results"
|
||||
# release:
|
||||
|
@ -321,17 +321,17 @@ jobs:
|
|||
# docker-password: "${{ secrets.DOCKER_PASSWORD }}"
|
||||
# docker-username: "${{ env.DOCKER_LOGIN }}"
|
||||
# - name: restore_cache
|
||||
# uses: actions/cache@v3.3.1
|
||||
# uses: actions/cache@v3.3.2
|
||||
# with:
|
||||
# key: linux-go-${{ hashFiles('go.sum') }}-${{ env.cache-key }}
|
||||
# restore-keys: linux-go-${{ hashFiles('go.sum') }}-${{ env.cache-key }}
|
||||
# - name: Install goreleaser
|
||||
# run: go install github.com/goreleaser/goreleaser@latest
|
||||
# - run: goreleaser release
|
||||
# - uses: actions/upload-artifact@v3.1.2
|
||||
# - uses: actions/upload-artifact@v3.1.3
|
||||
# with:
|
||||
# path: dist
|
||||
# - uses: actions/upload-artifact@v3.1.2
|
||||
# - uses: actions/upload-artifact@v3.1.3
|
||||
# with:
|
||||
# path: |-
|
||||
# dist/*.rpm
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -45,6 +46,13 @@ type PreviewArgs struct {
|
|||
Full bool
|
||||
}
|
||||
|
||||
type ReportItem struct {
|
||||
Domain string `json:"domain"`
|
||||
Corrections int `json:"corrections"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
Registrar string `json:"registrar,omitempty"`
|
||||
}
|
||||
|
||||
func (args *PreviewArgs) flags() []cli.Flag {
|
||||
flags := args.GetDNSConfigArgs.flags()
|
||||
flags = append(flags, args.GetCredentialsArgs.flags()...)
|
||||
|
@ -93,6 +101,7 @@ var _ = cmd(catMain, func() *cli.Command {
|
|||
type PushArgs struct {
|
||||
PreviewArgs
|
||||
Interactive bool
|
||||
Report string
|
||||
}
|
||||
|
||||
func (args *PushArgs) flags() []cli.Flag {
|
||||
|
@ -102,21 +111,26 @@ func (args *PushArgs) flags() []cli.Flag {
|
|||
Destination: &args.Interactive,
|
||||
Usage: "Interactive. Confirm or Exclude each correction before they run",
|
||||
})
|
||||
flags = append(flags, &cli.StringFlag{
|
||||
Name: "report",
|
||||
Destination: &args.Report,
|
||||
Usage: `Generate a machine-parseable report of performed corrections.`,
|
||||
})
|
||||
return flags
|
||||
}
|
||||
|
||||
// Preview implements the preview subcommand.
|
||||
func Preview(args PreviewArgs) error {
|
||||
return run(args, false, false, printer.DefaultPrinter)
|
||||
return run(args, false, false, printer.DefaultPrinter, nil)
|
||||
}
|
||||
|
||||
// Push implements the push subcommand.
|
||||
func Push(args PushArgs) error {
|
||||
return run(args.PreviewArgs, true, args.Interactive, printer.DefaultPrinter)
|
||||
return run(args.PreviewArgs, true, args.Interactive, printer.DefaultPrinter, &args.Report)
|
||||
}
|
||||
|
||||
// run is the main routine common to preview/push
|
||||
func run(args PreviewArgs, push bool, interactive bool, out printer.CLI) error {
|
||||
func run(args PreviewArgs, push bool, interactive bool, out printer.CLI, report *string) error {
|
||||
// TODO: make truly CLI independent. Perhaps return results on a channel as they occur
|
||||
|
||||
// This is a hack until we have the new printer replacement.
|
||||
|
@ -151,7 +165,7 @@ func run(args PreviewArgs, push bool, interactive bool, out printer.CLI) error {
|
|||
// create a WaitGroup with the length of domains for the anonymous functions (later goroutines) to wait for
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(cfg.Domains))
|
||||
|
||||
var reportItems []ReportItem
|
||||
// For each domain in dnsconfig.js...
|
||||
for _, domain := range cfg.Domains {
|
||||
// Run preview or push operations per domain as anonymous function, in preparation for the later use of goroutines.
|
||||
|
@ -232,6 +246,11 @@ func run(args PreviewArgs, push bool, interactive bool, out printer.CLI) error {
|
|||
totalCorrections += len(corrections)
|
||||
// When diff1 goes away, the call to printReports() should be moved to HERE.
|
||||
//printReports(domain.Name, provider.Name, reports, out, push, notifier)
|
||||
reportItems = append(reportItems, ReportItem{
|
||||
Domain: domain.Name,
|
||||
Corrections: len(corrections),
|
||||
Provider: provider.Name,
|
||||
})
|
||||
anyErrors = printOrRunCorrections(domain.Name, provider.Name, corrections, out, push, interactive, notifier) || anyErrors
|
||||
}
|
||||
|
||||
|
@ -253,6 +272,11 @@ func run(args PreviewArgs, push bool, interactive bool, out printer.CLI) error {
|
|||
return
|
||||
}
|
||||
totalCorrections += len(corrections)
|
||||
reportItems = append(reportItems, ReportItem{
|
||||
Domain: domain.Name,
|
||||
Corrections: len(corrections),
|
||||
Registrar: domain.RegistrarName,
|
||||
})
|
||||
anyErrors = printOrRunCorrections(domain.Name, domain.RegistrarName, corrections, out, push, interactive, notifier) || anyErrors
|
||||
}(domain)
|
||||
}
|
||||
|
@ -269,6 +293,20 @@ func run(args PreviewArgs, push bool, interactive bool, out printer.CLI) error {
|
|||
if totalCorrections != 0 && args.WarnChanges {
|
||||
return fmt.Errorf("there are pending changes")
|
||||
}
|
||||
if report != nil {
|
||||
f, err := os.OpenFile(*report, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
b, err := json.MarshalIndent(reportItems, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -154,6 +154,7 @@
|
|||
* [Nameservers and Delegations](nameservers.md)
|
||||
* [Notifications](notifications.md)
|
||||
* [Useful code tricks](code-tricks.md)
|
||||
* [JSON Reports](json-reports.md)
|
||||
|
||||
## Developer info
|
||||
|
||||
|
|
|
@ -8,17 +8,38 @@ ts_ignore: true
|
|||
`require(...)` loads the specified JavaScript or JSON file, allowing
|
||||
to split your configuration across multiple files.
|
||||
|
||||
A better name for this function might be "include".
|
||||
|
||||
If the supplied `path` string ends with `.js`, the file is interpreted
|
||||
as JavaScript code, almost as though its contents had been included in
|
||||
the currently-executing file. If the path string ends with `.json`,
|
||||
`require()` returns the `JSON.parse()` of the file's contents.
|
||||
|
||||
If the path string begins with a `.`, it is interpreted relative to
|
||||
If the path string begins with a `./`, it is interpreted relative to
|
||||
the currently-loading file (which may not be the file where the
|
||||
`require()` statement is, if called within a function), otherwise it
|
||||
`require()` statement is, if called within a function). Otherwise it
|
||||
is interpreted relative to the program's working directory at the time
|
||||
of the call.
|
||||
|
||||
### Example 1: Simple
|
||||
|
||||
In this example, we separate our macros in one file, and put groups of domains
|
||||
in 3 other files. The result is a cleaner separation of code vs. domains.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
require("lib/macros.json");
|
||||
|
||||
require("domains/main.json");
|
||||
require("domains/parked.json");
|
||||
require("domains/otherstuff.json");
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
### Example 2: Complex
|
||||
|
||||
Here's a more complex example:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
require("kubernetes/clusters.js");
|
||||
|
@ -60,7 +81,9 @@ function includeK8Sdev() {
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
You can also use it to require JSON files and initialize variables with it:
|
||||
### Example 3: JSON
|
||||
|
||||
Requiring JSON files initializes variables:
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
|
@ -83,16 +106,13 @@ for (var domain in domains) {
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
# Future
|
||||
# Notes
|
||||
|
||||
It might be better to rename the function to something like
|
||||
`include()` instead, (leaving `require` as a deprecated alias) because
|
||||
by analogy it is *much* closer to PHP's `include()` function than it
|
||||
is to node's `require()`. After all, the reason node.js calls it
|
||||
"require" is because it's a declarative statement saying the file is
|
||||
needed, and so should be loaded if it hasn't already been loaded.
|
||||
`require()` is *much* closer to PHP's `include()` function than it
|
||||
is to node's `require()`.
|
||||
|
||||
Node's `require()` only includes a file once.
|
||||
In contrast, DNSControl's `require()` is actually an imperative command to
|
||||
load the file and execute the code or parse the data from it. (So if
|
||||
two files both `require("./tools.js")`, for example, then it will be
|
||||
loaded twice, whereas in node.js it would only be loaded once.)
|
||||
load the file and execute the code or parse the data from it. For example if
|
||||
two files both `require("./tools.js")`, then it will be
|
||||
loaded twice, whereas in node.js it would only be loaded once.
|
||||
|
|
|
@ -8,7 +8,7 @@ parameter_types:
|
|||
recursive: boolean
|
||||
---
|
||||
|
||||
`require_glob()` can recursively load `.js` files, optionally non-recursive as well.
|
||||
`require_glob()` recursively loads `.js` files that match a glob (wildcard). The recursion can be disabled.
|
||||
|
||||
Possible parameters are:
|
||||
|
||||
|
@ -31,8 +31,13 @@ require_glob("./domains/", false);
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
One more important thing to note: `require_glob()` is as smart as `require()` is. It loads files always relative to the JavaScript
|
||||
file where it's being executed in. Let's go with an example, as it describes it better:
|
||||
# Comparison to require()
|
||||
|
||||
`require_glob()` and `require()` both use the same rules for determining which directory path is
|
||||
relative to.
|
||||
|
||||
This will load files being present underneath `./domains/user1/` and **NOT** at below `./domains/`, as `require_glob()`
|
||||
is called in the subfolder `domains/`.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
|
@ -45,6 +50,3 @@ require("domains/index.js");
|
|||
require_glob("./user1/");
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
This will now load files being present underneath `./domains/user1/` and **NOT** at below `./domains/`, as `require_glob()`
|
||||
is called in the subfolder `domains/`.
|
||||
|
|
34
documentation/json-reports.md
Normal file
34
documentation/json-reports.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# JSON Reports
|
||||
|
||||
DNSControl has build in functionality to generate a machine-parseable report after pushing changes. This report is JSON formated and contains the zonename, the provider or registrar name and the amount of performed changes.
|
||||
|
||||
## Usage
|
||||
|
||||
To enable the report option you must use the `push` operation in combination with the `--report <filename>` option. This generates the json file.
|
||||
|
||||
{% code title="report.json" %}
|
||||
```json
|
||||
[
|
||||
{
|
||||
"domain": "private.example.com",
|
||||
"corrections": 10,
|
||||
"provider": "bind"
|
||||
},
|
||||
{
|
||||
"domain": "private.example.com",
|
||||
"corrections": 0,
|
||||
"registrar": "none"
|
||||
},
|
||||
{
|
||||
"domain": "admin.example.com",
|
||||
"corrections": 5,
|
||||
"provider": "bind"
|
||||
},
|
||||
{
|
||||
"domain": "admin.example.com",
|
||||
"corrections": 0,
|
||||
"registrar": "none"
|
||||
}
|
||||
]
|
||||
```
|
||||
{% endcode %}
|
|
@ -53,7 +53,7 @@ If a feature is definitively not supported for whatever reason, we would also li
|
|||
| [`ORACLE`](providers/oracle.md) | ❌ | ✅ | ❌ | ✅ | ✅ | ❔ | ❔ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
|
||||
| [`OVH`](providers/ovh.md) | ❌ | ✅ | ✅ | ❌ | ✅ | ❔ | ❔ | ❔ | ❌ | ❔ | ✅ | ✅ | ✅ | ❔ | ✅ | ❌ | ✅ | ✅ |
|
||||
| [`PACKETFRAME`](providers/packetframe.md) | ❌ | ✅ | ❌ | ❔ | ❔ | ❔ | ❔ | ❔ | ✅ | ❔ | ✅ | ❔ | ❔ | ❔ | ❌ | ❌ | ✅ | ❔ |
|
||||
| [`PORKBUN`](providers/porkbun.md) | ❌ | ✅ | ❌ | ✅ | ❔ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
|
||||
| [`PORKBUN`](providers/porkbun.md) | ❌ | ✅ | ✅ | ✅ | ❔ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
|
||||
| [`POWERDNS`](providers/powerdns.md) | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ | ❔ | ✅ | ✅ | ❔ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| [`ROUTE53`](providers/route53.md) | ✅ | ✅ | ✅ | ❌ | ✅ | ❔ | ❌ | ❔ | ✅ | ❔ | ✅ | ❔ | ❔ | ❔ | ✅ | ✅ | ✅ | ✅ |
|
||||
| [`RWTH`](providers/rwth.md) | ❌ | ✅ | ❌ | ❌ | ✅ | ❔ | ❌ | ❌ | ✅ | ❔ | ✅ | ✅ | ❌ | ❔ | ❌ | ❌ | ✅ | ✅ |
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -18,7 +19,7 @@ type porkbunProvider struct {
|
|||
secretKey string
|
||||
}
|
||||
|
||||
type requestParams map[string]string
|
||||
type requestParams map[string]any
|
||||
|
||||
type errorResponse struct {
|
||||
Status string `json:"status"`
|
||||
|
@ -40,6 +41,11 @@ type recordResponse struct {
|
|||
Records []domainRecord `json:"records"`
|
||||
}
|
||||
|
||||
type nsResponse struct {
|
||||
Status string `json:"status"`
|
||||
Nameservers []string `json:"ns"`
|
||||
}
|
||||
|
||||
func (c *porkbunProvider) post(endpoint string, params requestParams) ([]byte, error) {
|
||||
params["apikey"] = c.apiKey
|
||||
params["secretapikey"] = c.secretKey
|
||||
|
@ -82,7 +88,7 @@ func (c *porkbunProvider) ping() error {
|
|||
|
||||
func (c *porkbunProvider) createRecord(domain string, rec requestParams) error {
|
||||
if _, err := c.post("/dns/create/"+domain, rec); err != nil {
|
||||
return fmt.Errorf("failed create record (porkbun): %s", err)
|
||||
return fmt.Errorf("failed create record (porkbun): %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -90,14 +96,14 @@ func (c *porkbunProvider) createRecord(domain string, rec requestParams) error {
|
|||
func (c *porkbunProvider) deleteRecord(domain string, recordID string) error {
|
||||
params := requestParams{}
|
||||
if _, err := c.post(fmt.Sprintf("/dns/delete/%s/%s", domain, recordID), params); err != nil {
|
||||
return fmt.Errorf("failed delete record (porkbun): %s", err)
|
||||
return fmt.Errorf("failed delete record (porkbun): %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *porkbunProvider) modifyRecord(domain string, recordID string, rec requestParams) error {
|
||||
if _, err := c.post(fmt.Sprintf("/dns/edit/%s/%s", domain, recordID), rec); err != nil {
|
||||
return fmt.Errorf("failed update (porkbun): %s", err)
|
||||
return fmt.Errorf("failed update (porkbun): %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -106,7 +112,7 @@ func (c *porkbunProvider) getRecords(domain string) ([]domainRecord, error) {
|
|||
params := requestParams{}
|
||||
var bodyString, err = c.post("/dns/retrieve/"+domain, params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed fetching record list from porkbun: %s", err)
|
||||
return nil, fmt.Errorf("failed fetching record list from porkbun: %w", err)
|
||||
}
|
||||
|
||||
var dr recordResponse
|
||||
|
@ -121,3 +127,26 @@ func (c *porkbunProvider) getRecords(domain string) ([]domainRecord, error) {
|
|||
}
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func (c *porkbunProvider) getNameservers(domain string) ([]string, error) {
|
||||
params := requestParams{}
|
||||
var bodyString, err = c.post(fmt.Sprintf("/domain/getNs/%s", domain), params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed fetching nameserver list from porkbun: %w", err)
|
||||
}
|
||||
|
||||
var ns nsResponse
|
||||
json.Unmarshal(bodyString, &ns)
|
||||
|
||||
sort.Strings(ns.Nameservers)
|
||||
return ns.Nameservers, nil
|
||||
}
|
||||
|
||||
func (c *porkbunProvider) updateNameservers(ns []string, domain string) error {
|
||||
params := requestParams{}
|
||||
params["ns"] = ns
|
||||
if _, err := c.post(fmt.Sprintf("/domain/updateNs/%s", domain), params); err != nil {
|
||||
return fmt.Errorf("failed NS update (porkbun): %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package porkbun
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -25,8 +26,16 @@ var defaultNS = []string{
|
|||
"salvador.ns.porkbun.com",
|
||||
}
|
||||
|
||||
// NewPorkbun creates the provider.
|
||||
func NewPorkbun(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||
func newReg(conf map[string]string) (providers.Registrar, error) {
|
||||
return newPorkbun(conf, nil)
|
||||
}
|
||||
|
||||
func newDsp(conf map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||
return newPorkbun(conf, metadata)
|
||||
}
|
||||
|
||||
// newPorkbun creates the provider.
|
||||
func newPorkbun(m map[string]string, metadata json.RawMessage) (*porkbunProvider, error) {
|
||||
c := &porkbunProvider{}
|
||||
|
||||
c.apiKey, c.secretKey = m["api_key"], m["secret_key"]
|
||||
|
@ -63,8 +72,9 @@ var features = providers.DocumentationNotes{
|
|||
}
|
||||
|
||||
func init() {
|
||||
providers.RegisterRegistrarType("PORKBUN", newReg)
|
||||
fns := providers.DspFuncs{
|
||||
Initializer: NewPorkbun,
|
||||
Initializer: newDsp,
|
||||
RecordAuditor: AuditRecords,
|
||||
}
|
||||
providers.RegisterDomainServiceProviderType("PORKBUN", fns, features)
|
||||
|
@ -317,3 +327,31 @@ func fixTTL(ttl uint32) uint32 {
|
|||
}
|
||||
return minimumTTL
|
||||
}
|
||||
|
||||
func (c *porkbunProvider) GetRegistrarCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
|
||||
nss, err := c.getNameservers(dc.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
foundNameservers := strings.Join(nss, ",")
|
||||
|
||||
expected := []string{}
|
||||
for _, ns := range dc.Nameservers {
|
||||
expected = append(expected, ns.Name)
|
||||
}
|
||||
sort.Strings(expected)
|
||||
expectedNameservers := strings.Join(expected, ",")
|
||||
|
||||
if foundNameservers == expectedNameservers {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return []*models.Correction{
|
||||
{
|
||||
Msg: fmt.Sprintf("Update nameservers %s -> %s", foundNameservers, expectedNameservers),
|
||||
F: func() error {
|
||||
return c.updateNameservers(expected, dc.Name)
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue