Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove dependency on dnscontrol #3941

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ require (
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0
github.com/IBM/go-sdk-core/v5 v5.13.4
github.com/IBM/networking-go-sdk v0.42.2
github.com/StackExchange/dnscontrol/v3 v3.31.6
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2
github.com/alecthomas/kingpin v2.2.6+incompatible
github.com/aliyun/alibaba-cloud-sdk-go v1.62.483
Expand Down Expand Up @@ -124,6 +123,7 @@ require (
github.com/google/s2a-go v0.1.4 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
Expand All @@ -145,6 +145,7 @@ require (
github.com/leodido/go-urn v1.2.3 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
Expand All @@ -166,6 +167,7 @@ require (
github.com/prometheus/procfs v0.10.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/schollz/progressbar/v3 v3.8.6 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
github.com/smartystreets/gunit v1.3.4 // indirect
github.com/sony/gobreaker v0.5.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/dnscontrol/v3 v3.31.6 h1:QIfe5mN+PveeW0DeE+M7wvWkYpeTtT3IKJdnUb94qps=
github.com/StackExchange/dnscontrol/v3 v3.31.6/go.mod h1:ySJb55bSINayq5h9sK/BePPp52yLAXXCisd0DTs9Ies=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/Yamashou/gqlgenc v0.14.0 h1:KVzUuVQKfl4Phm5Cw4yeFThDAxZoIBR9XLoK/4O1O6U=
github.com/Yamashou/gqlgenc v0.14.0/go.mod h1:+z+FRCtGrNmgTxweAUiCodOmQJLTCNtnRNAqhewf1Q8=
Expand Down
127 changes: 127 additions & 0 deletions pkg/rfc2317/arpa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
Copyright 2023 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package rfc2317

import (
"fmt"
"net"
"strconv"
"strings"
)

// CidrToInAddr converts a CIDR block into its reverse lookup (in-addr) name.
// Given "2001::/16" returns "1.0.0.2.ip6.arpa"
// Given "10.20.30.0/24" returns "30.20.10.in-addr.arpa"
// Given "10.20.30.0/25" returns "0/25.30.20.10.in-addr.arpa" (RFC2317)
func CidrToInAddr(cidr string) (string, error) {
// If the user sent an IP instead of a CIDR (i.e. no "/"), turn it
// into a CIDR by adding /32 or /128 as appropriate.
ip := net.ParseIP(cidr)
if ip != nil {
if ip.To4() != nil {
cidr = ip.String() + "/32"
// Older code used `cidr + "/32"` but that didn't work with
// "IPv4 mapped IPv6 address". ip.String() returns the IPv4
// address for all IPv4 addresses no matter how they are
// expressed internally.
} else {
cidr = cidr + "/128"
}
}

a, c, err := net.ParseCIDR(cidr)
if err != nil {
return "", err
}
base, err := reverseaddr(a.String())
if err != nil {
return "", err
}
base = strings.TrimRight(base, ".")
if !a.Equal(c.IP) {
return "", fmt.Errorf("CIDR %v has 1 bits beyond the mask", cidr)
}

bits, total := c.Mask.Size()
var toTrim int
if bits == 0 {
return "", fmt.Errorf("cannot use /0 in reverse CIDR")
}

// Handle IPv4 "Classless in-addr.arpa delegation" RFC2317:
if total == 32 && bits >= 25 && bits < 32 {
// first address / netmask . Class-b-arpa.
fparts := strings.Split(c.IP.String(), ".")
first := fparts[3]
bparts := strings.SplitN(base, ".", 2)
return fmt.Sprintf("%s/%d.%s", first, bits, bparts[1]), nil
}

// Handle IPv4 Class-full and IPv6:
if total == 32 {
if bits%8 != 0 {
return "", fmt.Errorf("IPv4 mask must be multiple of 8 bits")
}
toTrim = (total - bits) / 8
} else if total == 128 {
if bits%4 != 0 {
return "", fmt.Errorf("IPv6 mask must be multiple of 4 bits")
}
toTrim = (total - bits) / 4
} else {
return "", fmt.Errorf("invalid address (not IPv4 or IPv6): %v", cidr)
}

parts := strings.SplitN(base, ".", toTrim+1)
return parts[len(parts)-1], nil
}

// copied from go source.
// https://github.com/golang/go/blob/38b2c06e144c6ea7087c575c76c66e41265ae0b7/src/net/dnsclient.go#L26C1-L51C1
// The go source does not export this function so we copy it here.

// reverseaddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
// address addr suitable for rDNS (PTR) record lookup or an error if it fails
// to parse the IP address.
func reverseaddr(addr string) (arpa string, err error) {
ip := net.ParseIP(addr)
if ip == nil {
return "", &net.DNSError{Err: "unrecognized address", Name: addr}
}
if ip.To4() != nil {
return Uitoa(uint(ip[15])) + "." + Uitoa(uint(ip[14])) + "." + Uitoa(uint(ip[13])) + "." + Uitoa(uint(ip[12])) + ".in-addr.arpa.", nil
}
// Must be IPv6
buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
// Add it, in reverse, to the buffer
for i := len(ip) - 1; i >= 0; i-- {
v := ip[i]
buf = append(buf, hexDigit[v&0xF],
'.',
hexDigit[v>>4],
'.')
}
// Append "ip6.arpa." and return (buf already has the final .)
buf = append(buf, "ip6.arpa."...)
return string(buf), nil
}

const hexDigit = "0123456789abcdef"

func Uitoa(val uint) string {
return strconv.FormatInt(int64(val), 10)
}
129 changes: 129 additions & 0 deletions pkg/rfc2317/arpa_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
Copyright 2023 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package rfc2317

import (
"fmt"
"testing"
)

func TestCidrToInAddr(t *testing.T) {
var tests = []struct {
in string
out string
errmsg string
}{

{"174.136.107.0/24", "107.136.174.in-addr.arpa", ""},
{"174.136.107.1/24", "107.136.174.in-addr.arpa", "CIDR 174.136.107.1/24 has 1 bits beyond the mask"},

{"174.136.0.0/16", "136.174.in-addr.arpa", ""},
{"174.136.43.0/16", "136.174.in-addr.arpa", "CIDR 174.136.43.0/16 has 1 bits beyond the mask"},

{"174.0.0.0/8", "174.in-addr.arpa", ""},
{"174.136.43.0/8", "174.in-addr.arpa", "CIDR 174.136.43.0/8 has 1 bits beyond the mask"},
{"174.136.0.44/8", "174.in-addr.arpa", "CIDR 174.136.0.44/8 has 1 bits beyond the mask"},
{"174.136.45.45/8", "174.in-addr.arpa", "CIDR 174.136.45.45/8 has 1 bits beyond the mask"},

{"2001::/16", "1.0.0.2.ip6.arpa", ""},
{"2001:0db8:0123:4567:89ab:cdef:1234:5670/124", "7.6.5.4.3.2.1.f.e.d.c.b.a.9.8.7.6.5.4.3.2.1.0.8.b.d.0.1.0.0.2.ip6.arpa", ""},

{"174.136.107.14/32", "14.107.136.174.in-addr.arpa", ""},
{"2001:0db8:0123:4567:89ab:cdef:1234:5678/128", "8.7.6.5.4.3.2.1.f.e.d.c.b.a.9.8.7.6.5.4.3.2.1.0.8.b.d.0.1.0.0.2.ip6.arpa", ""},

// IPv4 "Classless in-addr.arpa delegation" RFC2317.
// From examples in the RFC:
{"192.0.2.0/25", "0/25.2.0.192.in-addr.arpa", ""},
{"192.0.2.128/26", "128/26.2.0.192.in-addr.arpa", ""},
{"192.0.2.192/26", "192/26.2.0.192.in-addr.arpa", ""},
// All the base cases:
{"174.1.0.0/25", "0/25.0.1.174.in-addr.arpa", ""},
{"174.1.0.0/26", "0/26.0.1.174.in-addr.arpa", ""},
{"174.1.0.0/27", "0/27.0.1.174.in-addr.arpa", ""},
{"174.1.0.0/28", "0/28.0.1.174.in-addr.arpa", ""},
{"174.1.0.0/29", "0/29.0.1.174.in-addr.arpa", ""},
{"174.1.0.0/30", "0/30.0.1.174.in-addr.arpa", ""},
{"174.1.0.0/31", "0/31.0.1.174.in-addr.arpa", ""},
// /25 (all cases)
{"174.1.0.0/25", "0/25.0.1.174.in-addr.arpa", ""},
{"174.1.0.128/25", "128/25.0.1.174.in-addr.arpa", ""},
// /26 (all cases)
{"174.1.0.0/26", "0/26.0.1.174.in-addr.arpa", ""},
{"174.1.0.64/26", "64/26.0.1.174.in-addr.arpa", ""},
{"174.1.0.128/26", "128/26.0.1.174.in-addr.arpa", ""},
{"174.1.0.192/26", "192/26.0.1.174.in-addr.arpa", ""},
// /27 (all cases)
{"174.1.0.0/27", "0/27.0.1.174.in-addr.arpa", ""},
{"174.1.0.32/27", "32/27.0.1.174.in-addr.arpa", ""},
{"174.1.0.64/27", "64/27.0.1.174.in-addr.arpa", ""},
{"174.1.0.96/27", "96/27.0.1.174.in-addr.arpa", ""},
{"174.1.0.128/27", "128/27.0.1.174.in-addr.arpa", ""},
{"174.1.0.160/27", "160/27.0.1.174.in-addr.arpa", ""},
{"174.1.0.192/27", "192/27.0.1.174.in-addr.arpa", ""},
{"174.1.0.224/27", "224/27.0.1.174.in-addr.arpa", ""},
// /28 (first 2, last 2)
{"174.1.0.0/28", "0/28.0.1.174.in-addr.arpa", ""},
{"174.1.0.16/28", "16/28.0.1.174.in-addr.arpa", ""},
{"174.1.0.224/28", "224/28.0.1.174.in-addr.arpa", ""},
{"174.1.0.240/28", "240/28.0.1.174.in-addr.arpa", ""},
// /29 (first 2 cases)
{"174.1.0.0/29", "0/29.0.1.174.in-addr.arpa", ""},
{"174.1.0.8/29", "8/29.0.1.174.in-addr.arpa", ""},
// /30 (first 2 cases)
{"174.1.0.0/30", "0/30.0.1.174.in-addr.arpa", ""},
{"174.1.0.4/30", "4/30.0.1.174.in-addr.arpa", ""},
// /31 (first 2 cases)
{"174.1.0.0/31", "0/31.0.1.174.in-addr.arpa", ""},
{"174.1.0.2/31", "2/31.0.1.174.in-addr.arpa", ""},

// IPv4-mapped IPv6 addresses:
{"::ffff:174.136.107.15", "15.107.136.174.in-addr.arpa", ""},

// Error Cases:
{"0.0.0.0/0", "", "cannot use /0 in reverse CIDR"},
{"2001::/0", "", "CIDR 2001::/0 has 1 bits beyond the mask"},
{"4.5/16", "", "invalid CIDR address: 4.5/16"},
{"foo.com", "", "invalid CIDR address: foo.com"},
}
for i, tst := range tests {
t.Run(fmt.Sprintf("%d--%s", i, tst.in), func(t *testing.T) {
d, err := CidrToInAddr(tst.in)

if tst.errmsg == "" {
// We DO NOT expect an error.
if err != nil {
// ...but we got one.
t.Errorf("Expected '%s' but got ERROR('%s')", tst.out, err)
} else if (tst.errmsg == "") && d != tst.out {
// but the expected output was wrong
t.Errorf("Expected '%s' but got '%s'", tst.out, d)
}
} else {
// We DO expect an error.
if err == nil {
// ...but we didn't get one.
t.Errorf("Expected ERROR('%s') but got result '%s'", tst.errmsg, d)
}
if err.Error() != tst.errmsg {
TomOnTime marked this conversation as resolved.
Show resolved Hide resolved
// ...but not the right error.
t.Errorf("Expected ERROR('%s') but got ERROR('%s')", tst.errmsg, err)
}

}
})
}
}
4 changes: 2 additions & 2 deletions provider/infoblox/infoblox.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ import (
"strconv"
"strings"

"github.com/StackExchange/dnscontrol/v3/pkg/transform"
ibclient "github.com/infobloxopen/infoblox-go-client/v2"
"github.com/sirupsen/logrus"

"sigs.k8s.io/external-dns/endpoint"
"sigs.k8s.io/external-dns/pkg/rfc2317"
"sigs.k8s.io/external-dns/plan"
"sigs.k8s.io/external-dns/provider"
)
Expand Down Expand Up @@ -284,7 +284,7 @@ func (p *ProviderConfig) Records(ctx context.Context) (endpoints []*endpoint.End
// infoblox doesn't accept reverse zone's fqdn, and instead expects .in-addr.arpa zone
// so convert our zone fqdn (if it is a correct cidr block) into in-addr.arpa address and pass that into infoblox
// example: 10.196.38.0/24 becomes 38.196.10.in-addr.arpa
arpaZone, err := transform.ReverseDomainName(zone.Fqdn)
arpaZone, err := rfc2317.CidrToInAddr(zone.Fqdn)
if err == nil {
var resP []ibclient.RecordPTR
objP := ibclient.NewEmptyRecordPTR()
Expand Down
Loading