hub v0.137.0 source + burn-down round 2 in felhom.eu: R-277 R-581 R-600 R-544 R-855 R-134 R-92 R-292 R-599 R-725 R-728 (hub), R-819 R-857 R-555 R-364 R-587 (gates/tools), R-571 R-129 R-124-runbook (docs); 28 rows closed incl. catalog + agent v0.147.0 rows, R-350 merged into R-132, R-888 opened, R-887 mechanism (249 -> 222)
gates / gates (push) Successful in 2m3s
gates / gates (push) Successful in 2m3s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -113,11 +113,9 @@ type rule struct {
|
||||
}
|
||||
|
||||
func resolveZone(apiToken, domain string) (string, error) {
|
||||
// Try exact domain first, then parent domain
|
||||
for _, name := range []string{domain, parentDomain(domain)} {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
// Try the exact domain first, then every parent down to two labels (R-134: the controller's
|
||||
// GetZoneID strips progressively; stripping ONE label missed the zone for a deeper name).
|
||||
for _, name := range zoneCandidates(domain) {
|
||||
resp, err := cfDo(apiToken, "GET", fmt.Sprintf("/zones?name=%s&status=active", name), nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -133,12 +131,27 @@ func resolveZone(apiToken, domain string) (string, error) {
|
||||
return "", fmt.Errorf("no active zone found for %s", domain)
|
||||
}
|
||||
|
||||
func parentDomain(domain string) string {
|
||||
parts := strings.SplitN(domain, ".", 2)
|
||||
if len(parts) < 2 {
|
||||
return ""
|
||||
// zoneCandidates lists the names a zone lookup tries, most specific first: the domain itself, then each
|
||||
// parent that still has at least two labels ("a.b.felhom.eu" → a.b.felhom.eu, b.felhom.eu, felhom.eu).
|
||||
// A bare TLD is never tried — no Cloudflare zone is named "eu". Pinned by TestZoneCandidates.
|
||||
func zoneCandidates(domain string) []string {
|
||||
domain = strings.Trim(strings.TrimSpace(domain), ".")
|
||||
if domain == "" {
|
||||
return nil
|
||||
}
|
||||
return parts[1]
|
||||
out := []string{domain}
|
||||
for name := domain; ; {
|
||||
i := strings.IndexByte(name, '.')
|
||||
if i < 0 {
|
||||
break
|
||||
}
|
||||
name = name[i+1:]
|
||||
if !strings.Contains(name, ".") {
|
||||
break // a single label (the TLD) is not a zone
|
||||
}
|
||||
out = append(out, name)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func findFirewallRuleset(apiToken, zoneID string) (string, error) {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package cloudflare
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// R-134: the hub's zone lookup must reach the zone for a name more than one label below it, as the
|
||||
// controller's does. Stripping ONE label tried only [a.b.felhom.eu b.felhom.eu] and never felhom.eu,
|
||||
// so the geo-unblock no-op'd with "no active zone found".
|
||||
func TestZoneCandidates(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
in string
|
||||
want []string
|
||||
}{
|
||||
{"a.b.felhom.eu", []string{"a.b.felhom.eu", "b.felhom.eu", "felhom.eu"}},
|
||||
{"demo.felhom.eu", []string{"demo.felhom.eu", "felhom.eu"}},
|
||||
{"felhom.eu", []string{"felhom.eu"}},
|
||||
{"x.y.z.example.co", []string{"x.y.z.example.co", "y.z.example.co", "z.example.co", "example.co"}},
|
||||
{"", nil},
|
||||
{"localhost", []string{"localhost"}},
|
||||
} {
|
||||
if got := zoneCandidates(tc.in); !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("zoneCandidates(%q) = %v, want %v", tc.in, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user