diff --git a/cluster/prov_k8s.go b/cluster/prov_k8s.go index 6459ed7b8..cc49a78c7 100644 --- a/cluster/prov_k8s.go +++ b/cluster/prov_k8s.go @@ -1,6 +1,7 @@ package cluster import ( + "context" "encoding/json" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -34,7 +35,7 @@ func (cluster *Cluster) K8SGetNodes() ([]Agent, error) { cluster.LogPrintf(LvlErr, "Cannot init Kubernetes client API %s ", err) return nil, err } - nodes, err := client.CoreV1().Nodes().List(metav1.ListOptions{}) + nodes, err := client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) agents := []Agent{} for _, n := range nodes.Items { var agent Agent diff --git a/cluster/prov_k8s_db.go b/cluster/prov_k8s_db.go index 1cfe5c1f7..f59a21560 100644 --- a/cluster/prov_k8s_db.go +++ b/cluster/prov_k8s_db.go @@ -1,6 +1,7 @@ package cluster import ( + "context" "strconv" appsv1 "k8s.io/api/apps/v1" @@ -18,7 +19,7 @@ func (cluster *Cluster) K8SProvisionDatabaseService(s *ServerMonitor) { return } namespace := &apiv1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: cluster.Name}} - _, err = client.CoreV1().Namespaces().Create(namespace) + _, err = client.CoreV1().Namespaces().Create(context.TODO(), namespace, metav1.CreateOptions{}) if err != nil { cluster.LogPrintf(LvlErr, "Cannot create namespace %s ", err) } @@ -88,7 +89,7 @@ func (cluster *Cluster) K8SProvisionDatabaseService(s *ServerMonitor) { }, }, } - pvcresult, pvcerr := persistentVolumeClaims.Create(pvc) + pvcresult, pvcerr := persistentVolumeClaims.Create(context.TODO(), pvc, metav1.CreateOptions{}) if pvcerr != nil { cluster.LogPrintf(LvlErr, "Cannot deploy Kubernetes pvc %s ", pvcerr) } @@ -182,7 +183,7 @@ func (cluster *Cluster) K8SProvisionDatabaseService(s *ServerMonitor) { // Create Deployment cluster.LogPrintf(LvlInfo, "Creating Kubernetes deployment...") - result, err := deploymentsClient.Create(deployment) + result, err := deploymentsClient.Create(context.TODO(), deployment, metav1.CreateOptions{}) if err != nil { cluster.LogPrintf(LvlErr, "Cannot deploy Kubernetes deployment %s ", err) } @@ -209,7 +210,7 @@ func (cluster *Cluster) K8SProvisionDatabaseService(s *ServerMonitor) { }, } cluster.LogPrintf(LvlInfo, "Creating service...") - result2, err2 := servicesClient.Create(service) + result2, err2 := servicesClient.Create(context.TODO(), service, metav1.CreateOptions{}) if err2 != nil { cluster.LogPrintf(LvlErr, "Cannot deploy Kubernetes service %s ", err2) cluster.errorChan <- err2 @@ -238,7 +239,7 @@ func (cluster *Cluster) K8SUnprovisionDatabaseService(s *ServerMonitor) { } deletePolicy := metav1.DeletePropagationForeground - if err := deploymentsClient.Delete(s.Name, &metav1.DeleteOptions{ + if err := deploymentsClient.Delete(context.TODO(), s.Name, metav1.DeleteOptions{ PropagationPolicy: &deletePolicy, }); err != nil { cluster.LogPrintf(LvlErr, "Cannot delete Kubernetes deployment %s %s ", s.Name, err) @@ -246,7 +247,7 @@ func (cluster *Cluster) K8SUnprovisionDatabaseService(s *ServerMonitor) { } cluster.LogPrintf(LvlInfo, "Deleted Kubernetes deployment %s.", s.Name) servicesClient := client.CoreV1().Services(cluster.Name) - if err := servicesClient.Delete(s.Name, &metav1.DeleteOptions{ + if err := servicesClient.Delete(context.TODO(), s.Name, metav1.DeleteOptions{ PropagationPolicy: &deletePolicy, }); err != nil { cluster.LogPrintf(LvlErr, "Cannot delete Kubernetes service %s %s ", s.Name, err) diff --git a/cluster/prov_k8s_prx.go b/cluster/prov_k8s_prx.go index 43d8cc984..7fd76b76b 100644 --- a/cluster/prov_k8s_prx.go +++ b/cluster/prov_k8s_prx.go @@ -1,6 +1,7 @@ package cluster import ( + "context" "errors" "strconv" @@ -57,7 +58,7 @@ func (cluster *Cluster) K8SProvisionProxyService(prx DatabaseProxy) { // Create Deployment cluster.LogPrintf(LvlInfo, "Creating deployment...") - result, err := deploymentsClient.Create(deployment) + result, err := deploymentsClient.Create(context.TODO(), deployment, metav1.CreateOptions{}) if err != nil { cluster.LogPrintf(LvlErr, "Cannot deploy Kubernetes service %s ", err) diff --git a/go.mod b/go.mod index 1ce2e87a7..2c295b79f 100644 --- a/go.mod +++ b/go.mod @@ -1,35 +1,27 @@ module github.com/signal18/replication-manager -go 1.12 +go 1.16 replace github.com/kahing/goofys => github.com/georgyo/goofys v0.21.0 require ( github.com/Azure/azure-pipeline-go v0.2.2 - github.com/Azure/azure-sdk-for-go v33.2.0+incompatible + github.com/Azure/azure-sdk-for-go v44.0.0+incompatible github.com/Azure/azure-storage-blob-go v0.8.0 - github.com/Azure/go-autorest v12.2.0+incompatible - github.com/Azure/go-autorest/autorest v0.9.0 - github.com/Azure/go-autorest/autorest/adal v0.6.0 - github.com/Azure/go-autorest/autorest/azure/auth v0.3.0 - github.com/Azure/go-autorest/autorest/azure/cli v0.3.0 - github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect - github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect + github.com/Azure/go-autorest/autorest v0.11.0 + github.com/Azure/go-autorest/autorest/adal v0.9.0 + github.com/Azure/go-autorest/autorest/azure/auth v0.5.0 + github.com/Azure/go-autorest/autorest/azure/cli v0.4.0 github.com/BurntSushi/toml v0.3.1 github.com/JaderDias/movingmedian v0.0.0-20170611140316-de8c410559fa github.com/NYTimes/gziphandler v0.0.0-20180125165240-289a3b81f5ae - github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect - github.com/aclements/go-moremath v0.0.0-20170210193428-033754ab1fee github.com/alyu/configparser v0.0.0-20151125021232-26b2fe18bee1 - github.com/armon/go-metrics v0.0.0-20171117184120-7aa49fde8082 github.com/asaskevich/govalidator v0.0.0-20180115102450-4b3d68f87f17 github.com/aws/aws-sdk-go v1.29.24 github.com/bluele/logrus_slack v0.0.0-20170812021752-74aa3c9b7cc3 - github.com/bluele/slack v0.0.0-20180528010058-b4b4d354a079 github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d github.com/codegangsta/negroni v0.3.0 github.com/davecgh/go-spew v1.1.1 - github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgryski/carbonzipper v0.0.0-20170426152955-d1a3cec4169b github.com/dgryski/go-expirecache v0.0.0-20170314133854-743ef98b2adb @@ -37,137 +29,130 @@ require ( github.com/dgryski/go-trigram v0.0.0-20160407183937-79ec494e1ad0 github.com/dgryski/httputil v0.0.0-20160116060654-189c2918cd08 github.com/dustin/go-humanize v1.0.0 - github.com/elgs/gojq v0.0.0-20201120033525-b5293fef2759 - github.com/elgs/gosplitargs v0.0.0-20161028071935-a491c5eeb3c8 // indirect github.com/evmar/gocairo v0.0.0-20160222165215-ddd30f837497 - github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 - github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a github.com/facebookgo/grace v0.0.0-20170218225239-4afe952a37a4 - github.com/facebookgo/httpdown v0.0.0-20160323221027-a3b1354551a2 github.com/facebookgo/pidfile v0.0.0-20150612191647-f242e2999868 - github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4 - github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect - github.com/fsnotify/fsnotify v1.4.7 - github.com/fsouza/go-dockerclient v1.7.3 - github.com/gin-contrib/cors v1.3.1 - github.com/gin-gonic/gin v1.7.2 - github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-sql-driver/mysql v1.5.0 github.com/gogo/protobuf v1.3.2 - github.com/gonum/blas v0.0.0-20180125090452-e7c5890b24cf - github.com/gonum/floats v0.0.0-20180125090339-7de1f4ea7ab5 - github.com/gonum/internal v0.0.0-20180125090855-fda53f8d2571 - github.com/gonum/lapack v0.0.0-20180125091020-f0b8b25edece github.com/gonum/matrix v0.0.0-20180124231301-a41cc49d4c29 github.com/google/uuid v1.1.2 - github.com/googleapis/gnostic v0.3.1 // indirect - github.com/gorilla/context v1.1.1 github.com/gorilla/handlers v1.3.0 github.com/gorilla/mux v1.8.0 - github.com/gorilla/securecookie v1.1.1 - github.com/gorilla/sessions v0.0.0-20180209192218-6ba88b7f1c1e github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 - github.com/grpc-ecosystem/grpc-gateway v1.9.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 github.com/gwenn/yacr v0.0.0-20180209192453-77093bdc7e72 - github.com/hashicorp/consul v0.0.0-20180215214858-1ce90e2a19ea - github.com/hashicorp/go-cleanhttp v0.0.0-20171218145408-d5fe4b57a186 - github.com/hashicorp/go-immutable-radix v0.0.0-20180129170900-7f3cd4390caa - github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 - github.com/hashicorp/golang-lru v0.5.1 - github.com/hashicorp/hcl v1.0.0 - github.com/hashicorp/serf v0.0.0-20180213013805-d4f33d5b6a0b github.com/helloyi/go-sshclient v1.0.0 github.com/howeyc/fsnotify v0.0.0-20151003194602-f0c08ee9c607 github.com/hpcloud/tail v1.0.0 github.com/hydrogen18/stalecucumber v0.0.0-20161215203336-0a94983f3e27 github.com/improbable-eng/grpc-web v0.14.0 - github.com/inconshreveable/mousetrap v1.0.0 github.com/iu0v1/gelada v1.2.2 github.com/jacobsa/fuse v0.0.0-20211125163655-ffd6c474e806 github.com/jmoiron/sqlx v1.2.0 github.com/jordan-wright/email v0.0.0-20160301001728-a62870b0c368 - github.com/juju/errors v0.0.0-20170703010042-c7d06af17c68 - github.com/juju/go4 v0.0.0-20160222163258-40d72ab9641a // indirect - github.com/juju/persistent-cookiejar v0.0.0-20171026135701-d5e5a8405ef9 // indirect - github.com/kahing/goofys v0.23.1 - github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/juju/errors v0.0.0-20220203013757-bd733f3c86b9 github.com/kisielk/og-rek v0.0.0-20170425174049-dd41cde712de github.com/lestrrat/go-file-rotatelogs v0.0.0-20171229092148-f984502973a0 github.com/lestrrat/go-strftime v0.0.0-20170113112000-04ef93e28531 github.com/lib/pq v1.3.0 - github.com/lxc/lxd v0.0.0-20210622204105-d8ec22465902 - github.com/magiconair/properties v1.8.0 github.com/magneticio/vamp-router v0.0.0-20151116102511-29379b621548 - github.com/mattn/go-runewidth v0.0.0-20170510074858-97311d9f7767 github.com/mattn/go-sqlite3 v1.9.0 - github.com/micro/go-log v0.1.0 // indirect github.com/micro/go-micro v0.1.4 - github.com/micro/misc v0.1.0 // indirect - github.com/miekg/dns v1.1.43 github.com/mitchellh/go-homedir v1.1.0 - github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 - github.com/mitchellh/mapstructure v1.1.2 github.com/mjibson/go-dsp v0.0.0-20170104183934-49dba8372707 github.com/nsf/termbox-go v0.0.0-20180129072728-88b7b944be8b - github.com/pborman/uuid v1.2.0 // indirect - github.com/pelletier/go-toml v1.2.0 github.com/percona/go-mysql v0.0.0-20190307200310-f5cfaf6a5e55 github.com/peterbourgon/g2g v0.0.0-20161124161852-0c2bab2b173d github.com/pingcap/dumpling v0.0.0-20200319081211-255ce0d25719 - github.com/pingcap/errors v0.11.4 - github.com/pires/go-proxyproto v0.0.0-20190615163442-2c19fd512994 - github.com/pkg/errors v0.9.1 - github.com/pmezard/go-difflib v1.0.0 - github.com/rs/cors v1.7.0 // indirect github.com/satori/go.uuid v1.2.0 github.com/shirou/gopsutil v2.20.2+incompatible - github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 - github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed github.com/siddontang/go-mysql v0.0.0-20190311123328-7fc3b28d6104 github.com/siddontang/go-mysql-elasticsearch v0.0.0-20180201161913-f34f371d4391 github.com/sirupsen/logrus v1.7.0 - github.com/spf13/afero v1.1.2 - github.com/spf13/cast v1.3.0 github.com/spf13/cobra v0.0.6 - github.com/spf13/jwalterweatherman v1.0.0 - github.com/spf13/pflag v1.0.3 + github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.4.0 - github.com/stretchr/testify v1.5.1 - github.com/swaggest/swgui v1.4.2 // indirect + github.com/stretchr/testify v1.6.1 github.com/tebeka/strftime v0.1.5 github.com/urfave/cli v1.22.3 - github.com/walle/lll v1.0.1 // indirect github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f github.com/xwb1989/sqlparser v0.0.0-20171128062118-da747e0c62c4 github.com/yoheimuta/protolint v0.32.0 - go.uber.org/zap v1.14.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/net v0.0.0-20211105192438-b53810dc28af - golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e - golang.org/x/text v0.3.6 - google.golang.org/appengine v1.6.6 + google.golang.org/api v0.30.0 google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced google.golang.org/grpc v1.38.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 google.golang.org/protobuf v1.26.0 - gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect - gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b - gopkg.in/fsnotify/fsnotify.v1 v1.4.7 - gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/ini.v1 v1.55.0 - gopkg.in/macaroon-bakery.v2 v2.3.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 - gopkg.in/retry.v1 v1.0.3 // indirect - gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 - gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.0.0-20191016225839-816a9b7df678 - k8s.io/apimachinery v0.0.0-20191017185446-6e68a40eebf9 - k8s.io/client-go v0.0.0-20190620085101-78d2af792bab - mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect - mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect + k8s.io/api v0.18.2 + k8s.io/apimachinery v0.18.2 + k8s.io/client-go v0.18.2 +) + +require ( + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect + github.com/aclements/go-moremath v0.0.0-20170210193428-033754ab1fee // indirect + github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/bluele/slack v0.0.0-20180528010058-b4b4d354a079 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect + github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect + github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect + github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c // indirect + github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 // indirect + github.com/facebookgo/httpdown v0.0.0-20160323221027-a3b1354551a2 // indirect + github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect + github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4 // indirect + github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect + github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect + github.com/gin-gonic/gin v1.7.2 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect + github.com/gonum/blas v0.0.0-20180125090452-e7c5890b24cf // indirect + github.com/gonum/floats v0.0.0-20180125090339-7de1f4ea7ab5 // indirect + github.com/gonum/internal v0.0.0-20180125090855-fda53f8d2571 // indirect + github.com/gonum/lapack v0.0.0-20180125091020-f0b8b25edece // indirect + github.com/googleapis/gnostic v0.3.1 // indirect + github.com/gorilla/context v1.1.1 // indirect + github.com/gorilla/securecookie v1.1.1 // indirect + github.com/gorilla/sessions v0.0.0-20180209192218-6ba88b7f1c1e // indirect + github.com/hashicorp/consul v0.0.0-20180215214858-1ce90e2a19ea // indirect + github.com/hashicorp/go-discover v0.0.0-20220105235006-b95dfa40aaed // indirect + github.com/hashicorp/go-memdb v1.3.2 // indirect + github.com/hashicorp/go-msgpack v1.1.5 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect + github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/go-syslog v1.0.0 // indirect + github.com/hashicorp/go-uuid v1.0.2 // indirect + github.com/hashicorp/go-version v1.4.0 // indirect + github.com/hashicorp/hil v0.0.0-20210521165536-27a72121fd40 // indirect + github.com/hashicorp/logutils v1.0.0 // indirect + github.com/hashicorp/memberlist v0.3.1 // indirect + github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 // indirect + github.com/hashicorp/raft v1.3.6 // indirect + github.com/hashicorp/raft-boltdb v0.0.0-20211202195631-7d34b9fb3f42 // indirect + github.com/hashicorp/serf v0.0.0-20180213013805-d4f33d5b6a0b // indirect + github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect + github.com/juju/testing v0.0.0-20220203020004-a0ff61f03494 // indirect + github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect + github.com/mattn/go-runewidth v0.0.0-20170510074858-97311d9f7767 // indirect + github.com/miekg/dns v1.1.43 // indirect + github.com/mitchellh/cli v1.1.2 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect + github.com/pkg/xattr v0.4.6 + github.com/rs/cors v1.7.0 // indirect + github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed // indirect + github.com/smartystreets/goconvey v1.7.2 // indirect + golang.org/x/tools v0.1.7 // indirect + google.golang.org/grpc/examples v0.0.0-20220316190256-c4cabf78f4a2 // indirect nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/go.sum b/go.sum index 2d37c1cdc..f059dbef3 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -13,6 +12,7 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -35,51 +35,56 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-sdk-for-go v33.2.0+incompatible h1:eDPeIqsD1UxYEcrn/DMxhfA47QcvaOXGtj4MkGIHIio= -github.com/Azure/azure-sdk-for-go v33.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v44.0.0+incompatible h1:e82Yv2HNpS0kuyeCrV29OPKvEiqfs2/uJHic3/3iKdg= +github.com/Azure/azure-sdk-for-go v44.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-storage-blob-go v0.8.0 h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFEY95rZLK0Tj6o= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v12.2.0+incompatible h1:2Fxszbg492oAJrcvJlgyVaTqnQYRkxmEK6VPCLLVpBI= -github.com/Azure/go-autorest v12.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v14.0.0+incompatible h1:r/ug62X9o8vikt53/nkAPmFmzfSrCCAplPH7wa+mK0U= -github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY= +github.com/Azure/go-autorest/autorest v0.11.0 h1:tnO41Uo+/0sxTMFY/U7aKg2abek3JOnnXcuSuba74jI= +github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.6.0 h1:UCTq22yE3RPgbU/8u4scfnnzuCW6pwQ9n+uBtV78ouo= -github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/azure/auth v0.3.0 h1:JwftqZDtWkr3qt1kcEgPd7H57uCHsXKXf66agWUQcGw= -github.com/Azure/go-autorest/autorest/azure/auth v0.3.0/go.mod h1:CI4BQYBct8NS7BXNBBX+RchsFsUu5+oz+OSyR/ZIi7U= -github.com/Azure/go-autorest/autorest/azure/cli v0.3.0 h1:5PAqnv+CSTwW9mlZWZAizmzrazFWEgZykEZXpr2hDtY= -github.com/Azure/go-autorest/autorest/azure/cli v0.3.0/go.mod h1:rNYMNAefZMRowqCV0cVhr/YDW5dD7afFq9nXAXL4ykE= +github.com/Azure/go-autorest/autorest/adal v0.9.0 h1:SigMbuFNuKgc1xcGhaeapbh+8fgsu+GxgDRFyg7f5lM= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.0 h1:nSMjYIe24eBYasAIxt859TxyXef/IqoH+8/g4+LmcVs= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.0/go.mod h1:QRTvSZQpxqm8mSErhnbI+tANIBAKP7B+UIE2z4ypUO0= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.0 h1:Ml+UCrnlKD+cJmSzrZ/RDcDw86NjkRUpnFh7V5JUhzU= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= -github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/autorest/validation v0.2.0 h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4= -github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= -github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/autorest/mocks v0.4.0 h1:z20OWOSG5aCye0HEkDp6TPmP17ZcfeMxPi6HnSALa8c= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.0 h1:3I9AAI63HfcLtphd9g39ruUwRI+Ca+z/f36KHPFRUss= +github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8Pcx+3oqrE= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/BurntSushi/toml v0.0.0-20170626110600-a368813c5e64/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/JaderDias/movingmedian v0.0.0-20170611140316-de8c410559fa h1:bV0zbEchxY6+/yBbwqBAtdLyCPRDJtkp0qRRaK2BseI= github.com/JaderDias/movingmedian v0.0.0-20170611140316-de8c410559fa/go.mod h1:zsfWLaDctbM7aV1TsQAwkVswuKQ0k7PK4rjC1VZqpbI= -github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v0.0.0-20180125165240-289a3b81f5ae h1:wwJ+IRgMBau0lvtcpBePc2kv+EcrGB4PM/S/s7Vj7hY= github.com/NYTimes/gziphandler v0.0.0-20180125165240-289a3b81f5ae/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -88,81 +93,76 @@ github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY= github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/aclements/go-moremath v0.0.0-20170210193428-033754ab1fee h1:U/M5WeoRJXGbprTIaGaw8egvYgNU8eXlS727Y4QM1tA= github.com/aclements/go-moremath v0.0.0-20170210193428-033754ab1fee/go.mod h1:idZL3yvz4kzx1dsBOAC+oYv6L92P1oFEhUXUB1A/lwQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alexflint/go-arg v0.0.0-20160306200701-e71d6514f40a h1:Bc+P30eTWphhueyACA/fjiHJXRDq/kGiqO38nGxvml0= -github.com/alexflint/go-arg v0.0.0-20160306200701-e71d6514f40a/go.mod h1:PHxo6ZWOLVMZZgWSAqBynb/KhIqoGO6WKwOVX7rM9dg= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alyu/configparser v0.0.0-20151125021232-26b2fe18bee1 h1:1Gx9bRdpjHB117HvjqEhUJpc47jWVnQCyCv4YfLsBjo= github.com/alyu/configparser v0.0.0-20151125021232-26b2fe18bee1/go.mod h1:AQsRkKr3LShUSgddjIcPP5axBgCGGegOiMu9nHAlqJw= -github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 h1:7Ip0wMmLHLRJdrloDxZfhMm0xrLXZS8+COSu2bXmEQs= +github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20171117184120-7aa49fde8082 h1:nMRgtnDf0vgx26vmAxGbYXE7dVpjeB4JGf8Xxx5+yEw= -github.com/armon/go-metrics v0.0.0-20171117184120-7aa49fde8082/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.8 h1:oOxq3KPj0WhCuy50EhzwiyMyG2ovRQZpZLXQuOh2a/M= +github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20180115102450-4b3d68f87f17 h1:GnZsKG2FxFy+VjHNiM8/EhHTWJJvOkzT0sY9bo7yyXo= github.com/asaskevich/govalidator v0.0.0-20180115102450-4b3d68f87f17/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.29.24 h1:KOnds/LwADMDBaALL4UB98ZR+TUR1A1mYmAYbdLixLA= github.com/aws/aws-sdk-go v1.29.24/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bluele/logrus_slack v0.0.0-20170812021752-74aa3c9b7cc3 h1:kKYT0P5SrzKEzyUIYyQYesnwf781tSrQiDCd9CxW1rI= github.com/bluele/logrus_slack v0.0.0-20170812021752-74aa3c9b7cc3/go.mod h1:Tm/trewgCoBsNWfA7ZNTQEQSZUeb21MUdWsB6fNVF5Y= github.com/bluele/slack v0.0.0-20180528010058-b4b4d354a079 h1:dm7wU6Dyf+rVGryOAB8/J/I+pYT/9AdG8dstD3kdMWU= github.com/bluele/slack v0.0.0-20180528010058-b4b4d354a079/go.mod h1:W679Ri2W93VLD8cVpEY/zLH1ow4zhJcCyjzrKxfM3QM= -github.com/bool64/dev v0.1.41/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= -github.com/bool64/dev v0.1.42/go.mod h1:cTHiTDNc8EewrQPy3p1obNilpMpdmlUesDkFTF2zRWU= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d h1:7IjN4QP3c38xhg6wz8R3YjoU+6S9e7xBc0DAVLLIpHE= github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/codegangsta/negroni v0.3.0 h1:ByBtJaE0u71x6Ebli7lm95c8oCkrmF88+s5qB2o6j8I= github.com/codegangsta/negroni v0.3.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= -github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= -github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.3 h1:ijQT13JedHSHrQGWFcGEwzcNKrAGIiZ+jSD5QQG07SY= -github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= -github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v0.0.0-20180203072859-87df7c60d582/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o= +github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e/go.mod h1:3ZQK6DMPSz/QZ73jlWxBtUhNA8xZx7LzUFSq/OfP8vk= -github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgrijalva/jwt-go v3.1.0+incompatible h1:FFziAwDQQ2dz1XClWMkwvukur3evtZx7x/wMHKM1i20= -github.com/dgrijalva/jwt-go v3.1.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/carbonzipper v0.0.0-20170426152955-d1a3cec4169b h1:rHojBB8Tas7hIH00MJsRyZU9yIXYNxE7mmVWHgcW/ik= @@ -176,32 +176,27 @@ github.com/dgryski/go-trigram v0.0.0-20160407183937-79ec494e1ad0 h1:b+7JSiBM+hnL github.com/dgryski/go-trigram v0.0.0-20160407183937-79ec494e1ad0/go.mod h1:qzKC/DpcxK67zaSHdCmIv3L9WJViHVinYXN2S7l3RM8= github.com/dgryski/httputil v0.0.0-20160116060654-189c2918cd08 h1:BGzXzhmOgLHlylvQ27Tcgz235JvonPEgdMtpaZaeZt0= github.com/dgryski/httputil v0.0.0-20160116060654-189c2918cd08/go.mod h1:FdR8QjYJOW8OhZGga6zhJxYW2zdtZIqe7to/I3DOnwg= +github.com/digitalocean/godo v1.7.5 h1:JOQbAO6QT1GGjor0doT0mXefX2FgUDPOpYh2RaXA+ko= +github.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ= -github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4 h1:qk/FSDDxo05wdJH28W+p5yivv7LuLYLRXPPD8KQCtZs= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elgs/gojq v0.0.0-20201120033525-b5293fef2759 h1:WtAKk9RULee8RXnR3to5hg7TrsPVCdxYVrOZRjR54LU= -github.com/elgs/gojq v0.0.0-20201120033525-b5293fef2759/go.mod h1:rQELVIqRXpraeUryHOBadz99ePvEVQmTVpGr8M9QQ4Q= -github.com/elgs/gosplitargs v0.0.0-20161028071935-a491c5eeb3c8 h1:bD2/rCXwgXJm2vgoSSSCM9IPjVFfEoQFFblzg7HHABI= -github.com/elgs/gosplitargs v0.0.0-20161028071935-a491c5eeb3c8/go.mod h1:o4DgpccPNAQAlPSxo7I4L/LWNh2oyr/BBGSynrLTmZM= +github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw= +github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evmar/gocairo v0.0.0-20160222165215-ddd30f837497 h1:DIQ8EvZ8OjuPNfcV4NgsyBeZho7WsTD0JEkDM5napMI= github.com/evmar/gocairo v0.0.0-20160222165215-ddd30f837497/go.mod h1:YXKUYPSqs+jDG8mvexHN2uTik4PKwg2B0WK9itQ0VrE= @@ -209,38 +204,35 @@ github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 h1:wWke/RUCl7VRjQhwPlR/v0glZXNYzBHdNUzf/Am2Nmg= +github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9/go.mod h1:uPmAp6Sws4L7+Q/OokbWDAK1ibXYhB3PXFP1kol5hPg= github.com/facebookgo/grace v0.0.0-20170218225239-4afe952a37a4 h1:c8bY3vJpaia8nrZANEBY8yL7rGg7TSit8O1eAJe4hbo= github.com/facebookgo/grace v0.0.0-20170218225239-4afe952a37a4/go.mod h1:KigFdumBXUPSwzLDbeuzyt0elrL7+CP7TKuhrhT4bcU= github.com/facebookgo/httpdown v0.0.0-20160323221027-a3b1354551a2 h1:3Zvf9wRhl1cOhckN1oRGWPOkIhOketmEcrQ4TeFAoR4= github.com/facebookgo/httpdown v0.0.0-20160323221027-a3b1354551a2/go.mod h1:TUV/fX3XrTtBQb5+ttSUJzcFgLNpILONFTKmBuk5RSw= github.com/facebookgo/pidfile v0.0.0-20150612191647-f242e2999868 h1:KZ75X3ZCl6yy4jg9R1ziYoCZFDBRqildm+fGComWU7U= github.com/facebookgo/pidfile v0.0.0-20150612191647-f242e2999868/go.mod h1:3Hzo46xzfVpIdv4lJw7YBp9fUJ7HpUgbjH1fFDgy4qM= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4 h1:0YtRCqIZs2+Tz49QuH6cJVw/IFqzo39gEqZ0iYLxD2M= github.com/facebookgo/stats v0.0.0-20151006221625-1b76add642e4/go.mod h1:vsJz7uE339KUCpBXx3JAJzSRH7Uk4iGGyJzR529qDIA= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 h1:fmFk0Wt3bBxxwZnu48jqMdaOR/IZ4vdtJFuaFV8MpIE= -github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3/go.mod h1:bJWSKrZyQvfTnb2OudyUjurSG4/edverV7n82+K3JiM= -github.com/frankban/quicktest v1.0.0/go.mod h1:R98jIehRai+d1/3Hv2//jOVCTJhW1VBavT6B6CuGq2k= -github.com/frankban/quicktest v1.1.0/go.mod h1:R98jIehRai+d1/3Hv2//jOVCTJhW1VBavT6B6CuGq2k= -github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsouza/go-dockerclient v1.7.3 h1:i6iMcktl688vsKUEExA6gU1UjPgIvmGtJeQ0mbuFqZo= -github.com/fsouza/go-dockerclient v1.7.3/go.mod h1:8xfZB8o9SptLNJ13VoV5pMiRbZGWkU/Omu5VOu/KC9Y= -github.com/georgyo/goofys v0.21.0 h1:SOuQwIUFqWDQ4V4WMiRiVtA9xwUPtntGGGDppSuA5f8= -github.com/georgyo/goofys v0.21.0/go.mod h1:rB6r+OqpoZThKFnCEGPlmUWDV3Jtb5QSupOtQ1ZA1q4= github.com/gertd/go-pluralize v0.1.1 h1:fQhql/WRRwr4TVp+TCw12s2esCacvEVBdkTUUwNqF/Q= github.com/gertd/go-pluralize v0.1.1/go.mod h1:t5DfHcumb6m0RqyVJDrDLEzL2AGeaiqUXIcDNwLaeAs= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA= -github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk= 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-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA= github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= @@ -249,13 +241,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-log/log v0.1.0 h1:wudGTNsiGzrD5ZjgIkVZ517ugi2XRe9Q/xRCzwEO4/U= -github.com/go-log/log v0.1.0/go.mod h1:4mBwpdRMFLiuXZDCwU2lKQFsoSCo72j3HqBK9d81N2M= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-macaroon-bakery/macaroonpb v1.0.0 h1:It9exBaRMZ9iix1iJ6gwzfwsDE6ExNuwtAJ9e09v6XE= -github.com/go-macaroon-bakery/macaroonpb v1.0.0/go.mod h1:UzrGOcbiwTXISFP2XDLDPjfhMINZa+fX/7A2lMd31zc= github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= @@ -263,32 +251,25 @@ github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1 github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v0.0.0-20180215110351-b75782e777cf h1:3YMuiXhfyUNRAYvHmDq5q8aCv+Od8yE/1zw/f2KayEk= -github.com/gogo/protobuf v0.0.0-20180215110351-b75782e777cf/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -299,6 +280,7 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -308,12 +290,9 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= @@ -324,8 +303,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -339,26 +316,24 @@ github.com/gonum/lapack v0.0.0-20180125091020-f0b8b25edece h1:dXIQoswVYAQd8m2jqY github.com/gonum/lapack v0.0.0-20180125091020-f0b8b25edece/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A= github.com/gonum/matrix v0.0.0-20180124231301-a41cc49d4c29 h1:Aj+poYy0aVF2abLrHVN2aAxynAGg2AO8VtIJKSnmxMA= github.com/gonum/matrix v0.0.0-20180124231301-a41cc49d4c29/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw= -github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/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.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0= +github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -369,97 +344,132 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= +github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.3.0 h1:tsg9qP3mjt1h4Roxp+M1paRjrVBfPSOpBuVclh6YluI= github.com/gorilla/handlers v1.3.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v0.0.0-20180120075819-c0091a029979 h1:UsXWMy9j+GSCN/I1/Oyc4wGaeW2CDYqeqAkEvWPu+cs= -github.com/gorilla/mux v0.0.0-20180120075819-c0091a029979/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v0.0.0-20180209192218-6ba88b7f1c1e h1:bvt9oeSrSj2llWZrgdfoSuTQVc0YX/pkE+f7KU1ztgo= github.com/gorilla/sessions v0.0.0-20180209192218-6ba88b7f1c1e/go.mod h1:+WVp8kdw6VhyKExm03PAMRn2ZxnPtm58pV0dBVPdhHE= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 h1:ajue7SzQMywqRjg2fK7dcpc0QhFGpTR2plWfV4EZWR4= github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0/go.mod h1:r1hZAcvfFXuYmcKyCJI9wlyOPIZUJl6FCB8Cpca/NLE= github.com/gwenn/yacr v0.0.0-20180209192453-77093bdc7e72 h1:FRg1rT3HjkstYbHdbJ3ZDNSD1cuTSlK2C6iscyd+Ra0= github.com/gwenn/yacr v0.0.0-20180209192453-77093bdc7e72/go.mod h1:5SNcBGxZ5OaJAMJCSI/x3V7SGsvXqbwnwP/sHZLgYsw= github.com/hashicorp/consul v0.0.0-20180215214858-1ce90e2a19ea h1:TYn84wm66RQBJJU31lPvZxu55NNht/vTCMG9PwluW5g= github.com/hashicorp/consul v0.0.0-20180215214858-1ce90e2a19ea/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= -github.com/hashicorp/go-cleanhttp v0.0.0-20171218145408-d5fe4b57a186 h1:URgjUo+bs1KwatoNbwG0uCO4dHN4r1jsp4a5AGgHRjo= -github.com/hashicorp/go-cleanhttp v0.0.0-20171218145408-d5fe4b57a186/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-discover v0.0.0-20220105235006-b95dfa40aaed h1:TOX8g4kKKZ1tkDRZo7hiqHwUSJTNK5li8pU6GmpVQD0= +github.com/hashicorp/go-discover v0.0.0-20220105235006-b95dfa40aaed/go.mod h1:3/4dzY4lR1Hzt9bBqMhBzG7lngZ0GKx/nL6G/ad62wE= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.10.0 h1:b86HUuA126IcSHyC55WjPo7KtCOVeTCKIjr+3lBhPxI= github.com/hashicorp/go-hclog v0.10.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v0.0.0-20180129170900-7f3cd4390caa h1:0nA8i+6Rwqaq9xlpmVxxTwk6rxiEhX+E6Wh4vPNHiS8= -github.com/hashicorp/go-immutable-radix v0.0.0-20180129170900-7f3cd4390caa/go.mod h1:6ij3Z20p+OhOkCSrA0gImAWoHYQRGbnlcuk6XYTiaRw= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.2 h1:RBKHOsnSszpU6vxq80LzC2BaQjuuvoyaQbkLTf7V7g8= +github.com/hashicorp/go-memdb v1.3.2/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= +github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE= github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:VBj0QYQ0u2MCJzBfeYXGexnAl17GsH1yidnoxCqqD9E= github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= -github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47 h1:UnszMmmmm5vLwWzDjTFVIkfhvWF1NdrmChl8L2NUDCw= -github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= +github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v0.0.0-20171017181929-23c074d0eceb h1:1OvvPvZkn/yCQ3xBcM8y4020wdkMXPHLB4+NfoGWh4U= -github.com/hashicorp/hcl v0.0.0-20171017181929-23c074d0eceb/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hil v0.0.0-20210521165536-27a72121fd40 h1:ExwaL+hUy1ys2AWDbsbh/lxQS2EVCYxuj0LoyLTdB3Y= +github.com/hashicorp/hil v0.0.0-20210521165536-27a72121fd40/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.1 h1:XFSOubp8KWB+Jd2PDyaX5xUd5bhSP/+pTDZVDMzZJM8= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/memberlist v0.3.1 h1:MXgUXLqva1QvpVEDQW1IQLG0wivQAtmFlHRQ+1vWZfM= +github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 h1:lc3c72qGlIMDqQpQH82Y4vaglRMMFdJbziYWriR4UcE= +github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft v1.3.6 h1:v5xW5KzByoerQlN/o31VJrFNiozgzGyDoMgDJgXpsto= +github.com/hashicorp/raft v1.3.6/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft-boltdb v0.0.0-20211202195631-7d34b9fb3f42 h1:Ye8SofeDHJzu9xvvaMmpMkqHELWW7rTcXwdUR0CWW48= +github.com/hashicorp/raft-boltdb v0.0.0-20211202195631-7d34b9fb3f42/go.mod h1:wcXL8otVu5cpJVLjcmq7pmfdRCdaP+xnvu7WQcKJAhs= github.com/hashicorp/serf v0.0.0-20180213013805-d4f33d5b6a0b h1:zDlT8SQxogA9IfDmGrQqkjJ3ke6gou+ifrKlXvFS3rM= github.com/hashicorp/serf v0.0.0-20180213013805-d4f33d5b6a0b/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 h1:O/pT5C1Q3mVXMyuqg7yuAWUg/jMZR1/0QTzTRdNR6Uw= +github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/helloyi/go-sshclient v0.0.0-20191203124208-f1e205501005 h1:Oryd+XkS5Tk+8RB1aqF+r5WPtNi8xVPQ9KYh4lTRhkk= -github.com/helloyi/go-sshclient v0.0.0-20191203124208-f1e205501005/go.mod h1:SONC5bXENAC+Y960BqCKzML+BP2/kF1RWeXNdJfysYg= github.com/helloyi/go-sshclient v1.0.0 h1:pwDDc54wwyMlkwYbhszsX2UB1ajJM296WqLDtNDvcn8= github.com/helloyi/go-sshclient v1.0.0/go.mod h1:NrhRWsYJDjoQXTDWZ4YtVk84wZ4LK3NSM9jD2TZDAm8= github.com/howeyc/fsnotify v0.0.0-20151003194602-f0c08ee9c607 h1:+7wvV++11s0Okyl1dekihkIiCIYDz+Qk2LvxAShINU4= github.com/howeyc/fsnotify v0.0.0-20151003194602-f0c08ee9c607/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= -github.com/hpcloud/tail v0.0.0-20180514194441-a1dbeea552b7 h1:lus8hJKTrh146vNoUWNHv2F1jdtsud5ajNL0/YndJUw= -github.com/hpcloud/tail v0.0.0-20180514194441-a1dbeea552b7/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hydrogen18/stalecucumber v0.0.0-20161215203336-0a94983f3e27 h1:gWNC2gGClIz7pzjw4zDXxDCgXw/KfPCWCnosj6s0Fj4= github.com/hydrogen18/stalecucumber v0.0.0-20161215203336-0a94983f3e27/go.mod h1:KE5xQoh/IqNckSFoQXL5o5nEkrBiUDxatgac7TSMQ8Y= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/improbable-eng/grpc-web v0.14.0 h1:GdoK+cXABdB+1keuqsV1drSFO2XLYIxqt/4Rj8SWGBk= github.com/improbable-eng/grpc-web v0.14.0/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/iu0v1/gelada v1.2.2 h1:WH0vmDBPPvtb5F4ml/9dq1PAymJUsHblPwvdrHv+bis= github.com/iu0v1/gelada v1.2.2/go.mod h1:iU0D1s3teiLgoZZP25l2x0pgwh2KLux9wMfwnNYQW/Q= -github.com/jacobsa/fuse v0.0.0-20180417054321-cd3959611bcb h1:TRAjtOoio6kvnrIMLeXesGT9IydfO+zQoioKWrv40nI= -github.com/jacobsa/fuse v0.0.0-20180417054321-cd3959611bcb/go.mod h1:9Aml1MG17JVeXrN4D2mtJvYHtHklJH5bESjCKNzVjFU= -github.com/jacobsa/fuse v0.0.0-20200311085126-7d791d27a25d h1:4gaMlb9FOx56oj4XJaISZjPpVYWWk7+qkZ8gN4bWwXQ= -github.com/jacobsa/fuse v0.0.0-20200311085126-7d791d27a25d/go.mod h1:9Aml1MG17JVeXrN4D2mtJvYHtHklJH5bESjCKNzVjFU= github.com/jacobsa/fuse v0.0.0-20211125163655-ffd6c474e806 h1:DiUk5AzBZMGRMljnsHBvI4uc+rm4UCfgv5nTpAvFLi8= github.com/jacobsa/fuse v0.0.0-20211125163655-ffd6c474e806/go.mod h1:xtZnnLxHY6QniCrfIpTwr5h8mH8zr+jsOFj0y9cfyp4= github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd/go.mod h1:TlmyIZDpGmwRoTWiakdr+HA1Tukze6C6XbRVidYq02M= @@ -468,96 +478,115 @@ github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11/go.mod h1:+DBdDyf github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb/go.mod h1:ivcmUvxXWjb27NsPEaiYK7AidlZXS7oQ5PowUS9z3I4= github.com/jacobsa/syncutil v0.0.0-20180201203307-228ac8e5a6c3/go.mod h1:mPvulh9VKXvo+yOlrD4VYOOYuLdZJ36wa/5QIrtXvWs= github.com/jacobsa/timeutil v0.0.0-20170205232429-577e5acbbcf6/go.mod h1:JEWKD6V8xETMW+DEv+IQVz++f8Cn8O/X0HPeDY3qNis= +github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= +github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= +github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade h1:ryslCsfLTV4Cm/9NXqCJirlbYodWqFiTH454IaSn/fY= -github.com/jmoiron/sqlx v0.0.0-20180124204410-05cef0741ade/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jordan-wright/email v0.0.0-20160301001728-a62870b0c368 h1:b2TVkqHrUSBN4SLLHd4XS/ViQgBUN2R857jpD8ze+bg= github.com/jordan-wright/email v0.0.0-20160301001728-a62870b0c368/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be h1:AHimNtVIpiBjPUhEF5KNCkrUyqTSA5zWUl8sQ2bfGBE= -github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62 h1:JHCT6xuyPUrbbgAPE/3dqlvUKzRHMNuTBKKUb6OeR/k= +github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/juju/errors v0.0.0-20170703010042-c7d06af17c68 h1:d2hBkTvi7B89+OXY8+bBBshPlc+7JYacGrG/dFak8SQ= -github.com/juju/errors v0.0.0-20170703010042-c7d06af17c68/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/go4 v0.0.0-20160222163258-40d72ab9641a h1:45JtCyuNYE+QN9aPuR1ID9++BQU+NMTMudHSuaK0Las= -github.com/juju/go4 v0.0.0-20160222163258-40d72ab9641a/go.mod h1:RVHtZuvrpETIepiNUrNlih2OynoFf1eM6DGC6dloXzk= -github.com/juju/mgotest v1.0.1/go.mod h1:vTaDufYul+Ps8D7bgseHjq87X8eu0ivlKLp9mVc/Bfc= -github.com/juju/persistent-cookiejar v0.0.0-20171026135701-d5e5a8405ef9 h1:5g7E7WtWRslad/0fq68VHgHhFRvTWo30VDaEJ5KEvEc= -github.com/juju/persistent-cookiejar v0.0.0-20171026135701-d5e5a8405ef9/go.mod h1:zrbmo4nBKaiP/Ez3F67ewkMbzGYfXyMvRtbOfuAwG0w= -github.com/juju/postgrestest v1.1.0/go.mod h1:/n17Y2T6iFozzXwSCO0JYJ5gSiz2caEtSwAjh/uLXDM= -github.com/juju/qthttptest v0.0.1/go.mod h1://LCf/Ls22/rPw2u1yWukUJvYtfPY4nYpWUl2uZhryo= -github.com/juju/schema v1.0.0 h1:sZvJ7iQXHhMw/lJ4YfUmq+fe7R2ZSUzZzd/eSokaB3M= -github.com/juju/schema v1.0.0/go.mod h1:Y+ThzXpUJ0E7NYYocAbuvJ7vTivXfrof/IfRPq/0abI= -github.com/juju/webbrowser v0.0.0-20160309143629-54b8c57083b4 h1:go1FDIXkFL8AUWgJ7B68rtFWCidyrMfZH9x3xwFK74s= -github.com/juju/webbrowser v0.0.0-20160309143629-54b8c57083b4/go.mod h1:G6PCelgkM6cuvyD10iYJsjLBsSadVXtJ+nBxFAxE2BU= -github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ansiterm v0.0.0-20160907234532-b99631de12cf/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= +github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA= +github.com/juju/cmd v0.0.0-20171107070456-e74f39857ca0/go.mod h1:yWJQHl73rdSX4DHVKGqkAip+huBslxRwS8m9CrOLq18= +github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271/go.mod h1:5XgO71dV1JClcOJE+4dzdn4HrI5LiyKd7PlVG6eZYhY= +github.com/juju/errors v0.0.0-20150916125642-1b5e39b83d18/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/errors v0.0.0-20200330140219-3fe23663418f/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/errors v0.0.0-20220203013757-bd733f3c86b9 h1:EJHbsNpQyupmMeWTq7inn+5L/WZ7JfzCVPJ+DP9McCQ= +github.com/juju/errors v0.0.0-20220203013757-bd733f3c86b9/go.mod h1:TRm7EVGA3mQOqSVcBySRY7a9Y1/gyVhh/WTCnc5sD4U= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/juju/httpprof v0.0.0-20141217160036-14bf14c30767/go.mod h1:+MaLYz4PumRkkyHYeXJ2G5g5cIW0sli2bOfpmbaMV/g= +github.com/juju/loggo v0.0.0-20170605014607-8232ab8918d9/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/loggo v0.0.0-20200526014432-9ce3a2e09b5e/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/loggo v0.0.0-20210728185423-eebad3a902c4 h1:NO5tuyw++EGLnz56Q8KMyDZRwJwWO8jQnj285J3FOmY= +github.com/juju/loggo v0.0.0-20210728185423-eebad3a902c4/go.mod h1:NIXFioti1SmKAlKNuUwbMenNdef59IF52+ZzuOmHYkg= +github.com/juju/mgo/v2 v2.0.0-20210302023703-70d5d206e208 h1:/WiCm+Vpj87e4QWuWwPD/bNE9kDrWCLvPBHOQNcG2+A= +github.com/juju/mgo/v2 v2.0.0-20210302023703-70d5d206e208/go.mod h1:0OChplkvPTZ174D2FYZXg4IB9hbEwyHkD+zT+/eK+Fg= +github.com/juju/mutex v0.0.0-20171110020013-1fe2a4bf0a3a/go.mod h1:Y3oOzHH8CQ0Ppt0oCKJ2JFO81/EsWenH5AEqigLH+yY= +github.com/juju/retry v0.0.0-20151029024821-62c620325291/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4= +github.com/juju/retry v0.0.0-20180821225755-9058e192b216/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4= +github.com/juju/testing v0.0.0-20180402130637-44801989f0f7/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/juju/testing v0.0.0-20190723135506-ce30eb24acd2/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/juju/testing v0.0.0-20210302031854-2c7ee8570c07/go.mod h1:7lxZW0B50+xdGFkvhAb8bwAGt6IU87JB1H9w4t8MNVM= +github.com/juju/testing v0.0.0-20220202055744-1ad0816210a6/go.mod h1:QgWc2UdIPJ8t3rnvv95tFNOsQDfpXYEZDbP281o3b2c= +github.com/juju/testing v0.0.0-20220203020004-a0ff61f03494 h1:XEDzpuZb8Ma7vLja3+5hzUqVTvAqm5Y+ygvnDs5iTMM= +github.com/juju/testing v0.0.0-20220203020004-a0ff61f03494/go.mod h1:rUquetT0ALL48LHZhyRGvjjBH8xZaZ8dFClulKK5wK4= +github.com/juju/utils v0.0.0-20180424094159-2000ea4ff043/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk= +github.com/juju/utils v0.0.0-20200116185830-d40c2fe10647/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk= +github.com/juju/utils/v2 v2.0.0-20200923005554-4646bfea2ef1/go.mod h1:fdlDtQlzundleLLz/ggoYinEt/LmnrpNKcNTABQATNI= +github.com/juju/utils/v3 v3.0.0-20220130232349-cd7ecef0e94a/go.mod h1:LzwbbEN7buYjySp4nqnti6c6olSqRXUk6RkbSUUP1n8= +github.com/juju/version v0.0.0-20161031051906-1f41e27e54f2/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U= +github.com/juju/version v0.0.0-20180108022336-b64dbd566305/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U= +github.com/juju/version v0.0.0-20191219164919-81c1be00b9a6/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U= +github.com/juju/version/v2 v2.0.0-20211007103408-2e8da085dc23/go.mod h1:Ljlbryh9sYaUSGXucslAEDf0A2XUSGvDbHJgW8ps6nc= +github.com/julienschmidt/httprouter v1.1.1-0.20151013225520-77a895ad01eb/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kahing/fusego v0.0.0-20190829004836-cb66eea2377f h1:j9DNzQ+wrambYEr0IVsoE5RmOg1ZyCYS4Uu4rH6PMM8= -github.com/kahing/fusego v0.0.0-20190829004836-cb66eea2377f/go.mod h1:Qk5T6wYqwRWfKHhEKkRsIXwsAtQ0GK8rBJNYf5LVdwo= -github.com/kahing/goofys v0.23.1 h1:iKqwaGyYp3w+spqQ+bJ97urSTpCPF4juxfR//QCq3T8= -github.com/kahing/goofys v0.23.1/go.mod h1:erC9E45nY5m8v6FE+tYIGRVjIC2N8viMlJrgrsXB2Q4= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/og-rek v0.0.0-20170425174049-dd41cde712de h1:1PkYBSyecuAnHiXSq5B2xXO0VptdSyBHVNv45MiRNsk= github.com/kisielk/og-rek v0.0.0-20170425174049-dd41cde712de/go.mod h1:Fo0gkB8QTO7j5Ha+ObtDMW5GtL5UoY66JUU8ZoLJeLQ= github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 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/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 h1:0iQektZGS248WXmGIYOwRXSQhD4qn3icjMpuxwO7qlo= +github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE= github.com/lestrrat/go-file-rotatelogs v0.0.0-20171229092148-f984502973a0 h1:iVr3oVautdZxVynLvbUBipvk4EnAe+joJMoS+nIdqMo= github.com/lestrrat/go-file-rotatelogs v0.0.0-20171229092148-f984502973a0/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8= github.com/lestrrat/go-strftime v0.0.0-20170113112000-04ef93e28531 h1:qA9RB9NobSxHKYfJrOcqHFL8uanRWCG3+rN4CibuNPc= github.com/lestrrat/go-strftime v0.0.0-20170113112000-04ef93e28531/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lxc/lxd v0.0.0-20210622204105-d8ec22465902 h1:qIeIqkOtJS+csu95FXhPO/Whz4hwlEu1dP2hl03jVaE= -github.com/lxc/lxd v0.0.0-20210622204105-d8ec22465902/go.mod h1:2BaZflfwsv8a3uy3/Vw+de4Avn4DSrAiqaHJjCIXMV4= -github.com/magiconair/properties v1.7.6 h1:U+1DqNen04MdEPgFiIwdOUiqZ8qPa37xgogX/sd3+54= -github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/linode/linodego v0.7.1 h1:4WZmMpSA2NRwlPZcc0+4Gyn7rr99Evk9bnr0B3gXRKE= +github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= +github.com/lunixbochs/vtclean v0.0.0-20160125035106-4fbf7632a2c6/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magneticio/vamp-router v0.0.0-20151116102511-29379b621548 h1:FMcPpuQjLoW8rClUj/Kuun/Uc80zegM8GZth5eAbp40= github.com/magneticio/vamp-router v0.0.0-20151116102511-29379b621548/go.mod h1:nq9RYST5Lx2yy8xKabmS42QYxJfxlmCXzckIO5zl7GY= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/masterzen/azure-sdk-for-go v3.2.0-beta.0.20161014135628-ee4f0065d00c+incompatible/go.mod h1:mf8fjOu33zCqxUjuiU3I8S1lJMyEAlH+0F2+M5xl3hE= +github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= +github.com/masterzen/winrm v0.0.0-20161014151040-7a535cd943fc/go.mod h1:CfZSN7zwz5gJiFhZJz49Uzk7mEBHIceWmbFmYx7Hf7E= +github.com/masterzen/xmlpath v0.0.0-20140218185901-13f4951698ad/go.mod h1:A0zPC53iKKKcXYxr4ROjpQRQ5FgJXtelNdSmHHuq/tY= +github.com/mattn/go-colorable v0.0.6/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.0-20160806122752-66b8e73f3f5c/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -566,72 +595,61 @@ github.com/mattn/go-runewidth v0.0.0-20170510074858-97311d9f7767/go.mod h1:LwmH8 github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/micro/go-log v0.1.0 h1:szYSR+yyTsomZM2jyinJC5562DlqffSjHmTZFaeZ2vY= -github.com/micro/go-log v0.1.0/go.mod h1:qaFBF6d6Jk01Gz4cbMkCA2vVuLk3FSaLLjmEGrMCreA= github.com/micro/go-micro v0.1.4 h1:m8TER3Lfaf1S6NSXLzIQPGegZlnMJXR/ptVbpawcgB4= github.com/micro/go-micro v0.1.4/go.mod h1:3z3lfMkNU9Sr1L/CxL++8pVJmQapRo0N6kNjwYDtOVs= -github.com/micro/misc v0.1.0 h1:/1KLiSWPxYq2uZ89nSEdrupk4zgniDRLtamTO5rdm1I= -github.com/micro/misc v0.1.0/go.mod h1:BEMDgD2UU32Jtb6tgdErzF9xDvZXGKsxv2jYgfKb3o0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747 h1:eQox4Rh4ewJF+mqYPxCkmBAirRnPaHEB26UkNuPyjlk= -github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8= -github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mjibson/go-dsp v0.0.0-20170104183934-49dba8372707 h1:onb6q16M5ft2+b3zu6YCkMRaWONPM5ofIIZI0OZWtps= github.com/mjibson/go-dsp v0.0.0-20170104183934-49dba8372707/go.mod h1:i/KKcxEWEO8Yyl11DYafRPKOPVYTrhxiTRigjtEEXZU= -github.com/moby/sys/mount v0.2.0 h1:WhCW5B355jtxndN5ovugJlMFJawbUODuW8fSnEH6SSM= -github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM= -github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM= -github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= -github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= +github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/nsf/termbox-go v0.0.0-20180129072728-88b7b944be8b h1:juxXUBpBuF6yPbNHz/8Rv997YZIkeDy4AMb9P7xIqOc= github.com/nsf/termbox-go v0.0.0-20180129072728-88b7b944be8b/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= +github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -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/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.1.0 h1:cmiOvKzEunMsAxyhXSzpL5Q1CRKpVv0KQsnAIcSEVYM= -github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE= +github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/percona/go-mysql v0.0.0-20190307200310-f5cfaf6a5e55 h1:kx48fD4K+GXb7YqwykiWirM8GRtoMcpWbGlaAb3IsqE= @@ -643,7 +661,6 @@ github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 h1:USx2/E1bX46VG32FI github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ= github.com/pingcap/dumpling v0.0.0-20200319081211-255ce0d25719 h1:KUr7fCTCrOdKvaSouVNPo/csZSd9MfhDN/LlLZ1u8gM= github.com/pingcap/dumpling v0.0.0-20200319081211-255ce0d25719/go.mod h1:MJGJT/kwefTq0LWB8mi+SCiJItSsal4N2dw4gb+t5QI= -github.com/pingcap/errors v0.11.0 h1:DCJQB8jrHbQ1VVlMFIrbj2ApScNNotVmkSNplu2yUt4= github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= @@ -651,30 +668,38 @@ github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd h1:CV3VsP3Z02MVtdpTMfE github.com/pingcap/log v0.0.0-20200117041106-d28c14d3b1cd/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= github.com/pingcap/tidb-tools v4.0.0-beta.1.0.20200306103835-530c669f7112+incompatible h1:RYNZrH30AoPmXBJhpFNB6UYE1ivwApG3VfScyQm3opA= github.com/pingcap/tidb-tools v4.0.0-beta.1.0.20200306103835-530c669f7112+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM= -github.com/pires/go-proxyproto v0.0.0-20190615163442-2c19fd512994 h1:3ssKn22MN6oLH+l2iimsBdCliSgELXTBWWR+yooB2lQ= -github.com/pires/go-proxyproto v0.0.0-20190615163442-2c19fd512994/go.mod h1:6/gX3+E/IYGa0wMORlSMla999awQFdbaeQCHjSMKIzY= -github.com/pkg/errors v0.0.0-20180127015812-30136e27e2ac h1:VBnETtEnERI/n2qzYv96JVEYp+sbD0O+n1mXRyXSsxM= -github.com/pkg/errors v0.0.0-20180127015812-30136e27e2ac/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pkg/xattr v0.4.6 h1:0vqthLIMxQKA9VscyMcxjvAUGvyfzlk009vwLE8OZJg= +github.com/pkg/xattr v0.4.6/go.mod h1:sBD3RAqlr8Q+RC3FutZcikpT8nyDrIEEBw2J744gVWs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a/go.mod h1:4r5QyqhjIWCcK8DO4KMclc5Iknq5qVBAlbYYzAbUScQ= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng= +github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o= +github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -682,20 +707,17 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/satori/go.uuid v0.0.0-20180103174451-36e9d2ebbde5/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil v2.20.2+incompatible h1:ucK79BhBpgqQxPASyS2cu9HX8cfDVljBN1WWFvbNvgY= github.com/shirou/gopsutil v2.20.2+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0 h1:mj/nMDAwTBiaCqMEs4cYCqF7pO6Np7vhy1D1wcQGz+E= -github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM= github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4= @@ -705,74 +727,58 @@ github.com/siddontang/go-mysql v0.0.0-20190311123328-7fc3b28d6104 h1:cDoSyBVFZjs github.com/siddontang/go-mysql v0.0.0-20190311123328-7fc3b28d6104/go.mod h1:/b8ZcWjAShCcHp2dWpjb1vTlNyiG03UeHEQr2jteOpI= github.com/siddontang/go-mysql-elasticsearch v0.0.0-20180201161913-f34f371d4391 h1:txoiomEyvmKuMi/8S2p/5sU091TycsNCrXDH6m2gRa4= github.com/siddontang/go-mysql-elasticsearch v0.0.0-20180201161913-f34f371d4391/go.mod h1:/8uSrAf9cCROryrZl3dqZPApfRGeDyzpcvbtnNG8A+Y= -github.com/signal18/replication-manager v0.0.0-20190611114957-f0721d9a5ef8 h1:OufCpe26t0a1KtcaoBka+EeJjJREWTYtYpzZS2QbpOc= -github.com/signal18/replication-manager v0.0.0-20190611114957-f0721d9a5ef8/go.mod h1:Nb4VrJ67KcB8e/n2ldy6xyli8cVhZvjmPj69BnON8Yk= -github.com/sirupsen/logrus v0.0.0-20180213143110-8c0189d9f6bb h1:eKjx20EiekBRT2tjZ0XEdKpftfPJQwiavtFshwTyqf0= -github.com/sirupsen/logrus v0.0.0-20180213143110-8c0189d9f6bb/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= +github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQvfjNUeRqaY/uT0tFuvuFY0ulgnczuR684Xic= +github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v0.0.0-20180211162714-bbf41cb36dff h1:HLvGWId7M56TfuxTeZ6aoiTAcrWO5Mnq/ArwVRgV62I= -github.com/spf13/afero v0.0.0-20180211162714-bbf41cb36dff/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg= -github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.0-20180211162230-be77323fc051 h1:VwGeM0WDoZwUGgTbuvPboprTYzo48S33AwDprcA4GlA= -github.com/spf13/cobra v0.0.0-20180211162230-be77323fc051/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig= -github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v0.0.0-20180208215315-6a877ebacf28 h1:cgqCWD+gHiZTYcEnQbVdIuTvCzZ+0KefZRuUugY9iIM= -github.com/spf13/pflag v0.0.0-20180208215315-6a877ebacf28/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v0.0.0-20171227194143-aafc9e6bc7b7 h1:Wj4cg2M6Um7j1N7yD/mxsdy1/wrsdjzVha2eWdOhti8= -github.com/spf13/viper v0.0.0-20171227194143-aafc9e6bc7b7/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +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/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/swaggest/swgui v1.4.2 h1:6AT8ICO0+t6WpbIFsACf5vBmviVX0sqspNbZLoe6vgw= -github.com/swaggest/swgui v1.4.2/go.mod h1:xWDsT2h8obEoGHzX/a6FRClUOS8NvkICyInhi7s3fN8= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg= github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig= +github.com/tencentcloud/tencentcloud-sdk-go v1.0.162 h1:8fDzz4GuVg4skjY2B0nMN7h6uN61EDVkuLyI2+qGHhI= +github.com/tencentcloud/tencentcloud-sdk-go v1.0.162/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.3 h1:FpNT6zq26xNpHZy08emi755QwzLPs6Pukqjlc7RfOMU= github.com/urfave/cli v1.22.3/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vearutop/statigz v1.1.5/go.mod h1:czAv7iXgPv/s+xsgXpVEhhD0NSOQ4wZPgmM/n7LANDI= -github.com/walle/lll v1.0.1 h1:lbK8008fOXbQNYt8daBGUrjvElvlwlE7D7N/9dLP5IQ= -github.com/walle/lll v1.0.1/go.mod h1:lYxcXzoPhiAHR9eaq+Yv7RYg1nIipLloBCIfPUzfaWQ= +github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo= +github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f h1:9DDCDwOyEy/gId+IEMrFHLuQ5R/WV0KNxWLler8X2OY= github.com/wangjohn/quickselect v0.0.0-20161129230411-ed8402a42d5f/go.mod h1:8sdOQnirw1PrcnTJYkmW1iOHtUmblMmGdUOHyWYycLI= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -794,6 +800,7 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -808,23 +815,18 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0 h1:/pduUoebOeeJzTDFuoMgC6nRkiasr1sBCIEorly7m4o= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -golang.org/x/crypto v0.0.0-20180214000028-650f4a345ab4 h1:OfaUle5HH9Y0obNU74mlOZ/Igdtwi3eGOKcljJsTnbw= golang.org/x/crypto v0.0.0-20180214000028-650f4a345ab4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181025213731-e84da0312774 h1:a4tQYYYuK9QdeO/+kEvNYyuR21S+7ve5EANok6hABhI= -golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/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-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk= -golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -845,7 +847,6 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 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= @@ -859,21 +860,19 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20150829230318-ea47fc708ee3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180215212450-dc948dff8834 h1:7cwvC38gv4F9Js9rQFThHZGeSd4fXeWATRt8kVke3vM= -golang.org/x/net v0.0.0-20180215212450-dc948dff8834/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180406214816-61147c48b25b/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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/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-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190206173232-65e2d4e15006/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-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -881,19 +880,17 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -904,18 +901,15 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ 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-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211105192438-b53810dc28af h1:SMeNJG/vclJ5wyBBd4xupMsSJIHTd1coW9g7q6KOjmY= golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= -golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -926,7 +920,6 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -934,31 +927,28 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5 h1:MF92a0wJ3gzSUVBpjcwdrDr5+klMFRNEEu6Mev4n00I= -golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/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-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -967,12 +957,10 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/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-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -982,52 +970,34 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210216224549-f992740a1bac/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201113234701-d7a72108b828/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.0.0-20180208041248-4e4a3210bb54 h1:a5WocgxWTnjG0C4hZblDx+yonFbQMMbv8yJGhHMz/nY= -golang.org/x/text v0.0.0-20180208041248-4e4a3210bb54/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU= -golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wktg7Jn/a/fNmr33HSj8g= -golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1035,18 +1005,19 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/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= @@ -1074,9 +1045,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/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-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.3 h1:L69ShwSZEyCsLKoAxDKeMvLDZkumEe8gXUZAjab0tX8= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= @@ -1100,10 +1069,10 @@ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= @@ -1138,6 +1107,7 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced h1:c5geK1iMU3cDKtFrCVQIcjR3W+JOZMuhIyICMCTbtus= google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= @@ -1147,20 +1117,21 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc/examples v0.0.0-20220316190256-c4cabf78f4a2 h1:4y3mE8il4dBO1nkkmItfFJftXLYWRIJxXIJlQK4cThY= +google.golang.org/grpc/examples v0.0.0-20220316190256-c4cabf78f4a2/go.mod h1:wKDg0brwMZpaizQ1i7IzYcJjH1TmbJudYdnQC9+J+LE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1170,116 +1141,81 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20160105164936-4f90aeace3a2/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v1 v1.0.0/go.mod h1:CxwszS/Xz1C49Ucd2i6Zil5UToP1EmyrFhKaMVbg1mk= -gopkg.in/errgo.v1 v1.0.1 h1:oQFRXzZ7CkBGdm1XZm/EbQYaYNNEElNBOd09M6cqNso= -gopkg.in/errgo.v1 v1.0.1/go.mod h1:3NjfXwocQRYAPTq4/fzX+CwUhPRcR/azYRhj8G+LqMo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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/errgo.v1 v1.0.0-20161222125816-442357a80af5/go.mod h1:u0ALmqvLRxLI95fkdCEWrE6mhWYZW1aMOJHp5YXLHTg= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= -gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= -gopkg.in/httprequest.v1 v1.2.0 h1:YTGV1oXzaoKI6oPzQ0knoIPcrrVzeRG3amkoxoP7Xng= -gopkg.in/httprequest.v1 v1.2.0/go.mod h1:T61ZUaJLpMnzvoJDO03ZD8yRXD4nZzBeDoW5e9sffjg= -gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o= -gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/httprequest.v1 v1.1.1/go.mod h1:/CkavNL+g3qLOrpFHVrEx4NKepeqR4XTZWNj4sGGjz0= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ= gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/juju/environschema.v1 v1.0.0 h1:51vT1bzbP9fntQ0I9ECSlku2p19Szj/N2beZFeIH2kM= -gopkg.in/juju/environschema.v1 v1.0.0/go.mod h1:WTgU3KXKCVoO9bMmG/4KHzoaRvLeoxfjArpgd1MGWFA= -gopkg.in/macaroon-bakery.v2 v2.3.0 h1:b40knPgPTke1QLTE8BSYeH7+R/hiIozB1A8CTLYN0Ic= -gopkg.in/macaroon-bakery.v2 v2.3.0/go.mod h1:/8YhtPARXeRzbpEPLmRB66+gQE8/pzBBkWwg7Vz/guc= -gopkg.in/macaroon.v2 v2.1.0 h1:HZcsjBCzq9t0eBPMKqTN/uSN6JOm78ZJ2INbqcBQOUI= -gopkg.in/macaroon.v2 v2.1.0/go.mod h1:OUb+TQP/OP0WOerC2Jp/3CwhIKyIa9kQjuc7H24e6/o= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3 h1:AFxeG48hTWHhDTQDk/m2gorfVHUEa9vo3tp3D7TzwjI= -gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/mgo.v2 v2.0.0-20160818015218-f2b6f6c918c4/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/retry.v1 v1.0.3 h1:a9CArYczAVv6Qs6VGoLMio99GEs7kY9UzSF9+LD+iGs= -gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g= -gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5 h1:E846t8CnR+lv5nE+VuiKTDG/v1U2stad0QzddfJC7kY= -gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5/go.mod h1:hiOFpYm0ZJbusNj2ywpbrXowU3G8U6GIQzqn2mw1UIE= -gopkg.in/tomb.v1 v1.0.0-20140529071818-c131134a1947 h1:aNEcl02ps/eZaBJi2LycKl0jPsUryySSSgrCxieZRYA= -gopkg.in/tomb.v1 v1.0.0-20140529071818-c131134a1947/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 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.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= +gopkg.in/yaml.v2 v2.0.0-20170712054546-1be3d31502d6/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.0.0 h1:uUkhRGrsEyx/laRdeS6YIQKIys8pg+lRSRdVMTYjivs= -gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +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.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A= -k8s.io/api v0.0.0-20190819141258-3544db3b9e44 h1:7Gz7/nQ7X2qmPXMyN0bNq7Zm9Uip+UnFuMZTd2l3vms= -k8s.io/api v0.0.0-20190819141258-3544db3b9e44/go.mod h1:AOxZTnaXR/xiarlQL0JUfwQPxjmKDvVYoRp58cA7lUo= -k8s.io/api v0.0.0-20191016225839-816a9b7df678 h1:z/0BV/tMBIvdwZvqBH/f7TWjQX9y3dj1nMNhrSK0h/8= -k8s.io/api v0.0.0-20191016225839-816a9b7df678/go.mod h1:LZQaT8MvVpl7Bg2lYFcQm7+Mpdxq8p1NFl3yh+5DCwY= -k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA= -k8s.io/apimachinery v0.0.0-20190817020851-f2f3a405f61d h1:7Kns6qqhMAQWvGkxYOLSLRZ5hJO0/5pcE5lPGP2fxUw= -k8s.io/apimachinery v0.0.0-20190817020851-f2f3a405f61d/go.mod h1:3jediapYqJ2w1BFw7lAZPCx7scubsTfosqHkhXCWJKw= -k8s.io/apimachinery v0.0.0-20191016225534-b1267f8c42b4/go.mod h1:92mWDd8Ji2sw2157KIgino5wCxffA8KSvhW2oY4ypdw= -k8s.io/apimachinery v0.0.0-20191017185446-6e68a40eebf9 h1:namb+ObYHUIr+emdTPeozPwFkVlwiiiWHnXCx0z1L6Y= -k8s.io/apimachinery v0.0.0-20191017185446-6e68a40eebf9/go.mod h1:92mWDd8Ji2sw2157KIgino5wCxffA8KSvhW2oY4ypdw= -k8s.io/client-go v0.0.0-20190620085101-78d2af792bab h1:E8Fecph0qbNsAbijJJQryKu4Oi9QTp5cVpjTE+nqg6g= -k8s.io/client-go v0.0.0-20190620085101-78d2af792bab/go.mod h1:E95RaSlHr79aHaX0aGSwcPNfygDiPKOVXdmivCIZT0k= -k8s.io/client-go v0.0.0-20190819141724-e14f31a72a77 h1:w1BoabVnPpPqQCY3sHK4qVwa12Lk8ip1pKMR1C+qbdo= -k8s.io/client-go v0.0.0-20190819141724-e14f31a72a77/go.mod h1:DmkJD5UDP87MVqUQ5VJ6Tj9Oen8WzXPhk3la4qpyG4g= -k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o= -k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8= +k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= +k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA= +k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= +k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE= +k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= -k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/utils v0.0.0-20190221042446-c2654d5206da h1:ElyM7RPonbKnQqOcw7dG2IK5uvQQn3b/WPHqD5mBvP4= -k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= +launchpad.net/xmlpath v0.0.0-20130614043138-000000000004/go.mod h1:vqyExLOM3qBx7mvYRkoxjSCF945s0mbe7YynlKYXtsA= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/goofys/api/common/conf_azure.go b/goofys/api/common/conf_azure.go index 824584d5d..ee1d0539f 100644 --- a/goofys/api/common/conf_azure.go +++ b/goofys/api/common/conf_azure.go @@ -269,7 +269,7 @@ func azureFindAccount(client azblob.AccountsClient, account string) (*azblob.End return nil, "", err } - for _, acc := range *accountsRes.Value { + for _, acc := range accountsRes.Values() { if *acc.Name == account { // /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/... parts := strings.SplitN(*acc.ID, "/", 6) @@ -370,7 +370,7 @@ func AzureBlobConfig(endpoint string, location string, storageType string) (conf if key == "" { var keysRes azblob.AccountListKeysResult - keysRes, err = client.ListKeys(context.TODO(), resourceGroup, account) + keysRes, err = client.ListKeys(context.TODO(), resourceGroup, account, azblob.Kerb) if err != nil || len(*keysRes.Keys) == 0 { err = fmt.Errorf("Missing key: configure via AZURE_STORAGE_KEY "+ "or %v/config", configDir) diff --git a/goofys/internal/goofys_test.go b/goofys/internal/goofys_test.go index 933b5cad1..69e5bb795 100644 --- a/goofys/internal/goofys_test.go +++ b/goofys/internal/goofys_test.go @@ -47,7 +47,7 @@ import ( "github.com/Azure/go-autorest/autorest/azure" azureauth "github.com/Azure/go-autorest/autorest/azure/auth" - "github.com/signal18/replication-manager/go-xattr" + "github.com/pkg/xattr" "github.com/jacobsa/fuse" "github.com/jacobsa/fuse/fuseops" @@ -2092,13 +2092,13 @@ func (s *GoofysTest) TestXAttrSet(t *C) { in, err := s.LookUpInode(t, "file1") t.Assert(err, IsNil) - err = in.SetXattr("user.bar", []byte("hello"), xattr.REPLACE) + err = in.SetXattr("user.bar", []byte("hello"), xattr.XATTR_REPLACE) t.Assert(err, Equals, syscall.ENODATA) - err = in.SetXattr("user.bar", []byte("hello"), xattr.CREATE) + err = in.SetXattr("user.bar", []byte("hello"), xattr.XATTR_CREATE) t.Assert(err, IsNil) - err = in.SetXattr("user.bar", []byte("hello"), xattr.CREATE) + err = in.SetXattr("user.bar", []byte("hello"), xattr.XATTR_CREATE) t.Assert(err, Equals, syscall.EEXIST) in, err = s.LookUpInode(t, "file1") @@ -2110,7 +2110,7 @@ func (s *GoofysTest) TestXAttrSet(t *C) { value = []byte("file1+%/#\x00") - err = in.SetXattr("user.bar", value, xattr.REPLACE) + err = in.SetXattr("user.bar", value, xattr.XATTR_REPLACE) t.Assert(err, IsNil) in, err = s.LookUpInode(t, "file1") diff --git a/router/gobetween/api/api.go b/router/gobetween/api/api.go deleted file mode 100644 index 52efc8003..000000000 --- a/router/gobetween/api/api.go +++ /dev/null @@ -1,83 +0,0 @@ -/** - * api.go - rest api implementation - * - * @author Yaroslav Pogrebnyak - */ -package api - -import ( - "../config" - "../logging" - "github.com/gin-gonic/gin" - "github.com/gin-contrib/cors" -) - -/* gin app */ -var app *gin.Engine - -/** - * Initialize module - */ -func init() { - gin.SetMode(gin.ReleaseMode) -} - -/** - * Starts REST API server - */ -func Start(cfg config.ApiConfig) { - - var log = logging.For("api") - - if !cfg.Enabled { - log.Info("API disabled") - return - } - - log.Info("Starting up API") - - app = gin.New() - - if cfg.Cors { - corsConfig := cors.DefaultConfig() - corsConfig.AllowAllOrigins = true - corsConfig.AllowCredentials = true - corsConfig.AllowMethods = []string{"PUT", "POST", "DELETE", "GET", "OPTIONS"} - corsConfig.AllowHeaders = []string{"Origin", "Authorization"} - - app.Use(cors.New(corsConfig)) - log.Info("API CORS enabled") - } - - r := app.Group("/") - - if cfg.BasicAuth != nil { - log.Info("Using HTTP Basic Auth") - r.Use(gin.BasicAuth(gin.Accounts{ - cfg.BasicAuth.Login: cfg.BasicAuth.Password, - })) - } - - /* attach endpoints */ - attachRoot(r) - attachServers(r) - - /* attach endpoints with no auth */ - p := app.Group("/") - attachPublic(p) - - var err error - /* start rest api server */ - if cfg.Tls != nil { - log.Info("Starting HTTPS server ", cfg.Bind) - err = app.RunTLS(cfg.Bind, cfg.Tls.CertPath, cfg.Tls.KeyPath) - } else { - log.Info("Starting HTTP server ", cfg.Bind) - err = app.Run(cfg.Bind) - } - - if err != nil { - log.Fatal(err) - } - -} diff --git a/router/gobetween/api/public.go b/router/gobetween/api/public.go deleted file mode 100644 index f65a3a69a..000000000 --- a/router/gobetween/api/public.go +++ /dev/null @@ -1,24 +0,0 @@ -/** - * public.go - / rest api implementation - * - * @author Mike Schroeder - */ -package api - -import ( - "github.com/gin-gonic/gin" - "net/http" -) - -/** - * Attaches / handlers - */ -func attachPublic(app *gin.RouterGroup) { - - /** - * Simple 200 and OK response - */ - app.GET("/ping", func(c *gin.Context) { - c.String(http.StatusOK, "OK") - }) -} diff --git a/router/gobetween/api/root.go b/router/gobetween/api/root.go deleted file mode 100644 index e1da77336..000000000 --- a/router/gobetween/api/root.go +++ /dev/null @@ -1,51 +0,0 @@ -/** - * root.go - / rest api implementation - * - * @author Yaroslav Pogrebnyak - */ -package api - -import ( - "../info" - "../manager" - "github.com/gin-gonic/gin" - "net/http" - "os" - "time" -) - -/** - * Attaches / handlers - */ -func attachRoot(app *gin.RouterGroup) { - - /** - * Global stats - */ - app.GET("/", func(c *gin.Context) { - - c.IndentedJSON(http.StatusOK, gin.H{ - "pid": os.Getpid(), - "time": time.Now(), - "startTime": info.StartTime, - "uptime": time.Now().Sub(info.StartTime).String(), - "version": info.Version, - "configuration": info.Configuration, - }) - }) - - /** - * Dump current config as TOML - */ - app.GET("/dump", func(c *gin.Context) { - format := c.DefaultQuery("format", "toml") - - data, err := manager.DumpConfig(format) - if err != nil { - c.IndentedJSON(http.StatusInternalServerError, err.Error()) - return - } - - c.String(http.StatusOK, data) - }) -} diff --git a/router/gobetween/api/servers.go b/router/gobetween/api/servers.go deleted file mode 100644 index 685bbbd15..000000000 --- a/router/gobetween/api/servers.go +++ /dev/null @@ -1,74 +0,0 @@ -/** - * servers.go - /servers rest api implementation - * - * @author Yaroslav Pogrebnyak - */ -package api - -import ( - "../config" - "../manager" - "../stats" - "github.com/gin-gonic/gin" - "net/http" -) - -/** - * Attaches /servers handlers - */ -func attachServers(app *gin.RouterGroup) { - - /** - * Find all current configured servers - */ - app.GET("/servers", func(c *gin.Context) { - c.IndentedJSON(http.StatusOK, manager.All()) - }) - - /** - * Find server by name - */ - app.GET("/servers/:name", func(c *gin.Context) { - name := c.Param("name") - c.IndentedJSON(http.StatusOK, manager.Get(name)) - }) - - /** - * Delete server by name - */ - app.DELETE("/servers/:name", func(c *gin.Context) { - name := c.Param("name") - manager.Delete(name) - c.IndentedJSON(http.StatusOK, nil) - }) - - /** - * Create new server with name :name - */ - app.POST("/servers/:name", func(c *gin.Context) { - - name := c.Param("name") - - cfg := config.Server{} - if err := c.BindJSON(&cfg); err != nil { - c.IndentedJSON(http.StatusBadRequest, err.Error()) - return - } - - if err := manager.Create(name, cfg); err != nil { - c.IndentedJSON(http.StatusConflict, err.Error()) - return - } - - c.IndentedJSON(http.StatusOK, nil) - }) - - /** - * Get server stats - */ - app.GET("/servers/:name/stats", func(c *gin.Context) { - name := c.Param("name") - c.IndentedJSON(http.StatusOK, stats.GetStats(name)) - }) - -} diff --git a/router/gobetween/balance/iphash.go b/router/gobetween/balance/iphash.go deleted file mode 100644 index 703fbbc5c..000000000 --- a/router/gobetween/balance/iphash.go +++ /dev/null @@ -1,37 +0,0 @@ -/** - * iphash.go - iphash balance impl - * - * @author Yaroslav Pogrebnyak - */ - -package balance - -import ( - "../core" - "errors" - "hash/fnv" -) - -/** - * Iphash balancer - */ -type IphashBalancer struct{} - -/** - * Elect backend using iphash strategy - * Using fnv1a for speed - * - * TODO: Improve as needed - */ -func (b *IphashBalancer) Elect(context core.Context, backends []*core.Backend) (*core.Backend, error) { - - if len(backends) == 0 { - return nil, errors.New("Can't elect backend, Backends empty") - } - - hash := fnv.New32a() - hash.Write(context.Ip()) - backend := backends[hash.Sum32()%uint32(len(backends))] - - return backend, nil -} diff --git a/router/gobetween/balance/iphash1.go b/router/gobetween/balance/iphash1.go deleted file mode 100644 index 5580b8e1a..000000000 --- a/router/gobetween/balance/iphash1.go +++ /dev/null @@ -1,51 +0,0 @@ -/** - * iphash1.go - semi-consistent iphash balance impl - * - * @author Illarion Kovalchuk - */ - -package balance - -import ( - "../core" - "errors" - "hash/fnv" -) - -/** - * Iphash balancer - */ -type Iphash1Balancer struct { -} - -/** - * Elect backend using semi-consistent iphash strategy. This is naive implementation - * using Key+Node Hash Algorithm for stable sharding described at http://kennethxu.blogspot.com/2012/11/sharding-algorithm.html - * It survives removing nodes (removing stability), so that clients connected to backends that have not been removed stay - * untouched. - * - */ -func (b *Iphash1Balancer) Elect(context core.Context, backends []*core.Backend) (*core.Backend, error) { - - if len(backends) == 0 { - return nil, errors.New("Can't elect backend, Backends empty") - } - - var result *core.Backend - { - var bestHash uint32 - - for i, backend := range backends { - hasher := fnv.New32a() - hasher.Write(context.Ip()) - hasher.Write([]byte(backend.Address())) - s32 := hasher.Sum32() - if s32 > bestHash { - bestHash = s32 - result = backends[i] - } - } - } - - return result, nil -} diff --git a/router/gobetween/balance/leastbandwidth.go b/router/gobetween/balance/leastbandwidth.go deleted file mode 100644 index 952becf58..000000000 --- a/router/gobetween/balance/leastbandwidth.go +++ /dev/null @@ -1,37 +0,0 @@ -/** - * leastbandwidth.go - leastbandwidth balance impl - * - * @author Yaroslav Pogrebnyak - */ - -package balance - -import ( - "errors" - - "../core" -) - -/** - * Leastbandwidth balancer - */ -type LeastbandwidthBalancer struct{} - -/** - * Elect backend using leastbandwidth strategy - */ -func (b *LeastbandwidthBalancer) Elect(context core.Context, backends []*core.Backend) (*core.Backend, error) { - - if len(backends) == 0 { - return nil, errors.New("Can't elect backend, Backends empty") - } - - least := backends[0] - for _, b := range backends { - if b.Stats.TxSecond+b.Stats.RxSecond < least.Stats.TxSecond+least.Stats.RxSecond { - least = b - } - } - - return least, nil -} diff --git a/router/gobetween/balance/leastconn.go b/router/gobetween/balance/leastconn.go deleted file mode 100644 index fa24134b3..000000000 --- a/router/gobetween/balance/leastconn.go +++ /dev/null @@ -1,38 +0,0 @@ -/** - * leastconn.go - leastconn balance impl - * - * @author Yaroslav Pogrebnyak - */ - -package balance - -import ( - "errors" - - "../core" -) - -/** - * Leastconn balancer - */ -type LeastconnBalancer struct{} - -/** - * Elect backend using roundrobin strategy - */ -func (b *LeastconnBalancer) Elect(context core.Context, backends []*core.Backend) (*core.Backend, error) { - - if len(backends) == 0 { - return nil, errors.New("Can't elect backend, Backends empty") - } - - least := backends[0] - - for key, backend := range backends { - if backend.Stats.ActiveConnections <= least.Stats.ActiveConnections { - least = backends[key] - } - } - - return least, nil -} diff --git a/router/gobetween/balance/middleware/sni.go b/router/gobetween/balance/middleware/sni.go deleted file mode 100644 index cee533b77..000000000 --- a/router/gobetween/balance/middleware/sni.go +++ /dev/null @@ -1,113 +0,0 @@ -/** - * sni.go - sni middleware - * - * @author Illarion Kovalchuk - * @author Yaroslav Pogrebnyak - */ - -package middleware - -import ( - "errors" - "regexp" - "strings" - - "../../config" - "../../core" - "../../logging" -) - -/** - * SniBalancer middleware delegate - */ -type SniBalancer struct { - SniConf *config.Sni - Delegate core.Balancer -} - -/** - * Elect backend using sni pre-processing - */ -func (sniBalancer *SniBalancer) Elect(ctx core.Context, backends []*core.Backend) (*core.Backend, error) { - - /* ------ try find matching to requesedSni backends ------ */ - - matchedBackends := sniBalancer.matchingBackends(ctx.Sni(), backends) - if len(matchedBackends) > 0 { - return sniBalancer.Delegate.Elect(ctx, matchedBackends) - } - - /* ------ if no matched backends, fallback to unexpected hostname strategy ------ */ - - switch sniBalancer.SniConf.UnexpectedHostnameStrategy { - case "reject": - return nil, errors.New("No matching sni [" + ctx.Sni() + "] found, rejecting due to 'reject' unexpected hostname strategy") - - case "any": - return sniBalancer.Delegate.Elect(ctx, backends) - - default: - if ctx.Sni() == "" { - return sniBalancer.Delegate.Elect(ctx, []*core.Backend{}) - } - - // default, select only from backends without any sni - return sniBalancer.Delegate.Elect(ctx, sniBalancer.matchingBackends("", backends)) - } -} - -/** - * Filter out backends that match requestedSni - */ -func (sniBalancer *SniBalancer) matchingBackends(requestedSni string, backends []*core.Backend) []*core.Backend { - - log := logging.For("balance/middleware/sni") - - var matchedBackends []*core.Backend - - for _, backend := range backends { - - match, err := sniBalancer.matchSni(requestedSni, backend.Sni) - - if err != nil { - log.Error(err) - continue - } - - if match { - matchedBackends = append(matchedBackends, backend) - } - } - - return matchedBackends -} - -/** - * Try match requested sni to actual backend sni - */ -func (sniBalancer *SniBalancer) matchSni(requestedSni string, backendSni string) (bool, error) { - - sniMatching := sniBalancer.SniConf.HostnameMatchingStrategy - - switch sniMatching { - case "regexp": - - if backendSni == "" && requestedSni != "" { - return false, nil - } - - regexp, err := regexp.Compile(backendSni) - if err != nil { - return false, err - } - - return regexp.MatchString(requestedSni), nil - - case "exact": - return strings.ToLower(requestedSni) == strings.ToLower(backendSni), nil - - default: - return false, errors.New("Unsupported sni matching mechanism: " + sniMatching) - } - -} diff --git a/router/gobetween/balance/registry.go b/router/gobetween/balance/registry.go deleted file mode 100644 index 055d596ed..000000000 --- a/router/gobetween/balance/registry.go +++ /dev/null @@ -1,50 +0,0 @@ -/** - * registry.go - balancers registry - * - * @author Yaroslav Pogrebnyak - */ - -package balance - -import ( - "reflect" - - "./middleware" - - "../config" - "../core" -) - -/** - * Type registry of available Balancers - */ -var typeRegistry = make(map[string]reflect.Type) - -/** - * Initialize type registry - */ -func init() { - typeRegistry["leastconn"] = reflect.TypeOf(LeastconnBalancer{}) - typeRegistry["roundrobin"] = reflect.TypeOf(RoundrobinBalancer{}) - typeRegistry["weight"] = reflect.TypeOf(WeightBalancer{}) - typeRegistry["iphash"] = reflect.TypeOf(IphashBalancer{}) - typeRegistry["iphash1"] = reflect.TypeOf(Iphash1Balancer{}) - typeRegistry["leastbandwidth"] = reflect.TypeOf(LeastbandwidthBalancer{}) -} - -/** - * Create new Balancer based on balancing strategy - * Wrap it in middlewares if needed - */ -func New(sniConf *config.Sni, balance string) core.Balancer { - balancer := reflect.New(typeRegistry[balance]).Elem().Addr().Interface().(core.Balancer) - - if sniConf == nil { - return balancer - } - - return &middleware.SniBalancer{ - SniConf: sniConf, - Delegate: balancer, - } -} diff --git a/router/gobetween/balance/roundrobin.go b/router/gobetween/balance/roundrobin.go deleted file mode 100644 index efdbf9be9..000000000 --- a/router/gobetween/balance/roundrobin.go +++ /dev/null @@ -1,49 +0,0 @@ -/** - * roundrobin.go - roundrobin balance impl - * - * @author Yaroslav Pogrebnyak - */ - -package balance - -import ( - "errors" - "sort" - - "../core" -) - -/** - * Roundrobin balancer - */ -type RoundrobinBalancer struct { - - /* Current backend position */ - current int -} - -/** - * Elect backend using roundrobin strategy - */ -func (b *RoundrobinBalancer) Elect(context core.Context, backends []*core.Backend) (*core.Backend, error) { - - if len(backends) == 0 { - return nil, errors.New("Can't elect backend, Backends empty") - } - - sorted := make([]*core.Backend, len(backends)) - copy(sorted, backends) - - sort.SliceStable(sorted, func(i, j int) bool { - return sorted[i].Target.String() < sorted[j].Target.String() - }) - - if b.current >= len(sorted) { - b.current = 0 - } - - backend := sorted[b.current] - b.current += 1 - - return backend, nil -} diff --git a/router/gobetween/balance/weight.go b/router/gobetween/balance/weight.go deleted file mode 100644 index 0cd4ccfb7..000000000 --- a/router/gobetween/balance/weight.go +++ /dev/null @@ -1,49 +0,0 @@ -/** - * weight.go - weight balance impl - * - * @author Yaroslav Pogrebnyak - */ - -package balance - -import ( - "../core" - "errors" - "math/rand" -) - -/** - * Weight balancer - */ -type WeightBalancer struct{} - -/** - * Elect backend based on weight strategy - */ -func (b *WeightBalancer) Elect(context core.Context, backends []*core.Backend) (*core.Backend, error) { - - if len(backends) == 0 { - return nil, errors.New("Can't elect backend, Backends empty") - } - - totalWeight := 0 - for _, backend := range backends { - if backend.Weight <= 0 { - return nil, errors.New("Invalid backend weight 0") - } - totalWeight += backend.Weight - } - - r := rand.Intn(totalWeight) - pos := 0 - - for _, backend := range backends { - pos += backend.Weight - if r >= pos { - continue - } - return backend, nil - } - - return nil, errors.New("Can't elect backend") -} diff --git a/router/gobetween/cmd/cmd.go b/router/gobetween/cmd/cmd.go deleted file mode 100644 index 569d8ad39..000000000 --- a/router/gobetween/cmd/cmd.go +++ /dev/null @@ -1,23 +0,0 @@ -/** - * cmd.go - command line runner - * - * @author Yaroslav Pogrebnyak - */ -package cmd - -import ( - "../config" -) - -/** - * App Start function to call after initialization - */ -var start func(*config.Config) - -/** - * Execute processing flags - */ -func Execute(f func(*config.Config)) { - start = f - RootCmd.Execute() -} diff --git a/router/gobetween/cmd/from-consul.go b/router/gobetween/cmd/from-consul.go deleted file mode 100644 index 643100276..000000000 --- a/router/gobetween/cmd/from-consul.go +++ /dev/null @@ -1,74 +0,0 @@ -/** - * from-consul.go - pull config from consul and run - * - * @author Yaroslav Pogrebnyak - */ -package cmd - -import ( - "../config" - "../info" - "../utils/codec" - consul "github.com/hashicorp/consul/api" - "github.com/spf13/cobra" - "log" -) - -/* Parsed options */ -var consulKey string -var consulConfig consul.Config = consul.Config{} - -/** - * Add command - */ -func init() { - - FromConsulCmd.Flags().StringVarP(&consulKey, "key", "k", "gobetween", "Consul Key to pull config from") - FromConsulCmd.Flags().StringVarP(&consulConfig.Scheme, "scheme", "s", "http", "http or https") - - RootCmd.AddCommand(FromConsulCmd) -} - -/** - * FromConsul command - */ -var FromConsulCmd = &cobra.Command{ - Use: "from-consul ", - Short: "Start using config from Consul", - Long: `Start using config from the Consul key-value storage`, - Run: func(cmd *cobra.Command, args []string) { - - if len(args) != 1 { - cmd.Help() - return - } - - consulConfig.Address = args[0] - client, err := consul.NewClient(&consulConfig) - if err != nil { - log.Fatal(err) - } - - pair, _, err := client.KV().Get(consulKey, nil) - if err != nil { - log.Fatal(err) - } - - if pair == nil { - log.Fatal("Empty value for key " + consulKey) - } - - var cfg config.Config - if err := codec.Decode(string(pair.Value), &cfg, format); err != nil { - log.Fatal(err) - } - - info.Configuration = struct { - Kind string `json:"kind"` - Host string `json:"host"` - Key string `json:"key"` - }{"consul", consulConfig.Address, consulKey} - - start(&cfg) - }, -} diff --git a/router/gobetween/cmd/from-file.go b/router/gobetween/cmd/from-file.go deleted file mode 100644 index a9b388e40..000000000 --- a/router/gobetween/cmd/from-file.go +++ /dev/null @@ -1,54 +0,0 @@ -/** - * from-file.go - pull config from file and run - * - * @author Yaroslav Pogrebnyak - */ -package cmd - -import ( - "../config" - "../info" - "../utils/codec" - "github.com/spf13/cobra" - "io/ioutil" - "log" -) - -/** - * Add Root Command - */ -func init() { - RootCmd.AddCommand(FromFileCmd) -} - -/** - * FromFile Command - */ -var FromFileCmd = &cobra.Command{ - Use: "from-file ", - Short: "Start using config from file", - Run: func(cmd *cobra.Command, args []string) { - - if len(args) != 1 { - cmd.Help() - return - } - - data, err := ioutil.ReadFile(args[0]) - if err != nil { - log.Fatal(err) - } - - var cfg config.Config - if err = codec.Decode(string(data), &cfg, format); err != nil { - log.Fatal(err) - } - - info.Configuration = struct { - Kind string `json:"kind"` - Path string `json:"path"` - }{"file", args[0]} - - start(&cfg) - }, -} diff --git a/router/gobetween/cmd/from-url.go b/router/gobetween/cmd/from-url.go deleted file mode 100644 index 642a2c4a8..000000000 --- a/router/gobetween/cmd/from-url.go +++ /dev/null @@ -1,65 +0,0 @@ -/** - * from-url.go - pull config from url and run - * - * @author Yaroslav Pogrebnyak - */ -package cmd - -import ( - "../config" - "../info" - "../utils/codec" - "github.com/spf13/cobra" - "io/ioutil" - "log" - "net/http" -) - -/** - * Add command - */ -func init() { - - RootCmd.AddCommand(FromUrlCmd) -} - -/** - * FromUrlCmd command - */ -var FromUrlCmd = &cobra.Command{ - Use: "from-url ", - Short: "Start using config from URL", - Run: func(cmd *cobra.Command, args []string) { - - if len(args) != 1 { - cmd.Help() - return - } - - client := http.Client{} - res, err := client.Get(args[0]) - if err != nil { - log.Fatal(err) - } - - defer res.Body.Close() - - // Read response - content, err := ioutil.ReadAll(res.Body) - if err != nil { - log.Fatal(err) - } - - var cfg config.Config - if err := codec.Decode(string(content), &cfg, format); err != nil { - log.Fatal(err) - } - - info.Configuration = struct { - Kind string `json:"kind"` - Url string `json:"url"` - }{"url", args[0]} - - start(&cfg) - }, -} diff --git a/router/gobetween/cmd/root.go b/router/gobetween/cmd/root.go deleted file mode 100644 index 7b4b101b0..000000000 --- a/router/gobetween/cmd/root.go +++ /dev/null @@ -1,52 +0,0 @@ -/** - * root.go - root cmd emulates from-file TODO: remove when time will come - * - * @author Yaroslav Pogrebnyak - */ -package cmd - -import ( - "../info" - "fmt" - "github.com/spf13/cobra" -) - -/* Persistent parsed options */ -var format string - -/* Parsed options */ -var configPath string - -/* Show version */ -var showVersion bool - -/** - * Add Root Command - */ -func init() { - RootCmd.Flags().BoolVarP(&showVersion, "version", "v", false, "Print version information and quit") - RootCmd.Flags().StringVarP(&configPath, "config", "c", "", "Path to configuration file") - RootCmd.PersistentFlags().StringVarP(&format, "format", "f", "toml", "Configuration file format: \"toml\" or \"json\"") -} - -/** - * Root Command - */ -var RootCmd = &cobra.Command{ - Use: "gobetween", - Short: "Modern & minimalistic load balancer for the Cloud era", - Run: func(cmd *cobra.Command, args []string) { - - if showVersion { - fmt.Println(info.Version) - return - } - - if configPath == "" { - cmd.Help() - return - } - - FromFileCmd.Run(cmd, []string{configPath}) - }, -} diff --git a/router/gobetween/config/config.go b/router/gobetween/config/config.go deleted file mode 100644 index 3f545d559..000000000 --- a/router/gobetween/config/config.go +++ /dev/null @@ -1,298 +0,0 @@ -/** - * config.go - config file definitions - * - * @author Yaroslav Pogrebnyak - * @author Gene Ponomarenko - */ -package config - -/** - * Config file top-level object - */ -type Config struct { - Logging LoggingConfig `toml:"logging" json:"logging"` - Api ApiConfig `toml:"api" json:"api"` - Defaults ConnectionOptions `toml:"defaults" json:"defaults"` - Acme *AcmeConfig `toml:"acme" json:"acme"` - Servers map[string]Server `toml:"servers" json:"servers"` -} - -/** - * Logging config section - */ -type LoggingConfig struct { - Level string `toml:"level" json:"level"` - Output string `toml:"output" json:"output"` -} - -/** - * Api config section - */ -type ApiConfig struct { - Enabled bool `toml:"enabled" json:"enabled"` - Bind string `toml:"bind" json:"bind"` - BasicAuth *ApiBasicAuthConfig `toml:"basic_auth" json:"basic_auth"` - Tls *ApiTlsConfig `toml:"tls" json:"tls"` - Cors bool `toml:"cors" json:"cors"` -} - -/** - * Api Basic Auth Config - */ -type ApiBasicAuthConfig struct { - Login string `toml:"login" json:"login"` - Password string `toml:"password" json:"password"` -} - -/** - * Api TLS server Config - */ -type ApiTlsConfig struct { - CertPath string `toml:"cert_path" json:"cert_path"` - KeyPath string `toml:"key_path" json:"key_path"` -} - -/** - * Default values can be overridden in server - */ -type ConnectionOptions struct { - MaxConnections *int `toml:"max_connections" json:"max_connections"` - ClientIdleTimeout *string `toml:"client_idle_timeout" json:"client_idle_timeout"` - BackendIdleTimeout *string `toml:"backend_idle_timeout" json:"backend_idle_timeout"` - BackendConnectionTimeout *string `toml:"backend_connection_timeout" json:"backend_connection_timeout"` -} - -/** - * Acme config - */ -type AcmeConfig struct { - Challenge string `toml:"challenge" json:"challenge"` - HttpBind string `toml:"http_bind" json:"http_bind"` - CacheDir string `toml:"cache_dir" json:"cache_dir"` -} - -/** - * Server section config - */ -type Server struct { - ConnectionOptions - - // hostname:port - Bind string `toml:"bind" json:"bind"` - - // tcp | udp | tls - Protocol string `toml:"protocol" json:"protocol"` - - // weight | leastconn | roundrobin - Balance string `toml:"balance" json:"balance"` - - // Optional configuration for server name indication - Sni *Sni `toml:"sni" json:"sni"` - - // Optional configuration for protocol = tls - Tls *Tls `toml:"tls" json:"tls"` - - // Optional configuration for backend_tls_enabled = true - BackendsTls *BackendsTls `toml:"backends_tls" json:"backends_tls"` - - // Optional configuration for protocol = udp - Udp *Udp `toml:"udp" json:"udp"` - - // Access configuration - Access *AccessConfig `toml:"access" json:"access"` - - // ProxyProtocol configuration - ProxyProtocol *ProxyProtocol `toml:"proxy_protocol" json:"proxy_protocol"` - - // Discovery configuration - Discovery *DiscoveryConfig `toml:"discovery" json:"discovery"` - - // Healthcheck configuration - Healthcheck *HealthcheckConfig `toml:"healthcheck" json:"healthcheck"` -} - -/** - * ProxyProtocol configurtion - */ -type ProxyProtocol struct { - Version string `toml:"version" json:"version"` -} - -/** - * Server Sni options - */ -type Sni struct { - HostnameMatchingStrategy string `toml:"hostname_matching_strategy" json:"hostname_matching_strategy"` - UnexpectedHostnameStrategy string `toml:"unexpected_hostname_strategy" json:"unexpected_hostname_strategy"` - ReadTimeout string `toml:"read_timeout" json:"read_timeout"` -} - -/** - * Common part of Tls and BackendTls types - */ -type tlsCommon struct { - Ciphers []string `toml:"ciphers" json:"ciphers"` - PreferServerCiphers bool `toml:"prefer_server_ciphers" json:"prefer_server_ciphers"` - MinVersion string `toml:"min_version" json:"min_version"` - MaxVersion string `toml:"max_version" json:"max_version"` - SessionTickets bool `toml:"session_tickets" json:"session_tickets"` -} - -/** - * Server Tls options - * for protocol = "tls" - */ -type Tls struct { - AcmeHosts []string `toml:"acme_hosts" json:"acme_hosts"` - CertPath string `toml:"cert_path" json:"cert_path"` - KeyPath string `toml:"key_path" json:"key_path"` - tlsCommon -} - -type BackendsTls struct { - IgnoreVerify bool `toml:"ignore_verify" json:"ignore_verify"` - RootCaCertPath *string `toml:"root_ca_cert_path" json:"root_ca_cert_path"` - CertPath *string `toml:"cert_path" json:"cert_path"` - KeyPath *string `toml:"key_path" json:"key_path"` - tlsCommon -} - -/** - * Server udp options - * for protocol = "udp" - */ -type Udp struct { - MaxRequests uint64 `toml:"max_requests" json:"max_requests"` - MaxResponses uint64 `toml:"max_responses" json:"max_responses"` -} - -/** - * Access configuration - */ -type AccessConfig struct { - Default string `toml:"default" json:"default"` - Rules []string `toml:"rules" json:"rules"` -} - -/** - * Discovery configuration - */ -type DiscoveryConfig struct { - Kind string `toml:"kind" json:"kind"` - Failpolicy string `toml:"failpolicy" json:"failpolicy"` - Interval string `toml:"interval" json:"interval"` - Timeout string `toml:"timeout" json:"timeout"` - - /* Depends on Kind */ - - *StaticDiscoveryConfig - *SrvDiscoveryConfig - *DockerDiscoveryConfig - *JsonDiscoveryConfig - *ExecDiscoveryConfig - *PlaintextDiscoveryConfig - *ConsulDiscoveryConfig - *LXDDiscoveryConfig -} - -type StaticDiscoveryConfig struct { - StaticList []string `toml:"static_list" json:"static_list"` -} - -type SrvDiscoveryConfig struct { - SrvLookupServer string `toml:"srv_lookup_server" json:"srv_lookup_server"` - SrvLookupPattern string `toml:"srv_lookup_pattern" json:"srv_lookup_pattern"` - SrvDnsProtocol string `toml:"srv_dns_protocol" json:"srv_dns_protocol"` -} - -type ExecDiscoveryConfig struct { - ExecCommand []string `toml:"exec_command" json:"exec_command"` -} - -type JsonDiscoveryConfig struct { - JsonEndpoint string `toml:"json_endpoint" json:"json_endpoint"` - JsonHostPattern string `toml:"json_host_pattern" json:"json_host_pattern"` - JsonPortPattern string `toml:"json_port_pattern" json:"json_port_pattern"` - JsonWeightPattern string `toml:"json_weight_pattern" json:"json_weight_pattern"` - JsonPriorityPattern string `toml:"json_priority_pattern" json:"json_priority_pattern"` - JsonSniPattern string `toml:"json_sni_pattern" json:"json_sni_pattern"` -} - -type PlaintextDiscoveryConfig struct { - PlaintextEndpoint string `toml:"plaintext_endpoint" json:"plaintext_endpoint"` - PlaintextRegexpPattern string `toml:"plaintext_regex_pattern" json:"plaintext_regex_pattern"` -} - -type DockerDiscoveryConfig struct { - DockerEndpoint string `toml:"docker_endpoint" json:"docker_endpoint"` - DockerContainerLabel string `toml:"docker_container_label" json:"docker_container_label"` - DockerContainerPrivatePort int64 `toml:"docker_container_private_port" json:"docker_container_private_port"` - DockerContainerHostEnvVar string `toml:"docker_container_host_env_var" json:"docker_container_host_env_var"` - - DockerTlsEnabled bool `toml:"docker_tls_enabled" json:"docker_tls_enabled"` - DockerTlsCertPath string `toml:"docker_tls_cert_path" json:"docker_tls_cert_path"` - DockerTlsKeyPath string `toml:"docker_tls_key_path" json:"docker_tls_key_path"` - DockerTlsCacertPath string `toml:"docker_tls_cacert_path" json:"docker_tls_cacert_path"` -} - -type ConsulDiscoveryConfig struct { - ConsulHost string `toml:"consul_host" json:"consul_host"` - ConsulServiceName string `toml:"consul_service_name" json:"consul_service_name"` - ConsulServiceTag string `toml:"consul_service_tag" json:"consul_service_tag"` - ConsulServicePassingOnly bool `toml:"consul_service_passing_only" json:"consul_service_passing_only"` - ConsulDatacenter string `toml:"consul_datacenter" json:"consul_datacenter"` - - ConsulAuthUsername string `toml:"consul_auth_username" json:"consul_auth_username"` - ConsulAuthPassword string `toml:"consul_auth_password" json:"consul_auth_password"` - - ConsulTlsEnabled bool `toml:"consul_tls_enabled" json:"consul_tls_enabled"` - ConsulTlsCertPath string `toml:"consul_tls_cert_path" json:"consul_tls_cert_path"` - ConsulTlsKeyPath string `toml:"consul_tls_key_path" json:"consul_tls_key_path"` - ConsulTlsCacertPath string `toml:"consul_tls_cacert_path" json:"consul_tls_cacert_path"` -} - -type LXDDiscoveryConfig struct { - LXDServerAddress string `toml:"lxd_server_address" json:"lxd_server_address"` - LXDServerRemoteName string `toml:"lxd_server_remote_name" json:"lxd_server_remote_name"` - LXDServerRemotePassword string `toml:"lxd_server_remote_password" json:"lxd_server_remote_password"` - - LXDConfigDirectory string `toml:"lxd_config_directory" json:"lxd_config_directory"` - LXDGenerateClientCerts bool `toml:"lxd_generate_client_certs" json:"lxd_generate_client_certs"` - LXDAcceptServerCert bool `toml:"lxd_accept_server_cert" json:"lxd_accept_server_cert"` - - LXDContainerLabelKey string `toml:"lxd_container_label_key" json:"lxd_container_label_key"` - LXDContainerLabelValue string `toml:"lxd_container_label_value" json:"lxd_container_label_value"` - - LXDContainerPort int `toml:"lxd_container_port" json:"lxd_container_port"` - LXDContainerPortKey string `toml:"lxd_container_port_key" json:"lxd_container_port_key"` - - LXDContainerInterface string `toml:"lxd_container_interface" json:"lxd_container_interface"` - LXDContainerInterfaceKey string `toml:"lxd_container_interface_key" json:"lxd_container_interface_key"` - - LXDContainerSNIKey string `toml:"lxd_container_sni_key" json:"lxd_container_sni_key"` - LXDContainerAddressType string `toml:"lxd_container_address_type" json:"lxd_container_address_type"` -} - -/** - * Healthcheck configuration - */ -type HealthcheckConfig struct { - Kind string `toml:"kind" json:"kind"` - Interval string `toml:"interval" json:"interval"` - Passes int `toml:"passes" json:"passes"` - Fails int `toml:"fails" json:"fails"` - Timeout string `toml:"timeout" json:"timeout"` - - /* Depends on Kind */ - - *PingHealthcheckConfig - *ExecHealthcheckConfig -} - -type PingHealthcheckConfig struct{} - -type ExecHealthcheckConfig struct { - ExecCommand string `toml:"exec_command" json:"exec_command,omitempty"` - ExecExpectedPositiveOutput string `toml:"exec_expected_positive_output" json:"exec_expected_positive_output"` - ExecExpectedNegativeOutput string `toml:"exec_expected_negative_output" json:"exec_expected_negative_output"` -} diff --git a/router/gobetween/core/backend.go b/router/gobetween/core/backend.go deleted file mode 100644 index db415975b..000000000 --- a/router/gobetween/core/backend.go +++ /dev/null @@ -1,72 +0,0 @@ -/** - * backend.go - backend definition - * - * @author Yaroslav Pogrebnyak - */ - -package core - -import ( - "fmt" -) - -/** - * Backend means upstream server - * with all needed associate information - */ -type Backend struct { - Target - Priority int `json:"priority"` - Weight int `json:"weight"` - Sni string `json:"sni,omitempty"` - Stats BackendStats `json:"stats"` -} - -/** - * Backend status - */ -type BackendStats struct { - Live bool `json:"live"` - Discovered bool `json:"discovered"` - TotalConnections int64 `json:"total_connections"` - ActiveConnections uint `json:"active_connections"` - RefusedConnections uint64 `json:"refused_connections"` - RxBytes uint64 `json:"rx"` - TxBytes uint64 `json:"tx"` - RxSecond uint `json:"rx_second"` - TxSecond uint `json:"tx_second"` -} - -/** - * Check if backend equal to another - */ -func (this *Backend) EqualTo(other Backend) bool { - return this.Target.EqualTo(other.Target) -} - -/** - * Merge another backend to this one - */ -func (this *Backend) MergeFrom(other Backend) *Backend { - - this.Priority = other.Priority - this.Weight = other.Weight - this.Sni = other.Sni - - return this -} - -/** - * Get backends target address - */ -func (this *Backend) Address() string { - return this.Target.Address() -} - -/** - * String conversion - */ -func (this Backend) String() string { - return fmt.Sprintf("{%s p=%d,w=%d,l=%t,a=%d}", - this.Address(), this.Priority, this.Weight, this.Stats.Live, this.Stats.ActiveConnections) -} diff --git a/router/gobetween/core/balancer.go b/router/gobetween/core/balancer.go deleted file mode 100644 index 96cc9ba71..000000000 --- a/router/gobetween/core/balancer.go +++ /dev/null @@ -1,12 +0,0 @@ -package core - -/** - * Balancer interface - */ -type Balancer interface { - - /** - * Elect backend based on Balancer implementation - */ - Elect(Context, []*Backend) (*Backend, error) -} diff --git a/router/gobetween/core/context.go b/router/gobetween/core/context.go deleted file mode 100644 index 99d9c7b23..000000000 --- a/router/gobetween/core/context.go +++ /dev/null @@ -1,70 +0,0 @@ -/** - * context.go - proxy context - * - * @author Yaroslav Pogrebnyak - */ - -package core - -import "net" - -type Context interface { - String() string - Ip() net.IP - Port() int - Sni() string -} - -/** - * Proxy tcp context - */ -type TcpContext struct { - Hostname string - /** - * Current client connection - */ - Conn net.Conn -} - -func (t TcpContext) String() string { - return t.Conn.RemoteAddr().String() -} - -func (t TcpContext) Ip() net.IP { - return t.Conn.RemoteAddr().(*net.TCPAddr).IP -} - -func (t TcpContext) Port() int { - return t.Conn.RemoteAddr().(*net.TCPAddr).Port -} - -func (t TcpContext) Sni() string { - return t.Hostname -} - -/* - * Proxy udp context - */ -type UdpContext struct { - - /** - * Current client remote address - */ - ClientAddr net.UDPAddr -} - -func (u UdpContext) String() string { - return u.ClientAddr.String() -} - -func (u UdpContext) Ip() net.IP { - return u.ClientAddr.IP -} - -func (u UdpContext) Port() int { - return u.ClientAddr.Port -} - -func (u UdpContext) Sni() string { - return "" -} diff --git a/router/gobetween/core/misc.go b/router/gobetween/core/misc.go deleted file mode 100644 index db6ca1777..000000000 --- a/router/gobetween/core/misc.go +++ /dev/null @@ -1,25 +0,0 @@ -/** - * misc.go - * - * @author Yaroslav Pogrebnyak - */ - -package core - -/** - * Next r/w operation data counters - */ -type ReadWriteCount struct { - - /* Read bytes count */ - CountRead uint - - /* Write bytes count */ - CountWrite uint - - Target Target -} - -func (this ReadWriteCount) IsZero() bool { - return this.CountRead == 0 && this.CountWrite == 0 -} diff --git a/router/gobetween/core/server.go b/router/gobetween/core/server.go deleted file mode 100644 index f9d352208..000000000 --- a/router/gobetween/core/server.go +++ /dev/null @@ -1,33 +0,0 @@ -/** - * server.go - server - * - * @author Illarion Kovalchuk - * @author Yaroslav Pogrebnyak - */ - -package core - -import ( - "../config" -) - -/** - * Server interface - */ -type Server interface { - - /** - * Start server - */ - Start() error - - /** - * Stop server and wait until it stop - */ - Stop() - - /** - * Get server configuration - */ - Cfg() config.Server -} diff --git a/router/gobetween/core/service.go b/router/gobetween/core/service.go deleted file mode 100644 index 82c95cd20..000000000 --- a/router/gobetween/core/service.go +++ /dev/null @@ -1,18 +0,0 @@ -package core - -/** - * Service is a global facility that could be Enabled or Disabled for a number - * of core.Server instances, depending on their configration. See services/registry - * for exact examples. - */ -type Service interface { - /** - * Enable service for Server - */ - Enable(Server) error - - /** - * Disable service for Server - */ - Disable(Server) error -} diff --git a/router/gobetween/core/target.go b/router/gobetween/core/target.go deleted file mode 100644 index 2b6bcdc97..000000000 --- a/router/gobetween/core/target.go +++ /dev/null @@ -1,37 +0,0 @@ -/** - * target.go - backend target - * - * @author Yaroslav Pogrebnyak - */ -package core - -/** - * Target host and port - */ -type Target struct { - Host string `json:"host"` - Port string `json:"port"` -} - -/** - * Compare to other target - */ -func (t *Target) EqualTo(other Target) bool { - return t.Host == other.Host && - t.Port == other.Port -} - -/** - * Get target full address - * host:port - */ -func (this *Target) Address() string { - return this.Host + ":" + this.Port -} - -/** - * To String conversion - */ -func (this *Target) String() string { - return this.Address() -} diff --git a/router/gobetween/discovery/consul.go b/router/gobetween/discovery/consul.go deleted file mode 100644 index a716869ec..000000000 --- a/router/gobetween/discovery/consul.go +++ /dev/null @@ -1,134 +0,0 @@ -/** - * consul.go - Consul API discovery implementation - * - * @author Yaroslav Pogrebnyak - */ - -package discovery - -import ( - "../config" - "../core" - "../logging" - "../utils" - "fmt" - consul "github.com/hashicorp/consul/api" - "net/http" - "strings" - "time" -) - -const ( - consulRetryWaitDuration = 2 * time.Second - consulTimeout = 2 * time.Second -) - -/** - * Create new Discovery with Consul fetch func - */ -func NewConsulDiscovery(cfg config.DiscoveryConfig) interface{} { - - d := Discovery{ - opts: DiscoveryOpts{consulRetryWaitDuration}, - fetch: consulFetch, - cfg: cfg, - } - - return &d -} - -/** - * Fetch backends from Consul API - */ -func consulFetch(cfg config.DiscoveryConfig) (*[]core.Backend, error) { - - log := logging.For("consulFetch") - - log.Info("Fetching ", cfg) - - // Prepare vars for http client - // TODO move http & consul client creation to constructor - scheme := "http" - transport := &http.Transport{ - DisableKeepAlives: true, - } - - // Enable tls if needed - if cfg.ConsulTlsEnabled { - tlsConfig := &consul.TLSConfig{ - Address: cfg.ConsulHost, - CertFile: cfg.ConsulTlsCertPath, - KeyFile: cfg.ConsulTlsKeyPath, - CAFile: cfg.ConsulTlsCacertPath, - } - tlsClientConfig, err := consul.SetupTLSConfig(tlsConfig) - if err != nil { - return nil, err - } - transport.TLSClientConfig = tlsClientConfig - scheme = "https" - } - - // Parse http timeout - timeout := utils.ParseDurationOrDefault(cfg.Timeout, consulTimeout) - - // Create consul client - client, _ := consul.NewClient(&consul.Config{ - Scheme: scheme, - Address: cfg.ConsulHost, - Datacenter: cfg.ConsulDatacenter, - HttpAuth: &consul.HttpBasicAuth{ - Username: cfg.ConsulAuthUsername, - Password: cfg.ConsulAuthPassword, - }, - HttpClient: &http.Client{Timeout: timeout, Transport: transport}, - }) - - // Query service - service, _, err := client.Health().Service(cfg.ConsulServiceName, cfg.ConsulServiceTag, cfg.ConsulServicePassingOnly, nil) - if err != nil { - return nil, err - } - - // Gather backends - backends := []core.Backend{} - for _, entry := range service { - s := entry.Service - sni := "" - - for _, tag := range s.Tags { - split := strings.SplitN(tag, "=", 2) - - if len(split) != 2 { - continue - } - - if split[0] != "sni" { - continue - } - sni = split[1] - } - - var host string - if s.Address != "" { - host = s.Address - } else { - host = entry.Node.Address - } - - backends = append(backends, core.Backend{ - Target: core.Target{ - Host: host, - Port: fmt.Sprintf("%v", s.Port), - }, - Priority: 1, - Weight: 1, - Stats: core.BackendStats{ - Live: true, - }, - Sni: sni, - }) - } - - return &backends, nil -} diff --git a/router/gobetween/discovery/discovery.go b/router/gobetween/discovery/discovery.go deleted file mode 100644 index 035ce5819..000000000 --- a/router/gobetween/discovery/discovery.go +++ /dev/null @@ -1,147 +0,0 @@ -/** - * discovery.go - discovery - * - * @author Yaroslav Pogrebnyak - */ - -package discovery - -import ( - "../config" - "../core" - "../logging" - "time" -) - -/** - * Registry of factory methods for Discoveries - */ -var registry = make(map[string]func(config.DiscoveryConfig) interface{}) - -/** - * Initialize type registry - */ -func init() { - registry["static"] = NewStaticDiscovery - registry["srv"] = NewSrvDiscovery - registry["docker"] = NewDockerDiscovery - registry["json"] = NewJsonDiscovery - registry["exec"] = NewExecDiscovery - registry["plaintext"] = NewPlaintextDiscovery - registry["consul"] = NewConsulDiscovery - registry["lxd"] = NewLXDDiscovery -} - -/** - * Create new Discovery based on strategy - */ -func New(strategy string, cfg config.DiscoveryConfig) *Discovery { - return registry[strategy](cfg).(*Discovery) -} - -/** - * Fetch func for pullig backends - */ -type FetchFunc func(config.DiscoveryConfig) (*[]core.Backend, error) - -/** - * Options for pull discovery - */ -type DiscoveryOpts struct { - RetryWaitDuration time.Duration -} - -/** - * Discovery - */ -type Discovery struct { - - /** - * Cached backends - */ - backends *[]core.Backend - - /** - * Function to fetch / discovery backends - */ - fetch FetchFunc - - /** - * Options for fetch - */ - opts DiscoveryOpts - - /** - * Discovery configuration - */ - cfg config.DiscoveryConfig - - /** - * Channel where to push newly discovered backends - */ - out chan ([]core.Backend) -} - -/** - * Pull / fetch backends loop - */ -func (this *Discovery) Start() { - - log := logging.For("discovery") - - this.out = make(chan []core.Backend) - - // Prepare interval - interval, err := time.ParseDuration(this.cfg.Interval) - if err != nil { - log.Fatal(err) - } - - go func() { - for { - backends, err := this.fetch(this.cfg) - - if err != nil { - log.Error(this.cfg.Kind, " error ", err, " retrying in ", this.opts.RetryWaitDuration.String()) - - log.Info("Applying failpolicy ", this.cfg.Failpolicy) - - if this.cfg.Failpolicy == "setempty" { - this.backends = &[]core.Backend{} - this.out <- *this.backends - } - - time.Sleep(this.opts.RetryWaitDuration) - continue - } - - // cache - this.backends = backends - - // out - this.out <- *this.backends - - // exit gorouting if no cacheTtl - // used for static discovery - if interval == 0 { - return - } - - time.Sleep(interval) - } - }() -} - -/** - * Stop discovery - */ -func (this *Discovery) Stop() { - // TODO: Add stopping function -} - -/** - * Returns backends channel - */ -func (this *Discovery) Discover() <-chan []core.Backend { - return this.out -} diff --git a/router/gobetween/discovery/docker.go b/router/gobetween/discovery/docker.go deleted file mode 100644 index 88b496e59..000000000 --- a/router/gobetween/discovery/docker.go +++ /dev/null @@ -1,170 +0,0 @@ -/** - * docker.go - Docker API discovery implementation - * - * @author Yaroslav Pogrebnyak - */ - -package discovery - -import ( - "../config" - "../core" - "../logging" - "../utils" - "errors" - "fmt" - "github.com/fsouza/go-dockerclient" - "regexp" - "time" -) - -const ( - dockerRetryWaitDuration = 2 * time.Second - dockerTimeout = 5 * time.Second -) - -/** - * Create new Discovery with Docker fetch func - */ -func NewDockerDiscovery(cfg config.DiscoveryConfig) interface{} { - - d := Discovery{ - opts: DiscoveryOpts{dockerRetryWaitDuration}, - fetch: dockerFetch, - cfg: cfg, - } - - return &d -} - -/** - * Fetch backends from Docker API - */ -func dockerFetch(cfg config.DiscoveryConfig) (*[]core.Backend, error) { - - log := logging.For("dockerFetch") - - log.Info("Fetching ", cfg.DockerEndpoint, " ", cfg.DockerContainerLabel, " ", cfg.DockerContainerPrivatePort) - - var client *docker.Client - var err error - - if cfg.DockerTlsEnabled { - - // Client cert and key files should be specified together (or both not specified) - // Ca cert may be not specified, so not checked here - if (cfg.DockerTlsCertPath == "") != (cfg.DockerTlsKeyPath == "") { - return nil, errors.New("Missing key or certificate required for TLS client validation") - } - - client, err = docker.NewTLSClient(cfg.DockerEndpoint, cfg.DockerTlsCertPath, cfg.DockerTlsKeyPath, cfg.DockerTlsCacertPath) - - } else { - client, err = docker.NewClient(cfg.DockerEndpoint) - } - - if err != nil { - return nil, err - } - - /* Set timeout */ - client.HTTPClient.Timeout = utils.ParseDurationOrDefault(cfg.Timeout, dockerTimeout) - - /* Add filter labels if any */ - var filters map[string][]string - if cfg.DockerContainerLabel != "" { - filters = map[string][]string{"label": []string{cfg.DockerContainerLabel}} - } - - /* Fetch containers */ - containers, err := client.ListContainers(docker.ListContainersOptions{Filters: filters}) - if err != nil { - return nil, err - } - - /* Create backends from response */ - - backends := []core.Backend{} - - for _, container := range containers { - for _, port := range container.Ports { - - if port.PrivatePort != cfg.DockerContainerPrivatePort { - continue - } - - containerHost := dockerDetermineContainerHost(client, container.ID, cfg, port.IP) - - backends = append(backends, core.Backend{ - Target: core.Target{ - Host: containerHost, - Port: fmt.Sprintf("%v", port.PublicPort), - }, - Priority: 1, - Weight: 1, - Stats: core.BackendStats{ - Live: true, - }, - Sni: container.Labels["sni"], - }) - } - } - - return &backends, nil -} - -/** - * Determines container host - */ -func dockerDetermineContainerHost(client *docker.Client, id string, cfg config.DiscoveryConfig, portHost string) string { - - log := logging.For("dockerDetermineContainerHost") - - /* If host env var specified, try to get it from container vars */ - - if cfg.DockerContainerHostEnvVar != "" { - - container, err := client.InspectContainer(id) - - if err != nil { - log.Warn(err) - } else { - var e docker.Env = container.Config.Env - h := e.Get(cfg.DockerContainerHostEnvVar) - if h != "" { - return h - } - } - } - - /* If container portHost is not 'all interfaces', return it since it's good enough */ - - if portHost != "0.0.0.0" { - return portHost - } - - /* Last chance, try to parse docker host from endpoint string */ - - var reg = regexp.MustCompile("(.*?)://(?P[-.A-Za-z0-9]+)/?(.*)") - match := reg.FindStringSubmatch(cfg.DockerEndpoint) - - if len(match) == 0 { - return portHost - } - - result := make(map[string]string) - - // get named capturing groups - for i, name := range reg.SubexpNames() { - if name != "" { - result[name] = match[i] - } - } - - h, ok := result["host"] - if !ok { - return portHost - } - - return h -} diff --git a/router/gobetween/discovery/exec.go b/router/gobetween/discovery/exec.go deleted file mode 100644 index 20cc7f7d0..000000000 --- a/router/gobetween/discovery/exec.go +++ /dev/null @@ -1,74 +0,0 @@ -/** - * exec.go - Exec external process discovery implementation - * - * @author Yaroslav Pogrebnyak - * @author Ievgen Ponomarenko - */ - -package discovery - -import ( - "../config" - "../core" - "../logging" - "../utils" - "../utils/parsers" - "strings" - "time" -) - -const ( - execRetryWaitDuration = 2 * time.Second - execResponseWaitTimeout = 3 * time.Second -) - -/** - * Create new Discovery with Exec fetch func - */ -func NewExecDiscovery(cfg config.DiscoveryConfig) interface{} { - - d := Discovery{ - opts: DiscoveryOpts{execRetryWaitDuration}, - fetch: execFetch, - cfg: cfg, - } - - return &d -} - -/** - * Fetch / refresh backends exec process - */ -func execFetch(cfg config.DiscoveryConfig) (*[]core.Backend, error) { - - log := logging.For("execFetch") - - log.Info("Fetching ", cfg.ExecCommand) - - timeout := utils.ParseDurationOrDefault(cfg.Timeout, execResponseWaitTimeout) - out, err := utils.ExecTimeout(timeout, cfg.ExecCommand...) - if err != nil { - return nil, err - } - - backends := []core.Backend{} - - for _, line := range strings.Split(string(out), "\n") { - - if line == "" { - continue - } - - backend, err := parsers.ParseBackendDefault(line) - if err != nil { - log.Warn(err) - continue - } - - backends = append(backends, *backend) - } - - log.Info("Fetched ", backends) - - return &backends, nil -} diff --git a/router/gobetween/discovery/json.go b/router/gobetween/discovery/json.go deleted file mode 100644 index c17a999b0..000000000 --- a/router/gobetween/discovery/json.go +++ /dev/null @@ -1,153 +0,0 @@ -/** - * docker.go - Docker API discovery implementation - * - * @author Ievgen Ponomarenko - * @author Yaroslav Pogrebnyak - */ - -package discovery - -import ( - "errors" - "fmt" - "io/ioutil" - "net/http" - "strconv" - "time" - - "../config" - "../core" - "../logging" - "../utils" - "github.com/elgs/gojq" -) - -const ( - jsonRetryWaitDuration = 2 * time.Second - jsonDefaultHttpTimeout = 5 * time.Second - jsonDefaultHostPattern = "host" - jsonDefaultPortPattern = "port" - jsonDefaultWeightPattern = "weight" - jsonDefaultPriorityPattern = "priority" - jsonDefaultSniPattern = "sni" -) - -/** - * Create new Discovery with Json fetch func - */ -func NewJsonDiscovery(cfg config.DiscoveryConfig) interface{} { - - /* replace with defaults if needed */ - - if cfg.JsonHostPattern == "" { - cfg.JsonHostPattern = jsonDefaultHostPattern - } - - if cfg.JsonPortPattern == "" { - cfg.JsonPortPattern = jsonDefaultPortPattern - } - - if cfg.JsonWeightPattern == "" { - cfg.JsonWeightPattern = jsonDefaultWeightPattern - } - - if cfg.JsonPriorityPattern == "" { - cfg.JsonPriorityPattern = jsonDefaultPriorityPattern - } - - if cfg.JsonSniPattern == "" { - cfg.JsonSniPattern = jsonDefaultSniPattern - } - - d := Discovery{ - opts: DiscoveryOpts{jsonRetryWaitDuration}, - fetch: jsonFetch, - cfg: cfg, - } - - return &d -} - -/** - * Fetch / refresh backends from URL with json in response - */ -func jsonFetch(cfg config.DiscoveryConfig) (*[]core.Backend, error) { - - log := logging.For("jsonFetch") - - log.Info("fetching ", cfg.JsonEndpoint) - - // Make request - timeout := utils.ParseDurationOrDefault(cfg.Timeout, jsonDefaultHttpTimeout) - client := http.Client{Timeout: timeout} - res, err := client.Get(cfg.JsonEndpoint) - if err != nil { - return nil, err - } - - defer res.Body.Close() - - // Read response - content, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, err - } - - // Build query - parsed, err := gojq.NewStringQuery(string(content)) - if err != nil { - return nil, err - } - - // parse query to array to ensure right format and get length of it - parsedArray, err := parsed.QueryToArray(".") - if err != nil { - return nil, errors.New("Unexpected json in response") - } - - var backends []core.Backend - - for k := range parsedArray { - - var key = "[" + strconv.Itoa(k) + "]." - - backend := core.Backend{ - Weight: 1, - Priority: 1, - Stats: core.BackendStats{ - Live: true, - }, - } - - if backend.Host, err = parsed.QueryToString(key + cfg.JsonHostPattern); err != nil { - return nil, err - } - - // workaround to allow string or number port value - port, err := parsed.Query(key + cfg.JsonPortPattern) - if err != nil { - return nil, err - } - - // convert port to string (if not) - backend.Port = fmt.Sprintf("%v", port) - - if weight, err := parsed.QueryToInt64(key + cfg.JsonWeightPattern); err == nil { - backend.Weight = int(weight) - } - - if priority, err := parsed.QueryToFloat64(key + cfg.JsonPriorityPattern); err == nil { - backend.Priority = int(priority) - } - - if sni, err := parsed.QueryToString(key + cfg.JsonSniPattern); err == nil { - backend.Sni = sni - } - - backends = append(backends, backend) - } - - log.Info(backends) - - return &backends, nil -} diff --git a/router/gobetween/discovery/lxd.go b/router/gobetween/discovery/lxd.go deleted file mode 100644 index 368776bf0..000000000 --- a/router/gobetween/discovery/lxd.go +++ /dev/null @@ -1,360 +0,0 @@ -/** - * lxd.go - LXD API discovery implementation - * - * @author Joe Topjian - */ - -package discovery - -import ( - "encoding/pem" - "fmt" - "os" - "strings" - "time" - - "../config" - "../core" - "../logging" - "../utils" - - lxd "github.com/lxc/lxd/client" - lxd_config "github.com/lxc/lxd/lxc/config" - "github.com/lxc/lxd/shared" - lxd_api "github.com/lxc/lxd/shared/api" -) - -const ( - lxdRetryWaitDuration = 2 * time.Second - lxdTimeout = 5 * time.Second -) - -/** - * Create new Discovery with LXD fetch func - */ -func NewLXDDiscovery(cfg config.DiscoveryConfig) interface{} { - - d := Discovery{ - opts: DiscoveryOpts{lxdRetryWaitDuration}, - fetch: lxdFetch, - cfg: cfg, - } - - return &d -} - -/** - * Fetch backends from LXD API - */ -func lxdFetch(cfg config.DiscoveryConfig) (*[]core.Backend, error) { - log := logging.For("lxdFetch") - - /* Get an LXD client */ - client, err := lxdBuildClient(cfg) - if err != nil { - return nil, err - } - - /* Get an LXD config */ - lxdConfig, err := lxdBuildConfig(cfg) - if err != nil { - return nil, err - } - - /* Set the timeout for the client */ - httpClient, err := client.GetHTTPClient() - if err != nil { - return nil, err - } - - httpClient.Timeout = utils.ParseDurationOrDefault(cfg.Timeout, lxdTimeout) - - log.Debug("Fetching containers from ", lxdConfig.Remotes[cfg.LXDServerRemoteName].Addr) - - /* Create backends from response */ - backends := []core.Backend{} - - /* Fetch containers */ - containers, err := client.GetContainers() - if err != nil { - return nil, err - } - - for _, container := range containers { - - /* Ignore containers that aren't running */ - if container.Status != "Running" { - continue - } - - /* Ignore continers if not match label key and value */ - if cfg.LXDContainerLabelKey != "" { - - actualLabelValue, ok := container.Config[cfg.LXDContainerLabelKey] - if !ok { - continue - } - - if cfg.LXDContainerLabelValue != "" && actualLabelValue != cfg.LXDContainerLabelValue { - continue - } - } - - /* Try get container port either from label, or from discovery config */ - port := fmt.Sprintf("%v", cfg.LXDContainerPort) - - if cfg.LXDContainerPortKey != "" { - if p, ok := container.Config[cfg.LXDContainerPortKey]; ok { - port = p - } - } - - if port == "" { - log.Warn(fmt.Sprintf("Port is not found in neither in lxd_container_port config not in %s label for %s. Skipping", - cfg.LXDContainerPortKey, container.Name)) - continue - } - - /* iface is the container interface to get an IP address. */ - /* This isn't exposed by the LXD API, and containers can have multiple interfaces, */ - iface := cfg.LXDContainerInterface - if v, ok := container.Config[cfg.LXDContainerInterfaceKey]; ok { - iface = v - } - - ip := "" - if ip, err = lxdDetermineContainerIP(client, container.Name, iface, cfg.LXDContainerAddressType); err != nil { - log.Error(fmt.Sprintf("Can't determine %s container ip address: %s. Skipping", container.Name, err)) - continue - } - - sni := "" - if v, ok := container.Config[cfg.LXDContainerSNIKey]; ok { - sni = v - } - - backends = append(backends, core.Backend{ - Target: core.Target{ - Host: ip, - Port: port, - }, - Priority: 1, - Weight: 1, - Stats: core.BackendStats{ - Live: true, - }, - Sni: sni, - }) - } - - return &backends, nil -} - -/** - * Create new LXD Client - */ -func lxdBuildClient(cfg config.DiscoveryConfig) (lxd.ContainerServer, error) { - log := logging.For("lxdBuildClient") - - /* Make a client to pass around */ - var client lxd.ContainerServer - - /* Build a configuration with the requested options */ - lxdConfig, err := lxdBuildConfig(cfg) - if err != nil { - return client, err - } - - if strings.HasPrefix(cfg.LXDServerAddress, "https:") { - - /* Validate or generate certificates on the client side (gobetween) */ - if cfg.LXDGenerateClientCerts { - log.Debug("Generating LXD client certificates") - if err := lxdConfig.GenerateClientCertificate(); err != nil { - return nil, err - } - } - - /* Validate or accept certificates on the server side (LXD) */ - serverCertf := lxdConfig.ServerCertPath(cfg.LXDServerRemoteName) - if !shared.PathExists(serverCertf) { - /* If the server certificate was not found, either gobetween and the LXD server are set - * up for PKI, or gobetween must authenticate with the LXD server and accept its server - * certificate. - * - * First, see if communication with the LXD server is possible. - */ - _, err := lxdConfig.GetContainerServer(cfg.LXDServerRemoteName) - if err != nil { - /* If there was an error, then gobetween will try to download the server's cert. */ - if cfg.LXDAcceptServerCert { - log.Debug("Retrieving LXD server certificate") - err := lxdGetRemoteCertificate(lxdConfig, cfg.LXDServerRemoteName) - if err != nil { - return nil, fmt.Errorf("Could obtain LXD server certificate: %s", err) - } - } else { - err := fmt.Errorf("Unable to communicate with LXD server. Either set " + - "lxd_accept_server_cert to true or add the LXD server out of " + - "band of gobetween and try again.") - return nil, err - } - } - } - - /* - * Finally, check and see if gobetween needs to authenticate with the LXD server. - * Authentication happens only once. After that, gobetween will be a trusted client - * as long as the exchanged certificates to not change. - * - * Authentication must happen even if PKI is in use. - */ - client, err = lxdConfig.GetContainerServer(cfg.LXDServerRemoteName) - if err != nil { - return nil, err - } - - log.Info("Authenticating to LXD server") - err = lxdAuthenticateToServer(client, cfg.LXDServerRemoteName, cfg.LXDServerRemotePassword) - if err != nil { - log.Info("Authentication unsuccessful") - return nil, err - } - - log.Info("Authentication successful") - } - - /* Build a new client */ - client, err = lxdConfig.GetContainerServer(cfg.LXDServerRemoteName) - if err != nil { - return nil, err - } - - /* Validate the client config and connectivity */ - if _, _, err := client.GetServer(); err != nil { - return nil, err - } - - return client, nil -} - -/** - * Create LXD Client Config - */ -func lxdBuildConfig(cfg config.DiscoveryConfig) (*lxd_config.Config, error) { - log := logging.For("lxdBuildConfig") - - log.Debug("Using API: ", cfg.LXDServerAddress) - - /* Build an LXD configuration that will connect to the requested LXD server */ - var config *lxd_config.Config - if conf, err := lxd_config.LoadConfig(cfg.LXDConfigDirectory); err != nil { - config = &lxd_config.DefaultConfig - config.ConfigDir = cfg.LXDConfigDirectory - } else { - config = conf - } - - config.Remotes[cfg.LXDServerRemoteName] = lxd_config.Remote{Addr: cfg.LXDServerAddress} - return config, nil -} - -/** -* lxdGetRemoteCertificate will attempt to retrieve a remote LXD server's - certificate and save it to the servercert's path. -*/ -func lxdGetRemoteCertificate(config *lxd_config.Config, remote string) error { - addr := config.Remotes[remote] - certificate, err := shared.GetRemoteCertificate(addr.Addr) - if err != nil { - return err - } - - serverCertDir := config.ConfigPath("servercerts") - if err := os.MkdirAll(serverCertDir, 0750); err != nil { - return fmt.Errorf("Could not create server cert dir: %s", err) - } - - certf := fmt.Sprintf("%s/%s.crt", serverCertDir, remote) - certOut, err := os.Create(certf) - if err != nil { - return err - } - - pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certificate.Raw}) - certOut.Close() - - return nil -} - -/** - * lxdAuthenticateToServer authenticates to an LXD Server - */ -func lxdAuthenticateToServer(client lxd.ContainerServer, remote string, password string) error { - srv, _, err := client.GetServer() - if srv.Auth == "trusted" { - return nil - } - - req := lxd_api.CertificatesPost{ - Password: password, - } - req.Type = "client" - - err = client.CreateCertificate(req) - if err != nil { - return fmt.Errorf("Unable to authenticate with remote server: %s", err) - } - - _, _, err = client.GetServer() - if err != nil { - return err - } - - return nil -} - -/** - * Get container IP address depending on network interface and address type - */ -func lxdDetermineContainerIP(client lxd.ContainerServer, container, iface, addrType string) (string, error) { - var containerIP string - - /* Convert addrType to inet */ - var inet string - switch addrType { - case "IPv4": - inet = "inet" - case "IPv6": - inet = "inet6" - } - - cstate, _, err := client.GetContainerState(container) - if err != nil { - return "", err - } - - for i, network := range cstate.Network { - if i != iface { - continue - } - - for _, ip := range network.Addresses { - if ip.Family == inet { - containerIP = ip.Address - break - } - } - } - - /* If IPv6, format correctly */ - if inet == "inet6" { - containerIP = fmt.Sprintf("[%s]", containerIP) - } - - if containerIP == "" { - return "", fmt.Errorf("Unable to determine IP address for LXD container %s", container) - } - - return containerIP, nil -} diff --git a/router/gobetween/discovery/plaintext.go b/router/gobetween/discovery/plaintext.go deleted file mode 100644 index ccbe8c4c2..000000000 --- a/router/gobetween/discovery/plaintext.go +++ /dev/null @@ -1,90 +0,0 @@ -/** - * plaintext.go - Plaintext discovery implementation - * - * @author Ievgen Ponomarenko - * @author Yaroslav Pogrebnyak - */ - -package discovery - -import ( - "../config" - "../core" - "../logging" - "../utils" - "../utils/parsers" - "io/ioutil" - "net/http" - "strings" - "time" -) - -const ( - plaintextDefaultRetryWaitDuration = 2 * time.Second - plaintextDefaultHttpTimeout = 5 * time.Second -) - -/** - * Create new Discovery with Plaintext fetch func - */ -func NewPlaintextDiscovery(cfg config.DiscoveryConfig) interface{} { - - if cfg.PlaintextRegexpPattern == "" { - cfg.PlaintextRegexpPattern = parsers.DEFAULT_BACKEND_PATTERN - } - - d := Discovery{ - opts: DiscoveryOpts{plaintextDefaultRetryWaitDuration}, - fetch: plaintextFetch, - cfg: cfg, - } - - return &d -} - -/** - * Fetch / refresh backends from URL with plain text - */ -func plaintextFetch(cfg config.DiscoveryConfig) (*[]core.Backend, error) { - - log := logging.For("plaintextFetch") - - log.Info("Fetching ", cfg.PlaintextEndpoint) - - // Make request - timeout := utils.ParseDurationOrDefault(cfg.Timeout, plaintextDefaultHttpTimeout) - client := http.Client{Timeout: timeout} - res, err := client.Get(cfg.PlaintextEndpoint) - if err != nil { - return nil, err - } - - defer res.Body.Close() - - // Read response - content, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, err - } - - backends := []core.Backend{} - lines := strings.Split(string(content), "\n") - - // Iterate and parse - for _, line := range lines { - - if line == "" { - continue - } - - backend, err := parsers.ParseBackend(line, cfg.PlaintextRegexpPattern) - if err != nil { - log.Warn("Cant parse ", line, err) - continue - } - - backends = append(backends, *backend) - } - - return &backends, err -} diff --git a/router/gobetween/discovery/srv.go b/router/gobetween/discovery/srv.go deleted file mode 100644 index 5890a03d7..000000000 --- a/router/gobetween/discovery/srv.go +++ /dev/null @@ -1,140 +0,0 @@ -/** - * srv.go - SRV record DNS resolve discovery implementation - * - * @author Yaroslav Pogrebnyak - */ - -package discovery - -import ( - "errors" - "fmt" - "strings" - "time" - - "../config" - "../core" - "../logging" - "../utils" - "github.com/miekg/dns" -) - -const ( - srvRetryWaitDuration = 2 * time.Second - srvDefaultWaitTimeout = 5 * time.Second - srvUdpSize = 4096 -) - -func NewSrvDiscovery(cfg config.DiscoveryConfig) interface{} { - - d := Discovery{ - opts: DiscoveryOpts{srvRetryWaitDuration}, - fetch: srvFetch, - cfg: cfg, - } - - return &d -} - -/** - * Create new Discovery with Srv fetch func - */ -func srvFetch(cfg config.DiscoveryConfig) (*[]core.Backend, error) { - - log := logging.For("srvFetch") - - log.Info("Fetching ", cfg.SrvLookupServer, " ", cfg.SrvLookupPattern) - - /* ----- perform query srv ----- */ - - r, err := srvDnsLookup(cfg, cfg.SrvLookupPattern, dns.TypeSRV) - if err != nil { - return nil, err - } - - if len(r.Answer) == 0 { - log.Warn("Empty response from", cfg.SrvLookupServer, cfg.SrvLookupPattern) - return &[]core.Backend{}, nil - } - - /* ----- try to get A data from additional section ------ */ - - hosts := make(map[string]string) // name -> host - for _, ans := range r.Extra { - record, ok := ans.(*dns.A) - if !ok { - continue - } - - hosts[record.Header().Name] = record.A.String() - } - - /* ----- create backends list looking up for A if needed ----- */ - - backends := []core.Backend{} - for _, ans := range r.Answer { - - record, ok := ans.(*dns.SRV) - if !ok { - return nil, errors.New("Non-SRV record in SRV answer") - } - - // If there were no A record in additional SRV response, - // Fetch it explicitelly - if _, ok := hosts[record.Target]; !ok { - - log.Debug("Fetching ", cfg.SrvLookupServer, " A ", record.Target) - - resp, err := srvDnsLookup(cfg, record.Target, dns.TypeA) - if err != nil { - log.Warn("Error fetching A record for ", record.Target, " skipping...") - continue - } - - if len(resp.Answer) == 0 { - log.Warn("Empty answer for A records ", record.Target, " skipping...") - continue - } - - a, ok := resp.Answer[0].(*dns.A) - if !ok { - log.Warn("Non-A record in A answer ", record.Target, " skipping...") - continue - } - - hosts[record.Target] = a.A.String() - } - - // Append new backends - backends = append(backends, core.Backend{ - Target: core.Target{ - Host: hosts[record.Target], - Port: fmt.Sprintf("%v", record.Port), - }, - Priority: int(record.Priority), - Weight: int(record.Weight), - Stats: core.BackendStats{ - Live: true, - }, - Sni: strings.TrimRight(record.Target, "."), - }) - } - - return &backends, nil -} - -/** - * Perform DNS Lookup with needed pattern and type - */ -func srvDnsLookup(cfg config.DiscoveryConfig, pattern string, typ uint16) (*dns.Msg, error) { - - timeout := utils.ParseDurationOrDefault(cfg.Timeout, srvDefaultWaitTimeout) - c := dns.Client{Net: cfg.SrvDnsProtocol, Timeout: timeout} - m := dns.Msg{} - - m.SetQuestion(pattern, typ) - m.SetEdns0(srvUdpSize, true) - r, _, err := c.Exchange(&m, cfg.SrvLookupServer) - - return r, err -} diff --git a/router/gobetween/discovery/static.go b/router/gobetween/discovery/static.go deleted file mode 100644 index 8c22d5fed..000000000 --- a/router/gobetween/discovery/static.go +++ /dev/null @@ -1,48 +0,0 @@ -/** - * static.go - static list discovery implementation - * - * @author Yaroslav Pogrebnyak - */ - -package discovery - -import ( - "../config" - "../core" - "../logging" - "../utils/parsers" -) - -/** - * Creates new static discovery - */ -func NewStaticDiscovery(cfg config.DiscoveryConfig) interface{} { - - d := Discovery{ - opts: DiscoveryOpts{0}, - cfg: cfg, - fetch: staticFetch, - } - - return &d -} - -/** - * Start discovery - */ -func staticFetch(cfg config.DiscoveryConfig) (*[]core.Backend, error) { - - log := logging.For("discovery/static") - - var backends []core.Backend - for _, s := range cfg.StaticList { - backend, err := parsers.ParseBackendDefault(s) - if err != nil { - log.Warn(err) - continue - } - backends = append(backends, *backend) - } - - return &backends, nil -} diff --git a/router/gobetween/gobetween.go b/router/gobetween/gobetween.go deleted file mode 100644 index e10e4ac03..000000000 --- a/router/gobetween/gobetween.go +++ /dev/null @@ -1,75 +0,0 @@ -/** - * main.go - entry point - * @author Yaroslav Pogrebnyak - */ -package gobetween - -import ( - "io/ioutil" - "log" - "math/rand" - "os" - "runtime" - "time" - - "./api" - "./config" - "./info" - "./logging" - "./manager" - "./utils/codec" -) - -/** - * Version should be set while build using ldflags (see Makefile) - */ -var version string - -/** - * Initialize package - */ -func init() { - - // Set GOMAXPROCS if not set - if os.Getenv("GOMAXPROCS") == "" { - runtime.GOMAXPROCS(runtime.NumCPU()) - } - - // Init random seed - rand.Seed(time.Now().UnixNano()) - - // Save info - info.Version = version - info.StartTime = time.Now() - -} - -/** - * Entry point - */ -func Run(string path) { - - log.Printf("gobetween v%s", version) - - data, err := ioutil.ReadFile(path) - if err != nil { - log.Fatal(err) - } - - var cfg config.Config - if err = codec.Decode(string(data), &cfg, "json"); err != nil { - log.Fatal(err) - } - // Configure logging - logging.Configure(cfg.Logging.Output, cfg.Logging.Level) - - // Start API - go api.Start((*cfg).Api) - - // Start manager - go manager.Initialize(*cfg) - - // block forever - <-(chan string)(nil) - -} diff --git a/router/gobetween/healthcheck/exec.go b/router/gobetween/healthcheck/exec.go deleted file mode 100644 index eb1cad1bf..000000000 --- a/router/gobetween/healthcheck/exec.go +++ /dev/null @@ -1,50 +0,0 @@ -/** - * exec.go - Exec healthcheck - * - * @author Yaroslav Pogrebnyak - */ - -package healthcheck - -import ( - "../config" - "../core" - "../logging" - "../utils" - "time" -) - -/** - * Exec healthcheck - */ -func exec(t core.Target, cfg config.HealthcheckConfig, result chan<- CheckResult) { - - log := logging.For("healthcheck/exec") - - execTimeout, _ := time.ParseDuration(cfg.Timeout) - - checkResult := CheckResult{ - Target: t, - } - - out, err := utils.ExecTimeout(execTimeout, cfg.ExecCommand, t.Host, t.Port) - if err != nil { - // TODO: Decide better what to do in this case - checkResult.Live = false - log.Warn(err) - } else { - if out == cfg.ExecExpectedPositiveOutput { - checkResult.Live = true - } else if out == cfg.ExecExpectedNegativeOutput { - checkResult.Live = false - } else { - log.Warn("Unexpected output: ", out) - } - } - - select { - case result <- checkResult: - default: - log.Warn("Channel is full. Discarding value") - } -} diff --git a/router/gobetween/healthcheck/healthcheck.go b/router/gobetween/healthcheck/healthcheck.go deleted file mode 100644 index 5eaf106f8..000000000 --- a/router/gobetween/healthcheck/healthcheck.go +++ /dev/null @@ -1,182 +0,0 @@ -/** - * healthcheck.go - Healtheck - * - * @author Yaroslav Pogrebnyak - */ - -package healthcheck - -import ( - "../config" - "../core" -) - -/** - * Health Check function - * Returns channel in which only one check result will be delivered - */ -type CheckFunc func(core.Target, config.HealthcheckConfig, chan<- CheckResult) - -/** - * Check result - * Handles target and it's live status - */ -type CheckResult struct { - - /* Check target */ - Target core.Target - - /* Check live status */ - Live bool -} - -/** - * Healthcheck - */ -type Healthcheck struct { - - /* Healthcheck function */ - check CheckFunc - - /* Healthcheck configuration */ - cfg config.HealthcheckConfig - - /* Input channel to accept targets */ - In chan []core.Target - - /* Output channel to send check results for individual target */ - Out chan CheckResult - - /* Current check workers */ - workers []*Worker - - /* Channel to handle stop */ - stop chan bool -} - -/** - * Registry of factory methods - */ -var registry = make(map[string]CheckFunc) - -/** - * Initialize type registry - */ -func init() { - registry["ping"] = ping - registry["exec"] = exec - registry["none"] = nil -} - -/** - * Create new Discovery based on strategy - */ -func New(strategy string, cfg config.HealthcheckConfig) *Healthcheck { - - check := registry[strategy] - - /* Create healthcheck */ - - h := Healthcheck{ - check: check, - cfg: cfg, - In: make(chan []core.Target), - Out: make(chan CheckResult), - workers: []*Worker{}, - stop: make(chan bool), - } - - return &h -} - -/** - * Start healthcheck - */ -func (this *Healthcheck) Start() { - - go func() { - for { - select { - - /* got new targets */ - case targets := <-this.In: - this.UpdateWorkers(targets) - - /* got stop requst */ - case <-this.stop: - - // Stop all workers - for i := range this.workers { - this.workers[i].Stop() - } - - // And free it's memory - this.workers = []*Worker{} - - return - } - } - }() -} - -/** - * Sync current workers to represent healtcheck on targets - * Will remove not needed workers, and add needed - */ -func (this *Healthcheck) UpdateWorkers(targets []core.Target) { - - result := []*Worker{} - - // Keep or add needed workers - for _, t := range targets { - var keep *Worker - for i := range this.workers { - c := this.workers[i] - if t.EqualTo(c.target) { - keep = c - break - } - } - - if keep == nil { - keep = &Worker{ - target: t, - stop: make(chan bool), - out: this.Out, - cfg: this.cfg, - check: this.check, - LastResult: CheckResult{ - Live: true, - }, - } - keep.Start() - } - result = append(result, keep) - } - - // Stop needed workers - for i := range this.workers { - c := this.workers[i] - remove := true - for _, t := range targets { - if c.target.EqualTo(t) { - remove = false - break - } - } - - if remove { - c.Stop() - } - } - - this.workers = result - -} - -/** - * Stop healthcheck - */ -func (this *Healthcheck) Stop() { - this.stop <- true -} diff --git a/router/gobetween/healthcheck/ping.go b/router/gobetween/healthcheck/ping.go deleted file mode 100644 index 6a14e613a..000000000 --- a/router/gobetween/healthcheck/ping.go +++ /dev/null @@ -1,43 +0,0 @@ -/** - * ping.go - TCP ping healthcheck - * - * @author Yaroslav Pogrebnyak - */ - -package healthcheck - -import ( - "../config" - "../core" - "../logging" - "net" - "time" -) - -/** - * Ping healthcheck - */ -func ping(t core.Target, cfg config.HealthcheckConfig, result chan<- CheckResult) { - - pingTimeoutDuration, _ := time.ParseDuration(cfg.Timeout) - - log := logging.For("healthcheck/ping") - - checkResult := CheckResult{ - Target: t, - } - - conn, err := net.DialTimeout("tcp", t.Address(), pingTimeoutDuration) - if err != nil { - checkResult.Live = false - } else { - checkResult.Live = true - conn.Close() - } - - select { - case result <- checkResult: - default: - log.Warn("Channel is full. Discarding value") - } -} diff --git a/router/gobetween/healthcheck/worker.go b/router/gobetween/healthcheck/worker.go deleted file mode 100644 index 13d44d627..000000000 --- a/router/gobetween/healthcheck/worker.go +++ /dev/null @@ -1,123 +0,0 @@ -/** - * worker.go - Healtheck worker - * - * @author Yaroslav Pogrebnyak - */ - -package healthcheck - -import ( - "../config" - "../core" - "../logging" - "time" -) - -/** - * Healthcheck Worker - * Handles all periodic healthcheck logic - * and yields results on change - */ -type Worker struct { - - /* Target to monitor and check */ - target core.Target - - /* Function that does actual check */ - check CheckFunc - - /* Channel to write changed check results */ - out chan<- CheckResult - - /* Healthcheck configuration */ - cfg config.HealthcheckConfig - - /* Stop channel to worker to stop */ - stop chan bool - - /* Last confirmed check result */ - LastResult CheckResult - - /* Current passes count, if LastResult.Live = true */ - passes int - - /* Current fails count, if LastResult.Live = false */ - fails int -} - -/** - * Start worker - */ -func (this *Worker) Start() { - - log := logging.For("healthcheck/worker") - - // Special case for no healthcheck, don't actually start worker - if this.cfg.Kind == "none" { - return - } - - interval, _ := time.ParseDuration(this.cfg.Interval) - - ticker := time.NewTicker(interval) - c := make(chan CheckResult, 1) - - go func() { - for { - select { - - /* new check interval has reached */ - case <-ticker.C: - log.Debug("Next check ", this.cfg.Kind, " for ", this.target) - go this.check(this.target, this.cfg, c) - - /* new check result is ready */ - case checkResult := <-c: - log.Debug("Got check result ", this.cfg.Kind, ": ", checkResult) - this.process(checkResult) - - /* request to stop worker */ - case <-this.stop: - ticker.Stop() - //close(c) // TODO: Check! - return - } - } - }() -} - -/** - * Process next check result, - * counting passes and fails as needed, and - * sending updated check result to out - */ -func (this *Worker) process(checkResult CheckResult) { - - log := logging.For("healthcheck/worker") - - if this.LastResult.Live && !checkResult.Live { - this.passes = 0 - this.fails++ - } else if !this.LastResult.Live && checkResult.Live { - this.fails = 0 - this.passes++ - } else { - // check status not changed - return - } - - if this.passes == 0 && this.fails >= this.cfg.Fails || - this.fails == 0 && this.passes >= this.cfg.Passes { - this.LastResult = checkResult - - log.Info("Sending to scheduler: ", this.LastResult) - this.out <- checkResult - } -} - -/** - * Stop worker - */ -func (this *Worker) Stop() { - close(this.stop) -} diff --git a/router/gobetween/info/info.go b/router/gobetween/info/info.go deleted file mode 100644 index 586b923d6..000000000 --- a/router/gobetween/info/info.go +++ /dev/null @@ -1,9 +0,0 @@ -package info - -import ( - "time" -) - -var Version string -var StartTime time.Time -var Configuration interface{} diff --git a/router/gobetween/logging/log.go b/router/gobetween/logging/log.go deleted file mode 100644 index e212c99af..000000000 --- a/router/gobetween/logging/log.go +++ /dev/null @@ -1,99 +0,0 @@ -/** - * log.go - logging wrapper - * - * @author Yaroslav Pogrebnyak - */ - -package logging - -import ( - "bytes" - "fmt" - "github.com/sirupsen/logrus" - "os" - "strings" -) - -/** - * Logging initialize - */ -func init() { - logrus.SetFormatter(new(MyFormatter)) - logrus.SetLevel(logrus.InfoLevel) - logrus.SetOutput(os.Stdout) -} - -/** - * Configure logging - */ -func Configure(output string, l string) { - - if output == "" || output == "stdout" { - logrus.SetOutput(os.Stdout) - } else if output == "stderr" { - logrus.SetOutput(os.Stderr) - } else { - f, err := os.OpenFile(output, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755) - if err != nil { - logrus.Fatal(err) - } - logrus.SetOutput(f) - } - - if l == "" { - return - } - - if level, err := logrus.ParseLevel(l); err != nil { - logrus.Fatal("Unknown loglevel ", l) - } else { - logrus.SetLevel(level) - } -} - -/** - * Our custom formatter - */ -type MyFormatter struct{} - -/** - * Format entry - */ -func (f *MyFormatter) Format(entry *logrus.Entry) ([]byte, error) { - b := &bytes.Buffer{} - name, ok := entry.Data["name"] - if !ok { - name = "default" - } - fmt.Fprintf(b, "%s [%-5.5s] (%s): %s\n", entry.Time.Format("2006-01-02 15:04:05"), strings.ToUpper(entry.Level.String()), name, entry.Message) - return b.Bytes(), nil -} - -/** - * Add logger name as field var - */ -func For(name string) *logrus.Entry { - return logrus.WithField("name", name) -} - -/* ----- Wrap logrus ------ */ - -func Debug(args ...interface{}) { - logrus.Debug(args...) -} - -func Info(args ...interface{}) { - logrus.Info(args...) -} - -func Warn(args ...interface{}) { - logrus.Warn(args...) -} - -func Error(args ...interface{}) { - logrus.Error(args...) -} - -func Fatal(args ...interface{}) { - logrus.Fatal(args...) -} diff --git a/router/gobetween/main.go.old b/router/gobetween/main.go.old deleted file mode 100644 index 264f7f64e..000000000 --- a/router/gobetween/main.go.old +++ /dev/null @@ -1,83 +0,0 @@ -/** - * main.go - entry point - * @author Yaroslav Pogrebnyak - */ -package main - -import ( - "./api" - "./cmd" - "./config" - "./info" - "./logging" - "./manager" - "./utils/codec" - "log" - "math/rand" - "os" - "runtime" - "time" -) - -/** - * Version should be set while build using ldflags (see Makefile) - */ -var version string - -/** - * Initialize package - */ -func init() { - - // Set GOMAXPROCS if not set - if os.Getenv("GOMAXPROCS") == "" { - runtime.GOMAXPROCS(runtime.NumCPU()) - } - - // Init random seed - rand.Seed(time.Now().UnixNano()) - - // Save info - info.Version = version - info.StartTime = time.Now() - -} - -/** - * Entry point - */ -func main() { - - log.Printf("gobetween v%s", version) - - env := os.Getenv("GOBETWEEN") - if env != "" && len(os.Args) > 1 { - log.Fatal("Passed GOBETWEEN env var and command-line arguments: only one allowed") - } - - // Try parse env var to args - if env != "" { - a := []string{} - if err := codec.Decode(env, &a, "json"); err != nil { - log.Fatal("Error converting env var to parameters: ", err, " ", env) - } - os.Args = append([]string{""}, a...) - log.Println("Using parameters from env var: ", os.Args) - } - - // Process flags and start - cmd.Execute(func(cfg *config.Config) { - - // Configure logging - logging.Configure(cfg.Logging.Output, cfg.Logging.Level) - - // Start API - go api.Start((*cfg).Api) - - // Start manager - go manager.Initialize(*cfg) - - // block forever - <-(chan string)(nil) - }) -} diff --git a/router/gobetween/manager/manager.go b/router/gobetween/manager/manager.go deleted file mode 100644 index 59e473592..000000000 --- a/router/gobetween/manager/manager.go +++ /dev/null @@ -1,498 +0,0 @@ -/** - * manager.go - manages servers - * - * @author Yaroslav Pogrebnyak - */ -package manager - -import ( - "errors" - "os" - "strings" - "sync" - "time" - - "../config" - "../core" - "../logging" - "../server" - "../service" - "../utils/codec" -) - -/* Map of app current servers */ -var servers = struct { - sync.RWMutex - m map[string]core.Server -}{m: make(map[string]core.Server)} - -/* default configuration for server */ -var defaults config.ConnectionOptions - -/* services */ -var services []core.Service - -/* original cfg read from the file */ -var originalCfg config.Config - -/** - * Initialize manager from the initial/default configuration - */ -func Initialize(cfg config.Config) { - - log := logging.For("manager") - log.Info("Initializing...") - - originalCfg = cfg - - // save defaults for futher reuse - defaults = cfg.Defaults - initDefaults() - - //Initialize global sections - initConfigGlobals(&cfg) - - //create services - services = service.All(cfg) - - // Go through config and start servers for each server - for name, serverCfg := range cfg.Servers { - err := Create(name, serverCfg) - if err != nil { - log.Fatal(err) - } - } - - log.Info("Initialized") -} - -func initDefaults() { - //defaults - if defaults.MaxConnections == nil { - defaults.MaxConnections = new(int) - } - - if defaults.ClientIdleTimeout == nil { - defaults.ClientIdleTimeout = new(string) - *defaults.ClientIdleTimeout = "0" - } - - if defaults.BackendIdleTimeout == nil { - defaults.BackendIdleTimeout = new(string) - *defaults.BackendIdleTimeout = "0" - } - - if defaults.BackendConnectionTimeout == nil { - defaults.BackendConnectionTimeout = new(string) - *defaults.BackendConnectionTimeout = "0" - } -} - -func initConfigGlobals(cfg *config.Config) { - - //acme - if cfg.Acme != nil { - if cfg.Acme.Challenge == "" { - cfg.Acme.Challenge = "http" - } - - if cfg.Acme.HttpBind == "" { - cfg.Acme.HttpBind = "0.0.0.0:80" - } - - if cfg.Acme.CacheDir == "" { - cfg.Acme.CacheDir = "/tmp" - } - } -} - -/** - * Dumps current [servers] section to - * the config file - */ -func DumpConfig(format string) (string, error) { - - originalCfg.Servers = map[string]config.Server{} - - servers.RLock() - for name, server := range servers.m { - originalCfg.Servers[name] = server.Cfg() - } - servers.RUnlock() - - var out *string = new(string) - if err := codec.Encode(originalCfg, out, format); err != nil { - return "", err - } - - return *out, nil -} - -/** - * Returns map of servers with configurations - */ -func All() map[string]config.Server { - result := map[string]config.Server{} - - servers.RLock() - for name, server := range servers.m { - result[name] = server.Cfg() - } - servers.RUnlock() - - return result -} - -/** - * Returns server configuration by name - */ -func Get(name string) interface{} { - - servers.RLock() - server, ok := servers.m[name] - servers.RUnlock() - - if !ok { - return nil - } - - return server.Cfg() -} - -/** - * Create new server and launch it - */ -func Create(name string, cfg config.Server) error { - - servers.Lock() - defer servers.Unlock() - - if _, ok := servers.m[name]; ok { - return errors.New("Server with this name already exists: " + name) - } - - c, err := prepareConfig(name, cfg, defaults) - if err != nil { - return err - } - - server, err := server.New(name, c) - - if err != nil { - return err - } - - for _, srv := range services { - err = srv.Enable(server) - if err != nil { - return err - } - } - - if err = server.Start(); err != nil { - return err - } - - servers.m[name] = server - - return nil -} - -/** - * Delete server stopping all active connections - */ -func Delete(name string) error { - - servers.Lock() - defer servers.Unlock() - - server, ok := servers.m[name] - if !ok { - return errors.New("Server not found") - } - - server.Stop() - delete(servers.m, name) - - for _, s := range services { - s.Disable(server) - } - - return nil -} - -/** - * Returns stats for the server - */ -func Stats(name string) interface{} { - - servers.Lock() - server := servers.m[name] - servers.Unlock() - - return server -} - -/** - * Prepare config (merge default configuration, and try to validate) - * TODO: make validation better - */ -func prepareConfig(name string, server config.Server, defaults config.ConnectionOptions) (config.Server, error) { - - /* ----- Prerequisites ----- */ - - if server.Bind == "" { - return config.Server{}, errors.New("No bind specified") - } - - if server.Discovery == nil { - return config.Server{}, errors.New("No .discovery specified") - } - - if server.Healthcheck == nil { - server.Healthcheck = &config.HealthcheckConfig{ - Kind: "none", - Interval: "0", - Timeout: "0", - } - } - - switch server.Healthcheck.Kind { - case - "ping", - "exec", - "none": - default: - return config.Server{}, errors.New("Not supported healthcheck type " + server.Healthcheck.Kind) - } - - if server.Healthcheck.Interval == "" { - server.Healthcheck.Interval = "0" - } - - if server.Healthcheck.Timeout == "" { - server.Healthcheck.Timeout = "0" - } - - if server.Healthcheck.Fails <= 0 { - server.Healthcheck.Fails = 1 - } - - if server.Healthcheck.Passes <= 0 { - server.Healthcheck.Passes = 1 - } - - if server.ProxyProtocol != nil { - - if server.Protocol != "tcp" { - return config.Server{}, errors.New("proxy_protocol may be used only with 'tcp' protocol, not with " + server.Protocol) - } - - if server.ProxyProtocol.Version == "" { - return config.Server{}, errors.New("version field for proxy_protocol is not specified") - } - - if server.ProxyProtocol.Version != "1" { - return config.Server{}, errors.New("Unsupported proxy_protocol version " + server.ProxyProtocol.Version) - } - } - - if server.Sni != nil { - - if server.Sni.ReadTimeout == "" { - server.Sni.ReadTimeout = "2s" - } - - if server.Sni.UnexpectedHostnameStrategy == "" { - server.Sni.UnexpectedHostnameStrategy = "default" - } - - switch server.Sni.UnexpectedHostnameStrategy { - case - "default", - "reject", - "any": - default: - return config.Server{}, errors.New("Not supported sni unexprected hostname strategy " + server.Sni.UnexpectedHostnameStrategy) - } - - if server.Sni.HostnameMatchingStrategy == "" { - server.Sni.HostnameMatchingStrategy = "exact" - } - - switch server.Sni.HostnameMatchingStrategy { - case - "exact", - "regexp": - default: - return config.Server{}, errors.New("Not supported sni matching " + server.Sni.HostnameMatchingStrategy) - } - - if _, err := time.ParseDuration(server.Sni.ReadTimeout); err != nil { - return config.Server{}, errors.New("timeout parsing error") - } - } - - if _, err := time.ParseDuration(server.Healthcheck.Timeout); err != nil { - return config.Server{}, errors.New("timeout parsing error") - } - - if _, err := time.ParseDuration(server.Healthcheck.Interval); err != nil { - return config.Server{}, errors.New("interval parsing error") - } - - if server.BackendsTls != nil && ((server.BackendsTls.KeyPath == nil) != (server.BackendsTls.CertPath == nil)) { - return config.Server{}, errors.New("backend_tls.cert_path and .key_path should be specified together") - } - - if server.Tls != nil { - - if (len(server.Tls.AcmeHosts) == 0) && ((server.Tls.KeyPath == "") || (server.Tls.CertPath == "")) { - return config.Server{}, errors.New("tls requires specify either acme hosts or both key and cert paths") - } - - } - - /* ----- Connections params and overrides ----- */ - - /* Protocol */ - switch server.Protocol { - case "": - server.Protocol = "tcp" - case "tls": - if server.Tls == nil { - return config.Server{}, errors.New("Need tls section for tls protocol") - } - fallthrough - case "tcp": - case "udp": - if server.BackendsTls != nil { - return config.Server{}, errors.New("backends_tls should not be enabled for udp protocol") - } - - if server.Udp == nil { - server.Udp = &config.Udp{} - } - - if server.Udp.MaxRequests == 0 && server.Udp.MaxResponses == 0 && server.ClientIdleTimeout == nil && server.BackendIdleTimeout == nil { - return config.Server{}, errors.New("udp protocol requires to specify at least one of (client|backend)_idle_timeout, udp.max_requests, udp.max_responses") - } - - default: - return config.Server{}, errors.New("Not supported protocol " + server.Protocol) - } - - /* Healthcheck and protocol match */ - - if server.Healthcheck.Kind == "ping" && server.Protocol == "udp" { - return config.Server{}, errors.New("Cant use ping healthcheck with udp server") - } - - /* Balance */ - switch server.Balance { - case - "weight", - "leastconn", - "roundrobin", - "leastbandwidth", - "iphash1", - "iphash": - case "": - server.Balance = "weight" - default: - return config.Server{}, errors.New("Not supported balance type " + server.Balance) - } - - /* Discovery */ - switch server.Discovery.Failpolicy { - case - "keeplast", - "setempty": - case "": - server.Discovery.Failpolicy = "keeplast" - default: - return config.Server{}, errors.New("Not supported failpolicy " + server.Discovery.Failpolicy) - } - - if server.Discovery.Interval == "" { - server.Discovery.Interval = "0" - } - - if server.Discovery.Timeout == "" { - server.Discovery.Timeout = "0" - } - - /* SRV Discovery */ - if server.Discovery.Kind == "srv" { - switch server.Discovery.SrvDnsProtocol { - case - "udp", - "tcp": - case "": - server.Discovery.Failpolicy = "udp" - default: - return config.Server{}, errors.New("Not supported srv_dns_protocol " + server.Discovery.SrvDnsProtocol) - } - } - - /* LXD Discovery */ - if server.Discovery.Kind == "lxd" { - - if server.Discovery.LXDServerAddress == "" { - return config.Server{}, errors.New("lxd_server_address is required" + server.Discovery.LXDServerAddress) - } - - if !(strings.HasPrefix(server.Discovery.LXDServerAddress, "https:") || - strings.HasPrefix(server.Discovery.LXDServerAddress, "unix:")) { - - return config.Server{}, errors.New("lxd_server_address should start with either unix:// or https:// but got " + server.Discovery.LXDServerAddress) - } - - if server.Discovery.LXDServerRemoteName == "" { - server.Discovery.LXDServerRemoteName = "local" - } - - if server.Discovery.LXDConfigDirectory == "" { - server.Discovery.LXDConfigDirectory = os.ExpandEnv("$HOME/.config/lxc") - } - - if server.Discovery.LXDContainerInterface == "" { - server.Discovery.LXDContainerInterface = "eth0" - } - - switch server.Discovery.LXDContainerAddressType { - case - "IPv4", - "IPv6": - case "": - server.Discovery.LXDContainerAddressType = "IPv4" - default: - return config.Server{}, errors.New("Invalid lxd_container_address_type. Must be IPv4 or IPv6") - } - - } - - /* TODO: Still need to decide how to get rid of this */ - - if server.MaxConnections == nil { - server.MaxConnections = new(int) - *server.MaxConnections = *defaults.MaxConnections - } - - if server.ClientIdleTimeout == nil { - server.ClientIdleTimeout = new(string) - *server.ClientIdleTimeout = *defaults.ClientIdleTimeout - } - - if server.BackendIdleTimeout == nil { - server.BackendIdleTimeout = new(string) - *server.BackendIdleTimeout = *defaults.BackendIdleTimeout - } - - if server.BackendConnectionTimeout == nil { - server.BackendConnectionTimeout = new(string) - *server.BackendConnectionTimeout = *defaults.BackendConnectionTimeout - } - - return server, nil -} diff --git a/router/gobetween/server/modules/access/access.go b/router/gobetween/server/modules/access/access.go deleted file mode 100644 index d9b1a5679..000000000 --- a/router/gobetween/server/modules/access/access.go +++ /dev/null @@ -1,69 +0,0 @@ -/** - * access.go - access - * - * @author Yaroslav Pogrebnyak - */ - -package access - -import ( - "../../../config" - "errors" - "net" -) - -/** - * Access defines access rules chain - */ -type Access struct { - AllowDefault bool - Rules []AccessRule -} - -/** - * Creates new Access based on config - */ -func NewAccess(cfg *config.AccessConfig) (*Access, error) { - - if cfg == nil { - return nil, errors.New("AccessConfig is nil") - } - - if cfg.Default == "" { - cfg.Default = "allow" - } - - if cfg.Default != "allow" && cfg.Default != "deny" { - return nil, errors.New("AccessConfig Unexpected Default: " + cfg.Default) - } - - access := Access{ - AllowDefault: cfg.Default == "allow", - Rules: []AccessRule{}, - } - - // Parse rules - for _, r := range cfg.Rules { - rule, err := ParseAccessRule(r) - if err != nil { - return nil, err - } - access.Rules = append(access.Rules, *rule) - } - - return &access, nil -} - -/** - * Checks if ip is allowed - */ -func (this *Access) Allows(ip *net.IP) bool { - - for _, r := range this.Rules { - if r.Matches(ip) { - return r.Allows() - } - } - - return this.AllowDefault -} diff --git a/router/gobetween/server/modules/access/rule.go b/router/gobetween/server/modules/access/rule.go deleted file mode 100644 index 9c80c7f22..000000000 --- a/router/gobetween/server/modules/access/rule.go +++ /dev/null @@ -1,89 +0,0 @@ -/** - * rule.go - access rule - * - * @author Yaroslav Pogrebnyak - */ - -package access - -import ( - "errors" - "net" - "strings" -) - -/** - * AccessRule defines order (access, deny) - * and IP or Network - */ -type AccessRule struct { - Allow bool - IsNetwork bool - Ip *net.IP - Network *net.IPNet -} - -/** - * Parses string to AccessRule - */ -func ParseAccessRule(rule string) (*AccessRule, error) { - - parts := strings.Split(rule, " ") - if len(parts) != 2 { - return nil, errors.New("Bad access rule format: " + rule) - } - - r := parts[0] - cidrOrIp := parts[1] - - if r != "allow" && r != "deny" { - return nil, errors.New("Cant parse rule definition " + rule) - } - - // try check if cidrOrIp is ip and handle - - ipShould := net.ParseIP(cidrOrIp) - if ipShould != nil { - return &AccessRule{ - Allow: r == "allow", - Ip: &ipShould, - IsNetwork: false, - Network: nil, - }, nil - } - - _, ipNetShould, _ := net.ParseCIDR(cidrOrIp) - if ipNetShould != nil { - return &AccessRule{ - Allow: r == "allow", - Ip: nil, - IsNetwork: true, - Network: ipNetShould, - }, nil - } - - return nil, errors.New("Cant parse acces rule target, not an ip or cidr: " + cidrOrIp) - -} - -/** - * Checks if ip matches access rule - */ -func (this *AccessRule) Matches(ip *net.IP) bool { - - switch this.IsNetwork { - case true: - return this.Network.Contains(*ip) - case false: - return (*this.Ip).Equal(*ip) - } - - return false -} - -/** - * Checks is it's allow or deny rule - */ -func (this *AccessRule) Allows() bool { - return this.Allow -} diff --git a/router/gobetween/server/scheduler/scheduler.go b/router/gobetween/server/scheduler/scheduler.go deleted file mode 100644 index 3c5e30366..000000000 --- a/router/gobetween/server/scheduler/scheduler.go +++ /dev/null @@ -1,378 +0,0 @@ -/** - * scheduler.go - schedule operations on backends and manages them - * - * @author Yaroslav Pogrebnyak - */ - -package scheduler - -import ( - "time" - - "../../core" - "../../discovery" - "../../healthcheck" - "../../logging" - "../../stats" - "../../stats/counters" -) - -/** - * Backend Operation action - */ -type OpAction int - -/** - * Constants for backend operation - */ -const ( - IncrementConnection OpAction = iota - DecrementConnection - IncrementRefused - IncrementTx - IncrementRx -) - -/** - * Operation on backend - */ -type Op struct { - target core.Target - op OpAction - param interface{} -} - -/** - * Request to elect backend - */ -type ElectRequest struct { - Context core.Context - Response chan core.Backend - Err chan error -} - -/** - * Scheduler - */ -type Scheduler struct { - - /* Balancer impl */ - Balancer core.Balancer - - /* Discovery impl */ - Discovery *discovery.Discovery - - /* Healthcheck impl */ - Healthcheck *healthcheck.Healthcheck - - /* ----- backends ------*/ - - /* Current cached backends map */ - backends map[core.Target]*core.Backend - - /* Stats */ - StatsHandler *stats.Handler - - /* ----- channels ----- */ - - /* Backend operation channel */ - ops chan Op - - /* Stop channel */ - stop chan bool - - /* Elect backend channel */ - elect chan ElectRequest -} - -/** - * Start scheduler - */ -func (this *Scheduler) Start() { - - log := logging.For("scheduler") - - log.Info("Starting scheduler") - - this.ops = make(chan Op) - this.elect = make(chan ElectRequest) - this.stop = make(chan bool) - this.backends = make(map[core.Target]*core.Backend) - - this.Discovery.Start() - this.Healthcheck.Start() - - // backends stats pusher ticker - backendsPushTicker := time.NewTicker(2 * time.Second) - - /** - * Goroutine updates and manages backends - */ - go func() { - for { - select { - - /* ----- discovery ----- */ - - // handle newly discovered backends - case backends := <-this.Discovery.Discover(): - this.HandleBackendsUpdate(backends) - this.Healthcheck.In <- this.Targets() - this.StatsHandler.BackendsCounter.In <- this.Targets() - - /* ------ healthcheck ----- */ - - // handle backend healthcheck result - case checkResult := <-this.Healthcheck.Out: - this.HandleBackendLiveChange(checkResult.Target, checkResult.Live) - - /* ----- stats ----- */ - - // push current backends to stats handler - case <-backendsPushTicker.C: - this.StatsHandler.Backends <- this.Backends() - - // handle new bandwidth stats of a backend - case bs := <-this.StatsHandler.BackendsCounter.Out: - this.HandleBackendStatsChange(bs.Target, &bs) - - /* ----- operations ----- */ - - // handle backend operation - case op := <-this.ops: - this.HandleOp(op) - - // elect backend - case electReq := <-this.elect: - this.HandleBackendElect(electReq) - - /* ----- stop ----- */ - - // handle scheduler stop - case <-this.stop: - log.Info("Stopping scheduler") - backendsPushTicker.Stop() - this.Discovery.Stop() - this.Healthcheck.Stop() - return - } - } - }() -} - -/** - * Returns targets of current backends - */ -func (this *Scheduler) Targets() []core.Target { - - keys := make([]core.Target, 0, len(this.backends)) - for k := range this.backends { - keys = append(keys, k) - } - - return keys -} - -/** - * Return current backends - */ -func (this *Scheduler) Backends() []core.Backend { - - backends := make([]core.Backend, 0, len(this.backends)) - for _, b := range this.backends { - backends = append(backends, *b) - } - - return backends -} - -/** - * Updated backend stats - */ -func (this *Scheduler) HandleBackendStatsChange(target core.Target, bs *counters.BandwidthStats) { - - backend, ok := this.backends[target] - if !ok { - logging.For("scheduler").Warn("No backends for checkResult ", target) - return - } - - backend.Stats.RxBytes = bs.RxTotal - backend.Stats.TxBytes = bs.TxTotal - backend.Stats.RxSecond = bs.RxSecond - backend.Stats.TxSecond = bs.TxSecond -} - -/** - * Updated backend live status - */ -func (this *Scheduler) HandleBackendLiveChange(target core.Target, live bool) { - - backend, ok := this.backends[target] - if !ok { - logging.For("scheduler").Warn("No backends for checkResult ", target) - return - } - - backend.Stats.Live = live -} - -/** - * Update backends map - */ -func (this *Scheduler) HandleBackendsUpdate(backends []core.Backend) { - - // first mark all existing backends as not discovered - for _, b := range this.backends { - b.Stats.Discovered = false - } - - for _, b := range backends { - oldB, ok := this.backends[b.Target] - - if ok { - // if we have this backend, update it's discovery properties - oldB.MergeFrom(b) - // mark found backend as discovered - oldB.Stats.Discovered = true - continue - } - - b := b // b has to be local variable in order to make unique pointers - b.Stats.Discovered = true - this.backends[b.Target] = &b - } - - //remove not discovered backends without active connections - for t, b := range this.backends { - if b.Stats.Discovered || b.Stats.ActiveConnections > 0 { - continue - } - delete(this.backends, t) - } - -} - -/** - * Perform backend election - */ -func (this *Scheduler) HandleBackendElect(req ElectRequest) { - - // Filter only live and discovered backends - var backends []*core.Backend - for _, b := range this.backends { - - if !b.Stats.Live { - continue - } - - if !b.Stats.Discovered { - continue - } - - backends = append(backends, b) - } - - // Elect backend - backend, err := this.Balancer.Elect(req.Context, backends) - if err != nil { - req.Err <- err - return - } - - req.Response <- *backend -} - -/** - * Handle operation on the backend - */ -func (this *Scheduler) HandleOp(op Op) { - - // Increment global counter, even if - // backend for this count may be out of discovery pool - switch op.op { - case IncrementTx: - this.StatsHandler.Traffic <- core.ReadWriteCount{CountWrite: op.param.(uint), Target: op.target} - return - case IncrementRx: - this.StatsHandler.Traffic <- core.ReadWriteCount{CountRead: op.param.(uint), Target: op.target} - return - } - - log := logging.For("scheduler") - - backend, ok := this.backends[op.target] - if !ok { - log.Warn("Trying op ", op.op, " on not tracked target ", op.target) - return - } - - switch op.op { - case IncrementRefused: - backend.Stats.RefusedConnections++ - case IncrementConnection: - backend.Stats.ActiveConnections++ - backend.Stats.TotalConnections++ - case DecrementConnection: - backend.Stats.ActiveConnections-- - default: - log.Warn("Don't know how to handle op ", op.op) - } - -} - -/** - * Stop scheduler - */ -func (this *Scheduler) Stop() { - this.stop <- true -} - -/** - * Take elect backend for proxying - */ -func (this *Scheduler) TakeBackend(context core.Context) (*core.Backend, error) { - r := ElectRequest{context, make(chan core.Backend), make(chan error)} - this.elect <- r - select { - case err := <-r.Err: - return nil, err - case backend := <-r.Response: - return &backend, nil - } -} - -/** - * Increment connection refused count for backend - */ -func (this *Scheduler) IncrementRefused(backend core.Backend) { - this.ops <- Op{backend.Target, IncrementRefused, nil} -} - -/** - * Increment backend connection counter - */ -func (this *Scheduler) IncrementConnection(backend core.Backend) { - this.ops <- Op{backend.Target, IncrementConnection, nil} -} - -/** - * Decrement backends connection counter - */ -func (this *Scheduler) DecrementConnection(backend core.Backend) { - this.ops <- Op{backend.Target, DecrementConnection, nil} -} - -/** - * Increment Rx stats for backend - */ -func (this *Scheduler) IncrementRx(backend core.Backend, c uint) { - this.ops <- Op{backend.Target, IncrementRx, c} -} - -/** - * Increment Tx stats for backends - */ -func (this *Scheduler) IncrementTx(backend core.Backend, c uint) { - this.ops <- Op{backend.Target, IncrementTx, c} -} diff --git a/router/gobetween/server/server.go b/router/gobetween/server/server.go deleted file mode 100644 index 15f673bc9..000000000 --- a/router/gobetween/server/server.go +++ /dev/null @@ -1,30 +0,0 @@ -/** - * server.go - server creator - * - * @author Illarion Kovalchuk - * @author Yaroslav Pogrebnyak - */ - -package server - -import ( - "../config" - "../core" - "./tcp" - "./udp" - "errors" -) - -/** - * Creates new Server based on cfg.Protocol - */ -func New(name string, cfg config.Server) (core.Server, error) { - switch cfg.Protocol { - case "tls", "tcp": - return tcp.New(name, cfg) - case "udp": - return udp.New(name, cfg) - default: - return nil, errors.New("Can't create server for protocol " + cfg.Protocol) - } -} diff --git a/router/gobetween/server/tcp/proxy.go b/router/gobetween/server/tcp/proxy.go deleted file mode 100644 index 585fb1d9a..000000000 --- a/router/gobetween/server/tcp/proxy.go +++ /dev/null @@ -1,143 +0,0 @@ -/** - * proxy.go - proxy utils - * - * @author Yaroslav Pogrebnyak - */ - -package tcp - -import ( - "../../core" - "../../logging" - "io" - "net" - "time" -) - -const ( - - /* Buffer size to handle data from socket */ - BUFFER_SIZE = 16 * 1024 - - /* Interval of pushing aggregated read/write stats */ - PROXY_STATS_PUSH_INTERVAL = 1 * time.Second -) - -/** - * Perform copy/proxy data from 'from' to 'to' socket, counting r/w stats and - * dropping connection if timeout exceeded - */ -func proxy(to net.Conn, from net.Conn, timeout time.Duration) <-chan core.ReadWriteCount { - - log := logging.For("proxy") - - stats := make(chan core.ReadWriteCount) - outStats := make(chan core.ReadWriteCount) - - rwcBuffer := core.ReadWriteCount{} - ticker := time.NewTicker(PROXY_STATS_PUSH_INTERVAL) - flushed := false - - // Stats collecting goroutine - go func() { - - if timeout > 0 { - from.SetReadDeadline(time.Now().Add(timeout)) - } - - for { - select { - case <-ticker.C: - if !rwcBuffer.IsZero() { - outStats <- rwcBuffer - } - flushed = true - case rwc, ok := <-stats: - - if !ok { - ticker.Stop() - if !flushed && !rwcBuffer.IsZero() { - outStats <- rwcBuffer - } - close(outStats) - return - } - - if timeout > 0 && rwc.CountRead > 0 { - from.SetReadDeadline(time.Now().Add(timeout)) - } - - // Remove non blocking - if flushed { - rwcBuffer = rwc - } else { - rwcBuffer.CountWrite += rwc.CountWrite - rwcBuffer.CountRead += rwc.CountRead - } - - flushed = false - } - } - }() - - // Run proxy copier - go func() { - err := Copy(to, from, stats) - // hack to determine normal close. TODO: fix when it will be exposed in golang - e, ok := err.(*net.OpError) - if err != nil && (!ok || e.Err.Error() != "use of closed network connection") { - log.Warn(err) - } - - to.Close() - from.Close() - - // Stop stats collecting goroutine - close(stats) - }() - - return outStats -} - -/** - * It's build by analogy of io.Copy - */ -func Copy(to io.Writer, from io.Reader, ch chan<- core.ReadWriteCount) error { - - buf := make([]byte, BUFFER_SIZE) - var err error = nil - - for { - readN, readErr := from.Read(buf) - - if readN > 0 { - - writeN, writeErr := to.Write(buf[0:readN]) - - if writeN > 0 { - ch <- core.ReadWriteCount{CountRead: uint(readN), CountWrite: uint(writeN)} - } - - if writeErr != nil { - err = writeErr - break - } - - if readN != writeN { - err = io.ErrShortWrite - break - } - } - - if readErr == io.EOF { - break - } - - if readErr != nil { - err = readErr - break - } - } - - return err -} diff --git a/router/gobetween/server/tcp/server.go b/router/gobetween/server/tcp/server.go deleted file mode 100644 index 7d59ff58b..000000000 --- a/router/gobetween/server/tcp/server.go +++ /dev/null @@ -1,368 +0,0 @@ -/** - * server.go - proxy server implementation - * - * @author Yaroslav Pogrebnyak - */ - -package tcp - -import ( - "crypto/tls" - "net" - "time" - - "../../balance" - "../../config" - "../../core" - "../../discovery" - "../../healthcheck" - "../../logging" - "../../stats" - "../../utils" - "../../utils/proxyprotocol" - tlsutil "../../utils/tls" - "../../utils/tls/sni" - "../modules/access" - "../scheduler" -) - -/** - * Server listens for client connections and - * proxies it to backends - */ -type Server struct { - - /* Server friendly name */ - name string - - /* Listener */ - listener net.Listener - - /* Configuration */ - cfg config.Server - - /* Scheduler deals with discovery, balancing and healthchecks */ - scheduler scheduler.Scheduler - - /* Current clients connection */ - clients map[string]net.Conn - - /* Stats handler */ - statsHandler *stats.Handler - - /* ----- channels ----- */ - - /* Channel for new connections */ - connect chan (*core.TcpContext) - - /* Channel for dropping connections or connectons to drop */ - disconnect chan (net.Conn) - - /* Stop channel */ - stop chan bool - - /* Tls config used to connect to backends */ - backendsTlsConfg *tls.Config - - /* Tls config used for incoming connections */ - tlsConfig *tls.Config - - /* Get certificate filled by external service */ - GetCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error) - - /* ----- modules ----- */ - - /* Access module checks if client is allowed to connect */ - access *access.Access -} - -/** - * Creates new server instance - */ -func New(name string, cfg config.Server) (*Server, error) { - - log := logging.For("server") - - var err error = nil - statsHandler := stats.NewHandler(name) - - // Create server - server := &Server{ - name: name, - cfg: cfg, - stop: make(chan bool), - disconnect: make(chan net.Conn), - connect: make(chan *core.TcpContext), - clients: make(map[string]net.Conn), - statsHandler: statsHandler, - scheduler: scheduler.Scheduler{ - Balancer: balance.New(cfg.Sni, cfg.Balance), - Discovery: discovery.New(cfg.Discovery.Kind, *cfg.Discovery), - Healthcheck: healthcheck.New(cfg.Healthcheck.Kind, *cfg.Healthcheck), - StatsHandler: statsHandler, - }, - } - - /* Add access if needed */ - if cfg.Access != nil { - server.access, err = access.NewAccess(cfg.Access) - if err != nil { - return nil, err - } - } - - /* Add tls configs if needed */ - - server.backendsTlsConfg, err = tlsutil.MakeBackendTLSConfig(cfg.BackendsTls) - if err != nil { - return nil, err - } - - server.tlsConfig, err = tlsutil.MakeTlsConfig(cfg.Tls, server.GetCertificate) - if err != nil { - return nil, err - } - - log.Info("Creating '", name, "': ", cfg.Bind, " ", cfg.Balance, " ", cfg.Discovery.Kind, " ", cfg.Healthcheck.Kind) - - return server, nil -} - -/** - * Returns current server configuration - */ -func (this *Server) Cfg() config.Server { - return this.cfg -} - -/** - * Start server - */ -func (this *Server) Start() error { - - go func() { - - for { - select { - case client := <-this.disconnect: - this.HandleClientDisconnect(client) - - case ctx := <-this.connect: - this.HandleClientConnect(ctx) - - case <-this.stop: - this.scheduler.Stop() - this.statsHandler.Stop() - if this.listener != nil { - this.listener.Close() - for _, conn := range this.clients { - conn.Close() - } - } - this.clients = make(map[string]net.Conn) - return - } - } - }() - - // Start stats handler - this.statsHandler.Start() - - // Start scheduler - this.scheduler.Start() - - // Start listening - if err := this.Listen(); err != nil { - this.Stop() - return err - } - - return nil -} - -/** - * Handle client disconnection - */ -func (this *Server) HandleClientDisconnect(client net.Conn) { - client.Close() - delete(this.clients, client.RemoteAddr().String()) - this.statsHandler.Connections <- uint(len(this.clients)) -} - -/** - * Handle new client connection - */ -func (this *Server) HandleClientConnect(ctx *core.TcpContext) { - client := ctx.Conn - log := logging.For("server") - - if *this.cfg.MaxConnections != 0 && len(this.clients) >= *this.cfg.MaxConnections { - log.Warn("Too many connections to ", this.cfg.Bind) - client.Close() - return - } - - this.clients[client.RemoteAddr().String()] = client - this.statsHandler.Connections <- uint(len(this.clients)) - go func() { - this.handle(ctx) - this.disconnect <- client - }() -} - -/** - * Stop, dropping all connections - */ -func (this *Server) Stop() { - - log := logging.For("server.Listen") - log.Info("Stopping ", this.name) - - this.stop <- true -} - -func (this *Server) wrap(conn net.Conn, sniEnabled bool) { - log := logging.For("server.Listen.wrap") - - var hostname string - var err error - - if sniEnabled { - var sniConn net.Conn - sniConn, hostname, err = sni.Sniff(conn, utils.ParseDurationOrDefault(this.cfg.Sni.ReadTimeout, time.Second*2)) - - if err != nil { - log.Error("Failed to get / parse ClientHello for sni: ", err) - conn.Close() - return - } - - conn = sniConn - } - - if this.tlsConfig != nil { - conn = tls.Server(conn, this.tlsConfig) - } - - this.connect <- &core.TcpContext{ - hostname, - conn, - } - -} - -/** - * Listen on specified port for a connections - */ -func (this *Server) Listen() (err error) { - - log := logging.For("server.Listen") - - // create tcp listener - this.listener, err = net.Listen("tcp", this.cfg.Bind) - - if err != nil { - log.Error("Error starting ", this.cfg.Protocol+" server: ", err) - return err - } - - sniEnabled := this.cfg.Sni != nil - - go func() { - for { - conn, err := this.listener.Accept() - - if err != nil { - log.Error(err) - return - } - - go this.wrap(conn, sniEnabled) - } - }() - - return nil -} - -/** - * Handle incoming connection and prox it to backend - */ -func (this *Server) handle(ctx *core.TcpContext) { - clientConn := ctx.Conn - log := logging.For("server.handle [" + this.cfg.Bind + "]") - - /* Check access if needed */ - if this.access != nil { - if !this.access.Allows(&clientConn.RemoteAddr().(*net.TCPAddr).IP) { - log.Debug("Client disallowed to connect ", clientConn.RemoteAddr()) - clientConn.Close() - return - } - } - - log.Debug("Accepted ", clientConn.RemoteAddr(), " -> ", this.listener.Addr()) - - /* Find out backend for proxying */ - var err error - backend, err := this.scheduler.TakeBackend(ctx) - if err != nil { - log.Error(err, "; Closing connection: ", clientConn.RemoteAddr()) - return - } - - /* Connect to backend */ - var backendConn net.Conn - - if this.cfg.BackendsTls != nil { - backendConn, err = tls.DialWithDialer(&net.Dialer{ - Timeout: utils.ParseDurationOrDefault(*this.cfg.BackendConnectionTimeout, 0), - }, "tcp", backend.Address(), this.backendsTlsConfg) - - } else { - backendConn, err = net.DialTimeout("tcp", backend.Address(), utils.ParseDurationOrDefault(*this.cfg.BackendConnectionTimeout, 0)) - } - - if err != nil { - this.scheduler.IncrementRefused(*backend) - log.Error(err) - return - } - this.scheduler.IncrementConnection(*backend) - defer this.scheduler.DecrementConnection(*backend) - - /* Send proxy protocol header if configured */ - if this.cfg.ProxyProtocol != nil { - switch this.cfg.ProxyProtocol.Version { - case "1": - log.Debug("Sending proxy_protocol v1 header ", clientConn.RemoteAddr(), " -> ", this.listener.Addr(), " -> ", backendConn.RemoteAddr()) - err := proxyprotocol.SendProxyProtocolV1(clientConn, backendConn) - if err != nil { - log.Error(err) - return - } - default: - log.Error("Unsupported proxy_protocol version " + this.cfg.ProxyProtocol.Version + ", aborting connection") - return - } - } - - /* ----- Stat proxying ----- */ - - log.Debug("Begin ", clientConn.RemoteAddr(), " -> ", this.listener.Addr(), " -> ", backendConn.RemoteAddr()) - cs := proxy(clientConn, backendConn, utils.ParseDurationOrDefault(*this.cfg.BackendIdleTimeout, 0)) - bs := proxy(backendConn, clientConn, utils.ParseDurationOrDefault(*this.cfg.ClientIdleTimeout, 0)) - - isTx, isRx := true, true - for isTx || isRx { - select { - case s, ok := <-cs: - isRx = ok - this.scheduler.IncrementRx(*backend, s.CountWrite) - case s, ok := <-bs: - isTx = ok - this.scheduler.IncrementTx(*backend, s.CountWrite) - } - } - - log.Debug("End ", clientConn.RemoteAddr(), " -> ", this.listener.Addr(), " -> ", backendConn.RemoteAddr()) -} diff --git a/router/gobetween/server/udp/server.go b/router/gobetween/server/udp/server.go deleted file mode 100644 index c7235199c..000000000 --- a/router/gobetween/server/udp/server.go +++ /dev/null @@ -1,369 +0,0 @@ -/** - * server.go - UDP server implementation - * - * @author Illarion Kovalchuk - */ - -package udp - -import ( - "fmt" - "net" - "sync" - "sync/atomic" - "time" - - "../../balance" - "../../config" - "../../core" - "../../discovery" - "../../healthcheck" - "../../logging" - "../../stats" - "../../utils" - "../modules/access" - "../scheduler" - "./session" -) - -const UDP_PACKET_SIZE = 65507 -const CLEANUP_EVERY = time.Second * 2 - -/** - * UDP server implementation - */ -type Server struct { - /* Server name */ - name string - - /* Server configuration */ - cfg config.Server - - /* Scheduler */ - scheduler *scheduler.Scheduler - - /* Server connection */ - serverConn *net.UDPConn - - /* Flag indicating that server is stopped */ - stopped uint32 - - /* Stop channel */ - stop chan bool - - /* ----- modules ----- */ - - /* Access module checks if client is allowed to connect */ - access *access.Access - - /* ----- sessions ----- */ - sessions map[string]*session.Session - mu sync.Mutex -} - -/** - * Creates new UDP server - */ -func New(name string, cfg config.Server) (*Server, error) { - - log := logging.For("udp/server") - - statsHandler := stats.NewHandler(name) - scheduler := &scheduler.Scheduler{ - Balancer: balance.New(nil, cfg.Balance), - Discovery: discovery.New(cfg.Discovery.Kind, *cfg.Discovery), - Healthcheck: healthcheck.New(cfg.Healthcheck.Kind, *cfg.Healthcheck), - StatsHandler: statsHandler, - } - - server := &Server{ - name: name, - cfg: cfg, - scheduler: scheduler, - stop: make(chan bool), - sessions: make(map[string]*session.Session), - } - - /* Add access if needed */ - if cfg.Access != nil { - access, err := access.NewAccess(cfg.Access) - if err != nil { - return nil, fmt.Errorf("Could not initialize access restrictions: %v", err) - } - server.access = access - } - - log.Info("Creating UDP server '", name, "': ", cfg.Bind, " ", cfg.Balance, " ", cfg.Discovery.Kind, " ", cfg.Healthcheck.Kind) - return server, nil -} - -/** - * Returns current server configuration - */ -func (this *Server) Cfg() config.Server { - return this.cfg -} - -/** - * Starts server - */ -func (this *Server) Start() error { - - log := logging.For("udp/server") - - // Start listening - if err := this.listen(); err != nil { - return fmt.Errorf("Could not start listening UDP: %v", err) - } - - this.scheduler.StatsHandler.Start() - this.scheduler.Start() - this.serve() - - go func() { - - ticker := time.NewTicker(CLEANUP_EVERY) - - for { - select { - case <-ticker.C: - this.cleanup() - /* handle server stop */ - case <-this.stop: - log.Info("Stopping ", this.name) - atomic.StoreUint32(&this.stopped, 1) - - ticker.Stop() - - this.serverConn.Close() - - this.scheduler.StatsHandler.Stop() - this.scheduler.Stop() - - this.mu.Lock() - for k, s := range this.sessions { - delete(this.sessions, k) - s.CloseConn() - } - this.mu.Unlock() - - return - } - } - }() - - return nil -} - -/** - * Start accepting connections - */ -func (this *Server) listen() error { - listenAddr, err := net.ResolveUDPAddr("udp", this.cfg.Bind) - if err != nil { - return fmt.Errorf("Failed to resolve udp address %v : %v", this.cfg.Bind, err) - } - - this.serverConn, err = net.ListenUDP("udp", listenAddr) - - if err != nil { - return fmt.Errorf("Failed to create listening udp socket: %v", err) - } - - return nil -} - -/** - * Start serving - */ -func (this *Server) serve() { - log := logging.For("udp/server") - - cfg := session.Config{ - MaxRequests: this.cfg.Udp.MaxRequests, - MaxResponses: this.cfg.Udp.MaxResponses, - ClientIdleTimeout: utils.ParseDurationOrDefault(*this.cfg.ClientIdleTimeout, 0), - BackendIdleTimeout: utils.ParseDurationOrDefault(*this.cfg.BackendIdleTimeout, 0), - } - - // Main loop goroutine - reads incoming data and decides what to do - go func() { - - for { - buf := make([]byte, UDP_PACKET_SIZE) - n, clientAddr, err := this.serverConn.ReadFromUDP(buf) - - if err != nil { - if atomic.LoadUint32(&this.stopped) == 1 { - return - } - - log.Error("Failed to read from UDP: ", err) - - continue - } - - //special case for single request mode - if cfg.MaxRequests == 1 { - err := this.fireAndForget(clientAddr, buf[0:n]) - - if err != nil { - log.Errorf("Error sending data to backend: %v ", err) - } - - continue - } - - err = this.proxy(cfg, clientAddr, buf[0:n]) - - if err != nil { - log.Errorf("Failed to proxy packet from client %v: %v", clientAddr, err) - continue - } - - } - }() -} - -/** - * Safely remove connections that have marked themself as done - */ -func (this *Server) cleanup() { - this.mu.Lock() - defer this.mu.Unlock() - - for k, s := range this.sessions { - if s.IsDone() { - delete(this.sessions, k) - s.CloseConn() - } - - } - -} - -/** - * Elect and connect to backend - */ -func (this *Server) electAndConnect(clientAddr *net.UDPAddr) (*net.UDPConn, *core.Backend, error) { - backend, err := this.scheduler.TakeBackend(core.UdpContext{ - ClientAddr: *clientAddr, - }) - - if err != nil { - return nil, nil, fmt.Errorf("Could not elect backend for clientAddr %v: %v", clientAddr, err) - } - - host := backend.Host - port := backend.Port - - addrStr := host + ":" + port - - addr, err := net.ResolveUDPAddr("udp", addrStr) - if err != nil { - return nil, nil, fmt.Errorf("Could not resolve udp address %s: %v", addrStr, err) - } - - conn, err := net.DialUDP("udp", nil, addr) - if err != nil { - return nil, nil, fmt.Errorf("Could not dial UDP addr %v: %v", addr, err) - } - - return conn, backend, nil -} - -/** - * Get the session and send data via chosen session - */ -func (this *Server) proxy(cfg session.Config, clientAddr *net.UDPAddr, buf []byte) error { - - log := logging.For("udp/server") - - getOrCreateSession := func() (*session.Session, error) { - key := clientAddr.String() - - this.mu.Lock() - defer this.mu.Unlock() - - s, ok := this.sessions[key] - - //session exists and is not done yet - if ok && !s.IsDone() { - return s, nil - } - - //session exists but should be replaced with a new one - if ok { - delete(this.sessions, key) - s.CloseConn() - } - - conn, backend, err := this.electAndConnect(clientAddr) - if err != nil { - return nil, fmt.Errorf("Could not elect/connect to backend: %v", err) - } - - s = session.NewSession(clientAddr, conn, *backend, this.scheduler, cfg) - s.ListenResponses(this.serverConn) - this.sessions[key] = s - - return s, nil - } - - go func() { - s, err := getOrCreateSession() - - if err != nil { - log.Error(err) - return - } - - err = s.Write(buf) - if err != nil { - log.Errorf("Could not write data to UDP 'session' %v: %v", s, err) - return - } - - }() - - return nil - -} - -/** - * Omit creating session, just send one packet of data - */ -func (this *Server) fireAndForget(clientAddr *net.UDPAddr, buf []byte) error { - - log := logging.For("udp/server") - conn, backend, err := this.electAndConnect(clientAddr) - if err != nil { - return fmt.Errorf("Could not elect or connect to backend: %v", err) - } - - go func() { - - n, err := conn.Write(buf) - if err != nil { - log.Errorf("Could not write data to %v: %v", clientAddr, err) - return - } - - if n != len(buf) { - log.Errorf("Failed to send full packet, expected size %d, actually sent %d", len(buf), n) - return - } - - this.scheduler.IncrementTx(*backend, uint(n)) - }() - - return nil - -} - -/** - * Stop, dropping all connections - */ -func (this *Server) Stop() { - this.stop <- true -} diff --git a/router/gobetween/server/udp/session/config.go b/router/gobetween/server/udp/session/config.go deleted file mode 100644 index a2fb9c47d..000000000 --- a/router/gobetween/server/udp/session/config.go +++ /dev/null @@ -1,10 +0,0 @@ -package session - -import "time" - -type Config struct { - MaxRequests uint64 - MaxResponses uint64 - ClientIdleTimeout time.Duration - BackendIdleTimeout time.Duration -} diff --git a/router/gobetween/server/udp/session/session.go b/router/gobetween/server/udp/session/session.go deleted file mode 100644 index 2333cb882..000000000 --- a/router/gobetween/server/udp/session/session.go +++ /dev/null @@ -1,130 +0,0 @@ -package session - -import ( - "../../../core" - "../../../logging" - "../../scheduler" - "fmt" - "net" - "sync/atomic" - "time" -) - -const UDP_PACKET_SIZE = 65507 - -type Session struct { - /*atomics*/ - sent uint64 - recv uint64 - done uint32 - /*session config*/ - cfg Config - - lastClientActivity time.Time - clientAddr *net.UDPAddr - - //connection to backend - conn *net.UDPConn - backend core.Backend - - //scheduler - scheduler *scheduler.Scheduler -} - -func NewSession(clientAddr *net.UDPAddr, conn *net.UDPConn, backend core.Backend, scheduler *scheduler.Scheduler, cfg Config) *Session { - scheduler.IncrementConnection(backend) - return &Session{ - cfg: cfg, - clientAddr: clientAddr, - conn: conn, - backend: backend, - lastClientActivity: time.Now(), - scheduler: scheduler, - } -} - -func (s *Session) Write(buf []byte) error { - s.lastClientActivity = time.Now() - - n, err := s.conn.Write(buf) - - if err != nil { - return fmt.Errorf("Could not write data to udp connection: %v", err) - } - - if n != len(buf) { - return fmt.Errorf("Short write error: should write %d bytes, but %d written", len(buf), n) - } - - s.scheduler.IncrementTx(s.backend, uint(n)) - - if s.cfg.MaxRequests > 0 && atomic.AddUint64(&s.sent, 1) > s.cfg.MaxRequests { - atomic.StoreUint32(&s.done, 1) - return fmt.Errorf("Restricted to send more UDP packets") - } - - return nil -} - -/** - * ListenResponses waits for responses from backend, and sends them back to client address via - * server connection, so that client is not confused with source host:port of the - * packet it receives - */ -func (s *Session) ListenResponses(sendTo *net.UDPConn) { - - log := logging.For("udp/server/session") - - go func() { - defer atomic.StoreUint32(&s.done, 1) - - b := make([]byte, UDP_PACKET_SIZE) - - for { - - if s.cfg.BackendIdleTimeout > 0 { - s.conn.SetReadDeadline(time.Now().Add(s.cfg.BackendIdleTimeout)) - } - - n, err := s.conn.Read(b) - - if err != nil { - if atomic.CompareAndSwapUint32(&s.done, 0, 1) { - log.Errorf("Failed to read from backend: %v", err) - } - return - } - - s.scheduler.IncrementRx(s.backend, uint(n)) - - m, err := sendTo.WriteToUDP(b[0:n], s.clientAddr) - - if err != nil { - log.Errorf("Could not send backend response to client: %v", err) - return - } - - if m != n { - return - } - - if s.cfg.MaxResponses > 0 && atomic.AddUint64(&s.recv, 1) >= s.cfg.MaxResponses { - return - } - } - }() -} - -func (s *Session) IsDone() bool { - if s.cfg.ClientIdleTimeout > 0 && s.lastClientActivity.Add(s.cfg.ClientIdleTimeout).Before(time.Now()) { - atomic.StoreUint32(&s.done, 1) - return true - } - return atomic.LoadUint32(&s.done) == 1 -} - -func (s *Session) CloseConn() { - atomic.StoreUint32(&s.done, 1) - s.conn.Close() - s.scheduler.DecrementConnection(s.backend) -} diff --git a/router/gobetween/service/acme.go b/router/gobetween/service/acme.go deleted file mode 100644 index e481c129d..000000000 --- a/router/gobetween/service/acme.go +++ /dev/null @@ -1,114 +0,0 @@ -package service - -import ( - "../config" - "../core" - "../server/tcp" - "context" - "fmt" - "golang.org/x/crypto/acme/autocert" - "net/http" - "sync" -) - -/** - * AcmeService listens on http port (default 80) for incoming acme challenges from letsencrypt.org - * and updates it's certificate manager's hotpolicy depending on acme hosts configured for - * each core.Server instance with [acme] section in config - */ -type AcmeService struct { - certMan *autocert.Manager - hosts map[string]bool - sync.RWMutex -} - -func init() { - registry["acme"] = NewAcmeService -} - -func NewAcmeService(cfg config.Config) core.Service { - - if cfg.Acme == nil { - return nil - } - - a := &AcmeService{ - certMan: &autocert.Manager{ - Cache: autocert.DirCache(cfg.Acme.CacheDir), - Prompt: autocert.AcceptTOS, - }, - hosts: make(map[string]bool), - } - - a.certMan.HostPolicy = func(_ context.Context, host string) error { - a.RLock() - defer a.RUnlock() - - if a.hosts[host] { - return nil - } - - return fmt.Errorf("Acme: host %s is not configured", host) - } - - //accept http challenge - if cfg.Acme.Challenge == "http" { - go http.ListenAndServe(cfg.Acme.HttpBind, a.certMan.HTTPHandler(nil)) - } - - return a - -} - -func (a *AcmeService) Enable(server core.Server) error { - - if a == nil { - return nil - } - - serverCfg := server.Cfg() - - if serverCfg.Tls == nil { - return nil - } - - tcpServer, ok := server.(*tcp.Server) - - if !ok { - return nil - } - - tcpServer.GetCertificate = a.certMan.GetCertificate - - a.Lock() - defer a.Unlock() - - for _, host := range serverCfg.Tls.AcmeHosts { - - if a.hosts[host] { - return fmt.Errorf("Acme host %s is already configured", host) - } - - a.hosts[host] = true - } - - return nil -} - -func (a *AcmeService) Disable(server core.Server) error { - - serverCfg := server.Cfg() - - if serverCfg.Tls == nil { - return nil - } - - a.Lock() - defer a.Unlock() - - for _, host := range serverCfg.Tls.AcmeHosts { - delete(a.hosts, host) - } - - return nil -} diff --git a/router/gobetween/service/service.go b/router/gobetween/service/service.go deleted file mode 100644 index 21250d595..000000000 --- a/router/gobetween/service/service.go +++ /dev/null @@ -1,29 +0,0 @@ -package service - -import ( - "../config" - "../core" - "../logging" -) - -/** - * Registry of factory methods for Services - */ -var registry = make(map[string]func(config.Config) core.Service) - -func All(cfg config.Config) []core.Service { - log := logging.For("services") - - result := make([]core.Service, 0) - - for name, constructor := range registry { - service := constructor(cfg) - if service == nil { - continue - } - log.Info("Creating ", name) - result = append(result, service) - } - - return result -} diff --git a/router/gobetween/stats/counters/backendscounter.go b/router/gobetween/stats/counters/backendscounter.go deleted file mode 100644 index bb9cc69ff..000000000 --- a/router/gobetween/stats/counters/backendscounter.go +++ /dev/null @@ -1,139 +0,0 @@ -/** - * backendscounter.go - bandwidth counter for backends pool - * - * @author Yaroslav Pogrebnyak - */ - -package counters - -import ( - "../../core" - "time" -) - -const ( - /* Stats update interval */ - INTERVAL = 2 * time.Second -) - -/** - * Bandwidth counter for backends pool - */ -type BackendsBandwidthCounter struct { - - /* Map of counters of specific targets */ - counters map[core.Target]*BandwidthCounter - - /* ----- channels ------ */ - - /* Input channel of updated targets */ - In chan []core.Target - - /* Input channel of traffic deltas */ - Traffic chan core.ReadWriteCount - - /* Output channel for counted stats */ - Out chan BandwidthStats - - /* Stop channel */ - stop chan bool -} - -/** - * Creates new backends bandwidth counter - */ -func NewBackendsBandwidthCounter() *BackendsBandwidthCounter { - return &BackendsBandwidthCounter{ - counters: make(map[core.Target]*BandwidthCounter), - In: make(chan []core.Target), - Traffic: make(chan core.ReadWriteCount), - Out: make(chan BandwidthStats), - stop: make(chan bool), - } -} - -/** - * Start backends counter - */ -func (this *BackendsBandwidthCounter) Start() { - - go func() { - for { - select { - - // stop - case <-this.stop: - - // Stop all counters - for i := range this.counters { - this.counters[i].Stop() - } - this.counters = nil - - // close channels - close(this.In) - close(this.Traffic) - close(this.Out) - return - - // new backends available - case targets := <-this.In: - this.UpdateCounters(targets) - - // new traffic available - // route to appropriated counter - case rwc := <-this.Traffic: - counter, ok := this.counters[rwc.Target] - // ignore stats for backend that is not is list - if ok { - counter.Traffic <- rwc - } - } - - } - }() -} - -/** - * Update counters to match targets, optionally creating new - * and deleting old counters - */ -func (this *BackendsBandwidthCounter) UpdateCounters(targets []core.Target) { - - result := map[core.Target]*BandwidthCounter{} - - // Keep or add needed workers - for _, t := range targets { - c, ok := this.counters[t] - if !ok { - c = NewBandwidthCounter(INTERVAL, this.Out) - c.Target = t - c.Start() - } - result[t] = c - } - - // Stop needed counters - for currentT, c := range this.counters { - remove := true - for _, t := range targets { - if currentT.EqualTo(t) { - remove = false - break - } - } - - if remove { - c.Stop() - } - } - - this.counters = result -} - -/** - * Stop backends counter - */ -func (this *BackendsBandwidthCounter) Stop() { - this.stop <- true -} diff --git a/router/gobetween/stats/counters/bandwidth.go b/router/gobetween/stats/counters/bandwidth.go deleted file mode 100644 index 5bf62c245..000000000 --- a/router/gobetween/stats/counters/bandwidth.go +++ /dev/null @@ -1,32 +0,0 @@ -/** - * stats.go - bandwidth stats - * - * @author Yaroslav Pogrebnyak - */ - -package counters - -import ( - "../../core" -) - -/** - * Bandwidth stats object - */ -type BandwidthStats struct { - - // Total received bytes - RxTotal uint64 - - // Total transmitted bytes - TxTotal uint64 - - // Received bytes per second - RxSecond uint - - // Transmitted bytes per second - TxSecond uint - - // Optional target of stats - Target core.Target -} diff --git a/router/gobetween/stats/counters/counter.go b/router/gobetween/stats/counters/counter.go deleted file mode 100644 index b36c8a95c..000000000 --- a/router/gobetween/stats/counters/counter.go +++ /dev/null @@ -1,121 +0,0 @@ -/** - * counter.go - bandwidth counter - * - * @author Yaroslav Pogrebnyak - */ - -package counters - -import ( - "../../core" - "time" -) - -/** - * Count total bandwidth and bandwidth per second - */ -type BandwidthCounter struct { - - /* Bandwidth Stats */ - BandwidthStats - - /* Last received total bytes */ - RxTotalLast uint64 - /* Last transmitted total bytes */ - TxTotalLast uint64 - - /* Timeframe to calculate per-second bandwidth */ - interval time.Duration - /* Ticker for per-second bandwidth calculation and pushing stats */ - ticker *time.Ticker - - /* Indicates that new bandwidth delta was received */ - newTxRx bool - - /* ----- channels ----- */ - - /* Input channel for bandwidth deltas */ - Traffic chan core.ReadWriteCount - - /* Stop channel */ - stop chan bool - - /* Output channel for bandwidth stats */ - Out chan BandwidthStats -} - -/** - * Create new BandwidthCounter - */ -func NewBandwidthCounter(interval time.Duration, out chan BandwidthStats) *BandwidthCounter { - - return &BandwidthCounter{ - interval: interval, - ticker: time.NewTicker(interval), - BandwidthStats: BandwidthStats{ - RxTotal: 0, - TxTotal: 0, - }, - TxTotalLast: 0, - RxTotalLast: 0, - Out: out, - Traffic: make(chan core.ReadWriteCount), - stop: make(chan bool), - } -} - -/** - * Starts bandwidth counter - */ -func (this *BandwidthCounter) Start() { - - go func() { - - for { - select { - - // Stop requested - case <-this.stop: - this.ticker.Stop() - close(this.Traffic) - return - - // New counting cycle - case <-this.ticker.C: - - if !this.newTxRx { - this.RxSecond = 0 - this.TxSecond = 0 - } else { - - dRx := this.RxTotal - this.RxTotalLast - dTx := this.TxTotal - this.TxTotalLast - - this.RxSecond = uint(dRx / uint64(this.interval.Seconds())) - this.TxSecond = uint(dTx / uint64(this.interval.Seconds())) - - this.RxTotalLast = this.RxTotal - this.TxTotalLast = this.TxTotal - - this.newTxRx = false - } - - // Send results to out - this.Out <- this.BandwidthStats - - // New traffic deltas available - case rwc := <-this.Traffic: - this.newTxRx = true - this.RxTotal += uint64(rwc.CountRead) - this.TxTotal += uint64(rwc.CountWrite) - } - } - }() -} - -/** - * Stops bandwidth counter - */ -func (this *BandwidthCounter) Stop() { - this.stop <- true -} diff --git a/router/gobetween/stats/handler.go b/router/gobetween/stats/handler.go deleted file mode 100644 index b37d483ec..000000000 --- a/router/gobetween/stats/handler.go +++ /dev/null @@ -1,148 +0,0 @@ -/** - * handler.go - server stats handler - * - * @author Yaroslav Pogrebnyak - */ - -package stats - -import ( - "../core" - "./counters" - "time" -) - -const ( - /* Stats update interval */ - INTERVAL = 2 * time.Second -) - -/** - * Handler processess data from server - */ -type Handler struct { - - /* Server's name */ - name string - - /* Server counter */ - serverCounter *counters.BandwidthCounter - /* Backends counters */ - BackendsCounter *counters.BackendsBandwidthCounter - - /* Current stats */ - latestStats Stats - - /* ----- channels ----- */ - - /* Server traffic data */ - Traffic chan core.ReadWriteCount - - /* Server current connections count */ - Connections chan uint - - /* Current backends pool */ - Backends chan []core.Backend - - /* Channel for indicating stop request */ - stopChan chan bool - - /* Input channel for latest stats */ - ServerStats chan counters.BandwidthStats -} - -/** - * Creates new stats handler for the server - * with name 'name' - */ -func NewHandler(name string) *Handler { - - handler := &Handler{ - name: name, - ServerStats: make(chan counters.BandwidthStats, 1), - Traffic: make(chan core.ReadWriteCount), - Connections: make(chan uint), - Backends: make(chan []core.Backend), - stopChan: make(chan bool), - latestStats: Stats{ - RxTotal: 0, - TxTotal: 0, - RxSecond: 0, - TxSecond: 0, - Backends: []core.Backend{}, - }, - } - - handler.serverCounter = counters.NewBandwidthCounter(INTERVAL, handler.ServerStats) - handler.BackendsCounter = counters.NewBackendsBandwidthCounter() - - Store.Lock() - Store.handlers[name] = handler - Store.Unlock() - - return handler -} - -/** - * Start handler work asynchroniously - */ -func (this *Handler) Start() { - - this.serverCounter.Start() - this.BackendsCounter.Start() - - go func() { - - for { - select { - - /* stop stats processor requested */ - case <-this.stopChan: - - this.serverCounter.Stop() - this.BackendsCounter.Stop() - - Store.Lock() - delete(Store.handlers, this.name) - Store.Unlock() - - // close channels - close(this.ServerStats) - close(this.Traffic) - close(this.Connections) - return - - /* New server stats available */ - case b := <-this.ServerStats: - this.latestStats.RxTotal = b.RxTotal - this.latestStats.TxTotal = b.TxTotal - this.latestStats.RxSecond = b.RxSecond - this.latestStats.TxSecond = b.TxSecond - - /* New server backends with stats available */ - case backends := <-this.Backends: - this.latestStats.Backends = backends - - /* New sever connections count available */ - case connections := <-this.Connections: - this.latestStats.ActiveConnections = connections - - /* New traffic stats available */ - case rwc := <-this.Traffic: - // forward to counters - go func() { - this.serverCounter.Traffic <- rwc - this.BackendsCounter.Traffic <- rwc - }() - } - } - }() - -} - -/** - * Request handler stop and clear resources - */ -func (this *Handler) Stop() { - this.stopChan <- true -} diff --git a/router/gobetween/stats/stats.go b/router/gobetween/stats/stats.go deleted file mode 100644 index fd46efc47..000000000 --- a/router/gobetween/stats/stats.go +++ /dev/null @@ -1,35 +0,0 @@ -/** - * stats.go - server stats object - * - * @author Yaroslav Pogrebnyak - */ - -package stats - -import ( - "../core" -) - -/** - * Stats of the Server - */ -type Stats struct { - - /* Current active client connections */ - ActiveConnections uint `json:"active_connections"` - - /* Total received bytes from backend */ - RxTotal uint64 `json:"rx_total"` - - /* Total transmitter bytes to backend */ - TxTotal uint64 `json:"tx_total"` - - /* Received bytes to backend / second */ - RxSecond uint `json:"rx_second"` - - /* Transmitted bytes to backend / second */ - TxSecond uint `json:"tx_second"` - - /* Current backends pool */ - Backends []core.Backend `json:"backends"` -} diff --git a/router/gobetween/stats/store.go b/router/gobetween/stats/store.go deleted file mode 100644 index e47e94b0f..000000000 --- a/router/gobetween/stats/store.go +++ /dev/null @@ -1,34 +0,0 @@ -/** - * store.go - stats storage and getter - * - * @author Yaroslav Pogrebnyak - */ - -package stats - -import ( - "sync" -) - -/** - * Handlers Store - */ -var Store = struct { - sync.RWMutex - handlers map[string]*Handler -}{handlers: make(map[string]*Handler)} - -/** - * Get stats for the server - */ -func GetStats(name string) interface{} { - - Store.RLock() - defer Store.RUnlock() - - handler, ok := Store.handlers[name] - if !ok { - return nil - } - return handler.latestStats // TODO: syncronize? -} diff --git a/router/gobetween/utils/codec/codec.go b/router/gobetween/utils/codec/codec.go deleted file mode 100644 index 12ba78527..000000000 --- a/router/gobetween/utils/codec/codec.go +++ /dev/null @@ -1,57 +0,0 @@ -/** - * codec.go - decoding utils - * - * @author Yaroslav Pogrebnyak - */ -package codec - -import ( - "bytes" - "encoding/json" - "errors" - - "github.com/BurntSushi/toml" -) - -/** - * Encode data based on format - * Currently supported: toml and json - */ -func Encode(in interface{}, out *string, format string) error { - - switch format { - case "toml": - buf := new(bytes.Buffer) - if err := toml.NewEncoder(buf).Encode(in); err != nil { - return err - } - *out = buf.String() - return nil - case "json": - buf, err := json.MarshalIndent(in, "", " ") - if err != nil { - return err - } - *out = string(buf) - return nil - default: - return errors.New("Unknown format " + format) - } -} - -/** - * Decode data based on format - * Currently supported: toml and json - */ -func Decode(data string, out interface{}, format string) error { - - switch format { - case "toml": - _, err := toml.Decode(data, out) - return err - case "json": - return json.Unmarshal([]byte(data), out) - default: - return errors.New("Unknown format " + format) - } -} diff --git a/router/gobetween/utils/exec.go b/router/gobetween/utils/exec.go deleted file mode 100644 index 1969416de..000000000 --- a/router/gobetween/utils/exec.go +++ /dev/null @@ -1,40 +0,0 @@ -/** - * exec.go - Exec external process with timeout - * - * @author Yaroslav Pogrebnyak - * @author Ievgen Ponomarenko - */ - -package utils - -import ( - "../logging" - "os/exec" - "time" -) - -/** - * Exec with timeout - */ -func ExecTimeout(timeout time.Duration, params ...string) (string, error) { - - log := logging.For("execTimeout") - - cmd := exec.Command(params[0], params[1:]...) - - timer := time.AfterFunc(timeout, func() { - if cmd.Process != nil { - log.Info("Response from exec ", params, " is timed out. Killing process...") - cmd.Process.Kill() - } - }) - - out, err := cmd.Output() - timer.Stop() - - if err != nil { - return "", err - } - - return string(out), nil -} diff --git a/router/gobetween/utils/parsers/backend.go b/router/gobetween/utils/parsers/backend.go deleted file mode 100644 index 00fc3e935..000000000 --- a/router/gobetween/utils/parsers/backend.go +++ /dev/null @@ -1,78 +0,0 @@ -/** - * backend.go - backend parser utils - * - * @author Ievgen Ponomarenko - * @author Yaroslav Pogrebnyak - */ - -package parsers - -import ( - "../../core" - "errors" - "regexp" - "strconv" - "strings" -) - -const ( - DEFAULT_BACKEND_PATTERN = `^(?P\S+):(?P\d+)(\sweight=(?P\d+))?(\spriority=(?P\d+))?(\ssni=(?P[^\s]+))?$` -) - -/** - * Do parding of backend line with default pattern - */ -func ParseBackendDefault(line string) (*core.Backend, error) { - return ParseBackend(line, DEFAULT_BACKEND_PATTERN) -} - -/** - * Do parsing of backend line - */ -func ParseBackend(line string, pattern string) (*core.Backend, error) { - - //trim string - line = strings.TrimSpace(line) - - // parse string by regexp - var reg = regexp.MustCompile(pattern) - match := reg.FindStringSubmatch(line) - - if len(match) == 0 { - return nil, errors.New("Cant parse " + line) - } - - result := make(map[string]string) - - // get named capturing groups - for i, name := range reg.SubexpNames() { - if name != "" { - result[name] = match[i] - } - } - - weight, err := strconv.Atoi(result["weight"]) - if err != nil { - weight = 1 - } - - priority, err := strconv.Atoi(result["priority"]) - if err != nil { - priority = 1 - } - - backend := core.Backend{ - Target: core.Target{ - Host: result["host"], - Port: result["port"], - }, - Weight: weight, - Sni: result["sni"], - Priority: priority, - Stats: core.BackendStats{ - Live: true, - }, - } - - return &backend, nil -} diff --git a/router/gobetween/utils/proxyprotocol/proxyprotocol.go b/router/gobetween/utils/proxyprotocol/proxyprotocol.go deleted file mode 100644 index ea726c959..000000000 --- a/router/gobetween/utils/proxyprotocol/proxyprotocol.go +++ /dev/null @@ -1,62 +0,0 @@ -package proxyprotocol - -import ( - "fmt" - "net" - "strconv" - - proxyproto "github.com/pires/go-proxyproto" -) - -func addrToIPAndPort(addr net.Addr) (ip net.IP, port uint16, err error) { - ipString, portString, err := net.SplitHostPort(addr.String()) - if err != nil { - return - } - - ip = net.ParseIP(ipString) - if ip == nil { - err = fmt.Errorf("Could not parse IP") - return - } - - p, err := strconv.ParseInt(portString, 10, 64) - if err != nil { - return - } - port = uint16(p) - return -} - -/// SendProxyProtocolV1 sends a proxy protocol v1 header to initialize the connection -/// https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt -func SendProxyProtocolV1(client net.Conn, backend net.Conn) error { - sourceIP, sourcePort, err := addrToIPAndPort(client.RemoteAddr()) - if err != nil { - return err - } - - destinationIP, destinationPort, err := addrToIPAndPort(client.LocalAddr()) - if err != nil { - return err - } - - h := proxyproto.Header{ - Version: 1, - SourceAddress: sourceIP, - SourcePort: sourcePort, - DestinationAddress: destinationIP, - DestinationPort: destinationPort, - } - if sourceIP.To4() != nil { - h.TransportProtocol = proxyproto.TCPv4 - } else { - h.TransportProtocol = proxyproto.TCPv6 - } - - _, err = h.WriteTo(backend) - if err != nil { - return nil - } - return nil -} diff --git a/router/gobetween/utils/time.go b/router/gobetween/utils/time.go deleted file mode 100644 index 30d5d6d00..000000000 --- a/router/gobetween/utils/time.go +++ /dev/null @@ -1,31 +0,0 @@ -/** - * time.go - Time utils - * - * @author Yaroslav Pogrebnyak - */ - -package utils - -import ( - "time" -) - -/** - * Parse duration or return default - */ -func ParseDurationOrDefault(s string, defaultDuration time.Duration) time.Duration { - - var d time.Duration - var err error - - if s == "" { - return defaultDuration - } - - d, err = time.ParseDuration(s) - if err != nil { - return defaultDuration - } - - return d -} diff --git a/router/gobetween/utils/tls/sni/extract.go b/router/gobetween/utils/tls/sni/extract.go deleted file mode 100644 index 4a6d09428..000000000 --- a/router/gobetween/utils/tls/sni/extract.go +++ /dev/null @@ -1,68 +0,0 @@ -/** - * extract.go - extractor of hostname from ClientHello - * - * @author Illarion Kovalchuk - */ - -package sni - -import ( - "bytes" - "crypto/tls" - "io" - "net" - "time" -) - -type bufferConn struct { - io.Reader -} - -type localAddr struct{} - -func (l localAddr) String() string { - return "127.0.0.1" -} - -func (l localAddr) Network() string { - return "tcp" -} - -func newBufferConn(b []byte) *bufferConn { - return &bufferConn{bytes.NewReader(b)} -} - -func (c bufferConn) Write(b []byte) (n int, err error) { - return 0, nil -} - -func (c bufferConn) Close() error { - return nil -} - -func (c bufferConn) LocalAddr() net.Addr { - return localAddr{} -} - -func (c bufferConn) RemoteAddr() net.Addr { - return localAddr{} -} - -func (c bufferConn) SetDeadline(t time.Time) error { - return nil -} - -func (c bufferConn) SetReadDeadline(t time.Time) error { - return nil -} - -func (c bufferConn) SetWriteDeadline(t time.Time) error { - return nil -} - -func extractHostname(buf []byte) string { - conn := tls.Server(newBufferConn(buf), &tls.Config{}) - defer conn.Close() - conn.Handshake() - return conn.ConnectionState().ServerName -} diff --git a/router/gobetween/utils/tls/sni/sni.go b/router/gobetween/utils/tls/sni/sni.go deleted file mode 100644 index 2cf625039..000000000 --- a/router/gobetween/utils/tls/sni/sni.go +++ /dev/null @@ -1,61 +0,0 @@ -/** - * sni.go - sni sniffer implementation - * @author Illarion Kovalchuk - * - * Package sni provides transparent access to hostname provided by ClientHello - * message during TLS handshake. - */ - -package sni - -import ( - "bytes" - "io" - "net" - "sync" - "time" -) - -const MAX_HEADER_SIZE = 16385 - -var pool = sync.Pool{ - New: func() interface{} { - return make([]byte, MAX_HEADER_SIZE) - }, -} - -// Conn delegates all calls to net.Conn, but Read to reader -type Conn struct { - reader io.Reader - net.Conn //delegate -} - -func (c Conn) Read(b []byte) (n int, err error) { - return c.reader.Read(b) -} - -// Sniff sniffs hostname from ClientHello message (if any), -// returns sni.Conn, filling it's Hostname field -func Sniff(conn net.Conn, readTimeout time.Duration) (net.Conn, string, error) { - buf := pool.Get().([]byte) - defer pool.Put(buf) - - conn.SetReadDeadline(time.Now().Add(readTimeout)) - i, err := conn.Read(buf) - - if err != nil { - return nil, "", err - } - - conn.SetReadDeadline(time.Time{}) // Reset read deadline - - hostname := extractHostname(buf[0:i]) - - data := make([]byte, i) - copy(data, buf) // Since we reuse buf between invocations, we have to make copy of data - mreader := io.MultiReader(bytes.NewBuffer(data), conn) - - // Wrap connection so that it will Read from buffer first and remaining data - // from initial conn - return Conn{mreader, conn}, hostname, nil -} diff --git a/router/gobetween/utils/tls/tls.go b/router/gobetween/utils/tls/tls.go deleted file mode 100644 index a3e171ff1..000000000 --- a/router/gobetween/utils/tls/tls.go +++ /dev/null @@ -1,159 +0,0 @@ -/** - * tls.go - Tls mapping utils - * - * @author Yaroslav Pogrebnyak - */ - -package tls - -import ( - "crypto/tls" - "crypto/x509" - "io/ioutil" - - "../../config" -) - -/** - * TLS Ciphers mapping - */ -var suites map[string]uint16 = map[string]uint16{ - "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, - "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, - "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, - "TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, - "TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256, - "TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384, - "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - "TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, - "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, -} - -/** - * TLS Versions mappings - */ -var versions map[string]uint16 = map[string]uint16{ - "ssl3": tls.VersionSSL30, - "tls1": tls.VersionTLS10, - "tls1.1": tls.VersionTLS11, - "tls1.2": tls.VersionTLS12, -} - -/** - * Maps tls version from string to golang constant - */ -func MapVersion(version string) uint16 { - return versions[version] -} - -/** - * Maps tls ciphers from array of strings to array of golang constants - */ -func MapCiphers(ciphers []string) []uint16 { - - if ciphers == nil || len(ciphers) == 0 { - return nil - } - - result := []uint16{} - - for _, s := range ciphers { - c := suites[s] - if c == 0 { - continue - } - result = append(result, c) - } - - return result -} - -func MakeTlsConfig(tlsC *config.Tls, getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)) (*tls.Config, error) { - - if tlsC == nil { - return nil, nil - } - - tlsConfig := &tls.Config{} - - tlsConfig.CipherSuites = MapCiphers(tlsC.Ciphers) - tlsConfig.PreferServerCipherSuites = tlsC.PreferServerCiphers - tlsConfig.MinVersion = MapVersion(tlsC.MinVersion) - tlsConfig.MaxVersion = MapVersion(tlsC.MaxVersion) - tlsConfig.SessionTicketsDisabled = !tlsC.SessionTickets - - if getCertificate != nil { - tlsConfig.GetCertificate = getCertificate - return tlsConfig, nil - } - - var crt tls.Certificate - var err error - if crt, err = tls.LoadX509KeyPair(tlsC.CertPath, tlsC.KeyPath); err != nil { - return nil, err - } - - tlsConfig.Certificates = []tls.Certificate{crt} - - return tlsConfig, nil -} - -/** - * MakeBackendTLSConfig makes a tls.Config for connecting to backends - */ -func MakeBackendTLSConfig(backendsTls *config.BackendsTls) (*tls.Config, error) { - - if backendsTls == nil { - return nil, nil - } - - var err error - - result := &tls.Config{ - InsecureSkipVerify: backendsTls.IgnoreVerify, - CipherSuites: MapCiphers(backendsTls.Ciphers), - PreferServerCipherSuites: backendsTls.PreferServerCiphers, - MinVersion: MapVersion(backendsTls.MinVersion), - MaxVersion: MapVersion(backendsTls.MaxVersion), - SessionTicketsDisabled: !backendsTls.SessionTickets, - } - - if backendsTls.CertPath != nil && backendsTls.KeyPath != nil { - - var crt tls.Certificate - - if crt, err = tls.LoadX509KeyPair(*backendsTls.CertPath, *backendsTls.KeyPath); err != nil { - return nil, err - } - - result.Certificates = []tls.Certificate{crt} - } - - if backendsTls.RootCaCertPath != nil { - - var caCertPem []byte - - if caCertPem, err = ioutil.ReadFile(*backendsTls.RootCaCertPath); err != nil { - return nil, err - } - - caCertPool := x509.NewCertPool() - if ok := caCertPool.AppendCertsFromPEM(caCertPem); !ok { - return nil, err - } - - result.RootCAs = caCertPool - - } - - return result, nil - -}