add initial Go implementation of arcline-audit
Implements the full site health auditor with four check groups: - SSL/TLS (certificate validity, expiry, chain, TLS version, ciphers) - HTTP (redirect chain, security headers, response time) - DNS (A/AAAA, MX, SPF, DKIM, DMARC, DNSSEC) - Infrastructure (CDN detection, common port probes) Includes CLI with --checks filter, --json and --out flags, cross-compile Makefile, and GitLab CI pipeline. Signed-off-by: Blake Ridgway <blake@blakeridgway.com>
This commit is contained in:
111
internal/types/types.go
Normal file
111
internal/types/types.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package types
|
||||
|
||||
import "time"
|
||||
|
||||
// Status represents the result status of a single check.
|
||||
type Status string
|
||||
|
||||
const (
|
||||
StatusOK Status = "OK"
|
||||
StatusWarn Status = "WARN"
|
||||
StatusFail Status = "FAIL"
|
||||
StatusInfo Status = "INFO"
|
||||
)
|
||||
|
||||
// CheckResult represents the outcome of a single audit check.
|
||||
type CheckResult struct {
|
||||
Status Status `json:"status"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// SSLResult holds all SSL/TLS check results.
|
||||
type SSLResult struct {
|
||||
Checks []CheckResult `json:"checks"`
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
Expiry time.Time `json:"expiry,omitempty"`
|
||||
DaysLeft int `json:"days_left,omitempty"`
|
||||
TLSVersion string `json:"tls_version,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPResult holds all HTTP check results.
|
||||
type HTTPResult struct {
|
||||
Checks []CheckResult `json:"checks"`
|
||||
ResponseTime time.Duration `json:"response_time_ms"`
|
||||
FinalURL string `json:"final_url,omitempty"`
|
||||
RedirectHops int `json:"redirect_hops,omitempty"`
|
||||
}
|
||||
|
||||
// DNSResult holds all DNS check results.
|
||||
type DNSResult struct {
|
||||
Checks []CheckResult `json:"checks"`
|
||||
}
|
||||
|
||||
// InfraResult holds all infrastructure check results.
|
||||
type InfraResult struct {
|
||||
Checks []CheckResult `json:"checks"`
|
||||
ASN string `json:"asn,omitempty"`
|
||||
Org string `json:"org,omitempty"`
|
||||
CDN string `json:"cdn,omitempty"`
|
||||
}
|
||||
|
||||
// AuditResult is the top-level result containing all check sections.
|
||||
type AuditResult struct {
|
||||
Domain string `json:"domain"`
|
||||
Time time.Time `json:"time"`
|
||||
SSL SSLResult `json:"ssl"`
|
||||
HTTP HTTPResult `json:"http"`
|
||||
DNS DNSResult `json:"dns"`
|
||||
Infra InfraResult `json:"infra"`
|
||||
}
|
||||
|
||||
// CheckSet is a bitmask of check categories for filtering.
|
||||
type CheckSet int
|
||||
|
||||
const (
|
||||
CheckSSL CheckSet = 1 << iota
|
||||
CheckHTTP
|
||||
CheckDNS
|
||||
CheckInfra
|
||||
CheckAll = CheckSSL | CheckHTTP | CheckDNS | CheckInfra
|
||||
)
|
||||
|
||||
// ParseChecks parses a comma-separated list of check names into a CheckSet.
|
||||
func ParseChecks(s string) CheckSet {
|
||||
if s == "" || s == "all" {
|
||||
return CheckAll
|
||||
}
|
||||
var cs CheckSet
|
||||
m := map[string]CheckSet{
|
||||
"ssl": CheckSSL,
|
||||
"http": CheckHTTP,
|
||||
"dns": CheckDNS,
|
||||
"infra": CheckInfra,
|
||||
}
|
||||
for _, name := range splitCSV(s) {
|
||||
if v, ok := m[name]; ok {
|
||||
cs |= v
|
||||
}
|
||||
}
|
||||
if cs == 0 {
|
||||
return CheckAll
|
||||
}
|
||||
return cs
|
||||
}
|
||||
|
||||
func splitCSV(s string) []string {
|
||||
var parts []string
|
||||
start := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == ',' {
|
||||
if i > start {
|
||||
parts = append(parts, s[start:i])
|
||||
}
|
||||
start = i + 1
|
||||
}
|
||||
}
|
||||
if start < len(s) {
|
||||
parts = append(parts, s[start:])
|
||||
}
|
||||
return parts
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user