From 01ddce45b2c133dbbbbcf2c89fa1de340f75e34f Mon Sep 17 00:00:00 2001 From: a <a@a.a> Date: Sat, 3 Sep 2022 05:36:16 -0500 Subject: [PATCH] ok i guess --- cmd/cgat/main.go | 5 +- codegen/protocol/packets.tmpl | 14 +- .../config_data.toml => config_data.toml | 0 go.mod | 23 ++ go.sum | 347 +++++++++++++++++- lib/config/config.go | 6 +- lib/gat/client.go | 117 +++++- lib/gat/gatling.go | 26 +- lib/gat/messages.go | 4 +- lib/gat/protocol/backend.go | 104 +++--- lib/gat/protocol/frontend.go | 112 ++++-- lib/gat/protocol/shared.go | 8 +- lib/gat/query_router.go | 128 +++---- lib/gat/query_router_test.go | 89 +++-- spec/protocol/backend.yaml | 2 +- spec/protocol/frontend.yaml | 9 +- 16 files changed, 755 insertions(+), 239 deletions(-) rename lib/config/config_data.toml => config_data.toml (100%) diff --git a/cmd/cgat/main.go b/cmd/cgat/main.go index 4ff4c958..aaa05000 100644 --- a/cmd/cgat/main.go +++ b/cmd/cgat/main.go @@ -2,12 +2,14 @@ package main import ( "context" + "log" + "gfx.cafe/gfx/pggat/lib/config" "gfx.cafe/gfx/pggat/lib/gat" ) // test config, should be changed -const CONFIG = "./lib/config/config_data.toml" +const CONFIG = "./config_data.toml" func main() { conf, err := config.Load(CONFIG) @@ -20,6 +22,7 @@ func main() { panic(err) } + log.Println("listening on port", conf.General.Port) err = gatling.ListenAndServe(context.Background()) if err != nil { panic(err) diff --git a/codegen/protocol/packets.tmpl b/codegen/protocol/packets.tmpl index 33493420..5474639f 100644 --- a/codegen/protocol/packets.tmpl +++ b/codegen/protocol/packets.tmpl @@ -85,10 +85,10 @@ var _ io.Reader {{else if $field.While -}} var P {{template "fieldTypeNoArr" (list $parent $field)}} for ok := true; ok; ok = {{$field.While}} { - {{template "readFieldL1" (list $parent $field "P")}} - T.{{$field.Name}} = append(T.{{$field.Name}}, P) - var newp {{template "fieldTypeNoArr" (list $parent $field)}} - P = newp + var newP {{template "fieldTypeNoArr" (list $parent $field)}} + {{template "readFieldL1" (list $parent $field "newP")}} + T.{{$field.Name}} = append(T.{{$field.Name}}, newP) + P = newP } {{else -}} {{template "readFieldL1" (list $parent $field (printf "T.%s" $field.Name))}} @@ -216,9 +216,9 @@ var _ io.Reader return } {{end -}} - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length) + 4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -228,4 +228,4 @@ var _ io.Reader var _ Packet = (*{{$name}})(nil) -{{end -}} \ No newline at end of file +{{end -}} diff --git a/lib/config/config_data.toml b/config_data.toml similarity index 100% rename from lib/config/config_data.toml rename to config_data.toml diff --git a/go.mod b/go.mod index 556ba68b..979aff3f 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( git.tuxpa.in/a/zlog v1.32.0 github.com/BurntSushi/toml v1.2.0 + github.com/auxten/postgresql-parser v1.0.1 github.com/ethereum/go-ethereum v1.10.23 github.com/iancoleman/strcase v0.2.0 github.com/xdg-go/scram v1.1.1 @@ -13,10 +14,32 @@ require ( ) require ( + github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 // indirect + github.com/cockroachdb/apd v1.1.1-0.20181017181144-bced77f817b4 // indirect + github.com/cockroachdb/errors v1.8.2 // indirect + github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect + github.com/cockroachdb/redact v1.0.8 // indirect + github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/getsentry/raven-go v0.2.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect + github.com/kr/pretty v0.2.0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/lib/pq v1.9.0 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/sirupsen/logrus v1.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect golang.org/x/text v0.3.7 // indirect + google.golang.org/genproto v0.0.0-20200911024640-645f7a48b24f // indirect + google.golang.org/grpc v1.33.1 // indirect + google.golang.org/protobuf v1.26.0 // indirect ) diff --git a/go.sum b/go.sum index 87098b1d..0838b82a 100644 --- a/go.sum +++ b/go.sum @@ -1,36 +1,381 @@ +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= git.tuxpa.in/a/zlog v1.32.0 h1:KKXbRF1x8kJDSzUoGz/pivo+4TVY6xT5sVtdFZ6traY= git.tuxpa.in/a/zlog v1.32.0/go.mod h1:vUa2Qhu6DLPLqmfRy99FiPqaY2eb6/KQjtMekW3UNnA= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/auxten/postgresql-parser v1.0.1 h1:x+qiEHAe2cH55Kly64dWh4tGvUKEQwMmJgma7a1kbj4= +github.com/auxten/postgresql-parser v1.0.1/go.mod h1:Nf27dtv8EU1C+xNkoLD3zEwfgJfDDVi8Zl86gznxPvI= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +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/cockroachdb/apd v1.1.1-0.20181017181144-bced77f817b4 h1:XWEdfNxDkZI3DXXlpo0hZJ1xdaH/f3CKuZpk93pS/Y0= +github.com/cockroachdb/apd v1.1.1-0.20181017181144-bced77f817b4/go.mod h1:mdGz2CnkJrefFtlLevmE7JpL2zB9tKofya/6w7wWzNA= +github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= +github.com/cockroachdb/errors v1.8.2 h1:rnnWK9Nn5kEMOGz9531HuDx/FOleL4NVH20VsDexVC8= +github.com/cockroachdb/errors v1.8.2/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +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/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +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/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/go-ethereum v1.10.23 h1:Xk8XAT4/UuqcjMLIMF+7imjkg32kfVFKoeyQDaO2yWM= github.com/ethereum/go-ethereum v1.10.23/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +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= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +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/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +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/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= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +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.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.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +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/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +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/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= +github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +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.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= +github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +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 v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +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.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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-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-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-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/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-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200822124328-c89045814202/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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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-20180830151530-49385e6e1522/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-20181205085412-a5c9d58dba9a/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-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-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= +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/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200911024640-645f7a48b24f h1:Yv4xsIx7HZOoyUGSJ2ksDyWE2qIBXROsZKt2ny3hCGM= +google.golang.org/genproto v0.0.0-20200911024640-645f7a48b24f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.33.1 h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +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/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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/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= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/lib/config/config.go b/lib/config/config.go index 8bbaa2b1..778ada2e 100644 --- a/lib/config/config.go +++ b/lib/config/config.go @@ -1,8 +1,9 @@ package config import ( - "github.com/BurntSushi/toml" "os" + + "github.com/BurntSushi/toml" ) type PoolMode string @@ -45,6 +46,9 @@ type General struct { BanTime int `toml:"ban_time" yaml:"ban_time" json:"ban_time"` + TlsCertificate string `toml:"tls_certificate" yaml:"tls_certificate" json:"tls_certificate"` + TlsPrivateKey string `toml:"tls_private_key" yaml:"tls_private_key" json:"tls_private_key"` + AutoReload bool `toml:"autoreload" yaml:"autoreload" json:"autoreload"` } diff --git a/lib/gat/client.go b/lib/gat/client.go index 19f59f39..efd72bc2 100644 --- a/lib/gat/client.go +++ b/lib/gat/client.go @@ -5,13 +5,16 @@ import ( "bytes" "context" "crypto/rand" + "crypto/tls" "errors" "fmt" - "gfx.cafe/gfx/pggat/lib/gat/protocol" "io" "math/big" "net" "reflect" + "strings" + + "gfx.cafe/gfx/pggat/lib/gat/protocol" "gfx.cafe/gfx/pggat/lib/config" "git.tuxpa.in/a/zlog" @@ -101,12 +104,52 @@ func NewClient( } func (c *Client) Accept(ctx context.Context) error { + // read a packet startup := new(protocol.StartupMessage) err := startup.Read(c.r) if err != nil { return err } - + switch startup.Fields.ProtocolVersionNumber { + case 196608: + case 80877102: + return c.handle_cancel(ctx, startup) + case 80877103: + // ssl stuff now + useSsl := (c.conf.General.TlsCertificate != "") + if !useSsl { + _, err = protocol.WriteByte(c.wr, 'N') + if err != nil { + return err + } + startup = new(protocol.StartupMessage) + err := startup.Read(c.r) + if err != nil { + return err + } + } else { + _, err = protocol.WriteByte(c.wr, 'S') + if err != nil { + return err + } + //TODO: we need to do an ssl handshake here. + cert, err := tls.LoadX509KeyPair(c.conf.General.TlsCertificate, c.conf.General.TlsPrivateKey) + if err != nil { + return err + } + cfg := &tls.Config{ + Certificates: []tls.Certificate{cert}, + InsecureSkipVerify: true, + } + c.conn = tls.Server(c.conn, cfg) + c.r = bufio.NewReader(c.conn) + c.wr = c.conn + err = startup.Read(c.r) + if err != nil { + return err + } + } + } params := make(map[string]string) for _, v := range startup.Fields.Parameters { params[v.Name] = v.Value @@ -155,7 +198,9 @@ func (c *Client) Accept(ctx context.Context) error { var rsp protocol.Packet rsp, err = protocol.ReadFrontend(c.r) - + if err != nil { + return err + } var passwordResponse []byte switch r := rsp.(type) { case *protocol.AuthenticationResponse: @@ -165,19 +210,24 @@ func (c *Client) Accept(ctx context.Context) error { } // Authenticate admin user. - if c.admin { c.server_info = AdminServerInfo() pw_hash := Md5HashPassword(c.conf.General.AdminUsername, c.conf.General.AdminPassword, salt[:]) if !reflect.DeepEqual(pw_hash, passwordResponse) { - return fmt.Errorf("password denied") + return fmt.Errorf("password denied for admin") } } else { // TODO: actually get a server pool - pool := ServerPool{} + c.server_info = AdminServerInfo() + pool := ServerPool{ + user: config.User{ + Name: "postgres", + Password: "postgres", + }, + } pw_hash := Md5HashPassword(c.username, pool.user.Password, salt[:]) if !reflect.DeepEqual(pw_hash, passwordResponse) { - return fmt.Errorf("password denied") + return fmt.Errorf("password denied for %s", c.username) } } c.log.Debug().Msg("Password authentication successful") @@ -187,6 +237,8 @@ func (c *Client) Accept(ctx context.Context) error { if err != nil { return err } + + // _, err = c.wr.Write(c.server_info) if err != nil { return err @@ -205,6 +257,57 @@ func (c *Client) Accept(ctx context.Context) error { return err } c.log.Debug().Msg("Ready for Query") + for { + err := c.tick(ctx) + if err != nil { + return err + } + } +} + +// TODO: we need to keep track of queries so we can handle cancels +func (c *Client) handle_cancel(ctx context.Context, p *protocol.StartupMessage) error { + log.Println("cancel msg", p) + return nil +} + +// reads a packet from stream and handles it +func (c *Client) tick(ctx context.Context) error { + rsp, err := protocol.ReadFrontend(c.r) + if err != nil { + return err + } + log.Println("(%v): %s", reflect.TypeOf(c), c) + switch cast := rsp.(type) { + case *protocol.Describe: + case *protocol.Query: + return c.handle_query(ctx, cast) + default: + } + return nil +} + +func (c *Client) handle_query(ctx context.Context, q *protocol.Query) error { + //TODO: use the query router here + // get the first word of the query + ans := &protocol.CommandComplete{} + words := strings.Split(strings.ToLower(strings.TrimSpace(q.Fields.Query)), " ") + switch words[0] { + case "set": + ans.Fields.Data = "SET" + case "select": + ans.Fields.Data = "SELECT" + } + _, err := ans.Write(c.wr) + if err != nil { + return err + } + ready := &protocol.ReadyForQuery{} + ready.Fields.Status = 'I' + _, err = ready.Write(c.wr) + if err != nil { + return err + } return nil } diff --git a/lib/gat/gatling.go b/lib/gat/gatling.go index a2176686..00f37dae 100644 --- a/lib/gat/gatling.go +++ b/lib/gat/gatling.go @@ -3,9 +3,11 @@ package gat import ( "context" "fmt" + "log" "net" "gfx.cafe/gfx/pggat/lib/config" + "gfx.cafe/gfx/pggat/lib/gat/protocol" ) type Gatling struct { @@ -42,12 +44,32 @@ func (g *Gatling) ListenAndServe(ctx context.Context) error { if err != nil { return err } - go g.handleConnection(ctx, c) + go func() { + err := g.handleConnection(ctx, c) + if err != nil { + log.Println("disconnected:", err) + } + }() } } // TODO: TLS func (g *Gatling) handleConnection(ctx context.Context, c net.Conn) error { cl := NewClient(g.c, c, g.csm, false) - return cl.Accept(ctx) + err := cl.Accept(ctx) + if err != nil { + resp := &protocol.ErrorResponse{ + Fields: protocol.FieldsErrorResponse{ + Responses: []protocol.FieldsErrorResponseResponses{ + { + Code: 0, + Value: err.Error(), + }, + }, + }, + } + log.Println(err.Error()) + resp.Write(cl.wr) + } + return nil } diff --git a/lib/gat/messages.go b/lib/gat/messages.go index 9324764f..37d6a093 100644 --- a/lib/gat/messages.go +++ b/lib/gat/messages.go @@ -5,6 +5,7 @@ import ( "crypto/md5" "crypto/rand" "encoding/hex" + "gfx.cafe/gfx/pggat/lib/gat/protocol" ) @@ -33,7 +34,8 @@ func Md5HashPassword(user string, password string, salt []byte) []byte { []byte(hex.EncodeToString(hsh1.Sum(nil))), ) hsh2.Write(salt) - return append([]byte("md5"), hsh2.Sum(nil)...) + sum := hsh2.Sum(nil) + return append([]byte("md5"+hex.EncodeToString(sum)), 0) } // /// Implements a response to our custom `SET SHARDING KEY` diff --git a/lib/gat/protocol/backend.go b/lib/gat/protocol/backend.go index 890b969e..6159e499 100644 --- a/lib/gat/protocol/backend.go +++ b/lib/gat/protocol/backend.go @@ -67,9 +67,9 @@ func (T *Authentication) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -140,9 +140,9 @@ func (T *BackendKeyData) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -193,9 +193,9 @@ func (T *BindComplete) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -246,9 +246,9 @@ func (T *CloseComplete) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -309,9 +309,9 @@ func (T *CommandComplete) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -400,9 +400,9 @@ func (T *CopyBothResponse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -491,9 +491,9 @@ func (T *CopyInResponse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -582,9 +582,9 @@ func (T *CopyOutResponse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -704,9 +704,9 @@ func (T *DataRow) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -757,9 +757,9 @@ func (T *EmptyQueryResponse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -813,13 +813,13 @@ type FieldsErrorResponse struct { func (T *FieldsErrorResponse) Read(payloadLength int, reader io.Reader) (err error) { var P FieldsErrorResponseResponses for ok := true; ok; ok = P.Code != 0 { - err = P.Read(payloadLength, reader) + var newP FieldsErrorResponseResponses + err = newP.Read(payloadLength, reader) if err != nil { return } - T.Responses = append(T.Responses, P) - var newp FieldsErrorResponseResponses - P = newp + T.Responses = append(T.Responses, newP) + P = newP } return } @@ -865,9 +865,9 @@ func (T *ErrorResponse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -946,9 +946,9 @@ func (T *FunctionCallResponse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1037,9 +1037,9 @@ func (T *NegotiateProtocolVersion) Write(writer io.Writer) (length int, err erro length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1090,9 +1090,9 @@ func (T *NoData) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1146,13 +1146,13 @@ type FieldsNoticeResponse struct { func (T *FieldsNoticeResponse) Read(payloadLength int, reader io.Reader) (err error) { var P FieldsNoticeResponseResponses for ok := true; ok; ok = P.Code != 0 { - err = P.Read(payloadLength, reader) + var newP FieldsNoticeResponseResponses + err = newP.Read(payloadLength, reader) if err != nil { return } - T.Responses = append(T.Responses, P) - var newp FieldsNoticeResponseResponses - P = newp + T.Responses = append(T.Responses, newP) + P = newP } return } @@ -1198,9 +1198,9 @@ func (T *NoticeResponse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1281,9 +1281,9 @@ func (T *NotificationResponse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1362,9 +1362,9 @@ func (T *ParameterDescription) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1435,9 +1435,9 @@ func (T *ParameterStatus) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1488,9 +1488,9 @@ func (T *ParseComplete) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1541,9 +1541,9 @@ func (T *PortalSuspended) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1604,9 +1604,9 @@ func (T *ReadyForQuery) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1768,9 +1768,9 @@ func (T *RowDescription) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 diff --git a/lib/gat/protocol/frontend.go b/lib/gat/protocol/frontend.go index 45cea868..b5344bdc 100644 --- a/lib/gat/protocol/frontend.go +++ b/lib/gat/protocol/frontend.go @@ -67,9 +67,9 @@ func (T *AuthenticationResponse) Write(writer io.Writer) (length int, err error) length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -265,9 +265,9 @@ func (T *Bind) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -342,9 +342,9 @@ func (T *CancelRequest) Write(writer io.Writer) (length int, err error) { length = 0 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -415,9 +415,9 @@ func (T *Close) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -478,9 +478,9 @@ func (T *CopyFail) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -551,9 +551,9 @@ func (T *Describe) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -624,9 +624,9 @@ func (T *Execute) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -677,9 +677,9 @@ func (T *Flush) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -847,9 +847,9 @@ func (T *FunctionCall) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -904,9 +904,9 @@ func (T *GSSENCRequest) Write(writer io.Writer) (length int, err error) { length = 0 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1005,9 +1005,9 @@ func (T *Parse) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1068,9 +1068,9 @@ func (T *Query) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1125,9 +1125,9 @@ func (T *SSLRequest) Write(writer io.Writer) (length int, err error) { length = 0 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1176,6 +1176,8 @@ func (T *FieldsStartupMessageParameters) Write(writer io.Writer) (length int, er type FieldsStartupMessage struct { ProtocolVersionNumber int32 + ProcessKey int32 + SecretKey int32 Parameters []FieldsStartupMessageParameters } @@ -1184,15 +1186,29 @@ func (T *FieldsStartupMessage) Read(payloadLength int, reader io.Reader) (err er if err != nil { return } - var P FieldsStartupMessageParameters - for ok := true; ok; ok = P.Name != "" { - err = P.Read(payloadLength, reader) + if T.ProtocolVersionNumber == 80877102 { + T.ProcessKey, err = ReadInt32(reader) if err != nil { return } - T.Parameters = append(T.Parameters, P) - var newp FieldsStartupMessageParameters - P = newp + } + if T.ProtocolVersionNumber == 80877102 { + T.SecretKey, err = ReadInt32(reader) + if err != nil { + return + } + } + if T.ProtocolVersionNumber == 196608 { + var P FieldsStartupMessageParameters + for ok := true; ok; ok = P.Name != "" { + var newP FieldsStartupMessageParameters + err = newP.Read(payloadLength, reader) + if err != nil { + return + } + T.Parameters = append(T.Parameters, newP) + P = newP + } } return } @@ -1204,13 +1220,29 @@ func (T *FieldsStartupMessage) Write(writer io.Writer) (length int, err error) { return } length += temp - for _, v := range T.Parameters { - temp, err = v.Write(writer) + if T.ProtocolVersionNumber == 80877102 { + temp, err = WriteInt32(writer, T.ProcessKey) if err != nil { return } length += temp } + if T.ProtocolVersionNumber == 80877102 { + temp, err = WriteInt32(writer, T.SecretKey) + if err != nil { + return + } + length += temp + } + if T.ProtocolVersionNumber == 196608 { + for _, v := range T.Parameters { + temp, err = v.Write(writer) + if err != nil { + return + } + length += temp + } + } _ = temp return } @@ -1237,9 +1269,9 @@ func (T *StartupMessage) Write(writer io.Writer) (length int, err error) { length = 0 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1290,9 +1322,9 @@ func (T *Sync) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -1343,9 +1375,9 @@ func (T *Terminate) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 diff --git a/lib/gat/protocol/shared.go b/lib/gat/protocol/shared.go index 30aa5c1c..567fe6b5 100644 --- a/lib/gat/protocol/shared.go +++ b/lib/gat/protocol/shared.go @@ -67,9 +67,9 @@ func (T *CopyData) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 @@ -120,9 +120,9 @@ func (T *CopyDone) Write(writer io.Writer) (length int, err error) { length = 1 return } - _, err = WriteInt32(writer, int32(length)) + _, err = WriteInt32(writer, int32(length)+4) if err != nil { - length = 5 + length += 5 return } length += 5 diff --git a/lib/gat/query_router.go b/lib/gat/query_router.go index 9aaa5b3b..7e1a6c4b 100644 --- a/lib/gat/query_router.go +++ b/lib/gat/query_router.go @@ -1,10 +1,17 @@ package gat import ( + "fmt" "log" "regexp" + "strings" "gfx.cafe/gfx/pggat/lib/config" + "gfx.cafe/gfx/pggat/lib/gat/protocol" + + "github.com/auxten/postgresql-parser/pkg/sql/parser" + "github.com/auxten/postgresql-parser/pkg/sql/sem/tree" + "github.com/auxten/postgresql-parser/pkg/walk" ) var compiler = regexp.MustCompile @@ -54,17 +61,13 @@ func (r *QueryRouter) UpdatePoolSettings(pool_settings PoolSettings) { } // / Try to parse a command and execute it. -func (r *QueryRouter) try_execute_command(buf []byte) (Command, string) { +func (r *QueryRouter) try_execute_command(pkt protocol.Query) (Command, string) { // Only simple protocol supported for commands. - if buf[0] != 'Q' { - return nil, "" - } - msglen := 0 // TODO: read msg len // msglen := buf.get_i32() custom := false for _, v := range CustomSqlRegex { - if v.Match(buf[:msglen-5]) { + if v.MatchString(pkt.Fields.Query) { custom = true break } @@ -72,7 +75,7 @@ func (r *QueryRouter) try_execute_command(buf []byte) (Command, string) { // This is not a custom query, try to infer which // server it'll go to if the query parser is enabled. if !custom { - log.Println("Regular query, not a command") + log.Println("regular query, not a command") return nil, "" } @@ -198,80 +201,43 @@ func (r *QueryRouter) try_execute_command(buf []byte) (Command, string) { // / Try to infer which server to connect to based on the contents of the query. // TODO: implement -func (r *QueryRouter) InferRole(buf []byte) bool { - log.Println("Inferring role") - - //code := buf.get_u8() as char - //len := buf.get_i32() as usize - - //query := switch code { - // // Query - // 'Q' => { - // query := string(&buf[:len - 5]).to_string() - // log.Println("Query: '%v'", query) - // query - // } - - // // Parse (prepared statement) - // 'P' => { - // mut start := 0 - // mut end - - // // Skip the name of the prepared statement. - // while buf[start] != 0 && start < buf.len() { - // start += 1 - // } - // start += 1 // Skip terminating null - - // // Find the end of the prepared stmt (\0) - // end := start - // while buf[end] != 0 && end < buf.len() { - // end += 1 - // } - - // query := string(&buf[start:end]).to_string() - - // log.Println("Prepared statement: '%v'", query) - - // query.replace("$", "") // Remove placeholders turning them into "values" - // } - - // _ => return false, - //} - - //ast := switch Parser::parse_sql(&PostgreSqlDialect %v, &query) { - // Ok(ast) => ast, - // Err(err) => { - // log.Println("%v", err.to_string()) - // return false - // } - //} - - //if ast.len() == 0 { - // return false - //} - - //switch ast[0] { - // // All transactions go to the primary, probably a write. - // StartTransaction { : } => { - // self.active_role := Some(Role::Primary) - // } - - // // Likely a read-only query - // Query { : } => { - // self.active_role := switch self.primary_reads_enabled { - // false => Some(Role::Replica), // If primary should not be receiving reads, use a replica. - // true => None, // Any server role is fine in this case. - // } - // } - - // // Likely a write - // _ => { - // self.active_role := Some(Role::Primary) - // } - //} - - return true +func (r *QueryRouter) InferRole(pkt protocol.Packet) error { + var query string + switch c := pkt.(type) { + case *protocol.Query: + r.active_role = config.SERVERROLE_REPLICA + case *protocol.Parse: + query = c.Fields.Query + query = strings.ReplaceAll(query, "$", "") + default: + return fmt.Errorf("unknown packet %v", pkt) + } + // ok now parse the query + wk := &walk.AstWalker{ + Fn: func(ctx, node any) (stop bool) { + switch n := node.(type) { + case *tree.Update, *tree.UpdateExpr, + *tree.BeginTransaction, *tree.CommitTransaction, *tree.RollbackTransaction, + *tree.SetTransaction, *tree.ShowTransactionStatus, *tree.Delete, *tree.Insert: + // + r.active_role = config.SERVERROLE_PRIMARY + return true + default: + _ = n + } + return false + }, + } + r.active_role = config.SERVERROLE_REPLICA + stmts, err := parser.Parse(query) + if err != nil { + return err + } + _, err = wk.Walk(stmts, nil) + if err != nil { + return err + } + return nil } // / Get the current desired server role we should be talking to. diff --git a/lib/gat/query_router_test.go b/lib/gat/query_router_test.go index 9f9c0b18..a84edaa8 100644 --- a/lib/gat/query_router_test.go +++ b/lib/gat/query_router_test.go @@ -1,45 +1,54 @@ package gat -//TODO: adapt tests -//#[cfg(test)] -//mod test { -// use super::*; -// use crate::messages::simple_query; -// use crate::pool::PoolMode; -// use crate::sharding::ShardingFunction; -// use bytes::BufMut; -// -// #[test] -// fn test_defaults() { -// QueryRouter::setup(); -// let qr = QueryRouter::new(); -// -// assert_eq!(qr.role(), None); -// } -// -// #[test] -// fn test_infer_role_replica() { -// QueryRouter::setup(); -// let mut qr = QueryRouter::new(); -// assert!(qr.try_execute_command(simple_query("SET SERVER ROLE TO 'auto'")) != None); -// assert_eq!(qr.query_parser_enabled(), true); -// -// assert!(qr.try_execute_command(simple_query("SET PRIMARY READS TO off")) != None); -// -// let queries = vec![ -// simple_query("SELECT * FROM items WHERE id = 5"), -// simple_query( -// "SELECT id, name, value FROM items INNER JOIN prices ON item.id = prices.item_id", -// ), -// simple_query("WITH t AS (SELECT * FROM items) SELECT * FROM t"), -// ]; -// -// for query in queries { -// // It's a recognized query -// assert!(qr.infer_role(query)); -// assert_eq!(qr.role(), Some(Role::Replica)); -// } -// } +import ( + "testing" + + "gfx.cafe/gfx/pggat/lib/config" + "gfx.cafe/gfx/pggat/lib/gat/protocol" +) + +// TODO: adapt tests +func TestQueryRouterInterRoleReplica(t *testing.T) { + qr := &QueryRouter{} + pkt := &protocol.Parse{} + pkt.Fields.Query = `UPDATE items SET name = 'pumpkin' WHERE id = 5` + err := qr.InferRole(pkt) + if err != nil { + t.Fatal(err) + } + if qr.active_role != config.SERVERROLE_PRIMARY { + t.Error("expect primary") + } + pkt.Fields.Query = `select * from items WHERE id = 5` + err = qr.InferRole(pkt) + if err != nil { + t.Fatal(err) + } + if qr.active_role != config.SERVERROLE_REPLICA { + t.Error("expect replica") + } + +} + +// assert!(qr.try_execute_command(simple_query("SET SERVER ROLE TO 'auto'")) != None); +// assert_eq!(qr.query_parser_enabled(), true); + +// assert!(qr.try_execute_command(simple_query("SET PRIMARY READS TO off")) != None); + +// let queries = vec![ +// simple_query("SELECT * FROM items WHERE id = 5"), +// simple_query( +// "SELECT id, name, value FROM items INNER JOIN prices ON item.id = prices.item_id", +// ), +// simple_query("WITH t AS (SELECT * FROM items) SELECT * FROM t"), +// ]; + +// for query in queries { +// // It's a recognized query +// assert!(qr.infer_role(query)); +// assert_eq!(qr.role(), Some(Role::Replica)); +// } +// } // // #[test] // fn test_infer_role_primary() { diff --git a/spec/protocol/backend.yaml b/spec/protocol/backend.yaml index eeffccbd..a314557e 100644 --- a/spec/protocol/backend.yaml +++ b/spec/protocol/backend.yaml @@ -147,4 +147,4 @@ RowDescription: Type: int32 - Name: FormatCode Type: int16 - LengthPrefixed: int16 \ No newline at end of file + LengthPrefixed: int16 diff --git a/spec/protocol/frontend.yaml b/spec/protocol/frontend.yaml index 6ca2d85f..0a700e48 100644 --- a/spec/protocol/frontend.yaml +++ b/spec/protocol/frontend.yaml @@ -104,7 +104,14 @@ StartupMessage: Fields: - Name: ProtocolVersionNumber Type: int32 + - Name: ProcessKey + Type: int32 + If: 'T.ProtocolVersionNumber == 80877102' + - Name: SecretKey + Type: int32 + If: 'T.ProtocolVersionNumber == 80877102' - Name: Parameters + If: 'T.ProtocolVersionNumber == 196608' Struct: Fields: - Name: Name @@ -116,4 +123,4 @@ StartupMessage: Sync: Identifier: 'S' Terminate: - Identifier: 'X' \ No newline at end of file + Identifier: 'X' -- GitLab