mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-11-13 01:40:38 +08:00
feat(report): add correction details to json report
- fix correction count - fix provider and registrar name to report - disable HTMLEscape when writing the report - update docs
This commit is contained in:
parent
71c2cc24ca
commit
6ea71d50f7
3 changed files with 70 additions and 20 deletions
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
@ -300,7 +301,7 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor
|
||||||
if !skip {
|
if !skip {
|
||||||
totalCorrections += len(corrections)
|
totalCorrections += len(corrections)
|
||||||
out.EndProvider2(provider.Name, len(corrections))
|
out.EndProvider2(provider.Name, len(corrections))
|
||||||
reportItems = append(reportItems, genReportItem(zone.Name, corrections, provider.Name))
|
reportItems = append(reportItems, genReportItem(zone.Name, corrections, provider.Name, ""))
|
||||||
anyErrors = cmp.Or(anyErrors, pprintOrRunCorrections(zone.Name, provider.Name, corrections, out, push || args.PopulateOnPreview, interactive, notifier, report))
|
anyErrors = cmp.Or(anyErrors, pprintOrRunCorrections(zone.Name, provider.Name, corrections, out, push || args.PopulateOnPreview, interactive, notifier, report))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -367,7 +368,9 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor
|
||||||
numActions := zone.GetChangeCount(provider.Name)
|
numActions := zone.GetChangeCount(provider.Name)
|
||||||
totalCorrections += numActions
|
totalCorrections += numActions
|
||||||
out.EndProvider2(provider.Name, numActions)
|
out.EndProvider2(provider.Name, numActions)
|
||||||
reportItems = append(reportItems, genReportItem(zone.Name, corrections, provider.Name))
|
numCorrections := len(corrections)
|
||||||
|
out.Printf("numActions: %d \nnumCorrections: %d\n", totalCorrections, numCorrections)
|
||||||
|
reportItems = append(reportItems, genReportItem(zone.Name, corrections, provider.Name, ""))
|
||||||
anyErrors = cmp.Or(anyErrors, pprintOrRunCorrections(zone.Name, provider.Name, corrections, out, push, interactive, notifier, report))
|
anyErrors = cmp.Or(anyErrors, pprintOrRunCorrections(zone.Name, provider.Name, corrections, out, push, interactive, notifier, report))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -380,7 +383,7 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor
|
||||||
numActions := zone.GetChangeCount(zone.RegistrarInstance.Name)
|
numActions := zone.GetChangeCount(zone.RegistrarInstance.Name)
|
||||||
out.EndProvider2(zone.RegistrarName, numActions)
|
out.EndProvider2(zone.RegistrarName, numActions)
|
||||||
totalCorrections += numActions
|
totalCorrections += numActions
|
||||||
reportItems = append(reportItems, genReportItem(zone.Name, corrections, zone.RegistrarName))
|
reportItems = append(reportItems, genReportItem(zone.Name, corrections, "", zone.RegistrarName))
|
||||||
anyErrors = cmp.Or(anyErrors, pprintOrRunCorrections(zone.Name, zone.RegistrarInstance.Name, corrections, out, push, interactive, notifier, report))
|
anyErrors = cmp.Or(anyErrors, pprintOrRunCorrections(zone.Name, zone.RegistrarInstance.Name, corrections, out, push, interactive, notifier, report))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -564,19 +567,44 @@ func skipProvider(name string, providers []*models.DNSProviderInstance) bool {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func genReportItem(zname string, corrections []*models.Correction, pname string) *ReportItem {
|
func parseCorrectionMsg(s string) []string {
|
||||||
|
ansiRe := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
|
||||||
|
s = ansiRe.ReplaceAllString(s, "")
|
||||||
|
corrections := strings.Split(s, "\n")
|
||||||
|
|
||||||
|
// Clean up the slice, precaution remove any empty entries.
|
||||||
|
clean := make([]string, 0, len(corrections))
|
||||||
|
for _, l := range corrections {
|
||||||
|
l = strings.TrimSpace(l)
|
||||||
|
if l != "" {
|
||||||
|
clean = append(clean, l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clean
|
||||||
|
}
|
||||||
|
|
||||||
|
func genReportItem(zoneName string, corrections []*models.Correction, providerName string, registrarName string) *ReportItem {
|
||||||
// Only count the actions, not the messages.
|
// Only count the actions, not the messages.
|
||||||
|
// From my testing corrections is always just contains 1 connection, and Msg is concat of all the changes
|
||||||
cnt := 0
|
cnt := 0
|
||||||
|
correctionDetails := make([]string, 0)
|
||||||
for _, cor := range corrections {
|
for _, cor := range corrections {
|
||||||
if cor.F != nil {
|
if cor.F != nil {
|
||||||
cnt++
|
cnt++ // This seems to always be 1, so we will get the number of corrections from len(correctionDetails)
|
||||||
|
correctionDetails = append(correctionDetails, parseCorrectionMsg(cor.Msg)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r := ReportItem{
|
r := ReportItem{
|
||||||
Domain: zname,
|
Domain: zoneName,
|
||||||
Corrections: cnt,
|
Corrections: len(correctionDetails),
|
||||||
Provider: pname,
|
CorrectionDetails: correctionDetails,
|
||||||
|
}
|
||||||
|
if providerName != "" {
|
||||||
|
r.Provider = providerName
|
||||||
|
}
|
||||||
|
if registrarName != "" {
|
||||||
|
r.Registrar = registrarName
|
||||||
}
|
}
|
||||||
return &r
|
return &r
|
||||||
}
|
}
|
||||||
|
|
@ -635,11 +663,13 @@ func writeReport(report string, reportItems []*ReportItem) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
b, err := json.MarshalIndent(reportItems, "", " ")
|
|
||||||
if err != nil {
|
// Disabling HTML encoding
|
||||||
return err
|
enc := json.NewEncoder(f)
|
||||||
}
|
enc.SetIndent("", " ")
|
||||||
if _, err := f.Write(b); err != nil {
|
enc.SetEscapeHTML(false)
|
||||||
|
|
||||||
|
if err := enc.Encode(reportItems); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import (
|
||||||
type ReportItem struct {
|
type ReportItem struct {
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
Corrections int `json:"corrections"`
|
Corrections int `json:"corrections"`
|
||||||
|
CorrectionDetails []string `json:"correction_details,omitempty"`
|
||||||
Provider string `json:"provider,omitempty"`
|
Provider string `json:"provider,omitempty"`
|
||||||
Registrar string `json:"registrar,omitempty"`
|
Registrar string `json:"registrar,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
DNSControl can generate a machine-parseable report of changes.
|
DNSControl can generate a machine-parseable report of changes.
|
||||||
|
|
||||||
The report is JSON formatted and contains the zonename, the provider or
|
The report is JSON-formatted and contains the zonename, the provider or
|
||||||
registrar name, and the number of changes.
|
registrar name, the number of changes (corrections), and the correction details.
|
||||||
|
All values are in text, values may contain `<`,`>` and `&` escape as needed.
|
||||||
|
|
||||||
To generate the report, add the `--report <filename>` option to a preview or
|
To generate the report, add the `--report <filename>` option to a preview or
|
||||||
push command (this includes `preview`, `ppreview`, `push`,
|
push command (this includes `preview`, `ppreview`, `push`,
|
||||||
`ppush`).
|
`ppush`).
|
||||||
|
|
||||||
|
|
||||||
The report lists the changes that would be (preview) or are (push) attempted,
|
The report lists the changes that would be (preview) or are (push) attempted,
|
||||||
whether they are successful or not.
|
whether they are successful or not.
|
||||||
|
|
||||||
|
|
@ -23,6 +23,18 @@ If a fatal error happens during the run, no report is generated.
|
||||||
{
|
{
|
||||||
"domain": "private.example.com",
|
"domain": "private.example.com",
|
||||||
"corrections": 10,
|
"corrections": 10,
|
||||||
|
"correction_details": [
|
||||||
|
"± MODIFY private.example.com A (1.1.1.1 ttl=60) -> (1.1.1.6 ttl=300)",
|
||||||
|
"+ CREATE private.example.com A 1.1.1.7 ttl=300",
|
||||||
|
"± MODIFY-TTL private.example.com TXT \"v=spf1 include:spf.protection.outlook.com -all\" ttl=(60->300)",
|
||||||
|
"+ CREATE private.example.com TXT \"v=DKIM1; k=rsa; p=xxxx....xxx\" ttl=300",
|
||||||
|
"+ CREATE private.example.com MX 0 private-example-com.mail.protection.outlook.com. ttl=300",
|
||||||
|
"+ CREATE *.private.example.com A 1.1.1.6 ttl=300",
|
||||||
|
"+ CREATE *.private.example.com A 1.1.1.7 ttl=300",
|
||||||
|
"+ CREATE ns101.private.example.com A 1.1.1.1 ttl=300",
|
||||||
|
"+ CREATE ns102.private.example.com A 1.0.0.2 ttl=300",
|
||||||
|
"- DELETE out-of-band.private.example.com TXT \"This out-of-band TXT record should be removed.\" ttl=300"
|
||||||
|
],
|
||||||
"provider": "bind"
|
"provider": "bind"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -33,6 +45,13 @@ If a fatal error happens during the run, no report is generated.
|
||||||
{
|
{
|
||||||
"domain": "admin.example.com",
|
"domain": "admin.example.com",
|
||||||
"corrections": 5,
|
"corrections": 5,
|
||||||
|
"correction_details": [
|
||||||
|
"± MODIFY admin.example.com A (1.1.1.1 ttl=60) -> (1.1.1.6 ttl=300)",
|
||||||
|
"+ CREATE admin.example.com A 1.1.1.7 ttl=300",
|
||||||
|
"± MODIFY-TTL admin.example.com TXT \"v=spf1 include:spf.protection.outlook.com -all\" ttl=(60->300)",
|
||||||
|
"+ CREATE admin.example.com TXT \"v=DKIM1; k=rsa; p=xxxx....xxx\" ttl=300",
|
||||||
|
"- DELETE out-of-band.admin.example.com TXT \"This out-of-band TXT record should be removed.\" ttl=300"
|
||||||
|
],
|
||||||
"provider": "bind"
|
"provider": "bind"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue