mirror of
https://github.com/coredns/coredns.git
synced 2025-12-12 13:25:11 -05:00
plugin/geoip: Upgrade to geoip2-golang v2 (#7732)
Signed-off-by: Eric Case <eric.case@gmail.com>
This commit is contained in:
9
go.mod
9
go.mod
@@ -29,11 +29,12 @@ require (
|
|||||||
github.com/opentracing/opentracing-go v1.2.0
|
github.com/opentracing/opentracing-go v1.2.0
|
||||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0
|
github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0
|
||||||
github.com/openzipkin/zipkin-go v0.4.3
|
github.com/openzipkin/zipkin-go v0.4.3
|
||||||
github.com/oschwald/geoip2-golang v1.13.0
|
github.com/oschwald/geoip2-golang/v2 v2.0.1
|
||||||
github.com/prometheus/client_golang v1.23.0
|
github.com/prometheus/client_golang v1.23.0
|
||||||
github.com/prometheus/client_model v0.6.2
|
github.com/prometheus/client_model v0.6.2
|
||||||
github.com/prometheus/common v0.67.4
|
github.com/prometheus/common v0.67.4
|
||||||
github.com/quic-go/quic-go v0.57.1
|
github.com/quic-go/quic-go v0.57.0
|
||||||
|
github.com/stretchr/testify v1.11.1
|
||||||
go.etcd.io/etcd/api/v3 v3.6.6
|
go.etcd.io/etcd/api/v3 v3.6.6
|
||||||
go.etcd.io/etcd/client/v3 v3.6.6
|
go.etcd.io/etcd/client/v3 v3.6.6
|
||||||
go.uber.org/automaxprocs v1.6.0
|
go.uber.org/automaxprocs v1.6.0
|
||||||
@@ -49,8 +50,6 @@ require (
|
|||||||
sigs.k8s.io/mcs-api v0.3.0
|
sigs.k8s.io/mcs-api v0.3.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/stretchr/testify v1.11.1
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/auth v0.17.0 // indirect
|
cloud.google.com/go/auth v0.17.0 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||||
@@ -142,7 +141,7 @@ require (
|
|||||||
github.com/onsi/ginkgo/v2 v2.22.1 // indirect
|
github.com/onsi/ginkgo/v2 v2.22.1 // indirect
|
||||||
github.com/onsi/gomega v1.36.2 // indirect
|
github.com/onsi/gomega v1.36.2 // indirect
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect
|
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect
|
||||||
github.com/oschwald/maxminddb-golang v1.13.0 // indirect
|
github.com/oschwald/maxminddb-golang/v2 v2.1.1 // indirect
|
||||||
github.com/outcaste-io/ristretto v0.2.3 // indirect
|
github.com/outcaste-io/ristretto v0.2.3 // indirect
|
||||||
github.com/philhofer/fwd v1.2.0 // indirect
|
github.com/philhofer/fwd v1.2.0 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
|||||||
12
go.sum
12
go.sum
@@ -290,10 +290,10 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0 h1:uhcF5Jd7rP9DVEL10S
|
|||||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0/go.mod h1:+oCZ5GXXr7KPI/DNOQORPTq5AWHfALJj9c72b0+YsEY=
|
github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0/go.mod h1:+oCZ5GXXr7KPI/DNOQORPTq5AWHfALJj9c72b0+YsEY=
|
||||||
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
|
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
|
||||||
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
||||||
github.com/oschwald/geoip2-golang v1.13.0 h1:Q44/Ldc703pasJeP5V9+aFSZFmBN7DKHbNsSFzQATJI=
|
github.com/oschwald/geoip2-golang/v2 v2.0.1 h1:YcYoG/L+gmSfk7AlToTmoL0JvblNyhGC8NyVhwDzzi8=
|
||||||
github.com/oschwald/geoip2-golang v1.13.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
|
github.com/oschwald/geoip2-golang/v2 v2.0.1/go.mod h1:qdVmcPgrTJ4q2eP9tHq/yldMTdp2VMr33uVdFbHBiBc=
|
||||||
github.com/oschwald/maxminddb-golang v1.13.0 h1:R8xBorY71s84yO06NgTmQvqvTvlS/bnYZrrWX1MElnU=
|
github.com/oschwald/maxminddb-golang/v2 v2.1.1 h1:lA8FH0oOrM4u7mLvowq8IT6a3Q/qEnqRzLQn9eH5ojc=
|
||||||
github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o=
|
github.com/oschwald/maxminddb-golang/v2 v2.1.1/go.mod h1:PLdx6PR+siSIoXqqy7C7r3SB3KZnhxWr1Dp6g0Hacl8=
|
||||||
github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0=
|
github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0=
|
||||||
github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac=
|
github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac=
|
||||||
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
||||||
@@ -321,8 +321,8 @@ github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++
|
|||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
||||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||||
github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI10=
|
github.com/quic-go/quic-go v0.57.0 h1:AsSSrrMs4qI/hLrKlTH/TGQeTMY0ib1pAOX7vA3AdqE=
|
||||||
github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s=
|
github.com/quic-go/quic-go v0.57.0/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s=
|
||||||
github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3 h1:4+LEVOB87y175cLJC/mbsgKmoDOjrBldtXvioEy96WY=
|
github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3 h1:4+LEVOB87y175cLJC/mbsgKmoDOjrBldtXvioEy96WY=
|
||||||
github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3/go.mod h1:vl5+MqJ1nBINuSsUI2mGgH79UweUT/B5Fy8857PqyyI=
|
github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3/go.mod h1:vl5+MqJ1nBINuSsUI2mGgH79UweUT/B5Fy8857PqyyI=
|
||||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
|
|||||||
@@ -156,3 +156,7 @@ A limited set of fields will be exported as labels, all values are stored using
|
|||||||
| NA | North America |
|
| NA | North America |
|
||||||
| OC | Oceania |
|
| OC | Oceania |
|
||||||
| SA | South America |
|
| SA | South America |
|
||||||
|
|
||||||
|
## Notable changes
|
||||||
|
|
||||||
|
- In CoreDNS v1.13.2, the `geoip` plugin was upgraded to use [`oschwald/geoip2-golang/v2`](https://github.com/oschwald/geoip2-golang/blob/main/MIGRATION.md), the Go library that reads and parses [`.mmdb`](https://maxmind.github.io/MaxMind-DB/) databases. It has a small, but possibly-breaking change, where the `Location.Latitude` and `Location.Longitude` structs changed from value types to pointers (`float64` → `*float64`). In `oschwald/geoip2-golang` v1, missing coordinates returned "0" (which is a [valid location](https://en.wikipedia.org/wiki/Null_Island)), and in v2 they now return an empty string "".
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/coredns/coredns/plugin/metadata"
|
"github.com/coredns/coredns/plugin/metadata"
|
||||||
|
|
||||||
"github.com/oschwald/geoip2-golang"
|
"github.com/oschwald/geoip2-golang/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g GeoIP) setASNMetadata(ctx context.Context, data *geoip2.ASN) {
|
func (g GeoIP) setASNMetadata(ctx context.Context, data *geoip2.ASN) {
|
||||||
|
|||||||
@@ -7,27 +7,25 @@ import (
|
|||||||
|
|
||||||
"github.com/coredns/coredns/plugin/metadata"
|
"github.com/coredns/coredns/plugin/metadata"
|
||||||
|
|
||||||
"github.com/oschwald/geoip2-golang"
|
"github.com/oschwald/geoip2-golang/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultLang = "en"
|
|
||||||
|
|
||||||
func (g GeoIP) setCityMetadata(ctx context.Context, data *geoip2.City) {
|
func (g GeoIP) setCityMetadata(ctx context.Context, data *geoip2.City) {
|
||||||
// Set labels for city, country and continent names.
|
// Set labels for city, country and continent names.
|
||||||
cityName := data.City.Names[defaultLang]
|
cityName := data.City.Names.English
|
||||||
metadata.SetValueFunc(ctx, pluginName+"/city/name", func() string {
|
metadata.SetValueFunc(ctx, pluginName+"/city/name", func() string {
|
||||||
return cityName
|
return cityName
|
||||||
})
|
})
|
||||||
countryName := data.Country.Names[defaultLang]
|
countryName := data.Country.Names.English
|
||||||
metadata.SetValueFunc(ctx, pluginName+"/country/name", func() string {
|
metadata.SetValueFunc(ctx, pluginName+"/country/name", func() string {
|
||||||
return countryName
|
return countryName
|
||||||
})
|
})
|
||||||
continentName := data.Continent.Names[defaultLang]
|
continentName := data.Continent.Names.English
|
||||||
metadata.SetValueFunc(ctx, pluginName+"/continent/name", func() string {
|
metadata.SetValueFunc(ctx, pluginName+"/continent/name", func() string {
|
||||||
return continentName
|
return continentName
|
||||||
})
|
})
|
||||||
|
|
||||||
countryCode := data.Country.IsoCode
|
countryCode := data.Country.ISOCode
|
||||||
metadata.SetValueFunc(ctx, pluginName+"/country/code", func() string {
|
metadata.SetValueFunc(ctx, pluginName+"/country/code", func() string {
|
||||||
return countryCode
|
return countryCode
|
||||||
})
|
})
|
||||||
@@ -37,7 +35,7 @@ func (g GeoIP) setCityMetadata(ctx context.Context, data *geoip2.City) {
|
|||||||
// a comma separated string, with the exact values provided by the database, even if those were empty strings.
|
// a comma separated string, with the exact values provided by the database, even if those were empty strings.
|
||||||
subdivisionCodes := make([]string, 0, len(data.Subdivisions))
|
subdivisionCodes := make([]string, 0, len(data.Subdivisions))
|
||||||
for _, sub := range data.Subdivisions {
|
for _, sub := range data.Subdivisions {
|
||||||
subdivisionCodes = append(subdivisionCodes, sub.IsoCode)
|
subdivisionCodes = append(subdivisionCodes, sub.ISOCode)
|
||||||
}
|
}
|
||||||
metadata.SetValueFunc(ctx, pluginName+"/subdivisions/code", func() string {
|
metadata.SetValueFunc(ctx, pluginName+"/subdivisions/code", func() string {
|
||||||
return strings.Join(subdivisionCodes, ",")
|
return strings.Join(subdivisionCodes, ",")
|
||||||
@@ -52,11 +50,17 @@ func (g GeoIP) setCityMetadata(ctx context.Context, data *geoip2.City) {
|
|||||||
return continentCode
|
return continentCode
|
||||||
})
|
})
|
||||||
|
|
||||||
latitude := strconv.FormatFloat(data.Location.Latitude, 'f', -1, 64)
|
var latitude string
|
||||||
|
if data.Location.Latitude != nil {
|
||||||
|
latitude = strconv.FormatFloat(*data.Location.Latitude, 'f', -1, 64)
|
||||||
|
}
|
||||||
metadata.SetValueFunc(ctx, pluginName+"/latitude", func() string {
|
metadata.SetValueFunc(ctx, pluginName+"/latitude", func() string {
|
||||||
return latitude
|
return latitude
|
||||||
})
|
})
|
||||||
longitude := strconv.FormatFloat(data.Location.Longitude, 'f', -1, 64)
|
var longitude string
|
||||||
|
if data.Location.Longitude != nil {
|
||||||
|
longitude = strconv.FormatFloat(*data.Location.Longitude, 'f', -1, 64)
|
||||||
|
}
|
||||||
metadata.SetValueFunc(ctx, pluginName+"/longitude", func() string {
|
metadata.SetValueFunc(ctx, pluginName+"/longitude", func() string {
|
||||||
return longitude
|
return longitude
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package geoip
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/coredns/coredns/request"
|
"github.com/coredns/coredns/request"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/oschwald/geoip2-golang"
|
"github.com/oschwald/geoip2-golang/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = clog.NewWithPlugin(pluginName)
|
var log = clog.NewWithPlugin(pluginName)
|
||||||
@@ -37,7 +37,7 @@ const (
|
|||||||
asn
|
asn
|
||||||
)
|
)
|
||||||
|
|
||||||
var probingIP = net.ParseIP("127.0.0.1")
|
var probingIP = netip.MustParseAddr("127.0.0.1")
|
||||||
|
|
||||||
func newGeoIP(dbPath string, edns0 bool) (*GeoIP, error) {
|
func newGeoIP(dbPath string, edns0 bool) (*GeoIP, error) {
|
||||||
reader, err := geoip2.Open(dbPath)
|
reader, err := geoip2.Open(dbPath)
|
||||||
@@ -80,13 +80,22 @@ func (g GeoIP) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
|
|||||||
// Metadata implements the metadata.Provider Interface in the metadata plugin, and is used to store
|
// Metadata implements the metadata.Provider Interface in the metadata plugin, and is used to store
|
||||||
// the data associated with the source IP of every request.
|
// the data associated with the source IP of every request.
|
||||||
func (g GeoIP) Metadata(ctx context.Context, state request.Request) context.Context {
|
func (g GeoIP) Metadata(ctx context.Context, state request.Request) context.Context {
|
||||||
srcIP := net.ParseIP(state.IP())
|
srcIP, err := netip.ParseAddr(state.IP())
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("Failed to parse source IP %q: %v", state.IP(), err)
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
if g.edns0 {
|
if g.edns0 {
|
||||||
if o := state.Req.IsEdns0(); o != nil {
|
if o := state.Req.IsEdns0(); o != nil {
|
||||||
for _, s := range o.Option {
|
for _, s := range o.Option {
|
||||||
if e, ok := s.(*dns.EDNS0_SUBNET); ok {
|
if e, ok := s.(*dns.EDNS0_SUBNET); ok {
|
||||||
srcIP = e.Address
|
// e.Address is still a net.IP type
|
||||||
|
if addr, ok := netip.AddrFromSlice(e.Address); ok {
|
||||||
|
srcIP = addr
|
||||||
|
} else {
|
||||||
|
log.Debugf("Failed to parse EDNS0 subnet address %v", e.Address)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package geoip
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -19,7 +18,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestProbingIP(t *testing.T) {
|
func TestProbingIP(t *testing.T) {
|
||||||
if probingIP == nil {
|
if !probingIP.IsValid() {
|
||||||
t.Fatalf("Invalid probing IP: %q", probingIP)
|
t.Fatalf("Invalid probing IP: %q", probingIP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,19 +95,4 @@ func TestGeoIPParse(t *testing.T) {
|
|||||||
t.Errorf("Test %d: expected db type %d not found, database file provides %d", i, test.expectedDBType, geoIP.db.provides)
|
t.Errorf("Test %d: expected db type %d not found, database file provides %d", i, test.expectedDBType, geoIP.db.provides)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set nil probingIP to test unexpected validate error()
|
|
||||||
defer func(ip net.IP) { probingIP = ip }(probingIP)
|
|
||||||
probingIP = nil
|
|
||||||
|
|
||||||
c = caddy.NewTestController("dns", fmt.Sprintf("%s %s\n", pluginName, cityDBPath))
|
|
||||||
_, err := geoipParse(c)
|
|
||||||
if err != nil {
|
|
||||||
expectedErr := "unexpected failure looking up database"
|
|
||||||
if !strings.Contains(err.Error(), expectedErr) {
|
|
||||||
t.Errorf("expected error to contain: %s", expectedErr)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Errorf("with a nil probingIP test is expected to fail")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user