Initial commit
This commit is contained in:
commit
7c6f8ab8a7
21 changed files with 1891 additions and 0 deletions
115
checker/collect.go
Normal file
115
checker/collect.go
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package checker
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseGrokOutput decodes the JSON produced by `dnsviz grok` into a typed
|
||||
// map of zone analyses. The returned Order slice lists zone FQDNs sorted
|
||||
// from the most-specific (queried name) up to the root, matching DNSViz's
|
||||
// natural chain order.
|
||||
func ParseGrokOutput(raw []byte) (map[string]ZoneAnalysis, []string, error) {
|
||||
var top map[string]json.RawMessage
|
||||
if err := json.Unmarshal(raw, &top); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
out := make(map[string]ZoneAnalysis, len(top))
|
||||
for k, v := range top {
|
||||
out[k] = decodeZone(v)
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(out))
|
||||
for k := range out {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
return labelDepth(keys[i]) > labelDepth(keys[j])
|
||||
})
|
||||
return out, keys, nil
|
||||
}
|
||||
|
||||
func decodeZone(raw json.RawMessage) ZoneAnalysis {
|
||||
var z ZoneAnalysis
|
||||
var m map[string]json.RawMessage
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
var s string
|
||||
if json.Unmarshal(raw, &s) == nil {
|
||||
z.Status = s
|
||||
}
|
||||
return z
|
||||
}
|
||||
|
||||
if v, ok := m["status"]; ok {
|
||||
_ = json.Unmarshal(v, &z.Status)
|
||||
}
|
||||
z.Errors = decodeFindings(m["errors"])
|
||||
z.Warnings = decodeFindings(m["warnings"])
|
||||
|
||||
delete(m, "status")
|
||||
delete(m, "errors")
|
||||
delete(m, "warnings")
|
||||
if len(m) > 0 {
|
||||
z.Extra = make(map[string]any, len(m))
|
||||
for k, v := range m {
|
||||
var any any
|
||||
_ = json.Unmarshal(v, &any)
|
||||
z.Extra[k] = any
|
||||
}
|
||||
}
|
||||
return z
|
||||
}
|
||||
|
||||
func decodeFindings(raw json.RawMessage) []Finding {
|
||||
if len(raw) == 0 {
|
||||
return nil
|
||||
}
|
||||
var arr []map[string]any
|
||||
if err := json.Unmarshal(raw, &arr); err != nil {
|
||||
var strs []string
|
||||
if json.Unmarshal(raw, &strs) == nil {
|
||||
out := make([]Finding, 0, len(strs))
|
||||
for _, s := range strs {
|
||||
out = append(out, Finding{Description: s})
|
||||
}
|
||||
return out
|
||||
}
|
||||
return nil
|
||||
}
|
||||
out := make([]Finding, 0, len(arr))
|
||||
for _, item := range arr {
|
||||
f := Finding{}
|
||||
if s, ok := item["code"].(string); ok {
|
||||
f.Code = s
|
||||
}
|
||||
if s, ok := item["description"].(string); ok && s != "" {
|
||||
f.Description = s
|
||||
} else if s, ok := item["message"].(string); ok && s != "" {
|
||||
f.Description = s
|
||||
} else {
|
||||
b, _ := json.Marshal(item)
|
||||
f.Description = string(b)
|
||||
}
|
||||
if servers, ok := item["servers"].([]any); ok {
|
||||
for _, srv := range servers {
|
||||
if s, ok := srv.(string); ok {
|
||||
f.Servers = append(f.Servers, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
out = append(out, f)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func labelDepth(zone string) int {
|
||||
z := strings.TrimSuffix(zone, ".")
|
||||
if z == "" {
|
||||
return 0
|
||||
}
|
||||
return strings.Count(z, ".") + 1
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue