mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-12 06:24:10 +01:00
console: implement an HTTP cache for Clickhouse-backed requests
Fix #328
This commit is contained in:
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@@ -51,6 +51,12 @@ jobs:
|
|||||||
ALLOW_PLAINTEXT_LISTENER: "yes"
|
ALLOW_PLAINTEXT_LISTENER: "yes"
|
||||||
ports:
|
ports:
|
||||||
- 9092:9093
|
- 9092:9093
|
||||||
|
redis:
|
||||||
|
image: bitnami/redis:7.0
|
||||||
|
env:
|
||||||
|
ALLOW_EMPTY_PASSWORD: "yes"
|
||||||
|
ports:
|
||||||
|
- 6379:6379
|
||||||
clickhouse:
|
clickhouse:
|
||||||
image: clickhouse/clickhouse-server:22.8
|
image: clickhouse/clickhouse-server:22.8
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -22,17 +22,23 @@ run tests:
|
|||||||
variables:
|
variables:
|
||||||
FF_NETWORK_PER_BUILD: "true"
|
FF_NETWORK_PER_BUILD: "true"
|
||||||
CI_AKVORADO_FUNCTIONAL_TESTS: "true"
|
CI_AKVORADO_FUNCTIONAL_TESTS: "true"
|
||||||
|
# zookeeper
|
||||||
ALLOW_ANONYMOUS_LOGIN: "yes"
|
ALLOW_ANONYMOUS_LOGIN: "yes"
|
||||||
|
# kafka
|
||||||
ALLOW_PLAINTEXT_LISTENER: "yes"
|
ALLOW_PLAINTEXT_LISTENER: "yes"
|
||||||
KAFKA_BROKER_ID: "1"
|
KAFKA_BROKER_ID: "1"
|
||||||
KAFKA_CFG_LISTENERS: "PLAINTEXT://:9092"
|
KAFKA_CFG_LISTENERS: "PLAINTEXT://:9092"
|
||||||
KAFKA_CFG_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9092"
|
KAFKA_CFG_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9092"
|
||||||
KAFKA_CFG_ZOOKEEPER_CONNECT: "zookeeper:2181"
|
KAFKA_CFG_ZOOKEEPER_CONNECT: "zookeeper:2181"
|
||||||
|
# redis
|
||||||
|
ALLOW_EMPTY_PASSWORD: "yes"
|
||||||
services:
|
services:
|
||||||
- name: bitnami/zookeeper:3.7
|
- name: bitnami/zookeeper:3.7
|
||||||
alias: zookeeper
|
alias: zookeeper
|
||||||
- name: bitnami/kafka:3.3
|
- name: bitnami/kafka:3.3
|
||||||
alias: kafka
|
alias: kafka
|
||||||
|
- name: bitnami/redis:7.0
|
||||||
|
alias: redis
|
||||||
- name: clickhouse/clickhouse-server:22.8
|
- name: clickhouse/clickhouse-server:22.8
|
||||||
alias: clickhouse
|
alias: clickhouse
|
||||||
script:
|
script:
|
||||||
|
|||||||
66
common/http/cache.go
Normal file
66
common/http/cache.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2022 Free Mobile
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"hash/fnv"
|
||||||
|
"io/ioutil"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
cache "github.com/chenyahui/gin-cache"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"akvorado/common/reporter"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CacheByRequestPath is a middleware to cache the request using path as key
|
||||||
|
func (c *Component) CacheByRequestPath(expire time.Duration) gin.HandlerFunc {
|
||||||
|
opts := c.commonCacheOptions()
|
||||||
|
opts = append(opts, cache.WithCacheStrategyByRequest(func(gc *gin.Context) (bool, cache.Strategy) {
|
||||||
|
return true, cache.Strategy{
|
||||||
|
CacheKey: gc.Request.URL.Path,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return cache.Cache(c.cacheStore, expire, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CacheByRequestBody is a middleware to cache the request using body as key
|
||||||
|
func (c *Component) CacheByRequestBody(expire time.Duration) gin.HandlerFunc {
|
||||||
|
opts := c.commonCacheOptions()
|
||||||
|
opts = append(opts, cache.WithCacheStrategyByRequest(func(gc *gin.Context) (bool, cache.Strategy) {
|
||||||
|
requestBody, err := gc.GetRawData()
|
||||||
|
gc.Request.Body = ioutil.NopCloser(bytes.NewBuffer(requestBody))
|
||||||
|
if err != nil {
|
||||||
|
return false, cache.Strategy{}
|
||||||
|
}
|
||||||
|
h := fnv.New128()
|
||||||
|
bodyHash := string(h.Sum(requestBody))
|
||||||
|
return true, cache.Strategy{
|
||||||
|
CacheKey: bodyHash,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return cache.Cache(c.cacheStore, expire, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Component) commonCacheOptions() []cache.Option {
|
||||||
|
return []cache.Option{
|
||||||
|
cache.WithLogger(cacheLogger{c.r}),
|
||||||
|
cache.WithOnHitCache(func(gc *gin.Context) {
|
||||||
|
c.metrics.cacheHit.WithLabelValues(gc.Request.URL.Path, gc.Request.Method).Inc()
|
||||||
|
}),
|
||||||
|
cache.WithOnMissCache(func(gc *gin.Context) {
|
||||||
|
c.metrics.cacheMiss.WithLabelValues(gc.Request.URL.Path, gc.Request.Method).Inc()
|
||||||
|
}),
|
||||||
|
cache.WithPrefixKey("cache-"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type cacheLogger struct {
|
||||||
|
r *reporter.Reporter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cl cacheLogger) Errorf(msg string, args ...interface{}) {
|
||||||
|
cl.r.Error().Msgf(msg, args...)
|
||||||
|
}
|
||||||
174
common/http/cache_test.go
Normal file
174
common/http/cache_test.go
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2022 Free Mobile
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
package http_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
netHTTP "net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"akvorado/common/daemon"
|
||||||
|
"akvorado/common/helpers"
|
||||||
|
"akvorado/common/http"
|
||||||
|
"akvorado/common/reporter"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCacheByRequestPath(t *testing.T) {
|
||||||
|
r := reporter.NewMock(t)
|
||||||
|
h := http.NewMock(t, r)
|
||||||
|
|
||||||
|
count := 0
|
||||||
|
h.GinRouter.GET("/api/v0/test",
|
||||||
|
h.CacheByRequestPath(time.Minute),
|
||||||
|
func(c *gin.Context) {
|
||||||
|
count++
|
||||||
|
c.JSON(netHTTP.StatusOK, gin.H{
|
||||||
|
"message": "ping",
|
||||||
|
"count": count,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check the HTTP server is running and answering metrics
|
||||||
|
helpers.TestHTTPEndpoints(t, h.LocalAddr(), helpers.HTTPEndpointCases{
|
||||||
|
{
|
||||||
|
Description: "not cached",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 1},
|
||||||
|
}, {
|
||||||
|
Description: "cached",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 1},
|
||||||
|
}, {
|
||||||
|
Description: "cached twice",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 1},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
gotMetrics := r.GetMetrics("akvorado_common_http_", "requests_", "cache_")
|
||||||
|
expectedMetrics := map[string]string{
|
||||||
|
`cache_hit_total{method="GET",path="/api/v0/test"}`: "2",
|
||||||
|
`cache_miss_total{method="GET",path="/api/v0/test"}`: "1",
|
||||||
|
`requests_total{code="200",handler="/api/",method="get"}`: "3",
|
||||||
|
}
|
||||||
|
if diff := helpers.Diff(gotMetrics, expectedMetrics); diff != "" {
|
||||||
|
t.Fatalf("Metrics (-got, +want):\n%s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCacheByRequestBody(t *testing.T) {
|
||||||
|
r := reporter.NewMock(t)
|
||||||
|
h := http.NewMock(t, r)
|
||||||
|
|
||||||
|
count := 0
|
||||||
|
h.GinRouter.POST("/api/v0/test",
|
||||||
|
h.CacheByRequestBody(time.Minute),
|
||||||
|
func(c *gin.Context) {
|
||||||
|
count++
|
||||||
|
data, err := c.GetRawData()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetRawData() error:\n%+v", err)
|
||||||
|
}
|
||||||
|
c.JSON(netHTTP.StatusOK, gin.H{
|
||||||
|
"message": "ping",
|
||||||
|
"count": count,
|
||||||
|
"body": string(data),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check the HTTP server is running and answering metrics
|
||||||
|
helpers.TestHTTPEndpoints(t, h.LocalAddr(), helpers.HTTPEndpointCases{
|
||||||
|
{
|
||||||
|
Description: "not cached",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONInput: gin.H{"hop": 1},
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 1, "body": `{"hop":1}` + "\n"},
|
||||||
|
}, {
|
||||||
|
Description: "cached",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONInput: gin.H{"hop": 1},
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 1, "body": `{"hop":1}` + "\n"},
|
||||||
|
}, {
|
||||||
|
Description: "different body",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONInput: gin.H{"hop": 2},
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 2, "body": `{"hop":2}` + "\n"},
|
||||||
|
}, {
|
||||||
|
Description: "different body cached",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONInput: gin.H{"hop": 2},
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 2, "body": `{"hop":2}` + "\n"},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
gotMetrics := r.GetMetrics("akvorado_common_http_", "requests_", "cache_")
|
||||||
|
expectedMetrics := map[string]string{
|
||||||
|
`cache_hit_total{method="POST",path="/api/v0/test"}`: "2",
|
||||||
|
`cache_miss_total{method="POST",path="/api/v0/test"}`: "2",
|
||||||
|
`requests_total{code="200",handler="/api/",method="post"}`: "4",
|
||||||
|
}
|
||||||
|
if diff := helpers.Diff(gotMetrics, expectedMetrics); diff != "" {
|
||||||
|
t.Fatalf("Metrics (-got, +want):\n%s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRedis(t *testing.T) {
|
||||||
|
server := helpers.CheckExternalService(t, "Redis", []string{"redis", "localhost"}, "6379")
|
||||||
|
client := redis.NewClient(&redis.Options{
|
||||||
|
Addr: server,
|
||||||
|
DB: 10,
|
||||||
|
})
|
||||||
|
defer client.Close()
|
||||||
|
if err := client.FlushAll(context.Background()).Err(); err != nil {
|
||||||
|
t.Fatalf("FlushAll() error:\n%+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r := reporter.NewMock(t)
|
||||||
|
|
||||||
|
// HTTP with Redis
|
||||||
|
config := http.DefaultConfiguration()
|
||||||
|
config.Listen = "127.0.0.1:0"
|
||||||
|
config.Cache.Config = http.RedisCacheConfiguration{
|
||||||
|
Protocol: "tcp",
|
||||||
|
Server: server,
|
||||||
|
DB: 10,
|
||||||
|
}
|
||||||
|
h, err := http.New(r, config, http.Dependencies{Daemon: daemon.NewMock(t)})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New() error:\n%+v", err)
|
||||||
|
}
|
||||||
|
helpers.StartStop(t, h)
|
||||||
|
|
||||||
|
count := 0
|
||||||
|
h.GinRouter.GET("/api/v0/test",
|
||||||
|
h.CacheByRequestPath(time.Minute),
|
||||||
|
func(c *gin.Context) {
|
||||||
|
count++
|
||||||
|
c.JSON(netHTTP.StatusOK, gin.H{
|
||||||
|
"message": "ping",
|
||||||
|
"count": count,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check the HTTP server is running and answering metrics
|
||||||
|
helpers.TestHTTPEndpoints(t, h.LocalAddr(), helpers.HTTPEndpointCases{
|
||||||
|
{
|
||||||
|
Description: "not cached",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 1},
|
||||||
|
}, {
|
||||||
|
Description: "cached",
|
||||||
|
URL: "/api/v0/test",
|
||||||
|
JSONOutput: gin.H{"message": "ping", "count": 1},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := client.Get(context.Background(), "cache-/api/v0/test").Err(); err != nil {
|
||||||
|
t.Fatalf("GET(\"cache-/api/v0/test\") error:\n%+v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,17 +3,109 @@
|
|||||||
|
|
||||||
package http
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"akvorado/common/helpers"
|
||||||
|
|
||||||
|
"github.com/chenyahui/gin-cache/persist"
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
)
|
||||||
|
|
||||||
// Configuration describes the configuration for the HTTP server.
|
// Configuration describes the configuration for the HTTP server.
|
||||||
type Configuration struct {
|
type Configuration struct {
|
||||||
// Listen defines the listening string to listen to.
|
// Listen defines the listening string to listen to.
|
||||||
Listen string `validate:"required,listen"`
|
Listen string `validate:"required,listen"`
|
||||||
// Profiler enables Go profiler as /debug
|
// Profiler enables Go profiler as /debug
|
||||||
Profiler bool
|
Profiler bool
|
||||||
|
// Cache configuration
|
||||||
|
Cache CacheConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
// CacheConfiguration describes the configuration of the internal HTTP cache.
|
||||||
|
// Currently, it delegates everything to the implemented backends.
|
||||||
|
type CacheConfiguration struct {
|
||||||
|
// Config is the backend-specific configuration for the cache
|
||||||
|
Config CacheBackendConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
// CacheBackendConfiguration represents the configuration of a cache backend.
|
||||||
|
type CacheBackendConfiguration interface {
|
||||||
|
New() (persist.CacheStore, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemoryCacheConfiguration is the configuration for an in-memory cache. There
|
||||||
|
// is no configuration.
|
||||||
|
type MemoryCacheConfiguration struct{}
|
||||||
|
|
||||||
|
// New creates a new memory cache store from a memory cache configuration.
|
||||||
|
func (MemoryCacheConfiguration) New() (persist.CacheStore, error) {
|
||||||
|
return persist.NewMemoryStore(5 * time.Minute), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultMemoryCacheConfiguration returns the default configuration for an
|
||||||
|
// in-memory cache.
|
||||||
|
func DefaultMemoryCacheConfiguration() CacheBackendConfiguration {
|
||||||
|
return MemoryCacheConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RedisCacheConfiguration is the configuration for a Redis cache.
|
||||||
|
type RedisCacheConfiguration struct {
|
||||||
|
// Protocol to connect with
|
||||||
|
Protocol string `validate:"oneof=tcp unix"`
|
||||||
|
// Server to connect to (with port)
|
||||||
|
Server string `validate:"required,listen"`
|
||||||
|
// Optional username
|
||||||
|
Username string
|
||||||
|
// Optional password
|
||||||
|
Password string
|
||||||
|
// Database to connect to
|
||||||
|
DB int
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new Redis cache store from a Redis cache configuration.
|
||||||
|
func (c RedisCacheConfiguration) New() (persist.CacheStore, error) {
|
||||||
|
client := redis.NewClient(&redis.Options{
|
||||||
|
Network: c.Protocol,
|
||||||
|
Addr: c.Server,
|
||||||
|
Username: c.Username,
|
||||||
|
Password: c.Password,
|
||||||
|
DB: c.DB,
|
||||||
|
})
|
||||||
|
// TODO: defer client.Close()
|
||||||
|
if _, err := client.Ping(context.Background()).Result(); err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot ping Redis server: %w", err)
|
||||||
|
}
|
||||||
|
return persist.NewRedisStore(client), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultRedisCacheConfiguration returns the default configuration for a
|
||||||
|
// Redis-backed cache.
|
||||||
|
func DefaultRedisCacheConfiguration() CacheBackendConfiguration {
|
||||||
|
return RedisCacheConfiguration{
|
||||||
|
Protocol: "tcp",
|
||||||
|
Server: "127.0.0.1:6379",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultConfiguration is the default configuration of the HTTP server.
|
// DefaultConfiguration is the default configuration of the HTTP server.
|
||||||
func DefaultConfiguration() Configuration {
|
func DefaultConfiguration() Configuration {
|
||||||
return Configuration{
|
return Configuration{
|
||||||
Listen: "0.0.0.0:8080",
|
Listen: "0.0.0.0:8080",
|
||||||
|
Cache: CacheConfiguration{
|
||||||
|
Config: DefaultMemoryCacheConfiguration(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cacheConfigurationMap = map[string](func() CacheBackendConfiguration){
|
||||||
|
"memory": DefaultMemoryCacheConfiguration,
|
||||||
|
"redis": DefaultRedisCacheConfiguration,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
helpers.RegisterMapstructureUnmarshallerHook(
|
||||||
|
helpers.ParametrizedConfigurationUnmarshallerHook(CacheConfiguration{}, cacheConfigurationMap))
|
||||||
|
}
|
||||||
|
|||||||
56
common/http/metrics.go
Normal file
56
common/http/metrics.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2022 Free Mobile
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
package http
|
||||||
|
|
||||||
|
import "akvorado/common/reporter"
|
||||||
|
|
||||||
|
type metrics struct {
|
||||||
|
inflights reporter.Gauge
|
||||||
|
requests *reporter.CounterVec
|
||||||
|
durations *reporter.HistogramVec
|
||||||
|
sizes *reporter.HistogramVec
|
||||||
|
cacheHit *reporter.CounterVec
|
||||||
|
cacheMiss *reporter.CounterVec
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Component) initMetrics() {
|
||||||
|
c.metrics.inflights = c.r.Gauge(
|
||||||
|
reporter.GaugeOpts{
|
||||||
|
Name: "inflight_requests",
|
||||||
|
Help: "Number of requests currently being served by the HTTP server.",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
c.metrics.requests = c.r.CounterVec(
|
||||||
|
reporter.CounterOpts{
|
||||||
|
Name: "requests_total",
|
||||||
|
Help: "Number of requests handled by an handler.",
|
||||||
|
}, []string{"handler", "code", "method"},
|
||||||
|
)
|
||||||
|
c.metrics.durations = c.r.HistogramVec(
|
||||||
|
reporter.HistogramOpts{
|
||||||
|
Name: "request_duration_seconds",
|
||||||
|
Help: "Latencies for served requests.",
|
||||||
|
Buckets: []float64{.25, .5, 1, 2.5, 5, 10},
|
||||||
|
}, []string{"handler", "method"},
|
||||||
|
)
|
||||||
|
c.metrics.sizes = c.r.HistogramVec(
|
||||||
|
reporter.HistogramOpts{
|
||||||
|
Name: "response_size_bytes",
|
||||||
|
Help: "Response sizes for requests.",
|
||||||
|
Buckets: []float64{200, 500, 1000, 1500, 5000},
|
||||||
|
}, []string{"handler", "method"},
|
||||||
|
)
|
||||||
|
c.metrics.cacheHit = c.r.CounterVec(
|
||||||
|
reporter.CounterOpts{
|
||||||
|
Name: "cache_hit_total",
|
||||||
|
Help: "Number of requests served from cache",
|
||||||
|
}, []string{"path", "method"},
|
||||||
|
)
|
||||||
|
c.metrics.cacheMiss = c.r.CounterVec(
|
||||||
|
reporter.CounterOpts{
|
||||||
|
Name: "cache_miss_total",
|
||||||
|
Help: "Number of requests not served from cache",
|
||||||
|
}, []string{"path", "method"},
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"net/http/pprof"
|
"net/http/pprof"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/chenyahui/gin-cache/persist"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
@@ -30,16 +31,12 @@ type Component struct {
|
|||||||
config Configuration
|
config Configuration
|
||||||
|
|
||||||
mux *http.ServeMux
|
mux *http.ServeMux
|
||||||
metrics struct {
|
metrics metrics
|
||||||
inflights reporter.Gauge
|
|
||||||
requests *reporter.CounterVec
|
|
||||||
durations *reporter.HistogramVec
|
|
||||||
sizes *reporter.HistogramVec
|
|
||||||
}
|
|
||||||
address net.Addr
|
address net.Addr
|
||||||
|
|
||||||
// GinRouter is the router exposed for /api
|
// GinRouter is the router exposed for /api
|
||||||
GinRouter *gin.Engine
|
GinRouter *gin.Engine
|
||||||
|
cacheStore persist.CacheStore
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dependencies define the dependencies of the HTTP component.
|
// Dependencies define the dependencies of the HTTP component.
|
||||||
@@ -49,6 +46,7 @@ type Dependencies struct {
|
|||||||
|
|
||||||
// New creates a new HTTP component.
|
// New creates a new HTTP component.
|
||||||
func New(r *reporter.Reporter, configuration Configuration, dependencies Dependencies) (*Component, error) {
|
func New(r *reporter.Reporter, configuration Configuration, dependencies Dependencies) (*Component, error) {
|
||||||
|
var err error
|
||||||
c := Component{
|
c := Component{
|
||||||
r: r,
|
r: r,
|
||||||
d: &dependencies,
|
d: &dependencies,
|
||||||
@@ -57,35 +55,12 @@ func New(r *reporter.Reporter, configuration Configuration, dependencies Depende
|
|||||||
mux: http.NewServeMux(),
|
mux: http.NewServeMux(),
|
||||||
GinRouter: gin.New(),
|
GinRouter: gin.New(),
|
||||||
}
|
}
|
||||||
|
c.initMetrics()
|
||||||
c.d.Daemon.Track(&c.t, "common/http")
|
c.d.Daemon.Track(&c.t, "common/http")
|
||||||
|
c.cacheStore, err = configuration.Cache.Config.New()
|
||||||
c.metrics.inflights = c.r.Gauge(
|
if err != nil {
|
||||||
reporter.GaugeOpts{
|
return nil, err
|
||||||
Name: "inflight_requests",
|
}
|
||||||
Help: "Number of requests currently being served by the HTTP server.",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
c.metrics.requests = c.r.CounterVec(
|
|
||||||
reporter.CounterOpts{
|
|
||||||
Name: "requests_total",
|
|
||||||
Help: "Number of requests handled by an handler.",
|
|
||||||
}, []string{"handler", "code", "method"},
|
|
||||||
)
|
|
||||||
c.metrics.durations = c.r.HistogramVec(
|
|
||||||
reporter.HistogramOpts{
|
|
||||||
Name: "request_duration_seconds",
|
|
||||||
Help: "Latencies for served requests.",
|
|
||||||
Buckets: []float64{.25, .5, 1, 2.5, 5, 10},
|
|
||||||
}, []string{"handler", "method"},
|
|
||||||
)
|
|
||||||
c.metrics.sizes = c.r.HistogramVec(
|
|
||||||
reporter.HistogramOpts{
|
|
||||||
Name: "response_size_bytes",
|
|
||||||
Help: "Response sizes for requests.",
|
|
||||||
Buckets: []float64{200, 500, 1000, 1500, 5000},
|
|
||||||
}, []string{"handler", "method"},
|
|
||||||
)
|
|
||||||
|
|
||||||
c.GinRouter.Use(gin.Recovery())
|
c.GinRouter.Use(gin.Recovery())
|
||||||
c.AddHandler("/api/", c.GinRouter)
|
c.AddHandler("/api/", c.GinRouter)
|
||||||
if configuration.Profiler {
|
if configuration.Profiler {
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ import (
|
|||||||
// NewMock create a new HTTP component listening on a random free port.
|
// NewMock create a new HTTP component listening on a random free port.
|
||||||
func NewMock(t *testing.T, r *reporter.Reporter) *Component {
|
func NewMock(t *testing.T, r *reporter.Reporter) *Component {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
config := Configuration{
|
config := DefaultConfiguration()
|
||||||
Listen: "127.0.0.1:0",
|
config.Listen = "127.0.0.1:0"
|
||||||
}
|
|
||||||
c, err := New(r, config, Dependencies{Daemon: daemon.NewMock(t)})
|
c, err := New(r, config, Dependencies{Daemon: daemon.NewMock(t)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("New() error:\n%+v", err)
|
t.Fatalf("New() error:\n%+v", err)
|
||||||
|
|||||||
@@ -347,18 +347,30 @@ SNMPv2.
|
|||||||
### HTTP
|
### HTTP
|
||||||
|
|
||||||
The builtin HTTP server serves various pages. Its configuration
|
The builtin HTTP server serves various pages. Its configuration
|
||||||
supports the `listen` key to specify the address and port to listen.
|
supports the following keys:
|
||||||
For example:
|
|
||||||
|
- `listen` defines the address and port to listen to.
|
||||||
|
- `profiler` enables [Go profiler HTTP
|
||||||
|
interface](https://pkg.go.dev/net/http/pprof). Check the [troubleshooting
|
||||||
|
section]( 05-troubleshooting.html#profiling) for details.
|
||||||
|
- `cache` defines the cache backend to use for some HTTP requests. It accepts a
|
||||||
|
`type` key which can be either `memory` (the default value) or `redis`. When
|
||||||
|
using the Redis backend, the following additional keys are also accepted:
|
||||||
|
`protocol` (`tcp` or `unix`), `server` (host and port), `username`,
|
||||||
|
`password`, and `db` (an integer to specify which database to use).
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
http:
|
http:
|
||||||
listen: 0.0.0.0:8000
|
listen: 0.0.0.0:8000
|
||||||
|
cache:
|
||||||
|
type: redis
|
||||||
|
username: akvorado
|
||||||
|
password: akvorado
|
||||||
```
|
```
|
||||||
|
|
||||||
It also supports the `profiler` key. When set to `true`, various
|
Note that the cache backend is currently only useful with the console. You need
|
||||||
[profiling data](https://pkg.go.dev/net/http/pprof) are made available
|
to define the cache in the `http` key of the `console` section for it to be
|
||||||
on the `/debug/pprof/` endpoint. This is useful if you wish to
|
useful (not in the `inlet` section).
|
||||||
optimize CPU or memory usage of one of the components.
|
|
||||||
|
|
||||||
### Reporting
|
### Reporting
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,14 @@ identified with a specific icon:
|
|||||||
There is a schema update in this version: you also have to restart ClickHouse
|
There is a schema update in this version: you also have to restart ClickHouse
|
||||||
after upgrading for it to pick the new schema.
|
after upgrading for it to pick the new schema.
|
||||||
|
|
||||||
|
This version also introduces a cache for some HTTP requests, notably those to
|
||||||
|
plot the graphs in the “Visualize” tab. The default backend is in-memory,
|
||||||
|
however the shipped `akvorado.yaml` configuration file is using Redis instead.
|
||||||
|
The `docker-compose` setup has also been updated to start a Redis container for
|
||||||
|
this usage. Use of Redis is preferred but on upgrade, you need to enable it
|
||||||
|
explicitely by adding `console.http.cache` in your configuration.
|
||||||
|
|
||||||
|
- ✨ *console*: cache some costly requests to the backend
|
||||||
- ✨ *console*: add `SrcNetPrefix` and `DstNetPrefix` (as a dimension and a filter attribute)
|
- ✨ *console*: add `SrcNetPrefix` and `DstNetPrefix` (as a dimension and a filter attribute)
|
||||||
- ✨ *inlet*: add `inlet.flow.inputs.use-src-addr-for-exporter-addr` to override exporter address
|
- ✨ *inlet*: add `inlet.flow.inputs.use-src-addr-for-exporter-addr` to override exporter address
|
||||||
- 🌱 *console*: add `limit` and `graph-type` to `console.default-visualize-options`
|
- 🌱 *console*: add `limit` and `graph-type` to `console.default-visualize-options`
|
||||||
|
|||||||
@@ -121,6 +121,14 @@ const encodedState = computed(() => encodeState(state.value));
|
|||||||
|
|
||||||
// Fetch data
|
// Fetch data
|
||||||
const fetchedData = ref<GraphHandlerResult | SankeyHandlerResult | null>(null);
|
const fetchedData = ref<GraphHandlerResult | SankeyHandlerResult | null>(null);
|
||||||
|
const orderedJSONPayload = <T extends Record<string, any>>(input: T): T => {
|
||||||
|
return Object.keys(input)
|
||||||
|
.sort()
|
||||||
|
.reduce(
|
||||||
|
(o, k) => ((o[k] = input[k]), o),
|
||||||
|
{} as { [key: string]: any }
|
||||||
|
) as T;
|
||||||
|
};
|
||||||
const jsonPayload = computed(
|
const jsonPayload = computed(
|
||||||
(): SankeyHandlerInput | GraphHandlerInput | null => {
|
(): SankeyHandlerInput | GraphHandlerInput | null => {
|
||||||
if (state.value === null) return null;
|
if (state.value === null) return null;
|
||||||
@@ -134,19 +142,20 @@ const jsonPayload = computed(
|
|||||||
"humanEnd",
|
"humanEnd",
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
return input;
|
return orderedJSONPayload(input);
|
||||||
|
} else {
|
||||||
|
const input: GraphHandlerInput = {
|
||||||
|
...omit(state.value, [
|
||||||
|
"graphType",
|
||||||
|
"previousPeriod",
|
||||||
|
"humanStart",
|
||||||
|
"humanEnd",
|
||||||
|
]),
|
||||||
|
points: state.value.graphType === "grid" ? 50 : 200,
|
||||||
|
"previous-period": state.value.previousPeriod,
|
||||||
|
};
|
||||||
|
return orderedJSONPayload(input);
|
||||||
}
|
}
|
||||||
const input: GraphHandlerInput = {
|
|
||||||
...omit(state.value, [
|
|
||||||
"graphType",
|
|
||||||
"previousPeriod",
|
|
||||||
"humanStart",
|
|
||||||
"humanEnd",
|
|
||||||
]),
|
|
||||||
points: state.value.graphType === "grid" ? 50 : 200,
|
|
||||||
"previous-period": state.value.previousPeriod,
|
|
||||||
};
|
|
||||||
return input;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const request = ref<ModelType>(null); // Same as state, but once request is successful
|
const request = ref<ModelType>(null); // Same as state, but once request is successful
|
||||||
|
|||||||
@@ -81,15 +81,15 @@ func (c *Component) Start() error {
|
|||||||
endpoint := c.d.HTTP.GinRouter.Group("/api/v0/console", c.d.Auth.UserAuthentication())
|
endpoint := c.d.HTTP.GinRouter.Group("/api/v0/console", c.d.Auth.UserAuthentication())
|
||||||
endpoint.GET("/configuration", c.configHandlerFunc)
|
endpoint.GET("/configuration", c.configHandlerFunc)
|
||||||
endpoint.GET("/docs/:name", c.docsHandlerFunc)
|
endpoint.GET("/docs/:name", c.docsHandlerFunc)
|
||||||
endpoint.GET("/widget/flow-last", c.widgetFlowLastHandlerFunc)
|
endpoint.GET("/widget/flow-last", c.d.HTTP.CacheByRequestPath(5*time.Second), c.widgetFlowLastHandlerFunc)
|
||||||
endpoint.GET("/widget/flow-rate", c.widgetFlowRateHandlerFunc)
|
endpoint.GET("/widget/flow-rate", c.d.HTTP.CacheByRequestPath(5*time.Second), c.widgetFlowRateHandlerFunc)
|
||||||
endpoint.GET("/widget/exporters", c.widgetExportersHandlerFunc)
|
endpoint.GET("/widget/exporters", c.d.HTTP.CacheByRequestPath(30*time.Second), c.widgetExportersHandlerFunc)
|
||||||
endpoint.GET("/widget/top/:name", c.widgetTopHandlerFunc)
|
endpoint.GET("/widget/top/:name", c.d.HTTP.CacheByRequestPath(30*time.Second), c.widgetTopHandlerFunc)
|
||||||
endpoint.GET("/widget/graph", c.widgetGraphHandlerFunc)
|
endpoint.GET("/widget/graph", c.d.HTTP.CacheByRequestPath(5*time.Minute), c.widgetGraphHandlerFunc)
|
||||||
endpoint.POST("/graph", c.graphHandlerFunc)
|
endpoint.POST("/graph", c.d.HTTP.CacheByRequestBody(30*time.Minute), c.graphHandlerFunc)
|
||||||
endpoint.POST("/sankey", c.sankeyHandlerFunc)
|
endpoint.POST("/sankey", c.d.HTTP.CacheByRequestBody(30*time.Minute), c.sankeyHandlerFunc)
|
||||||
endpoint.POST("/filter/validate", c.filterValidateHandlerFunc)
|
endpoint.POST("/filter/validate", c.filterValidateHandlerFunc)
|
||||||
endpoint.POST("/filter/complete", c.filterCompleteHandlerFunc)
|
endpoint.POST("/filter/complete", c.d.HTTP.CacheByRequestBody(time.Minute), c.filterCompleteHandlerFunc)
|
||||||
endpoint.GET("/filter/saved", c.filterSavedListHandlerFunc)
|
endpoint.GET("/filter/saved", c.filterSavedListHandlerFunc)
|
||||||
endpoint.DELETE("/filter/saved/:id", c.filterSavedDeleteHandlerFunc)
|
endpoint.DELETE("/filter/saved/:id", c.filterSavedDeleteHandlerFunc)
|
||||||
endpoint.POST("/filter/saved", c.filterSavedAddHandlerFunc)
|
endpoint.POST("/filter/saved", c.filterSavedAddHandlerFunc)
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"akvorado/common/helpers"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -195,21 +193,8 @@ LIMIT 5
|
|||||||
gc.JSON(http.StatusOK, gin.H{"top": results})
|
gc.JSON(http.StatusOK, gin.H{"top": results})
|
||||||
}
|
}
|
||||||
|
|
||||||
type widgetParameters struct {
|
|
||||||
Points uint `form:"points" binding:"isdefault|min=5,max=1000"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Component) widgetGraphHandlerFunc(gc *gin.Context) {
|
func (c *Component) widgetGraphHandlerFunc(gc *gin.Context) {
|
||||||
ctx := c.t.Context(gc.Request.Context())
|
ctx := c.t.Context(gc.Request.Context())
|
||||||
|
|
||||||
var params widgetParameters
|
|
||||||
if err := gc.ShouldBindQuery(¶ms); err != nil {
|
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{"message": helpers.Capitalize(err.Error())})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if params.Points == 0 {
|
|
||||||
params.Points = 200
|
|
||||||
}
|
|
||||||
now := c.d.Clock.Now()
|
now := c.d.Clock.Now()
|
||||||
query := c.finalizeQuery(fmt.Sprintf(`
|
query := c.finalizeQuery(fmt.Sprintf(`
|
||||||
{{ with %s }}
|
{{ with %s }}
|
||||||
@@ -229,7 +214,7 @@ ORDER BY Time WITH FILL
|
|||||||
Start: now.Add(-24 * time.Hour),
|
Start: now.Add(-24 * time.Hour),
|
||||||
End: now,
|
End: now,
|
||||||
MainTableRequired: false,
|
MainTableRequired: false,
|
||||||
Points: params.Points,
|
Points: 200,
|
||||||
})))
|
})))
|
||||||
gc.Header("X-SQL-Query", query)
|
gc.Header("X-SQL-Query", query)
|
||||||
|
|
||||||
|
|||||||
@@ -232,8 +232,8 @@ func TestWidgetGraph(t *testing.T) {
|
|||||||
mockConn.EXPECT().
|
mockConn.EXPECT().
|
||||||
Select(gomock.Any(), gomock.Any(), strings.TrimSpace(`
|
Select(gomock.Any(), gomock.Any(), strings.TrimSpace(`
|
||||||
SELECT
|
SELECT
|
||||||
toStartOfInterval(TimeReceived + INTERVAL 144 second, INTERVAL 864 second) - INTERVAL 144 second AS Time,
|
toStartOfInterval(TimeReceived + INTERVAL 144 second, INTERVAL 432 second) - INTERVAL 144 second AS Time,
|
||||||
SUM(Bytes*SamplingRate*8/864)/1000/1000/1000 AS Gbps
|
SUM(Bytes*SamplingRate*8/432)/1000/1000/1000 AS Gbps
|
||||||
FROM flows
|
FROM flows
|
||||||
WHERE TimeReceived BETWEEN toDateTime('2009-11-10 23:00:00', 'UTC') AND toDateTime('2009-11-11 23:00:00', 'UTC')
|
WHERE TimeReceived BETWEEN toDateTime('2009-11-10 23:00:00', 'UTC') AND toDateTime('2009-11-11 23:00:00', 'UTC')
|
||||||
AND InIfBoundary = 'external'
|
AND InIfBoundary = 'external'
|
||||||
@@ -241,13 +241,13 @@ GROUP BY Time
|
|||||||
ORDER BY Time WITH FILL
|
ORDER BY Time WITH FILL
|
||||||
FROM toDateTime('2009-11-10 23:00:00', 'UTC')
|
FROM toDateTime('2009-11-10 23:00:00', 'UTC')
|
||||||
TO toDateTime('2009-11-11 23:00:00', 'UTC') + INTERVAL 1 second
|
TO toDateTime('2009-11-11 23:00:00', 'UTC') + INTERVAL 1 second
|
||||||
STEP 864`)).
|
STEP 432`)).
|
||||||
SetArg(1, expected).
|
SetArg(1, expected).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
|
|
||||||
helpers.TestHTTPEndpoints(t, h.LocalAddr(), helpers.HTTPEndpointCases{
|
helpers.TestHTTPEndpoints(t, h.LocalAddr(), helpers.HTTPEndpointCases{
|
||||||
{
|
{
|
||||||
URL: "/api/v0/console/widget/graph?points=100",
|
URL: "/api/v0/console/widget/graph",
|
||||||
JSONOutput: gin.H{
|
JSONOutput: gin.H{
|
||||||
"data": []gin.H{
|
"data": []gin.H{
|
||||||
{"t": "2009-11-10T23:00:00Z", "gbps": 25.3},
|
{"t": "2009-11-10T23:00:00Z", "gbps": 25.3},
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 127.0.0.1:9092:9093/tcp
|
- 127.0.0.1:9092:9093/tcp
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: bitnami/redis:7.0
|
||||||
|
environment:
|
||||||
|
- ALLOW_EMPTY_PASSWORD=yes
|
||||||
|
ports:
|
||||||
|
- 127.0.0.1:6379:6379/tcp
|
||||||
|
|
||||||
clickhouse:
|
clickhouse:
|
||||||
image: clickhouse/clickhouse-server:22.8
|
image: clickhouse/clickhouse-server:22.8
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ services:
|
|||||||
- traefik.http.routers.kafka-ui.entrypoints=private
|
- traefik.http.routers.kafka-ui.entrypoints=private
|
||||||
- traefik.http.routers.kafka-ui.rule=PathPrefix(`/kafka-ui`)
|
- traefik.http.routers.kafka-ui.rule=PathPrefix(`/kafka-ui`)
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: bitnami/redis:7.0
|
||||||
|
environment:
|
||||||
|
- ALLOW_EMPTY_PASSWORD=yes
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
# If you need to build from the source, uncomment the build option
|
# If you need to build from the source, uncomment the build option
|
||||||
# here and use `docker-compose build akvorado-service`.
|
# here and use `docker-compose build akvorado-service`.
|
||||||
akvorado-service: &akvorado-image
|
akvorado-service: &akvorado-image
|
||||||
@@ -77,6 +83,8 @@ services:
|
|||||||
akvorado-console:
|
akvorado-console:
|
||||||
<<: *akvorado-image
|
<<: *akvorado-image
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
command: console http://akvorado-orchestrator:8080
|
command: console http://akvorado-orchestrator:8080
|
||||||
volumes:
|
volumes:
|
||||||
- akvorado-console-db:/run/akvorado
|
- akvorado-console-db:/run/akvorado
|
||||||
|
|||||||
10
go.mod
10
go.mod
@@ -9,6 +9,7 @@ require (
|
|||||||
github.com/antonmedv/expr v1.9.0
|
github.com/antonmedv/expr v1.9.0
|
||||||
github.com/benbjohnson/clock v1.3.0
|
github.com/benbjohnson/clock v1.3.0
|
||||||
github.com/cenkalti/backoff/v4 v4.2.0
|
github.com/cenkalti/backoff/v4 v4.2.0
|
||||||
|
github.com/chenyahui/gin-cache v1.7.1
|
||||||
github.com/docker/docker v20.10.22+incompatible
|
github.com/docker/docker v20.10.22+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/eapache/go-resiliency v1.3.0
|
github.com/eapache/go-resiliency v1.3.0
|
||||||
@@ -16,6 +17,7 @@ require (
|
|||||||
github.com/gin-gonic/gin v1.8.1
|
github.com/gin-gonic/gin v1.8.1
|
||||||
github.com/glebarez/sqlite v1.6.0
|
github.com/glebarez/sqlite v1.6.0
|
||||||
github.com/go-playground/validator/v10 v10.11.1
|
github.com/go-playground/validator/v10 v10.11.1
|
||||||
|
github.com/go-redis/redis/v8 v8.11.4
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/golang/protobuf v1.5.2
|
github.com/golang/protobuf v1.5.2
|
||||||
github.com/google/gopacket v1.1.19
|
github.com/google/gopacket v1.1.19
|
||||||
@@ -26,6 +28,7 @@ require (
|
|||||||
github.com/mattn/go-isatty v0.0.16
|
github.com/mattn/go-isatty v0.0.16
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/netsampler/goflow2 v1.1.1-0.20221008154147-57fad2e0c837
|
github.com/netsampler/goflow2 v1.1.1-0.20221008154147-57fad2e0c837
|
||||||
|
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799
|
||||||
github.com/oschwald/maxminddb-golang v1.10.0
|
github.com/oschwald/maxminddb-golang v1.10.0
|
||||||
github.com/osrg/gobgp/v3 v3.9.0
|
github.com/osrg/gobgp/v3 v3.9.0
|
||||||
github.com/prometheus/client_golang v1.14.0
|
github.com/prometheus/client_golang v1.14.0
|
||||||
@@ -40,6 +43,7 @@ require (
|
|||||||
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594
|
github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594
|
||||||
golang.org/x/sys v0.3.0
|
golang.org/x/sys v0.3.0
|
||||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
|
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
|
||||||
|
google.golang.org/protobuf v1.28.1
|
||||||
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
|
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gorm.io/gorm v1.24.2
|
gorm.io/gorm v1.24.2
|
||||||
@@ -53,6 +57,7 @@ require (
|
|||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||||
github.com/docker/go-units v0.5.0 // indirect
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
@@ -79,6 +84,7 @@ require (
|
|||||||
github.com/jcmturner/gofork v1.0.0 // indirect
|
github.com/jcmturner/gofork v1.0.0 // indirect
|
||||||
github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect
|
github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect
|
||||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||||
|
github.com/jellydator/ttlcache/v2 v2.11.1 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
@@ -90,7 +96,6 @@ require (
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
|
|
||||||
github.com/paulmach/orb v0.7.1 // indirect
|
github.com/paulmach/orb v0.7.1 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||||
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
|
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
|
||||||
@@ -117,8 +122,8 @@ require (
|
|||||||
go.opentelemetry.io/otel/trace v1.11.1 // indirect
|
go.opentelemetry.io/otel/trace v1.11.1 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 // indirect
|
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 // indirect
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||||
|
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 // indirect
|
||||||
golang.org/x/text v0.3.8 // indirect
|
golang.org/x/text v0.3.8 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
gotest.tools/v3 v3.3.0 // indirect
|
gotest.tools/v3 v3.3.0 // indirect
|
||||||
modernc.org/libc v1.21.5 // indirect
|
modernc.org/libc v1.21.5 // indirect
|
||||||
@@ -129,5 +134,6 @@ require (
|
|||||||
|
|
||||||
replace (
|
replace (
|
||||||
github.com/benbjohnson/clock => github.com/vincentbernat/go-clock v0.0.0-20220922224448-739bd11b5833
|
github.com/benbjohnson/clock => github.com/vincentbernat/go-clock v0.0.0-20220922224448-739bd11b5833
|
||||||
|
github.com/chenyahui/gin-cache => github.com/vincentbernat/gin-cache v0.0.0-20221221202310-6f54afb45ed6
|
||||||
github.com/kentik/patricia => github.com/vincentbernat/patricia v0.0.0-20220923091046-b376a1167a94
|
github.com/kentik/patricia => github.com/vincentbernat/patricia v0.0.0-20220923091046-b376a1167a94
|
||||||
)
|
)
|
||||||
|
|||||||
55
go.sum
55
go.sum
@@ -82,6 +82,8 @@ github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
||||||
@@ -108,12 +110,15 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8
|
|||||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||||
github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns=
|
github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns=
|
||||||
github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||||
github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
|
github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
|
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
||||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||||
github.com/glebarez/go-sqlite v1.20.0 h1:6D9uRXq3Kd+W7At+hOU2eIAeahv6qcYfO8jzmvb4Dr8=
|
github.com/glebarez/go-sqlite v1.20.0 h1:6D9uRXq3Kd+W7At+hOU2eIAeahv6qcYfO8jzmvb4Dr8=
|
||||||
@@ -139,13 +144,19 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
|||||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||||
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||||
|
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||||
|
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
|
||||||
|
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||||
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
|
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
|
||||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
@@ -198,6 +209,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
@@ -233,6 +245,7 @@ github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2I
|
|||||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||||
@@ -253,6 +266,8 @@ github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJz
|
|||||||
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
|
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
|
||||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||||
|
github.com/jellydator/ttlcache/v2 v2.11.1 h1:AZGME43Eh2Vv3giG6GeqeLeFXxwxn1/qHItqWZl6U64=
|
||||||
|
github.com/jellydator/ttlcache/v2 v2.11.1/go.mod h1:RtE5Snf0/57e+2cLWFYWCCsLas2Hy3c5Z4n14XmSvTI=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
@@ -264,6 +279,7 @@ github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGu
|
|||||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1 h1:Q6uM1SfwyYPCBtezf829EqAqolrIGhAm6KfVx3QBRWg=
|
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1 h1:Q6uM1SfwyYPCBtezf829EqAqolrIGhAm6KfVx3QBRWg=
|
||||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
@@ -291,12 +307,14 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
|
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
|
||||||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
@@ -326,6 +344,17 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/netsampler/goflow2 v1.1.1-0.20221008154147-57fad2e0c837 h1:oO41e5uathu41BOCco3GIkyoYiKz9skbW805rMomwBc=
|
github.com/netsampler/goflow2 v1.1.1-0.20221008154147-57fad2e0c837 h1:oO41e5uathu41BOCco3GIkyoYiKz9skbW805rMomwBc=
|
||||||
github.com/netsampler/goflow2 v1.1.1-0.20221008154147-57fad2e0c837/go.mod h1:C9f54WtFVVbGpPWnpLMz+/hS3c7wc4L0g9ZzdIFAcuM=
|
github.com/netsampler/goflow2 v1.1.1-0.20221008154147-57fad2e0c837/go.mod h1:C9f54WtFVVbGpPWnpLMz+/hS3c7wc4L0g9ZzdIFAcuM=
|
||||||
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
|
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||||
|
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||||
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
|
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||||
|
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
|
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
|
||||||
@@ -439,11 +468,15 @@ github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03O
|
|||||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||||
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||||
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
|
github.com/vincentbernat/gin-cache v0.0.0-20221221202310-6f54afb45ed6 h1:qP2BJklMG2KpyRjeY1lbJYA5ezSNkjgKUIYlrDCyWLg=
|
||||||
|
github.com/vincentbernat/gin-cache v0.0.0-20221221202310-6f54afb45ed6/go.mod h1:eEAwR4874QJI3dY7rdkoartzwVD0e1iq8wEJaEbzA64=
|
||||||
github.com/vincentbernat/go-clock v0.0.0-20220922224448-739bd11b5833 h1:eeHgOFlrGNESR9TF+AJovNWOxH8AdmXWK2nGXKa6RUU=
|
github.com/vincentbernat/go-clock v0.0.0-20220922224448-739bd11b5833 h1:eeHgOFlrGNESR9TF+AJovNWOxH8AdmXWK2nGXKa6RUU=
|
||||||
github.com/vincentbernat/go-clock v0.0.0-20220922224448-739bd11b5833/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/vincentbernat/go-clock v0.0.0-20220922224448-739bd11b5833/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/vincentbernat/patricia v0.0.0-20220923091046-b376a1167a94 h1:T7+yyM6300NYIv1kqlXX53d2cjEHpgDt6cFbBYO+upk=
|
github.com/vincentbernat/patricia v0.0.0-20220923091046-b376a1167a94 h1:T7+yyM6300NYIv1kqlXX53d2cjEHpgDt6cFbBYO+upk=
|
||||||
@@ -480,6 +513,8 @@ go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4=
|
|||||||
go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE=
|
go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE=
|
||||||
go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ=
|
go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ=
|
||||||
go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk=
|
go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk=
|
||||||
|
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
||||||
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
@@ -514,6 +549,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
|||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
|
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
|
||||||
|
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
@@ -526,6 +563,7 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -550,6 +588,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
|
|||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
|
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
@@ -559,6 +598,7 @@ golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
@@ -584,8 +624,11 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
|
||||||
|
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -599,14 +642,18 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -626,6 +673,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -677,6 +725,7 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
@@ -704,9 +753,12 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
|||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
|
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -797,6 +849,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs=
|
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs=
|
||||||
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk=
|
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk=
|
||||||
@@ -805,6 +859,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
|||||||
Reference in New Issue
Block a user