mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
NEW FEATURE: diff2: A better "diff" mechanism (#1852)
This commit is contained in:
129
pkg/diff2/unmanaged.go
Normal file
129
pkg/diff2/unmanaged.go
Normal file
@ -0,0 +1,129 @@
|
||||
package diff2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v3/models"
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
|
||||
)
|
||||
|
||||
func handsoff(
|
||||
existing, desired models.Records,
|
||||
unmanaged []*models.UnmanagedConfig,
|
||||
beSafe bool,
|
||||
) (models.Records, error) {
|
||||
|
||||
// What foreign items should we ignore?
|
||||
foreign, err := manyQueries(existing, unmanaged)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(foreign) != 0 {
|
||||
printer.Printf("INFO: Foreign records being ignored: (%d)\n", len(foreign))
|
||||
for i, r := range foreign {
|
||||
printer.Printf("- % 4d: %s %s %s\n", i, r.GetLabelFQDN(), r.Type, r.GetTargetRFC1035Quoted())
|
||||
}
|
||||
}
|
||||
|
||||
// What desired items might conflict?
|
||||
conflicts, err := manyQueries(desired, unmanaged)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(conflicts) != 0 {
|
||||
level := "WARN"
|
||||
if beSafe {
|
||||
level = "ERROR"
|
||||
}
|
||||
printer.Printf("%s: dnsconfig.js records that overlap MANAGED: (%d)\n", level, len(conflicts))
|
||||
for i, r := range conflicts {
|
||||
printer.Printf("- % 4d: %s %s %s\n", i, r.GetLabelFQDN(), r.Type, r.GetTargetRFC1035Quoted())
|
||||
}
|
||||
if beSafe {
|
||||
return nil, fmt.Errorf("ERROR: Unsafe to continue. Add DISABLE_UNMANAGED_SAFETY_CHECK to D() to override")
|
||||
}
|
||||
}
|
||||
|
||||
// Add the foreign items to the desired list.
|
||||
// (Rather than literally ignoring them, we just add them to the desired list
|
||||
// and all the diffing algorithms become more simple.)
|
||||
desired = append(desired, foreign...)
|
||||
|
||||
return desired, nil
|
||||
}
|
||||
|
||||
func manyQueries(rcs models.Records, queries []*models.UnmanagedConfig) (result models.Records, err error) {
|
||||
|
||||
for _, q := range queries {
|
||||
|
||||
lab := q.Label
|
||||
if lab == "" {
|
||||
lab = "*"
|
||||
}
|
||||
glabel, err := glob.Compile(lab)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
targ := q.Target
|
||||
if targ == "" {
|
||||
targ = "*"
|
||||
}
|
||||
gtarget, err := glob.Compile(targ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hasRType := compileTypeGlob(q.RType)
|
||||
|
||||
for _, rc := range rcs {
|
||||
if match(rc, glabel, gtarget, hasRType) {
|
||||
result = append(result, rc)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func compileTypeGlob(g string) map[string]bool {
|
||||
m := map[string]bool{}
|
||||
for _, j := range strings.Split(g, ",") {
|
||||
m[strings.TrimSpace(j)] = true
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func match(rc *models.RecordConfig, glabel, gtarget glob.Glob, hasRType map[string]bool) bool {
|
||||
printer.Printf("DEBUG: match(%v, %v, %v, %v)\n", rc.NameFQDN, glabel, gtarget, hasRType)
|
||||
|
||||
// _ = glabel.Match(rc.NameFQDN)
|
||||
// _ = matchType(rc.Type, hasRType)
|
||||
// x := rc.GetTargetField()
|
||||
// _ = gtarget.Match(x)
|
||||
|
||||
if !glabel.Match(rc.NameFQDN) {
|
||||
printer.Printf("DEBUG: REJECTED LABEL: %s:%v\n", rc.NameFQDN, glabel)
|
||||
return false
|
||||
} else if !matchType(rc.Type, hasRType) {
|
||||
printer.Printf("DEBUG: REJECTED TYPE: %s:%v\n", rc.Type, hasRType)
|
||||
return false
|
||||
} else if gtarget == nil {
|
||||
return true
|
||||
} else if !gtarget.Match(rc.GetTargetField()) {
|
||||
printer.Printf("DEBUG: REJECTED TARGET: %v:%v\n", rc.GetTargetField(), gtarget)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func matchType(s string, hasRType map[string]bool) bool {
|
||||
printer.Printf("DEBUG: matchType map=%v\n", hasRType)
|
||||
if len(hasRType) == 0 {
|
||||
return true
|
||||
}
|
||||
_, ok := hasRType[s]
|
||||
return ok
|
||||
}
|
Reference in New Issue
Block a user