Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
a2fc7786f7 | |||
abbff86db3 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,2 @@
|
|||||||
geoipapi
|
./geoipapi
|
||||||
*~
|
*~
|
77
client/geoipapi/geoipclient.go
Normal file
77
client/geoipapi/geoipclient.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package geoipapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/oschwald/geoip2-golang"
|
||||||
|
"go.opentelemetry.io/otel"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
)
|
||||||
|
|
||||||
|
var client http.Client
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
netTransport := &http.Transport{
|
||||||
|
Dial: (&net.Dialer{
|
||||||
|
Timeout: 5 * time.Second,
|
||||||
|
}).Dial,
|
||||||
|
TLSHandshakeTimeout: 5 * time.Second,
|
||||||
|
}
|
||||||
|
client = http.Client{
|
||||||
|
Timeout: time.Second * 10,
|
||||||
|
Transport: netTransport,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCity(ctx context.Context, ip netip.Addr) (*geoip2.City, error) {
|
||||||
|
ctx, span := otel.Tracer("geoipapi").Start(ctx, "geoip.GetCity")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
baseURL := os.Getenv("geoip_service")
|
||||||
|
if len(baseURL) == 0 {
|
||||||
|
return nil, fmt.Errorf("geoip_service not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
q := url.Values{}
|
||||||
|
q.Set("ip", ip.String())
|
||||||
|
|
||||||
|
span.SetAttributes(attribute.String("ip", ip.String()))
|
||||||
|
|
||||||
|
reqURL, err := url.Parse(fmt.Sprintf("http://%s/api/json?%s", baseURL, q.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
span.RecordError(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, "GET", reqURL.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
span.RecordError(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
span.RecordError(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
dec := json.NewDecoder(resp.Body)
|
||||||
|
|
||||||
|
city := geoip2.City{}
|
||||||
|
err = dec.Decode(&city)
|
||||||
|
if err != nil {
|
||||||
|
span.RecordError(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &city, nil
|
||||||
|
}
|
36
geoipapi.go
36
geoipapi.go
@@ -105,7 +105,13 @@ func setupHTTP(ctx context.Context) error {
|
|||||||
BaseContext: func(_ net.Listener) context.Context { return ctx },
|
BaseContext: func(_ net.Listener) context.Context { return ctx },
|
||||||
ReadTimeout: time.Second,
|
ReadTimeout: time.Second,
|
||||||
WriteTimeout: 10 * time.Second,
|
WriteTimeout: 10 * time.Second,
|
||||||
Handler: otelhttp.NewHandler(versionHandler(mux), "geoipapi"),
|
Handler: otelhttp.NewHandler(
|
||||||
|
versionHandler(mux),
|
||||||
|
"geoipapi",
|
||||||
|
otelhttp.WithFilter(func(r *http.Request) bool {
|
||||||
|
return r.URL.Path != "/healthz"
|
||||||
|
}),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
srvErr := make(chan error, 1)
|
srvErr := make(chan error, 1)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -122,21 +128,22 @@ func setupHTTP(ctx context.Context) error {
|
|||||||
return srv.Shutdown(context.Background())
|
return srv.Shutdown(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCityIP(ip net.IP) (*geoip2.City, error) {
|
func getCityIP(ctx context.Context, ip net.IP) (*geoip2.City, error) {
|
||||||
rdr, err := open(cityDB)
|
rdr, err := open(cityDB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
city, err := rdr.City(ip)
|
city, err := rdr.City(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error looking up %q: %s", ip, err)
|
logger.FromContext(ctx).WarnContext(ctx, "error looking up city", "ip", ip, "err", err)
|
||||||
return nil, fmt.Errorf("db lookup error")
|
return nil, fmt.Errorf("db lookup error")
|
||||||
}
|
}
|
||||||
return city, nil
|
return city, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCity(req *http.Request) (*geoip2.City, error) {
|
func getCity(req *http.Request) (*geoip2.City, error) {
|
||||||
span := trace.SpanFromContext(req.Context())
|
ctx := req.Context()
|
||||||
|
span := trace.SpanFromContext(ctx)
|
||||||
req.ParseForm()
|
req.ParseForm()
|
||||||
ipStr := req.FormValue("ip")
|
ipStr := req.FormValue("ip")
|
||||||
span.SetAttributes(attribute.String("ip", ipStr))
|
span.SetAttributes(attribute.String("ip", ipStr))
|
||||||
@@ -144,22 +151,23 @@ func getCity(req *http.Request) (*geoip2.City, error) {
|
|||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, fmt.Errorf("missing IP address")
|
return nil, fmt.Errorf("missing IP address")
|
||||||
}
|
}
|
||||||
return getCityIP(ip)
|
return getCityIP(ctx, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleJSON(w http.ResponseWriter, req *http.Request) {
|
func handleJSON(w http.ResponseWriter, req *http.Request) {
|
||||||
span := trace.SpanFromContext(req.Context())
|
ctx := req.Context()
|
||||||
|
span := trace.SpanFromContext(ctx)
|
||||||
span.SetName("/api/json")
|
span.SetName("/api/json")
|
||||||
city, err := getCity(req)
|
city, err := getCity(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("getCity error: %s", err)
|
logger.FromContext(ctx).ErrorContext(ctx, "getCity error ", "err", err)
|
||||||
http.Error(w, "data error", 500)
|
http.Error(w, "data error", 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := json.Marshal(&city)
|
b, err := json.Marshal(&city)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error marshaling JSON: %s", err)
|
logger.FromContext(ctx).ErrorContext(ctx, "error marshaling JSON", "err", err)
|
||||||
http.Error(w, "internal error", 500)
|
http.Error(w, "internal error", 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -168,12 +176,13 @@ func handleJSON(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleCountry(w http.ResponseWriter, req *http.Request) {
|
func handleCountry(w http.ResponseWriter, req *http.Request) {
|
||||||
span := trace.SpanFromContext(req.Context())
|
ctx := req.Context()
|
||||||
|
span := trace.SpanFromContext(ctx)
|
||||||
span.SetName("/api/country")
|
span.SetName("/api/country")
|
||||||
|
|
||||||
city, err := getCity(req)
|
city, err := getCity(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("getCity error: %s", err)
|
logger.FromContext(ctx).ErrorContext(ctx, "getCity error ", "err", err)
|
||||||
http.Error(w, "data error", 500)
|
http.Error(w, "data error", 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -183,14 +192,15 @@ func handleCountry(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleHealth(w http.ResponseWriter, req *http.Request) {
|
func handleHealth(w http.ResponseWriter, req *http.Request) {
|
||||||
span := trace.SpanFromContext(req.Context())
|
ctx := req.Context()
|
||||||
|
span := trace.SpanFromContext(ctx)
|
||||||
span.SetAttributes(attribute.Bool("app.drop_sample", true))
|
span.SetAttributes(attribute.Bool("app.drop_sample", true))
|
||||||
span.SetName("/healthz")
|
span.SetName("/healthz")
|
||||||
|
|
||||||
ip := net.ParseIP("199.43.0.43")
|
ip := net.ParseIP("199.43.0.43")
|
||||||
city, err := getCityIP(ip)
|
city, err := getCityIP(ctx, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("getCity error: %s", err)
|
logger.FromContext(ctx).WarnContext(ctx, "health check getCity error ", "ip", ip, "err", err)
|
||||||
http.Error(w, "data error", 500)
|
http.Error(w, "data error", 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
18
go.mod
18
go.mod
@@ -6,7 +6,7 @@ toolchain go1.24rc1
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/oschwald/geoip2-golang v1.11.0
|
github.com/oschwald/geoip2-golang v1.11.0
|
||||||
go.ntppool.org/common v0.3.0
|
go.ntppool.org/common v0.3.1
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0
|
||||||
go.opentelemetry.io/otel v1.33.0
|
go.opentelemetry.io/otel v1.33.0
|
||||||
go.opentelemetry.io/otel/trace v1.33.0
|
go.opentelemetry.io/otel/trace v1.33.0
|
||||||
@@ -31,7 +31,7 @@ require (
|
|||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/remychantenay/slog-otel v1.3.2 // indirect
|
github.com/remychantenay/slog-otel v1.3.2 // indirect
|
||||||
github.com/samber/lo v1.47.0 // indirect
|
github.com/samber/lo v1.47.0 // indirect
|
||||||
github.com/samber/slog-multi v1.2.4 // indirect
|
github.com/samber/slog-multi v1.3.3 // indirect
|
||||||
github.com/spf13/cobra v1.8.1 // indirect
|
github.com/spf13/cobra v1.8.1 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||||
@@ -54,13 +54,13 @@ require (
|
|||||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk/log v0.9.0 // indirect
|
go.opentelemetry.io/otel/sdk/log v0.9.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.33.0 // indirect
|
go.opentelemetry.io/otel/sdk/metric v1.33.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||||
golang.org/x/mod v0.22.0 // indirect
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
golang.org/x/net v0.33.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.28.0 // indirect
|
golang.org/x/sys v0.29.0 // indirect
|
||||||
golang.org/x/text v0.21.0 // indirect
|
golang.org/x/text v0.21.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||||
google.golang.org/grpc v1.69.2 // indirect
|
google.golang.org/grpc v1.69.4 // indirect
|
||||||
google.golang.org/protobuf v1.36.0 // indirect
|
google.golang.org/protobuf v1.36.3 // indirect
|
||||||
)
|
)
|
||||||
|
36
go.sum
36
go.sum
@@ -49,16 +49,16 @@ github.com/remychantenay/slog-otel v1.3.2/go.mod h1:gKW4tQ8cGOKoA+bi7wtYba/tcJ6T
|
|||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
|
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
|
||||||
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
|
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
|
||||||
github.com/samber/slog-multi v1.2.4 h1:k9x3JAWKJFPKffx+oXZ8TasaNuorIW4tG+TXxkt6Ry4=
|
github.com/samber/slog-multi v1.3.3 h1:qhFXaYdW73FIWLt8SrXMXfPwY58NpluzKDwRdPvhWWY=
|
||||||
github.com/samber/slog-multi v1.2.4/go.mod h1:ACuZ5B6heK57TfMVkVknN2UZHoFfjCwRxR0Q2OXKHlo=
|
github.com/samber/slog-multi v1.3.3/go.mod h1:ACuZ5B6heK57TfMVkVknN2UZHoFfjCwRxR0Q2OXKHlo=
|
||||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
go.ntppool.org/common v0.3.0 h1:IuSmyjEhI1F3tr5kc5MqlR4cy5y0o5f3EKvC7Koc6rs=
|
go.ntppool.org/common v0.3.1 h1:JaJpS3m8oAc9jH0yhHYJnjOC+RUzxx/F+EDe0QON4eQ=
|
||||||
go.ntppool.org/common v0.3.0/go.mod h1:25pUt3YUusF1MY0nsljjskcMMeTvKZszVvNsubvWhSM=
|
go.ntppool.org/common v0.3.1/go.mod h1:1SKjFBH9AL7Fj2S0zy41isHzV6dTC+6yIKD5QDtX8aY=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||||
go.opentelemetry.io/contrib/bridges/otelslog v0.8.0 h1:G3sKsNueSdxuACINFxKrQeimAIst0A5ytA2YJH+3e1c=
|
go.opentelemetry.io/contrib/bridges/otelslog v0.8.0 h1:G3sKsNueSdxuACINFxKrQeimAIst0A5ytA2YJH+3e1c=
|
||||||
@@ -105,26 +105,26 @@ go.opentelemetry.io/otel/sdk/metric v1.33.0 h1:Gs5VK9/WUJhNXZgn8MR6ITatvAmKeIuCt
|
|||||||
go.opentelemetry.io/otel/sdk/metric v1.33.0/go.mod h1:dL5ykHZmm1B1nVRk9dDjChwDmt81MjVp3gLkQRwKf/Q=
|
go.opentelemetry.io/otel/sdk/metric v1.33.0/go.mod h1:dL5ykHZmm1B1nVRk9dDjChwDmt81MjVp3gLkQRwKf/Q=
|
||||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb h1:B7GIB7sr443wZ/EAEl7VZjmh1V6qzkt5V+RYcUYtS1U=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb/go.mod h1:E5//3O5ZIG2l71Xnt+P/CYUY8Bxs8E7WMoZ9tlcMbAY=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb h1:3oy2tynMOP1QbTC0MsNNAV+Se8M2Bd0A5+x1QHyw+pI=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||||
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
|
||||||
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||||
google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ=
|
google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
|
||||||
google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
Reference in New Issue
Block a user