From 9000d431b4733f36349a2706e3f72030ea6b40db Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Thu, 10 Dec 2020 13:31:12 -0800 Subject: [PATCH 01/21] Merge pull request #7128 from tinyspeck/am_vtctld_proto Initial implementation of vtctld service --- examples/local/scripts/vtctld-up.sh | 2 +- go.mod | 5 +- go.sum | 63 ++++- go/cmd/vtctlclient/main.go | 2 +- go/cmd/vtctld/plugin_grpcvtctldserver.go | 30 ++ go/cmd/vtctldclient/commands.go | 55 ++++ go/cmd/vtctldclient/main.go | 96 +++++++ .../vtctldclient/plugin_grpcvtctldclient.go | 23 ++ go/vt/proto/vtctldata/vtctldata.pb.go | 267 ++++++++++++++++-- go/vt/proto/vtctlservice/vtctlservice.pb.go | 125 +++++++- go/vt/vtctl/grpcvtctldclient/client.go | 90 ++++++ go/vt/vtctl/grpcvtctldclient/client_test.go | 102 +++++++ go/vt/vtctl/grpcvtctldserver/server.go | 62 ++++ go/vt/vtctl/grpcvtctldserver/server_test.go | 87 ++++++ go/vt/vtctl/vtctl.go | 21 +- go/vt/vtctl/vtctldclient/client.go | 49 ++++ proto/vtctldata.proto | 21 ++ proto/vtctlservice.proto | 8 + 18 files changed, 1057 insertions(+), 51 deletions(-) create mode 100644 go/cmd/vtctld/plugin_grpcvtctldserver.go create mode 100644 go/cmd/vtctldclient/commands.go create mode 100644 go/cmd/vtctldclient/main.go create mode 100644 go/cmd/vtctldclient/plugin_grpcvtctldclient.go create mode 100644 go/vt/vtctl/grpcvtctldclient/client.go create mode 100644 go/vt/vtctl/grpcvtctldclient/client_test.go create mode 100644 go/vt/vtctl/grpcvtctldserver/server.go create mode 100644 go/vt/vtctl/grpcvtctldserver/server_test.go create mode 100644 go/vt/vtctl/vtctldclient/client.go diff --git a/examples/local/scripts/vtctld-up.sh b/examples/local/scripts/vtctld-up.sh index 662a234ae48..853e5dbc544 100755 --- a/examples/local/scripts/vtctld-up.sh +++ b/examples/local/scripts/vtctld-up.sh @@ -28,7 +28,7 @@ vtctld \ -cell $cell \ -workflow_manager_init \ -workflow_manager_use_election \ - -service_map 'grpc-vtctl' \ + -service_map 'grpc-vtctl,grpc-vtctld' \ -backup_storage_implementation file \ -file_backup_storage_root $VTDATAROOT/backups \ -log_dir $VTDATAROOT/tmp \ diff --git a/go.mod b/go.mod index f1b2d8186d2..63e23c4803d 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,6 @@ require ( github.com/coreos/bbolt v1.3.2 // indirect github.com/coreos/etcd v3.3.10+incompatible github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect - github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/corpix/uarand v0.1.1 // indirect github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432 github.com/evanphx/json-patch v4.5.0+incompatible @@ -34,7 +33,7 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.1.1 github.com/googleapis/gnostic v0.2.0 // indirect - github.com/gorilla/websocket v1.4.0 + github.com/gorilla/websocket v1.4.2 github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/hashicorp/consul/api v1.5.0 @@ -84,11 +83,9 @@ require ( github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b github.com/tebeka/selenium v0.9.9 github.com/tinylib/msgp v1.1.1 // indirect - github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect github.com/uber-go/atomic v1.4.0 // indirect github.com/uber/jaeger-client-go v2.16.0+incompatible github.com/uber/jaeger-lib v2.0.0+incompatible // indirect - github.com/ugorji/go v1.1.7 // indirect github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 golang.org/x/lint v0.0.0-20190409202823-959b441ac422 diff --git a/go.sum b/go.sum index c700b4a7578..04a800b8582 100644 --- a/go.sum +++ b/go.sum @@ -6,7 +6,11 @@ cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6A cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= @@ -47,6 +51,7 @@ github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2o github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -89,11 +94,14 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 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/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/buger/jsonparser v0.0.0-20200322175846-f7e751efca13 h1:+qUNY4VRkEH46bLUwxCyUU+iOGJMQBVibAaYzWiwWcg= github.com/buger/jsonparser v0.0.0-20200322175846-f7e751efca13/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= @@ -111,6 +119,8 @@ github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= @@ -128,6 +138,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/corpix/uarand v0.1.1 h1:RMr1TWc9F4n5jiPDzFHtmaUXLKLNUFK0SgCLo4BhX/U= github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432 h1:M5QgkYacWj0Xs8MhpIK/5uwU02icXpEoSo9sM2aRCps= github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432/go.mod h1:xwIwAxMvYnVrGJPe2FKx5prTrnAjGOD8zvDOnxnrrkM= @@ -139,6 +150,7 @@ 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/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/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -162,6 +174,7 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 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-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -224,6 +237,7 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -277,16 +291,22 @@ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORR github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= 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.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 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.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 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/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.5.0 h1:Yo2bneoGy68A7aNwmuETFnPhjyBEm7n3vzRacEVMjvI= github.com/hashicorp/consul/api v1.5.0/go.mod h1:LqwrLNW876eYSuUOo4ZLHBcdKc038txr/IMfbLPATa4= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.5.0 h1:WC4594Wp/LkEeML/OdQKEC1yqBmEYkRp6i7X5u0zDAs= github.com/hashicorp/consul/sdk v0.5.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= @@ -309,6 +329,7 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= @@ -322,6 +343,7 @@ github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1 github.com/hashicorp/go-uuid v1.0.1/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.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= @@ -329,11 +351,14 @@ github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG 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/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 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.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.2.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.2.2 h1:5+RffWKwqJ71YPu9mWsF7ZOscZmwfasdA8kbdC7AO2g= github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqBC7vbYU= github.com/hashicorp/serf v0.9.2 h1:yJoyfZXo4Pk2p/M/viW+YLibBFiIbKoP79gu7kDAFP0= github.com/hashicorp/serf v0.9.2/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= @@ -360,6 +385,7 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u 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 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -439,6 +465,7 @@ github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJu github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 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-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= @@ -447,6 +474,8 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/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= @@ -468,6 +497,7 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+ github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5 h1:58+kh9C6jJVXYjt8IE48G2eWl6BjwU5Gj0gqY84fy78= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5-0.20200416053754-163badb3bac6 h1:F721VBMijn0OBFZ5wUSuMVVLQj2IJiiupn6UNd7UbBE= @@ -514,6 +544,7 @@ github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prY github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= 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.1 h1:FFSuS004yOQEtDdTq+TAOLP5xUq63KqAFYyOi8zA+Y8= github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= @@ -522,14 +553,17 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= 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 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= 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/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= 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 h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE= 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 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -539,6 +573,7 @@ github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uY github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -549,6 +584,7 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh 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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -563,6 +599,7 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 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 v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= @@ -572,6 +609,8 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= 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= @@ -590,6 +629,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf 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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b h1:i3lm+BZX5fAaH95wJavMgsSYU95LhSxdNCMa8nLv2gk= github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tebeka/selenium v0.9.9 h1:cNziB+etNgyH/7KlNI7RMC1ua5aH1+5wUlFQyzeMh+w= @@ -608,11 +648,7 @@ github.com/uber/jaeger-client-go v2.16.0+incompatible h1:Q2Pp6v3QYiocMxomCaJuwQG github.com/uber/jaeger-client-go v2.16.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.0.0+incompatible h1:iMSCV0rmXEogjNWPh2D0xk9YVKvrtGoHJNe9ebLu/pw= github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -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 v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -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.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -624,6 +660,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b h1:Itr7GbuXoM1PK/eCeNNia4Qd3ib9IgX9g9SpXgo8BwQ= github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b/go.mod h1:JNALoWa+nCXR8SmgLluHcBNVJgyejzpKPZk9pX2yXXE= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= @@ -661,16 +698,25 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= 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/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -778,7 +824,9 @@ golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624190245-7f2218787638/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-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191219041853-979b82bfef62 h1:vDaiisQl0rGVXqk3wT2yc43gSnwlj4haEG5J78IGZP4= golang.org/x/tools v0.0.0-20191219041853-979b82bfef62/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -794,6 +842,8 @@ google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 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/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -807,8 +857,9 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195 h1:dWzgMaXfaHsnkRKZ1l3iJLDmTEB40JMl/dqRbJX4D/o= -google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/go/cmd/vtctlclient/main.go b/go/cmd/vtctlclient/main.go index 4d2fcbee368..339be1ac84d 100644 --- a/go/cmd/vtctlclient/main.go +++ b/go/cmd/vtctlclient/main.go @@ -33,7 +33,7 @@ import ( ) // The default values used by these flags cannot be taken from wrangler and -// actionnode modules, as we do't want to depend on them at all. +// actionnode modules, as we don't want to depend on them at all. var ( actionTimeout = flag.Duration("action_timeout", time.Hour, "timeout for the total command") server = flag.String("server", "", "server to use for connection") diff --git a/go/cmd/vtctld/plugin_grpcvtctldserver.go b/go/cmd/vtctld/plugin_grpcvtctldserver.go new file mode 100644 index 00000000000..ee5d0aba22a --- /dev/null +++ b/go/cmd/vtctld/plugin_grpcvtctldserver.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "vitess.io/vitess/go/vt/servenv" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" +) + +func init() { + servenv.OnRun(func() { + if servenv.GRPCCheckServiceMap("vtctld") { + grpcvtctldserver.StartServer(servenv.GRPCServer, ts) + } + }) +} diff --git a/go/cmd/vtctldclient/commands.go b/go/cmd/vtctldclient/commands.go new file mode 100644 index 00000000000..28c8d4c3e75 --- /dev/null +++ b/go/cmd/vtctldclient/commands.go @@ -0,0 +1,55 @@ +package main + +import ( + "fmt" + + "github.com/spf13/cobra" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + getKeyspaceCmd = &cobra.Command{ + Use: "GetKeyspace keyspace", + Aliases: []string{"getkeyspace"}, + Args: cobra.ExactArgs(1), + RunE: commandGetKeyspace, + } + getKeyspacesCmd = &cobra.Command{ + Use: "GetKeyspaces", + Aliases: []string{"getkeyspaces"}, + Args: cobra.NoArgs, + RunE: commandGetKeyspaces, + } +) + +func commandGetKeyspace(cmd *cobra.Command, args []string) error { + ks := cmd.Flags().Arg(0) + resp, err := client.GetKeyspace(commandCtx, &vtctldatapb.GetKeyspaceRequest{ + Keyspace: ks, + }) + + if err != nil { + return err + } + + fmt.Printf("%+v\n", resp.Keyspace) + + return nil +} + +func commandGetKeyspaces(cmd *cobra.Command, args []string) error { + resp, err := client.GetKeyspaces(commandCtx, &vtctldatapb.GetKeyspacesRequest{}) + if err != nil { + return err + } + + fmt.Printf("%+v\n", resp.Keyspaces) + + return nil +} + +func init() { + rootCmd.AddCommand(getKeyspaceCmd) + rootCmd.AddCommand(getKeyspacesCmd) +} diff --git a/go/cmd/vtctldclient/main.go b/go/cmd/vtctldclient/main.go new file mode 100644 index 00000000000..0d8412ee2d8 --- /dev/null +++ b/go/cmd/vtctldclient/main.go @@ -0,0 +1,96 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "errors" + "flag" + "io" + "os" + "time" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/exit" + "vitess.io/vitess/go/trace" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/vtctl/vtctldclient" +) + +var ( + client vtctldclient.VtctldClient + traceCloser io.Closer + commandCtx context.Context + commandCancel func() + + server string + actionTimeout time.Duration + + // We use cobra to make subcommands easier to manage. And do a hack below + // in main to grab the rest of the flags globally scattered to make sure we + // pick up things like common servenv flags, tracing flags, etc. Refer to + // commands.go for all of the subcommands. + rootCmd = &cobra.Command{ + // We use PersistentPreRun to set up the tracer, grpc client, and + // command context for every command. + PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { + traceCloser = trace.StartTracing("vtctldclient") + if server == "" { + err = errors.New("please specify -server to specify the vtctld server to connect to") + log.Error(err) + return err + } + + client, err = vtctldclient.New("grpc", server) + + commandCtx, commandCancel = context.WithTimeout(context.Background(), actionTimeout) + return err + }, + // Similarly, PersistentPostRun cleans up the resources spawned by + // PersistentPreRun. + PersistentPostRunE: func(cmd *cobra.Command, args []string) error { + commandCancel() + err := client.Close() + trace.LogErrorsWhenClosing(traceCloser) + return err + }, + TraverseChildren: true, + } +) + +func main() { + defer exit.Recover() + + // Grab all those global flags across the codebase and shove 'em on in. + rootCmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) + // Attach our local flags + rootCmd.PersistentFlags().StringVar(&server, "server", "", "server to use for connection") + rootCmd.PersistentFlags().DurationVar(&actionTimeout, "action_timeout", time.Hour, "timeout for the total command") + + // hack to get rid of an "ERROR: logging before flag.Parse" + args := os.Args[:] + os.Args = os.Args[:1] + flag.Parse() + os.Args = args + + // back to your regularly scheduled cobra programming + if err := rootCmd.Execute(); err != nil { + log.Error(err) + exit.Return(1) + } +} diff --git a/go/cmd/vtctldclient/plugin_grpcvtctldclient.go b/go/cmd/vtctldclient/plugin_grpcvtctldclient.go new file mode 100644 index 00000000000..ca5320855d2 --- /dev/null +++ b/go/cmd/vtctldclient/plugin_grpcvtctldclient.go @@ -0,0 +1,23 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +// Imports and register the gRPC vtctld client. + +import ( + _ "vitess.io/vitess/go/vt/vtctl/grpcvtctldclient" +) diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 8734dc87f02..1a663eb202b 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -9,6 +9,7 @@ import ( proto "github.com/golang/protobuf/proto" logutil "vitess.io/vitess/go/vt/proto/logutil" + topodata "vitess.io/vitess/go/vt/proto/topodata" ) // Reference imports to suppress errors if they are not otherwise used. @@ -111,6 +112,201 @@ func (m *ExecuteVtctlCommandResponse) GetEvent() *logutil.Event { return nil } +type GetKeyspacesRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetKeyspacesRequest) Reset() { *m = GetKeyspacesRequest{} } +func (m *GetKeyspacesRequest) String() string { return proto.CompactTextString(m) } +func (*GetKeyspacesRequest) ProtoMessage() {} +func (*GetKeyspacesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{2} +} + +func (m *GetKeyspacesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetKeyspacesRequest.Unmarshal(m, b) +} +func (m *GetKeyspacesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetKeyspacesRequest.Marshal(b, m, deterministic) +} +func (m *GetKeyspacesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetKeyspacesRequest.Merge(m, src) +} +func (m *GetKeyspacesRequest) XXX_Size() int { + return xxx_messageInfo_GetKeyspacesRequest.Size(m) +} +func (m *GetKeyspacesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetKeyspacesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetKeyspacesRequest proto.InternalMessageInfo + +type GetKeyspacesResponse struct { + Keyspaces []*Keyspace `protobuf:"bytes,1,rep,name=keyspaces,proto3" json:"keyspaces,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetKeyspacesResponse) Reset() { *m = GetKeyspacesResponse{} } +func (m *GetKeyspacesResponse) String() string { return proto.CompactTextString(m) } +func (*GetKeyspacesResponse) ProtoMessage() {} +func (*GetKeyspacesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{3} +} + +func (m *GetKeyspacesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetKeyspacesResponse.Unmarshal(m, b) +} +func (m *GetKeyspacesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetKeyspacesResponse.Marshal(b, m, deterministic) +} +func (m *GetKeyspacesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetKeyspacesResponse.Merge(m, src) +} +func (m *GetKeyspacesResponse) XXX_Size() int { + return xxx_messageInfo_GetKeyspacesResponse.Size(m) +} +func (m *GetKeyspacesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetKeyspacesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetKeyspacesResponse proto.InternalMessageInfo + +func (m *GetKeyspacesResponse) GetKeyspaces() []*Keyspace { + if m != nil { + return m.Keyspaces + } + return nil +} + +type GetKeyspaceRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetKeyspaceRequest) Reset() { *m = GetKeyspaceRequest{} } +func (m *GetKeyspaceRequest) String() string { return proto.CompactTextString(m) } +func (*GetKeyspaceRequest) ProtoMessage() {} +func (*GetKeyspaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{4} +} + +func (m *GetKeyspaceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetKeyspaceRequest.Unmarshal(m, b) +} +func (m *GetKeyspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetKeyspaceRequest.Marshal(b, m, deterministic) +} +func (m *GetKeyspaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetKeyspaceRequest.Merge(m, src) +} +func (m *GetKeyspaceRequest) XXX_Size() int { + return xxx_messageInfo_GetKeyspaceRequest.Size(m) +} +func (m *GetKeyspaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetKeyspaceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetKeyspaceRequest proto.InternalMessageInfo + +func (m *GetKeyspaceRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +type GetKeyspaceResponse struct { + Keyspace *Keyspace `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetKeyspaceResponse) Reset() { *m = GetKeyspaceResponse{} } +func (m *GetKeyspaceResponse) String() string { return proto.CompactTextString(m) } +func (*GetKeyspaceResponse) ProtoMessage() {} +func (*GetKeyspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{5} +} + +func (m *GetKeyspaceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetKeyspaceResponse.Unmarshal(m, b) +} +func (m *GetKeyspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetKeyspaceResponse.Marshal(b, m, deterministic) +} +func (m *GetKeyspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetKeyspaceResponse.Merge(m, src) +} +func (m *GetKeyspaceResponse) XXX_Size() int { + return xxx_messageInfo_GetKeyspaceResponse.Size(m) +} +func (m *GetKeyspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetKeyspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetKeyspaceResponse proto.InternalMessageInfo + +func (m *GetKeyspaceResponse) GetKeyspace() *Keyspace { + if m != nil { + return m.Keyspace + } + return nil +} + +type Keyspace struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Keyspace *topodata.Keyspace `protobuf:"bytes,2,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Keyspace) Reset() { *m = Keyspace{} } +func (m *Keyspace) String() string { return proto.CompactTextString(m) } +func (*Keyspace) ProtoMessage() {} +func (*Keyspace) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{6} +} + +func (m *Keyspace) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Keyspace.Unmarshal(m, b) +} +func (m *Keyspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Keyspace.Marshal(b, m, deterministic) +} +func (m *Keyspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_Keyspace.Merge(m, src) +} +func (m *Keyspace) XXX_Size() int { + return xxx_messageInfo_Keyspace.Size(m) +} +func (m *Keyspace) XXX_DiscardUnknown() { + xxx_messageInfo_Keyspace.DiscardUnknown(m) +} + +var xxx_messageInfo_Keyspace proto.InternalMessageInfo + +func (m *Keyspace) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Keyspace) GetKeyspace() *topodata.Keyspace { + if m != nil { + return m.Keyspace + } + return nil +} + // TableMaterializeSttings contains the settings for one table. type TableMaterializeSettings struct { TargetTable string `protobuf:"bytes,1,opt,name=target_table,json=targetTable,proto3" json:"target_table,omitempty"` @@ -129,7 +325,7 @@ func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettin func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } func (*TableMaterializeSettings) ProtoMessage() {} func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{2} + return fileDescriptor_f41247b323a1ab2e, []int{7} } func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -192,7 +388,7 @@ func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } func (*MaterializeSettings) ProtoMessage() {} func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{3} + return fileDescriptor_f41247b323a1ab2e, []int{8} } func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -265,6 +461,11 @@ func (m *MaterializeSettings) GetTabletTypes() string { func init() { proto.RegisterType((*ExecuteVtctlCommandRequest)(nil), "vtctldata.ExecuteVtctlCommandRequest") proto.RegisterType((*ExecuteVtctlCommandResponse)(nil), "vtctldata.ExecuteVtctlCommandResponse") + proto.RegisterType((*GetKeyspacesRequest)(nil), "vtctldata.GetKeyspacesRequest") + proto.RegisterType((*GetKeyspacesResponse)(nil), "vtctldata.GetKeyspacesResponse") + proto.RegisterType((*GetKeyspaceRequest)(nil), "vtctldata.GetKeyspaceRequest") + proto.RegisterType((*GetKeyspaceResponse)(nil), "vtctldata.GetKeyspaceResponse") + proto.RegisterType((*Keyspace)(nil), "vtctldata.Keyspace") proto.RegisterType((*TableMaterializeSettings)(nil), "vtctldata.TableMaterializeSettings") proto.RegisterType((*MaterializeSettings)(nil), "vtctldata.MaterializeSettings") } @@ -272,32 +473,38 @@ func init() { func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 422 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xd1, 0x6e, 0xd3, 0x30, - 0x14, 0x86, 0x95, 0xb5, 0x1b, 0xeb, 0x29, 0x4d, 0xc1, 0xdc, 0x58, 0x45, 0x48, 0xa1, 0xc0, 0x88, - 0x84, 0xd4, 0x48, 0xe3, 0x09, 0xa0, 0xf4, 0x06, 0xc4, 0x4d, 0xa8, 0x40, 0xe2, 0x26, 0x72, 0x93, - 0xb3, 0xc8, 0x9a, 0x1b, 0x07, 0xfb, 0xa4, 0x5b, 0x79, 0x03, 0x5e, 0x86, 0x67, 0x44, 0xb6, 0xb3, - 0x70, 0xb3, 0xdd, 0x1d, 0x7f, 0xe7, 0xb7, 0xfd, 0x9f, 0x5f, 0x07, 0xe6, 0x07, 0x2a, 0x49, 0x55, - 0x82, 0xc4, 0xaa, 0x35, 0x9a, 0x34, 0x9b, 0x0c, 0x60, 0x31, 0x53, 0xba, 0xee, 0x48, 0xaa, 0xd0, - 0x59, 0xfe, 0x80, 0xc5, 0xe6, 0x16, 0xcb, 0x8e, 0xf0, 0xbb, 0x93, 0xac, 0xf5, 0x7e, 0x2f, 0x9a, - 0x2a, 0xc7, 0x5f, 0x1d, 0x5a, 0x62, 0x0c, 0xc6, 0xc2, 0xd4, 0x96, 0x47, 0xc9, 0x28, 0x9d, 0xe4, - 0xbe, 0x66, 0x6f, 0x20, 0x16, 0x25, 0x49, 0xdd, 0x14, 0x24, 0xf7, 0xa8, 0x3b, 0xe2, 0x27, 0x49, - 0x94, 0x8e, 0xf2, 0x59, 0xa0, 0xdb, 0x00, 0x97, 0x6b, 0x78, 0x7e, 0xef, 0xc3, 0xb6, 0xd5, 0x8d, - 0x45, 0xf6, 0x1a, 0x4e, 0xf1, 0x80, 0x0d, 0xf1, 0x28, 0x89, 0xd2, 0xe9, 0x65, 0xbc, 0xba, 0xb3, - 0xb5, 0x71, 0x34, 0x0f, 0xcd, 0xe5, 0x9f, 0x08, 0xf8, 0x56, 0xec, 0x14, 0x7e, 0x15, 0x84, 0x46, - 0x0a, 0x25, 0x7f, 0xe3, 0x37, 0x24, 0x92, 0x4d, 0x6d, 0xd9, 0x4b, 0x78, 0x4c, 0xc2, 0xd4, 0x48, - 0x05, 0x39, 0x89, 0x7f, 0x69, 0x92, 0x4f, 0x03, 0xf3, 0xb7, 0xd8, 0x3b, 0x78, 0x6a, 0x75, 0x67, - 0x4a, 0x2c, 0xf0, 0xb6, 0x35, 0x68, 0xad, 0xd4, 0x8d, 0xb7, 0x3b, 0xc9, 0x9f, 0x84, 0xc6, 0x66, - 0xe0, 0xec, 0x05, 0x40, 0x69, 0x50, 0x10, 0x16, 0x55, 0xa5, 0xf8, 0xc8, 0xab, 0x26, 0x81, 0x7c, - 0xaa, 0xd4, 0xf2, 0xef, 0x09, 0x3c, 0xbb, 0xcf, 0xc6, 0x02, 0xce, 0x6f, 0xb4, 0xb9, 0xbe, 0x52, - 0xfa, 0xa6, 0xb7, 0x30, 0x9c, 0xd9, 0x5b, 0x98, 0xf7, 0xff, 0x5f, 0xe3, 0xd1, 0xb6, 0xa2, 0xc4, - 0xfe, 0xf7, 0x38, 0xe0, 0x2f, 0x3d, 0x75, 0xc2, 0x7e, 0x96, 0x41, 0x18, 0x0c, 0xc4, 0x01, 0x0f, - 0xc2, 0x0b, 0x98, 0x5b, 0xd2, 0x6d, 0x21, 0xae, 0x08, 0x4d, 0x51, 0xea, 0xf6, 0xc8, 0xc7, 0x49, - 0x94, 0x9e, 0xe7, 0x33, 0x87, 0x3f, 0x38, 0xba, 0xd6, 0xed, 0x91, 0x7d, 0x86, 0xd8, 0xa7, 0x52, - 0xd8, 0xde, 0x27, 0x3f, 0x4d, 0x46, 0xe9, 0xf4, 0xf2, 0xd5, 0xea, 0xff, 0x6e, 0x3c, 0x94, 0x6c, - 0x3e, 0xf3, 0x57, 0x87, 0x09, 0x19, 0x8c, 0x4b, 0x54, 0x8a, 0x9f, 0x79, 0x47, 0xbe, 0x0e, 0xe1, - 0xef, 0x94, 0x0b, 0xff, 0xd8, 0xa2, 0xe5, 0x8f, 0xee, 0xc2, 0x77, 0x6c, 0xeb, 0xd0, 0xc7, 0xf4, - 0xe7, 0xc5, 0x41, 0x12, 0x5a, 0xbb, 0x92, 0x3a, 0x0b, 0x55, 0x56, 0xeb, 0xec, 0x40, 0x99, 0x5f, - 0xbd, 0x6c, 0x30, 0xb2, 0x3b, 0xf3, 0xe0, 0xfd, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x46, 0x37, - 0xd0, 0x53, 0xb8, 0x02, 0x00, 0x00, + // 514 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x93, 0xdf, 0x8e, 0xd2, 0x40, + 0x14, 0xc6, 0x53, 0x60, 0x57, 0x7a, 0x90, 0xa2, 0x83, 0x26, 0x0d, 0xc6, 0x04, 0xab, 0xee, 0x92, + 0x98, 0xb4, 0xba, 0x3e, 0x81, 0x22, 0x1a, 0x35, 0x7a, 0x51, 0x89, 0x26, 0xde, 0x34, 0x43, 0x39, + 0x4b, 0x9a, 0x1d, 0x3a, 0xb5, 0x73, 0xca, 0x2e, 0xbe, 0x81, 0x2f, 0xe3, 0x33, 0x9a, 0xce, 0xb4, + 0x05, 0x0c, 0x7b, 0x77, 0xe6, 0x37, 0xe7, 0xcf, 0x77, 0xbe, 0x69, 0x61, 0xb0, 0xa1, 0x98, 0xc4, + 0x92, 0x13, 0xf7, 0xb3, 0x5c, 0x92, 0x64, 0x76, 0x03, 0x46, 0x7d, 0x21, 0x57, 0x05, 0x25, 0xc2, + 0xdc, 0x8c, 0x1c, 0x92, 0x99, 0xdc, 0x65, 0x7a, 0x3f, 0x60, 0x34, 0xbb, 0xc1, 0xb8, 0x20, 0xfc, + 0x5e, 0x96, 0x4c, 0xe5, 0x7a, 0xcd, 0xd3, 0x65, 0x88, 0xbf, 0x0a, 0x54, 0xc4, 0x18, 0x74, 0x78, + 0xbe, 0x52, 0xae, 0x35, 0x6e, 0x4f, 0xec, 0x50, 0xc7, 0xec, 0x39, 0x38, 0x3c, 0xa6, 0x44, 0xa6, + 0x11, 0x25, 0x6b, 0x94, 0x05, 0xb9, 0xad, 0xb1, 0x35, 0x69, 0x87, 0x7d, 0x43, 0xe7, 0x06, 0x7a, + 0x53, 0x78, 0x74, 0xb4, 0xb1, 0xca, 0x64, 0xaa, 0x90, 0x3d, 0x83, 0x13, 0xdc, 0x60, 0x4a, 0xae, + 0x35, 0xb6, 0x26, 0xbd, 0x0b, 0xc7, 0xaf, 0x65, 0xce, 0x4a, 0x1a, 0x9a, 0x4b, 0xef, 0x21, 0x0c, + 0x3f, 0x20, 0x7d, 0xc6, 0xad, 0xca, 0x78, 0x8c, 0xaa, 0x92, 0xe5, 0x7d, 0x84, 0x07, 0x87, 0xb8, + 0x6a, 0xfa, 0x0a, 0xec, 0xab, 0x1a, 0x6a, 0xcd, 0xbd, 0x8b, 0xa1, 0xbf, 0xf3, 0xa6, 0x2e, 0x08, + 0x77, 0x59, 0xde, 0x4b, 0x60, 0x7b, 0xad, 0xea, 0xbd, 0x47, 0xd0, 0xad, 0x53, 0xb4, 0x40, 0x3b, + 0x6c, 0xce, 0xde, 0xfb, 0x03, 0x4d, 0xcd, 0xec, 0xe0, 0xbf, 0x92, 0x5b, 0x46, 0xef, 0xfa, 0x7c, + 0x85, 0x6e, 0x4d, 0x4b, 0x9f, 0x53, 0xbe, 0xae, 0x67, 0xe9, 0x98, 0xf9, 0x7b, 0x0d, 0x5b, 0xba, + 0x21, 0xf3, 0x9b, 0xc7, 0x3b, 0xd2, 0xef, 0x8f, 0x05, 0xee, 0x9c, 0x2f, 0x04, 0x7e, 0xe1, 0x84, + 0x79, 0xc2, 0x45, 0xf2, 0x1b, 0xbf, 0x21, 0x51, 0x92, 0xae, 0x14, 0x7b, 0x02, 0x77, 0x89, 0xe7, + 0x2b, 0xa4, 0x88, 0xca, 0x94, 0x6a, 0x50, 0xcf, 0x30, 0x5d, 0xc5, 0x5e, 0xc0, 0x7d, 0x25, 0x8b, + 0x3c, 0xc6, 0x08, 0x6f, 0xb2, 0x1c, 0x95, 0x4a, 0x64, 0xaa, 0x07, 0xdb, 0xe1, 0x3d, 0x73, 0x31, + 0x6b, 0x38, 0x7b, 0x0c, 0x10, 0xe7, 0xc8, 0x09, 0xa3, 0xe5, 0x52, 0xb8, 0x6d, 0x9d, 0x65, 0x1b, + 0xf2, 0x6e, 0x29, 0xbc, 0xbf, 0x2d, 0x18, 0x1e, 0x93, 0x31, 0x82, 0xee, 0xb5, 0xcc, 0xaf, 0x2e, + 0x85, 0xbc, 0xae, 0x7d, 0xad, 0xcf, 0xec, 0x1c, 0x06, 0xd5, 0xfc, 0x83, 0xb5, 0xed, 0xd0, 0x31, + 0xb8, 0x31, 0xeb, 0x1c, 0x06, 0xd5, 0x2e, 0x4d, 0xa2, 0x11, 0xe0, 0x18, 0xdc, 0x24, 0x9e, 0xc1, + 0x40, 0x91, 0xcc, 0x22, 0x7e, 0x49, 0x98, 0x47, 0xb1, 0xcc, 0xb6, 0x6e, 0x67, 0x6c, 0x4d, 0xba, + 0x61, 0xbf, 0xc4, 0x6f, 0x4a, 0x3a, 0x95, 0xd9, 0x96, 0x7d, 0x02, 0x47, 0xbb, 0x12, 0xa9, 0x4a, + 0xa7, 0x7b, 0xa2, 0xbf, 0x9d, 0xa7, 0x7b, 0x0f, 0x78, 0x9b, 0xb3, 0x61, 0x5f, 0x97, 0x36, 0x1b, + 0x32, 0xe8, 0xc4, 0x28, 0x84, 0x7b, 0x6a, 0x5e, 0xb2, 0x8c, 0x8d, 0xf9, 0x0b, 0x51, 0x9a, 0xbf, + 0xcd, 0x50, 0xb9, 0x77, 0x6a, 0xf3, 0x4b, 0x36, 0x2f, 0xd1, 0xdb, 0xc9, 0xcf, 0xb3, 0x4d, 0x42, + 0xa8, 0x94, 0x9f, 0xc8, 0xc0, 0x44, 0xc1, 0x4a, 0x06, 0x1b, 0x0a, 0xf4, 0x6f, 0x1a, 0x34, 0x42, + 0x16, 0xa7, 0x1a, 0xbc, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x85, 0x52, 0x57, 0xf4, 0x03, + 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index d661e476922..88c608dd5de 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,17 +29,20 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 146 bytes of a gzipped FileDescriptorProto + // 201 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x2b, 0x49, 0x2e, 0xc9, 0x29, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x41, 0x16, 0x93, 0xe2, 0x07, 0xf3, 0x52, 0x12, 0x4b, 0x12, 0x21, 0xd2, 0x46, 0x85, 0x5c, 0xac, 0x61, 0x20, 0x21, 0xa1, 0x0c, 0x2e, 0x61, 0xd7, 0x8a, 0xd4, 0xe4, 0xd2, 0x92, 0x54, 0x30, 0xdf, 0x39, 0x3f, 0x37, 0x37, 0x31, 0x2f, 0x45, 0x48, 0x55, 0x0f, 0xa1, 0x03, 0x8b, 0x7c, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89, 0x94, 0x1a, 0x21, 0x65, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x4a, - 0x0c, 0x06, 0x8c, 0x4e, 0xda, 0x51, 0x9a, 0x65, 0x99, 0x25, 0xa9, 0xc5, 0xc5, 0x7a, 0x99, 0xf9, - 0xfa, 0x10, 0x96, 0x7e, 0x7a, 0xbe, 0x7e, 0x59, 0x89, 0x3e, 0xd8, 0x49, 0xfa, 0xc8, 0x0e, 0x4e, - 0x62, 0x03, 0x8b, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x9d, 0xb5, 0x06, 0x92, 0xdb, 0x00, - 0x00, 0x00, + 0x0c, 0x06, 0x8c, 0x46, 0xab, 0x19, 0xb9, 0xd8, 0xc0, 0x92, 0x29, 0x42, 0x7e, 0x5c, 0xdc, 0xee, + 0xa9, 0x25, 0xde, 0xa9, 0x95, 0xc5, 0x05, 0x89, 0xc9, 0xa9, 0x42, 0xb2, 0x48, 0xa6, 0x20, 0x89, + 0xc3, 0x2c, 0x91, 0xc3, 0x25, 0x0d, 0x33, 0x5c, 0x28, 0x90, 0x8b, 0x07, 0x49, 0xa2, 0x58, 0x08, + 0x87, 0x8e, 0x62, 0x98, 0x89, 0xf2, 0x38, 0xe5, 0x61, 0x46, 0x3a, 0x69, 0x47, 0x69, 0x96, 0x65, + 0x96, 0xa4, 0x16, 0x17, 0xeb, 0x65, 0xe6, 0xeb, 0x43, 0x58, 0xfa, 0xe9, 0xf9, 0xfa, 0x65, 0x25, + 0xfa, 0xe0, 0x00, 0xd4, 0x47, 0x0e, 0xde, 0x24, 0x36, 0xb0, 0x98, 0x31, 0x20, 0x00, 0x00, 0xff, + 0xff, 0xf0, 0x37, 0xf3, 0x26, 0x89, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -148,3 +151,115 @@ var _Vtctl_serviceDesc = grpc.ServiceDesc{ }, Metadata: "vtctlservice.proto", } + +// VtctldClient is the client API for Vtctld service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type VtctldClient interface { + // GetKeyspace reads the given keyspace from the topo and returns it. + GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) + // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. + GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspacesRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspacesResponse, error) +} + +type vtctldClient struct { + cc *grpc.ClientConn +} + +func NewVtctldClient(cc *grpc.ClientConn) VtctldClient { + return &vtctldClient{cc} +} + +func (c *vtctldClient) GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) { + out := new(vtctldata.GetKeyspaceResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetKeyspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspacesRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspacesResponse, error) { + out := new(vtctldata.GetKeyspacesResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetKeyspaces", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VtctldServer is the server API for Vtctld service. +type VtctldServer interface { + // GetKeyspace reads the given keyspace from the topo and returns it. + GetKeyspace(context.Context, *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) + // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. + GetKeyspaces(context.Context, *vtctldata.GetKeyspacesRequest) (*vtctldata.GetKeyspacesResponse, error) +} + +// UnimplementedVtctldServer can be embedded to have forward compatible implementations. +type UnimplementedVtctldServer struct { +} + +func (*UnimplementedVtctldServer) GetKeyspace(ctx context.Context, req *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetKeyspace not implemented") +} +func (*UnimplementedVtctldServer) GetKeyspaces(ctx context.Context, req *vtctldata.GetKeyspacesRequest) (*vtctldata.GetKeyspacesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetKeyspaces not implemented") +} + +func RegisterVtctldServer(s *grpc.Server, srv VtctldServer) { + s.RegisterService(&_Vtctld_serviceDesc, srv) +} + +func _Vtctld_GetKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetKeyspaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetKeyspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetKeyspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetKeyspace(ctx, req.(*vtctldata.GetKeyspaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_GetKeyspaces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetKeyspacesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetKeyspaces(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetKeyspaces", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetKeyspaces(ctx, req.(*vtctldata.GetKeyspacesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Vtctld_serviceDesc = grpc.ServiceDesc{ + ServiceName: "vtctlservice.Vtctld", + HandlerType: (*VtctldServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetKeyspace", + Handler: _Vtctld_GetKeyspace_Handler, + }, + { + MethodName: "GetKeyspaces", + Handler: _Vtctld_GetKeyspaces_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "vtctlservice.proto", +} diff --git a/go/vt/vtctl/grpcvtctldclient/client.go b/go/vt/vtctl/grpcvtctldclient/client.go new file mode 100644 index 00000000000..306a8ecacb0 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldclient/client.go @@ -0,0 +1,90 @@ +// Package grpcvtctldclient contains the gRPC version of the vtctld client +// protocol. +package grpcvtctldclient + +import ( + "context" + "flag" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "vitess.io/vitess/go/vt/grpcclient" + "vitess.io/vitess/go/vt/vtctl/vtctldclient" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" +) + +const connClosedMsg = "grpc: the client connection is closed" + +// (TODO:@amason) - These flags match exactly the flags used in grpcvtctlclient. +// If a program attempts to import both of these packages, it will panic during +// startup due to the duplicate flags. +// +// For everything else I've been doing a sed s/vtctl/vtctld, but I cannot do +// that here, since these flags are already "vtctld_*". My other options are to +// name them "vtctld2_*" or to omit them completely. +// +// Not to pitch project ideas in comments, but a nice project to solve +var ( + cert = flag.String("vtctld_grpc_cert", "", "the cert to use to connect") + key = flag.String("vtctld_grpc_key", "", "the key to use to connect") + ca = flag.String("vtctld_grpc_ca", "", "the server ca to use to validate servers when connecting") + name = flag.String("vtctld_grpc_server_name", "", "the server name to use to validate server certificate") +) + +type gRPCVtctldClient struct { + cc *grpc.ClientConn + c vtctlservicepb.VtctldClient +} + +func gRPCVtctldClientFactory(addr string) (vtctldclient.VtctldClient, error) { + opt, err := grpcclient.SecureDialOption(*cert, *key, *ca, *name) + if err != nil { + return nil, err + } + + conn, err := grpcclient.Dial(addr, grpcclient.FailFast(false), opt) + if err != nil { + return nil, err + } + + return &gRPCVtctldClient{ + cc: conn, + c: vtctlservicepb.NewVtctldClient(conn), + }, nil +} + +func (client *gRPCVtctldClient) Close() error { + err := client.cc.Close() + if err == nil { + client.c = nil + } + + return err +} + +// (TODO:@amason) - This boilerplate should end up the same for all ~70 commands +// .... we should do this with code gen. + +func (client *gRPCVtctldClient) GetKeyspace(ctx context.Context, in *vtctldatapb.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.GetKeyspaceResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetKeyspace(ctx, in, opts...) +} + +func (client *gRPCVtctldClient) GetKeyspaces(ctx context.Context, in *vtctldatapb.GetKeyspacesRequest, opts ...grpc.CallOption) (*vtctldatapb.GetKeyspacesResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetKeyspaces(ctx, in, opts...) +} + +func init() { + vtctldclient.Register("grpc", gRPCVtctldClientFactory) +} diff --git a/go/vt/vtctl/grpcvtctldclient/client_test.go b/go/vt/vtctl/grpcvtctldclient/client_test.go new file mode 100644 index 00000000000..77a0941c6d7 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldclient/client_test.go @@ -0,0 +1,102 @@ +package grpcvtctldclient_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/net/nettest" + "google.golang.org/grpc" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" + "vitess.io/vitess/go/vt/vtctl/vtctldclient" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" +) + +func withTestServer( + t *testing.T, + server vtctlservicepb.VtctldServer, + test func(t *testing.T, addr string), +) { + lis, err := nettest.NewLocalListener("tcp") + require.NoError(t, err, "cannot create nettest listener") + defer lis.Close() + + s := grpc.NewServer() + vtctlservicepb.RegisterVtctldServer(s, server) + + go s.Serve(lis) + defer s.Stop() + + test(t, lis.Addr().String()) +} + +func TestGetKeyspace(t *testing.T) { + ctx := context.Background() + + ts := memorytopo.NewServer("cell1") + vtctld := grpcvtctldserver.NewVtctldServer(ts) + + withTestServer(t, vtctld, func(t *testing.T, addr string) { + client, err := vtctldclient.New("grpc", addr) + require.NoError(t, err) + + expected := &vtctldatapb.GetKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{ + ShardingColumnName: "col1", + }, + }, + } + in := *expected.Keyspace.Keyspace + + err = ts.CreateKeyspace(ctx, expected.Keyspace.Name, &in) + require.NoError(t, err) + + resp, err := client.GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{Keyspace: expected.Keyspace.Name}) + assert.NoError(t, err) + assert.Equal(t, expected, resp) + + client.Close() + _, err = client.GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{}) + assert.Error(t, err) + }) +} + +func TestGetKeyspaces(t *testing.T) { + ctx := context.Background() + + ts := memorytopo.NewServer("cell1") + vtctld := grpcvtctldserver.NewVtctldServer(ts) + + withTestServer(t, vtctld, func(t *testing.T, addr string) { + client, err := vtctldclient.New("grpc", addr) + require.NoError(t, err) + + resp, err := client.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) + assert.NoError(t, err) + assert.Empty(t, resp.Keyspaces) + + expected := &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + } + in := *expected.Keyspace + + err = ts.CreateKeyspace(ctx, expected.Name, &in) + require.NoError(t, err) + + resp, err = client.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) + assert.NoError(t, err) + assert.Equal(t, []*vtctldatapb.Keyspace{expected}, resp.Keyspaces) + + client.Close() + _, err = client.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) + assert.Error(t, err) + }) +} diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go new file mode 100644 index 00000000000..797a347d142 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -0,0 +1,62 @@ +package grpcvtctldserver + +import ( + "context" + + "google.golang.org/grpc" + "vitess.io/vitess/go/vt/topo" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" +) + +// VtctldServer implements the Vtctld RPC service protocol. +type VtctldServer struct { + ts *topo.Server +} + +// NewVtctldServer returns a new VtctldServer for the given topo server. +func NewVtctldServer(ts *topo.Server) *VtctldServer { + return &VtctldServer{ts: ts} +} + +// GetKeyspace is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetKeyspace(ctx context.Context, req *vtctldatapb.GetKeyspaceRequest) (*vtctldatapb.GetKeyspaceResponse, error) { + keyspace, err := s.ts.GetKeyspace(ctx, req.Keyspace) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: req.Keyspace, + Keyspace: keyspace.Keyspace, + }, + }, nil +} + +// GetKeyspaces is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetKeyspaces(ctx context.Context, req *vtctldatapb.GetKeyspacesRequest) (*vtctldatapb.GetKeyspacesResponse, error) { + names, err := s.ts.GetKeyspaces(ctx) + if err != nil { + return nil, err + } + + keyspaces := make([]*vtctldatapb.Keyspace, len(names)) + + for i, name := range names { + ks, err := s.GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{Keyspace: name}) + if err != nil { + return nil, err + } + + keyspaces[i] = ks.Keyspace + } + + return &vtctldatapb.GetKeyspacesResponse{Keyspaces: keyspaces}, nil +} + +// StartServer registers a VtctldServer for RPCs on the given gRPC server. +func StartServer(s *grpc.Server, ts *topo.Server) { + vtctlservicepb.RegisterVtctldServer(s, NewVtctldServer(ts)) +} diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go new file mode 100644 index 00000000000..504191ed19d --- /dev/null +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -0,0 +1,87 @@ +package grpcvtctldserver + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +func TestGetKeyspace(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + vtctld := NewVtctldServer(ts) + + expected := &vtctldatapb.GetKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{ + ShardingColumnName: "col1", + }, + }, + } + addKeyspace(ctx, t, ts, expected.Keyspace) + + ks, err := vtctld.GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{Keyspace: expected.Keyspace.Name}) + assert.NoError(t, err) + assert.Equal(t, expected, ks) + + _, err = vtctld.GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{Keyspace: "notfound"}) + assert.Error(t, err) +} + +func addKeyspace(ctx context.Context, t *testing.T, ts *topo.Server, ks *vtctldatapb.Keyspace) { + in := *ks.Keyspace // take a copy to avoid the XXX_ fields changing + + err := ts.CreateKeyspace(ctx, ks.Name, &in) + require.NoError(t, err) +} + +func TestGetKeyspaces(t *testing.T) { + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory("cell1") + vtctld := NewVtctldServer(ts) + + resp, err := vtctld.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) + assert.NoError(t, err) + assert.Empty(t, resp.Keyspaces) + + expected := []*vtctldatapb.Keyspace{ + { + Name: "ks1", + Keyspace: &topodatapb.Keyspace{ + ShardingColumnName: "ks1_col1", + }, + }, + { + Name: "ks2", + Keyspace: &topodatapb.Keyspace{ + ShardingColumnName: "ks2_col1", + }, + }, + { + Name: "ks3", + Keyspace: &topodatapb.Keyspace{ + ShardingColumnName: "ks3_col1", + }, + }, + } + for _, ks := range expected { + addKeyspace(ctx, t, ts, ks) + } + + resp, err = vtctld.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) + assert.NoError(t, err) + assert.Equal(t, expected, resp.Keyspaces) + + topofactory.SetError(errors.New("error from toposerver")) + _, err = vtctld.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) + assert.Error(t, err) +} diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 2c9f7333954..f5faa408f32 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -112,6 +112,7 @@ import ( "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/wrangler" @@ -1773,20 +1774,32 @@ func commandGetKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl } keyspace := subFlags.Arg(0) - keyspaceInfo, err := wr.TopoServer().GetKeyspace(ctx, keyspace) + + // TODO: make vtctld a field of the wrangler + vtctld := grpcvtctldserver.NewVtctldServer(wr.TopoServer()) + keyspaceInfo, err := vtctld.GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{ + Keyspace: keyspace, + }) if err != nil { return err } // Pass the embedded proto directly or jsonpb will panic. - return printJSON(wr.Logger(), keyspaceInfo.Keyspace) + return printJSON(wr.Logger(), keyspaceInfo.Keyspace.Keyspace) } func commandGetKeyspaces(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { - keyspaces, err := wr.TopoServer().GetKeyspaces(ctx) + vtctld := grpcvtctldserver.NewVtctldServer(wr.TopoServer()) + resp, err := vtctld.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) if err != nil { return err } - wr.Logger().Printf("%v\n", strings.Join(keyspaces, "\n")) + + names := make([]string, len(resp.Keyspaces)) + for i, ks := range resp.Keyspaces { + names[i] = ks.Name + } + + wr.Logger().Printf("%v\n", strings.Join(names, "\n")) return nil } diff --git a/go/vt/vtctl/vtctldclient/client.go b/go/vt/vtctl/vtctldclient/client.go new file mode 100644 index 00000000000..e064b8bd9ae --- /dev/null +++ b/go/vt/vtctl/vtctldclient/client.go @@ -0,0 +1,49 @@ +// Package vtctldclient contains the generic client side of the remote vtctld +// protocol. +package vtctldclient + +import ( + "fmt" + "log" + + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" +) + +// VtctldClient augments the vtctlservicepb.VtctlClient interface with io.Closer. +type VtctldClient interface { + vtctlservicepb.VtctldClient + Close() error +} + +// Factory is a function that creates new VtctldClients. +type Factory func(addr string) (VtctldClient, error) + +var registry = map[string]Factory{} + +// Register adds a VtctldClient factory for the given name (protocol). +// Attempting to register mulitple factories for the same protocol is a fatal +// error. +func Register(name string, factory Factory) { + if _, ok := registry[name]; ok { + log.Fatalf("Register: %s already registered", name) + } + + registry[name] = factory +} + +// New returns a VtctldClient for the given protocol, connected to a +// VtctldServer on the given addr. This function returns an error if no client +// factory was registered for the given protocol. +// +// This is a departure from vtctlclient's New, which relies on a flag in the +// global namespace to determine the protocol to use. Instead, we require +// users to specify their own flag in their own (hopefully not global) namespace +// to determine the protocol to pass into here. +func New(protocol string, addr string) (VtctldClient, error) { + factory, ok := registry[protocol] + if !ok { + return nil, fmt.Errorf("unknown vtctld client protocol: %s", protocol) + } + + return factory(addr) +} diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 0e8fa1a2553..db151d3b11d 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -23,6 +23,7 @@ option go_package = "vitess.io/vitess/go/vt/proto/vtctldata"; package vtctldata; import "logutil.proto"; +import "topodata.proto"; // ExecuteVtctlCommandRequest is the payload for ExecuteVtctlCommand. // timeouts are in nanoseconds. @@ -36,6 +37,26 @@ message ExecuteVtctlCommandResponse { logutil.Event event = 1; } +message GetKeyspacesRequest { +} + +message GetKeyspacesResponse { + repeated Keyspace keyspaces = 1; +} + +message GetKeyspaceRequest { + string keyspace = 1; +} + +message GetKeyspaceResponse { + Keyspace keyspace = 1; +} + +message Keyspace { + string name = 1; + topodata.Keyspace keyspace = 2; +} + // TableMaterializeSttings contains the settings for one table. message TableMaterializeSettings { string target_table = 1; diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 07cd70b3c3a..8b4d2b79c02 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -28,3 +28,11 @@ import "vtctldata.proto"; service Vtctl { rpc ExecuteVtctlCommand (vtctldata.ExecuteVtctlCommandRequest) returns (stream vtctldata.ExecuteVtctlCommandResponse) {}; } + +// Service Vtctld exposes gRPC endpoints for each vt command. +service Vtctld { + // GetKeyspace reads the given keyspace from the topo and returns it. + rpc GetKeyspace(vtctldata.GetKeyspaceRequest) returns (vtctldata.GetKeyspaceResponse) {}; + // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. + rpc GetKeyspaces(vtctldata.GetKeyspacesRequest) returns (vtctldata.GetKeyspacesResponse) {}; +} From 8e9f0dcb8abee08bc1421ce2363b30a819f0801d Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Sun, 10 Jan 2021 18:49:23 -0500 Subject: [PATCH 02/21] Commit go.sum change after running `make build` Signed-off-by: Andrew Mason --- go.sum | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.sum b/go.sum index 04a800b8582..9a187c01309 100644 --- a/go.sum +++ b/go.sum @@ -858,6 +858,8 @@ google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dT google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195 h1:dWzgMaXfaHsnkRKZ1l3iJLDmTEB40JMl/dqRbJX4D/o= +google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= From 82ceba0d106c9c0e91b4b880cef4a939b3d4b0a0 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Wed, 23 Dec 2020 21:41:52 +0100 Subject: [PATCH 03/21] Merge pull request #7201 from tinyspeck/am_find_all_shards_in_keyspace Add FindAllShardsInKeyspace to vtctldserver --- go/cmd/vtctldclient/commands.go | 43 ++++ go/cmd/vtctldclient/main.go | 2 +- .../vtctldclient/plugin_grpcvtctldclient.go | 2 +- go/vt/proto/vtctldata/vtctldata.pb.go | 216 +++++++++++++++--- go/vt/proto/vtctlservice/vtctlservice.pb.go | 56 ++++- go/vt/vtctl/grpcvtctldclient/client.go | 24 ++ go/vt/vtctl/grpcvtctldclient/client_test.go | 99 ++++++-- go/vt/vtctl/grpcvtctldserver/server.go | 37 +++ go/vt/vtctl/grpcvtctldserver/server_test.go | 56 +++++ go/vt/vtctl/vtctl.go | 15 +- go/vt/wrangler/wrangler.go | 11 + proto/vtctldata.proto | 14 ++ proto/vtctlservice.proto | 2 + 13 files changed, 504 insertions(+), 73 deletions(-) diff --git a/go/cmd/vtctldclient/commands.go b/go/cmd/vtctldclient/commands.go index 28c8d4c3e75..951b04f8679 100644 --- a/go/cmd/vtctldclient/commands.go +++ b/go/cmd/vtctldclient/commands.go @@ -1,6 +1,23 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package main import ( + "encoding/json" "fmt" "github.com/spf13/cobra" @@ -9,6 +26,12 @@ import ( ) var ( + findAllShardsInKeyspaceCmd = &cobra.Command{ + Use: "FindAllShardsInKeyspace keyspace", + Aliases: []string{"findallshardsinkeyspace"}, + Args: cobra.ExactArgs(1), + RunE: commandFindAllShardsInKeyspace, + } getKeyspaceCmd = &cobra.Command{ Use: "GetKeyspace keyspace", Aliases: []string{"getkeyspace"}, @@ -23,6 +46,25 @@ var ( } ) +func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { + ks := cmd.Flags().Arg(0) + resp, err := client.FindAllShardsInKeyspace(commandCtx, &vtctldatapb.FindAllShardsInKeyspaceRequest{ + Keyspace: ks, + }) + + if err != nil { + return err + } + + data, err := json.Marshal(&resp) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + return nil +} + func commandGetKeyspace(cmd *cobra.Command, args []string) error { ks := cmd.Flags().Arg(0) resp, err := client.GetKeyspace(commandCtx, &vtctldatapb.GetKeyspaceRequest{ @@ -50,6 +92,7 @@ func commandGetKeyspaces(cmd *cobra.Command, args []string) error { } func init() { + rootCmd.AddCommand(findAllShardsInKeyspaceCmd) rootCmd.AddCommand(getKeyspaceCmd) rootCmd.AddCommand(getKeyspacesCmd) } diff --git a/go/cmd/vtctldclient/main.go b/go/cmd/vtctldclient/main.go index 0d8412ee2d8..f00eee7a410 100644 --- a/go/cmd/vtctldclient/main.go +++ b/go/cmd/vtctldclient/main.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors. +Copyright 2020 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/cmd/vtctldclient/plugin_grpcvtctldclient.go b/go/cmd/vtctldclient/plugin_grpcvtctldclient.go index ca5320855d2..e93c2a6e700 100644 --- a/go/cmd/vtctldclient/plugin_grpcvtctldclient.go +++ b/go/cmd/vtctldclient/plugin_grpcvtctldclient.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors. +Copyright 2020 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 1a663eb202b..aba0d093fd3 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -307,6 +307,139 @@ func (m *Keyspace) GetKeyspace() *topodata.Keyspace { return nil } +type FindAllShardsInKeyspaceRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInKeyspaceRequest{} } +func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } +func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} +func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{7} +} + +func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Unmarshal(m, b) +} +func (m *FindAllShardsInKeyspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Marshal(b, m, deterministic) +} +func (m *FindAllShardsInKeyspaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_FindAllShardsInKeyspaceRequest.Merge(m, src) +} +func (m *FindAllShardsInKeyspaceRequest) XXX_Size() int { + return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Size(m) +} +func (m *FindAllShardsInKeyspaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_FindAllShardsInKeyspaceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_FindAllShardsInKeyspaceRequest proto.InternalMessageInfo + +func (m *FindAllShardsInKeyspaceRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +type FindAllShardsInKeyspaceResponse struct { + Shards map[string]*Shard `protobuf:"bytes,1,rep,name=shards,proto3" json:"shards,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsInKeyspaceResponse{} } +func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } +func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} +func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{8} +} + +func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Unmarshal(m, b) +} +func (m *FindAllShardsInKeyspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Marshal(b, m, deterministic) +} +func (m *FindAllShardsInKeyspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_FindAllShardsInKeyspaceResponse.Merge(m, src) +} +func (m *FindAllShardsInKeyspaceResponse) XXX_Size() int { + return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Size(m) +} +func (m *FindAllShardsInKeyspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_FindAllShardsInKeyspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_FindAllShardsInKeyspaceResponse proto.InternalMessageInfo + +func (m *FindAllShardsInKeyspaceResponse) GetShards() map[string]*Shard { + if m != nil { + return m.Shards + } + return nil +} + +type Shard struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Shard *topodata.Shard `protobuf:"bytes,3,opt,name=shard,proto3" json:"shard,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Shard) Reset() { *m = Shard{} } +func (m *Shard) String() string { return proto.CompactTextString(m) } +func (*Shard) ProtoMessage() {} +func (*Shard) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{9} +} + +func (m *Shard) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Shard.Unmarshal(m, b) +} +func (m *Shard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Shard.Marshal(b, m, deterministic) +} +func (m *Shard) XXX_Merge(src proto.Message) { + xxx_messageInfo_Shard.Merge(m, src) +} +func (m *Shard) XXX_Size() int { + return xxx_messageInfo_Shard.Size(m) +} +func (m *Shard) XXX_DiscardUnknown() { + xxx_messageInfo_Shard.DiscardUnknown(m) +} + +var xxx_messageInfo_Shard proto.InternalMessageInfo + +func (m *Shard) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *Shard) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Shard) GetShard() *topodata.Shard { + if m != nil { + return m.Shard + } + return nil +} + // TableMaterializeSttings contains the settings for one table. type TableMaterializeSettings struct { TargetTable string `protobuf:"bytes,1,opt,name=target_table,json=targetTable,proto3" json:"target_table,omitempty"` @@ -325,7 +458,7 @@ func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettin func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } func (*TableMaterializeSettings) ProtoMessage() {} func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{7} + return fileDescriptor_f41247b323a1ab2e, []int{10} } func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -388,7 +521,7 @@ func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } func (*MaterializeSettings) ProtoMessage() {} func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{8} + return fileDescriptor_f41247b323a1ab2e, []int{11} } func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -466,6 +599,10 @@ func init() { proto.RegisterType((*GetKeyspaceRequest)(nil), "vtctldata.GetKeyspaceRequest") proto.RegisterType((*GetKeyspaceResponse)(nil), "vtctldata.GetKeyspaceResponse") proto.RegisterType((*Keyspace)(nil), "vtctldata.Keyspace") + proto.RegisterType((*FindAllShardsInKeyspaceRequest)(nil), "vtctldata.FindAllShardsInKeyspaceRequest") + proto.RegisterType((*FindAllShardsInKeyspaceResponse)(nil), "vtctldata.FindAllShardsInKeyspaceResponse") + proto.RegisterMapType((map[string]*Shard)(nil), "vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry") + proto.RegisterType((*Shard)(nil), "vtctldata.Shard") proto.RegisterType((*TableMaterializeSettings)(nil), "vtctldata.TableMaterializeSettings") proto.RegisterType((*MaterializeSettings)(nil), "vtctldata.MaterializeSettings") } @@ -473,38 +610,45 @@ func init() { func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 514 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x93, 0xdf, 0x8e, 0xd2, 0x40, - 0x14, 0xc6, 0x53, 0x60, 0x57, 0x7a, 0x90, 0xa2, 0x83, 0x26, 0x0d, 0xc6, 0x04, 0xab, 0xee, 0x92, - 0x98, 0xb4, 0xba, 0x3e, 0x81, 0x22, 0x1a, 0x35, 0x7a, 0x51, 0x89, 0x26, 0xde, 0x34, 0x43, 0x39, - 0x4b, 0x9a, 0x1d, 0x3a, 0xb5, 0x73, 0xca, 0x2e, 0xbe, 0x81, 0x2f, 0xe3, 0x33, 0x9a, 0xce, 0xb4, - 0x05, 0x0c, 0x7b, 0x77, 0xe6, 0x37, 0xe7, 0xcf, 0x77, 0xbe, 0x69, 0x61, 0xb0, 0xa1, 0x98, 0xc4, - 0x92, 0x13, 0xf7, 0xb3, 0x5c, 0x92, 0x64, 0x76, 0x03, 0x46, 0x7d, 0x21, 0x57, 0x05, 0x25, 0xc2, - 0xdc, 0x8c, 0x1c, 0x92, 0x99, 0xdc, 0x65, 0x7a, 0x3f, 0x60, 0x34, 0xbb, 0xc1, 0xb8, 0x20, 0xfc, - 0x5e, 0x96, 0x4c, 0xe5, 0x7a, 0xcd, 0xd3, 0x65, 0x88, 0xbf, 0x0a, 0x54, 0xc4, 0x18, 0x74, 0x78, - 0xbe, 0x52, 0xae, 0x35, 0x6e, 0x4f, 0xec, 0x50, 0xc7, 0xec, 0x39, 0x38, 0x3c, 0xa6, 0x44, 0xa6, - 0x11, 0x25, 0x6b, 0x94, 0x05, 0xb9, 0xad, 0xb1, 0x35, 0x69, 0x87, 0x7d, 0x43, 0xe7, 0x06, 0x7a, - 0x53, 0x78, 0x74, 0xb4, 0xb1, 0xca, 0x64, 0xaa, 0x90, 0x3d, 0x83, 0x13, 0xdc, 0x60, 0x4a, 0xae, - 0x35, 0xb6, 0x26, 0xbd, 0x0b, 0xc7, 0xaf, 0x65, 0xce, 0x4a, 0x1a, 0x9a, 0x4b, 0xef, 0x21, 0x0c, - 0x3f, 0x20, 0x7d, 0xc6, 0xad, 0xca, 0x78, 0x8c, 0xaa, 0x92, 0xe5, 0x7d, 0x84, 0x07, 0x87, 0xb8, - 0x6a, 0xfa, 0x0a, 0xec, 0xab, 0x1a, 0x6a, 0xcd, 0xbd, 0x8b, 0xa1, 0xbf, 0xf3, 0xa6, 0x2e, 0x08, - 0x77, 0x59, 0xde, 0x4b, 0x60, 0x7b, 0xad, 0xea, 0xbd, 0x47, 0xd0, 0xad, 0x53, 0xb4, 0x40, 0x3b, - 0x6c, 0xce, 0xde, 0xfb, 0x03, 0x4d, 0xcd, 0xec, 0xe0, 0xbf, 0x92, 0x5b, 0x46, 0xef, 0xfa, 0x7c, - 0x85, 0x6e, 0x4d, 0x4b, 0x9f, 0x53, 0xbe, 0xae, 0x67, 0xe9, 0x98, 0xf9, 0x7b, 0x0d, 0x5b, 0xba, - 0x21, 0xf3, 0x9b, 0xc7, 0x3b, 0xd2, 0xef, 0x8f, 0x05, 0xee, 0x9c, 0x2f, 0x04, 0x7e, 0xe1, 0x84, - 0x79, 0xc2, 0x45, 0xf2, 0x1b, 0xbf, 0x21, 0x51, 0x92, 0xae, 0x14, 0x7b, 0x02, 0x77, 0x89, 0xe7, - 0x2b, 0xa4, 0x88, 0xca, 0x94, 0x6a, 0x50, 0xcf, 0x30, 0x5d, 0xc5, 0x5e, 0xc0, 0x7d, 0x25, 0x8b, - 0x3c, 0xc6, 0x08, 0x6f, 0xb2, 0x1c, 0x95, 0x4a, 0x64, 0xaa, 0x07, 0xdb, 0xe1, 0x3d, 0x73, 0x31, - 0x6b, 0x38, 0x7b, 0x0c, 0x10, 0xe7, 0xc8, 0x09, 0xa3, 0xe5, 0x52, 0xb8, 0x6d, 0x9d, 0x65, 0x1b, - 0xf2, 0x6e, 0x29, 0xbc, 0xbf, 0x2d, 0x18, 0x1e, 0x93, 0x31, 0x82, 0xee, 0xb5, 0xcc, 0xaf, 0x2e, - 0x85, 0xbc, 0xae, 0x7d, 0xad, 0xcf, 0xec, 0x1c, 0x06, 0xd5, 0xfc, 0x83, 0xb5, 0xed, 0xd0, 0x31, - 0xb8, 0x31, 0xeb, 0x1c, 0x06, 0xd5, 0x2e, 0x4d, 0xa2, 0x11, 0xe0, 0x18, 0xdc, 0x24, 0x9e, 0xc1, - 0x40, 0x91, 0xcc, 0x22, 0x7e, 0x49, 0x98, 0x47, 0xb1, 0xcc, 0xb6, 0x6e, 0x67, 0x6c, 0x4d, 0xba, - 0x61, 0xbf, 0xc4, 0x6f, 0x4a, 0x3a, 0x95, 0xd9, 0x96, 0x7d, 0x02, 0x47, 0xbb, 0x12, 0xa9, 0x4a, - 0xa7, 0x7b, 0xa2, 0xbf, 0x9d, 0xa7, 0x7b, 0x0f, 0x78, 0x9b, 0xb3, 0x61, 0x5f, 0x97, 0x36, 0x1b, - 0x32, 0xe8, 0xc4, 0x28, 0x84, 0x7b, 0x6a, 0x5e, 0xb2, 0x8c, 0x8d, 0xf9, 0x0b, 0x51, 0x9a, 0xbf, - 0xcd, 0x50, 0xb9, 0x77, 0x6a, 0xf3, 0x4b, 0x36, 0x2f, 0xd1, 0xdb, 0xc9, 0xcf, 0xb3, 0x4d, 0x42, - 0xa8, 0x94, 0x9f, 0xc8, 0xc0, 0x44, 0xc1, 0x4a, 0x06, 0x1b, 0x0a, 0xf4, 0x6f, 0x1a, 0x34, 0x42, - 0x16, 0xa7, 0x1a, 0xbc, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x85, 0x52, 0x57, 0xf4, 0x03, - 0x00, 0x00, + // 629 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xdf, 0x6e, 0xd3, 0x30, + 0x14, 0xc6, 0x95, 0x76, 0x1d, 0xed, 0x29, 0x6d, 0x87, 0x07, 0x52, 0x54, 0x04, 0x94, 0xc0, 0xb6, + 0x4a, 0x48, 0x29, 0x0c, 0x09, 0x21, 0xc4, 0xcd, 0x18, 0x1d, 0x1a, 0x13, 0xbb, 0xc8, 0x26, 0x90, + 0xb8, 0x20, 0xf2, 0x92, 0xb3, 0x12, 0xcd, 0x8d, 0x43, 0x7c, 0xda, 0xad, 0xbc, 0x01, 0x2f, 0xc3, + 0x23, 0xf0, 0x6c, 0x28, 0x76, 0x92, 0x66, 0x68, 0x03, 0x71, 0xe7, 0xfc, 0xce, 0xbf, 0xef, 0x7c, + 0xb6, 0x02, 0xbd, 0x39, 0x05, 0x24, 0x42, 0x4e, 0xdc, 0x4d, 0x52, 0x49, 0x92, 0xb5, 0x4a, 0xd0, + 0xef, 0x08, 0x39, 0x99, 0x51, 0x24, 0x4c, 0xa4, 0xdf, 0x25, 0x99, 0xc8, 0x65, 0xa6, 0xf3, 0x09, + 0xfa, 0xe3, 0x0b, 0x0c, 0x66, 0x84, 0x1f, 0xb3, 0x92, 0x5d, 0x39, 0x9d, 0xf2, 0x38, 0xf4, 0xf0, + 0xdb, 0x0c, 0x15, 0x31, 0x06, 0x2b, 0x3c, 0x9d, 0x28, 0xdb, 0x1a, 0xd4, 0x87, 0x2d, 0x4f, 0x9f, + 0xd9, 0x06, 0x74, 0x79, 0x40, 0x91, 0x8c, 0x7d, 0x8a, 0xa6, 0x28, 0x67, 0x64, 0xd7, 0x06, 0xd6, + 0xb0, 0xee, 0x75, 0x0c, 0x3d, 0x36, 0xd0, 0xd9, 0x85, 0xbb, 0x57, 0x36, 0x56, 0x89, 0x8c, 0x15, + 0xb2, 0xc7, 0xd0, 0xc0, 0x39, 0xc6, 0x64, 0x5b, 0x03, 0x6b, 0xd8, 0xde, 0xee, 0xba, 0x85, 0xcc, + 0x71, 0x46, 0x3d, 0x13, 0x74, 0xee, 0xc0, 0xfa, 0x3b, 0xa4, 0x03, 0x5c, 0xa8, 0x84, 0x07, 0xa8, + 0x72, 0x59, 0xce, 0x3e, 0xdc, 0xbe, 0x8c, 0xf3, 0xa6, 0xcf, 0xa0, 0x75, 0x56, 0x40, 0xad, 0xb9, + 0xbd, 0xbd, 0xee, 0x2e, 0xbd, 0x29, 0x0a, 0xbc, 0x65, 0x96, 0xf3, 0x14, 0x58, 0xa5, 0x55, 0xb1, + 0x77, 0x1f, 0x9a, 0x45, 0x8a, 0x16, 0xd8, 0xf2, 0xca, 0x6f, 0x67, 0xef, 0x92, 0xa6, 0x72, 0xf6, + 0xe8, 0x8f, 0x92, 0x6b, 0x46, 0x2f, 0xfb, 0x1c, 0x42, 0xb3, 0xa0, 0x99, 0xcf, 0x31, 0x9f, 0x16, + 0xb3, 0xf4, 0x99, 0xb9, 0x95, 0x86, 0x35, 0xdd, 0x90, 0xb9, 0xe5, 0xe5, 0x5d, 0xd1, 0xef, 0x35, + 0xdc, 0xdf, 0x8b, 0xe2, 0x70, 0x47, 0x88, 0xa3, 0xaf, 0x3c, 0x0d, 0xd5, 0x7e, 0xfc, 0x3f, 0x5b, + 0xfd, 0xb2, 0xe0, 0xc1, 0xb5, 0xe5, 0xf9, 0x8a, 0x87, 0xb0, 0xaa, 0x74, 0x2c, 0xf7, 0xf6, 0x45, + 0x65, 0xc1, 0x7f, 0xd4, 0xba, 0x26, 0x30, 0x8e, 0x29, 0x5d, 0x78, 0x79, 0x97, 0xfe, 0x01, 0xb4, + 0x2b, 0x98, 0xad, 0x41, 0xfd, 0x0c, 0x17, 0xb9, 0xb2, 0xec, 0xc8, 0x36, 0xa1, 0x31, 0xe7, 0x62, + 0x56, 0xec, 0xbf, 0x56, 0x99, 0xa7, 0x0b, 0x3d, 0x13, 0x7e, 0x55, 0x7b, 0x69, 0x39, 0x5f, 0xa0, + 0xa1, 0xd9, 0xdf, 0xb6, 0x2c, 0x7d, 0xae, 0x55, 0x7c, 0xde, 0x80, 0x86, 0xd6, 0x63, 0xd7, 0xf5, + 0x90, 0xde, 0xd2, 0xe4, 0x7c, 0x86, 0x8e, 0x3a, 0x3f, 0x2c, 0xb0, 0x8f, 0xf9, 0x89, 0xc0, 0x0f, + 0x9c, 0x30, 0x8d, 0xb8, 0x88, 0xbe, 0xe3, 0x11, 0x12, 0x45, 0xf1, 0x44, 0xb1, 0x87, 0x70, 0x93, + 0x78, 0x3a, 0x41, 0xf2, 0x29, 0x4b, 0xc9, 0xe7, 0xb6, 0x0d, 0xd3, 0x55, 0xec, 0x09, 0xdc, 0x52, + 0x72, 0x96, 0x06, 0xe8, 0xe3, 0x45, 0x92, 0xa2, 0x52, 0x91, 0x8c, 0x73, 0x1d, 0x6b, 0x26, 0x30, + 0x2e, 0x39, 0xbb, 0x07, 0x10, 0xa4, 0xc8, 0x09, 0xfd, 0x30, 0x14, 0x5a, 0x58, 0xcb, 0x6b, 0x19, + 0xf2, 0x36, 0x14, 0xce, 0xcf, 0x1a, 0xac, 0x5f, 0x25, 0xa3, 0x0f, 0xcd, 0x73, 0x99, 0x9e, 0x9d, + 0x0a, 0x79, 0x5e, 0xac, 0x5e, 0x7c, 0xb3, 0x2d, 0xe8, 0xe5, 0xf3, 0x2f, 0xbd, 0xaa, 0x96, 0xd7, + 0x35, 0xb8, 0x7c, 0x8b, 0x5b, 0xd0, 0xcb, 0x77, 0x29, 0x13, 0x8d, 0x80, 0xae, 0xc1, 0x65, 0xe2, + 0x26, 0xf4, 0x14, 0xc9, 0xc4, 0xe7, 0xa7, 0x84, 0xa9, 0x1f, 0xc8, 0x64, 0x61, 0xaf, 0x0c, 0xac, + 0x61, 0xd3, 0xeb, 0x64, 0x78, 0x27, 0xa3, 0xbb, 0x32, 0x59, 0xb0, 0xf7, 0xd0, 0xd5, 0xae, 0xf8, + 0x2a, 0xd7, 0x69, 0x37, 0xf4, 0xf3, 0x79, 0x54, 0xb9, 0xce, 0xeb, 0x9c, 0xf5, 0x3a, 0xba, 0xb4, + 0xdc, 0x90, 0xc1, 0x4a, 0x80, 0x42, 0xd8, 0xab, 0xe6, 0x02, 0xb3, 0xb3, 0x31, 0xff, 0x44, 0x64, + 0xe6, 0x2f, 0x12, 0x54, 0xf6, 0x8d, 0xc2, 0xfc, 0x8c, 0x1d, 0x67, 0xe8, 0xcd, 0xf0, 0xf3, 0xe6, + 0x3c, 0x22, 0x54, 0xca, 0x8d, 0xe4, 0xc8, 0x9c, 0x46, 0x13, 0x39, 0x9a, 0xd3, 0x48, 0xff, 0x05, + 0x47, 0xa5, 0x90, 0x93, 0x55, 0x0d, 0x9e, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x2e, 0xa9, 0x4e, + 0xcf, 0x53, 0x05, 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 88c608dd5de..b22a1288dec 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,20 +29,22 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 201 bytes of a gzipped FileDescriptorProto + // 235 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x2b, 0x49, 0x2e, 0xc9, 0x29, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x41, 0x16, 0x93, 0xe2, 0x07, 0xf3, 0x52, 0x12, 0x4b, 0x12, 0x21, 0xd2, 0x46, 0x85, 0x5c, 0xac, 0x61, 0x20, 0x21, 0xa1, 0x0c, 0x2e, 0x61, 0xd7, 0x8a, 0xd4, 0xe4, 0xd2, 0x92, 0x54, 0x30, 0xdf, 0x39, 0x3f, 0x37, 0x37, 0x31, 0x2f, 0x45, 0x48, 0x55, 0x0f, 0xa1, 0x03, 0x8b, 0x7c, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89, 0x94, 0x1a, 0x21, 0x65, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x4a, - 0x0c, 0x06, 0x8c, 0x46, 0xab, 0x19, 0xb9, 0xd8, 0xc0, 0x92, 0x29, 0x42, 0x7e, 0x5c, 0xdc, 0xee, - 0xa9, 0x25, 0xde, 0xa9, 0x95, 0xc5, 0x05, 0x89, 0xc9, 0xa9, 0x42, 0xb2, 0x48, 0xa6, 0x20, 0x89, - 0xc3, 0x2c, 0x91, 0xc3, 0x25, 0x0d, 0x33, 0x5c, 0x28, 0x90, 0x8b, 0x07, 0x49, 0xa2, 0x58, 0x08, - 0x87, 0x8e, 0x62, 0x98, 0x89, 0xf2, 0x38, 0xe5, 0x61, 0x46, 0x3a, 0x69, 0x47, 0x69, 0x96, 0x65, - 0x96, 0xa4, 0x16, 0x17, 0xeb, 0x65, 0xe6, 0xeb, 0x43, 0x58, 0xfa, 0xe9, 0xf9, 0xfa, 0x65, 0x25, - 0xfa, 0xe0, 0x00, 0xd4, 0x47, 0x0e, 0xde, 0x24, 0x36, 0xb0, 0x98, 0x31, 0x20, 0x00, 0x00, 0xff, - 0xff, 0xf0, 0x37, 0xf3, 0x26, 0x89, 0x01, 0x00, 0x00, + 0x0c, 0x06, 0x8c, 0x46, 0xf3, 0x99, 0xb8, 0xd8, 0xc0, 0x92, 0x29, 0x42, 0x45, 0x5c, 0xe2, 0x6e, + 0x99, 0x79, 0x29, 0x8e, 0x39, 0x39, 0xc1, 0x19, 0x89, 0x45, 0x29, 0xc5, 0x9e, 0x79, 0xde, 0xa9, + 0x95, 0xc5, 0x05, 0x89, 0xc9, 0xa9, 0x42, 0x9a, 0x48, 0x26, 0xe2, 0x50, 0x03, 0xb3, 0x5c, 0x8b, + 0x18, 0xa5, 0x30, 0x07, 0x08, 0xf9, 0x71, 0x71, 0xbb, 0xa7, 0x96, 0xc0, 0xed, 0x91, 0x45, 0xd2, + 0x8c, 0x24, 0x0e, 0x33, 0x5b, 0x0e, 0x97, 0x34, 0xdc, 0xbc, 0x40, 0x2e, 0x1e, 0x24, 0x89, 0x62, + 0x21, 0x1c, 0x3a, 0x8a, 0x61, 0x26, 0xca, 0xe3, 0x94, 0x87, 0x19, 0xe9, 0xa4, 0x1d, 0xa5, 0x59, + 0x96, 0x59, 0x92, 0x5a, 0x5c, 0xac, 0x97, 0x99, 0xaf, 0x0f, 0x61, 0xe9, 0xa7, 0xe7, 0xeb, 0x97, + 0x95, 0xe8, 0x83, 0x23, 0x4d, 0x1f, 0x39, 0x4a, 0x93, 0xd8, 0xc0, 0x62, 0xc6, 0x80, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xd5, 0x49, 0x16, 0xd1, 0xfd, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -156,6 +158,8 @@ var _Vtctl_serviceDesc = grpc.ServiceDesc{ // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type VtctldClient interface { + // FindAllShardsInKeyspace returns a map of shard names to shard references for a given keyspace. + FindAllShardsInKeyspace(ctx context.Context, in *vtctldata.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.FindAllShardsInKeyspaceResponse, error) // GetKeyspace reads the given keyspace from the topo and returns it. GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. @@ -170,6 +174,15 @@ func NewVtctldClient(cc *grpc.ClientConn) VtctldClient { return &vtctldClient{cc} } +func (c *vtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldata.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.FindAllShardsInKeyspaceResponse, error) { + out := new(vtctldata.FindAllShardsInKeyspaceResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/FindAllShardsInKeyspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) { out := new(vtctldata.GetKeyspaceResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetKeyspace", in, out, opts...) @@ -190,6 +203,8 @@ func (c *vtctldClient) GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspa // VtctldServer is the server API for Vtctld service. type VtctldServer interface { + // FindAllShardsInKeyspace returns a map of shard names to shard references for a given keyspace. + FindAllShardsInKeyspace(context.Context, *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) // GetKeyspace reads the given keyspace from the topo and returns it. GetKeyspace(context.Context, *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. @@ -200,6 +215,9 @@ type VtctldServer interface { type UnimplementedVtctldServer struct { } +func (*UnimplementedVtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindAllShardsInKeyspace not implemented") +} func (*UnimplementedVtctldServer) GetKeyspace(ctx context.Context, req *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetKeyspace not implemented") } @@ -211,6 +229,24 @@ func RegisterVtctldServer(s *grpc.Server, srv VtctldServer) { s.RegisterService(&_Vtctld_serviceDesc, srv) } +func _Vtctld_FindAllShardsInKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.FindAllShardsInKeyspaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).FindAllShardsInKeyspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/FindAllShardsInKeyspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).FindAllShardsInKeyspace(ctx, req.(*vtctldata.FindAllShardsInKeyspaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_GetKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.GetKeyspaceRequest) if err := dec(in); err != nil { @@ -251,6 +287,10 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ ServiceName: "vtctlservice.Vtctld", HandlerType: (*VtctldServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "FindAllShardsInKeyspace", + Handler: _Vtctld_FindAllShardsInKeyspace_Handler, + }, { MethodName: "GetKeyspace", Handler: _Vtctld_GetKeyspace_Handler, diff --git a/go/vt/vtctl/grpcvtctldclient/client.go b/go/vt/vtctl/grpcvtctldclient/client.go index 306a8ecacb0..d313ba0b568 100644 --- a/go/vt/vtctl/grpcvtctldclient/client.go +++ b/go/vt/vtctl/grpcvtctldclient/client.go @@ -1,3 +1,19 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + // Package grpcvtctldclient contains the gRPC version of the vtctld client // protocol. package grpcvtctldclient @@ -69,6 +85,14 @@ func (client *gRPCVtctldClient) Close() error { // (TODO:@amason) - This boilerplate should end up the same for all ~70 commands // .... we should do this with code gen. +func (client *gRPCVtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldatapb.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.FindAllShardsInKeyspaceResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.FindAllShardsInKeyspace(ctx, in, opts...) +} + func (client *gRPCVtctldClient) GetKeyspace(ctx context.Context, in *vtctldatapb.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.GetKeyspaceResponse, error) { if client.c == nil { return nil, status.Error(codes.Unavailable, connClosedMsg) diff --git a/go/vt/vtctl/grpcvtctldclient/client_test.go b/go/vt/vtctl/grpcvtctldclient/client_test.go index 77a0941c6d7..52ff3f7948c 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_test.go +++ b/go/vt/vtctl/grpcvtctldclient/client_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package grpcvtctldclient_test import ( @@ -8,22 +24,34 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/net/nettest" "google.golang.org/grpc" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" "vitess.io/vitess/go/vt/vtctl/vtctldclient" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vtctldata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" ) +// annoyingly, this is duplicated with theu tests in package grpcvtctldserver. +// fine for now, I suppose. +func addKeyspace(ctx context.Context, t *testing.T, ts *topo.Server, ks *vtctldatapb.Keyspace) { + in := *ks.Keyspace // take a copy to avoid the XXX_ fields changing + + err := ts.CreateKeyspace(ctx, ks.Name, &in) + require.NoError(t, err) +} + func withTestServer( t *testing.T, server vtctlservicepb.VtctldServer, - test func(t *testing.T, addr string), + test func(t *testing.T, client vtctldclient.VtctldClient), ) { lis, err := nettest.NewLocalListener("tcp") require.NoError(t, err, "cannot create nettest listener") + defer lis.Close() s := grpc.NewServer() @@ -32,31 +60,70 @@ func withTestServer( go s.Serve(lis) defer s.Stop() - test(t, lis.Addr().String()) + client, err := vtctldclient.New("grpc", lis.Addr().String()) + require.NoError(t, err, "cannot create vtctld client") + + test(t, client) } -func TestGetKeyspace(t *testing.T) { +func TestFindAllShardsInKeyspace(t *testing.T) { ctx := context.Background() - ts := memorytopo.NewServer("cell1") vtctld := grpcvtctldserver.NewVtctldServer(ts) - withTestServer(t, vtctld, func(t *testing.T, addr string) { - client, err := vtctldclient.New("grpc", addr) + withTestServer(t, vtctld, func(t *testing.T, client vtctldclient.VtctldClient) { + ks := &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + } + addKeyspace(ctx, t, ts, ks) + + si1, err := ts.GetOrCreateShard(ctx, ks.Name, "-80") require.NoError(t, err) + si2, err := ts.GetOrCreateShard(ctx, ks.Name, "80-") + require.NoError(t, err) + + resp, err := client.FindAllShardsInKeyspace(ctx, &vtctldatapb.FindAllShardsInKeyspaceRequest{Keyspace: ks.Name}) + assert.NoError(t, err) + assert.NotNil(t, resp) + + expected := map[string]*vtctldatapb.Shard{ + "-80": { + Keyspace: ks.Name, + Name: "-80", + Shard: si1.Shard, + }, + "80-": { + Keyspace: ks.Name, + Name: "80-", + Shard: si2.Shard, + }, + } + + assert.Equal(t, expected, resp.Shards) + + client.Close() + _, err = client.FindAllShardsInKeyspace(ctx, &vtctldatapb.FindAllShardsInKeyspaceRequest{Keyspace: ks.Name}) + assert.Error(t, err) + }) +} + +func TestGetKeyspace(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + vtctld := grpcvtctldserver.NewVtctldServer(ts) + + withTestServer(t, vtctld, func(t *testing.T, client vtctldclient.VtctldClient) { expected := &vtctldatapb.GetKeyspaceResponse{ - Keyspace: &vtctldatapb.Keyspace{ + Keyspace: &vtctldata.Keyspace{ Name: "testkeyspace", Keyspace: &topodatapb.Keyspace{ ShardingColumnName: "col1", }, }, } - in := *expected.Keyspace.Keyspace - - err = ts.CreateKeyspace(ctx, expected.Keyspace.Name, &in) - require.NoError(t, err) + addKeyspace(ctx, t, ts, expected.Keyspace) resp, err := client.GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{Keyspace: expected.Keyspace.Name}) assert.NoError(t, err) @@ -74,10 +141,7 @@ func TestGetKeyspaces(t *testing.T) { ts := memorytopo.NewServer("cell1") vtctld := grpcvtctldserver.NewVtctldServer(ts) - withTestServer(t, vtctld, func(t *testing.T, addr string) { - client, err := vtctldclient.New("grpc", addr) - require.NoError(t, err) - + withTestServer(t, vtctld, func(t *testing.T, client vtctldclient.VtctldClient) { resp, err := client.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) assert.NoError(t, err) assert.Empty(t, resp.Keyspaces) @@ -86,10 +150,7 @@ func TestGetKeyspaces(t *testing.T) { Name: "testkeyspace", Keyspace: &topodatapb.Keyspace{}, } - in := *expected.Keyspace - - err = ts.CreateKeyspace(ctx, expected.Name, &in) - require.NoError(t, err) + addKeyspace(ctx, t, ts, expected) resp, err = client.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) assert.NoError(t, err) diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 797a347d142..3814bc62165 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -1,3 +1,19 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package grpcvtctldserver import ( @@ -20,6 +36,27 @@ func NewVtctldServer(ts *topo.Server) *VtctldServer { return &VtctldServer{ts: ts} } +// FindAllShardsInKeyspace is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctldatapb.FindAllShardsInKeyspaceRequest) (*vtctldatapb.FindAllShardsInKeyspaceResponse, error) { + result, err := s.ts.FindAllShardsInKeyspace(ctx, req.Keyspace) + if err != nil { + return nil, err + } + + shards := map[string]*vtctldatapb.Shard{} + for _, shard := range result { + shards[shard.ShardName()] = &vtctldatapb.Shard{ + Keyspace: req.Keyspace, + Name: shard.ShardName(), + Shard: shard.Shard, + } + } + + return &vtctldatapb.FindAllShardsInKeyspaceResponse{ + Shards: shards, + }, nil +} + // GetKeyspace is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) GetKeyspace(ctx context.Context, req *vtctldatapb.GetKeyspaceRequest) (*vtctldatapb.GetKeyspaceResponse, error) { keyspace, err := s.ts.GetKeyspace(ctx, req.Keyspace) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 504191ed19d..faebf22e610 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package grpcvtctldserver import ( @@ -14,6 +30,45 @@ import ( vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) +func TestFindAllShardsInKeyspace(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + vtctld := NewVtctldServer(ts) + + ks := &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + } + addKeyspace(ctx, t, ts, ks) + + si1, err := ts.GetOrCreateShard(ctx, ks.Name, "-80") + require.NoError(t, err) + si2, err := ts.GetOrCreateShard(ctx, ks.Name, "80-") + require.NoError(t, err) + + resp, err := vtctld.FindAllShardsInKeyspace(ctx, &vtctldatapb.FindAllShardsInKeyspaceRequest{Keyspace: ks.Name}) + assert.NoError(t, err) + assert.NotNil(t, resp) + + expected := map[string]*vtctldatapb.Shard{ + "-80": { + Keyspace: ks.Name, + Name: "-80", + Shard: si1.Shard, + }, + "80-": { + Keyspace: ks.Name, + Name: "80-", + Shard: si2.Shard, + }, + } + + assert.Equal(t, expected, resp.Shards) + + _, err = vtctld.FindAllShardsInKeyspace(ctx, &vtctldatapb.FindAllShardsInKeyspaceRequest{Keyspace: "nothing"}) + assert.Error(t, err) +} + func TestGetKeyspace(t *testing.T) { ctx := context.Background() ts := memorytopo.NewServer("cell1") @@ -82,6 +137,7 @@ func TestGetKeyspaces(t *testing.T) { assert.Equal(t, expected, resp.Keyspaces) topofactory.SetError(errors.New("error from toposerver")) + _, err = vtctld.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) assert.Error(t, err) } diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index f5faa408f32..998fb4c18b6 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -112,7 +112,6 @@ import ( "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" - "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/wrangler" @@ -1775,9 +1774,7 @@ func commandGetKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl keyspace := subFlags.Arg(0) - // TODO: make vtctld a field of the wrangler - vtctld := grpcvtctldserver.NewVtctldServer(wr.TopoServer()) - keyspaceInfo, err := vtctld.GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{ + keyspaceInfo, err := wr.VtctldServer().GetKeyspace(ctx, &vtctldatapb.GetKeyspaceRequest{ Keyspace: keyspace, }) if err != nil { @@ -1788,8 +1785,7 @@ func commandGetKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl } func commandGetKeyspaces(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { - vtctld := grpcvtctldserver.NewVtctldServer(wr.TopoServer()) - resp, err := vtctld.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) + resp, err := wr.VtctldServer().GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) if err != nil { return err } @@ -2237,11 +2233,14 @@ func commandFindAllShardsInKeyspace(ctx context.Context, wr *wrangler.Wrangler, } keyspace := subFlags.Arg(0) - result, err := wr.TopoServer().FindAllShardsInKeyspace(ctx, keyspace) + result, err := wr.VtctldServer().FindAllShardsInKeyspace(ctx, &vtctldatapb.FindAllShardsInKeyspaceRequest{ + Keyspace: keyspace, + }) if err != nil { return err } - return printJSON(wr.Logger(), result) + + return printJSON(wr.Logger(), result.Shards) } func commandValidate(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { diff --git a/go/vt/wrangler/wrangler.go b/go/vt/wrangler/wrangler.go index 83672b0f880..787f5008fc7 100644 --- a/go/vt/wrangler/wrangler.go +++ b/go/vt/wrangler/wrangler.go @@ -21,7 +21,10 @@ package wrangler import ( "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" "vitess.io/vitess/go/vt/vttablet/tmclient" + + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" ) var ( @@ -42,6 +45,7 @@ type Wrangler struct { logger logutil.Logger ts *topo.Server tmc tmclient.TabletManagerClient + vtctld vtctlservicepb.VtctldServer } // New creates a new Wrangler object. @@ -50,6 +54,7 @@ func New(logger logutil.Logger, ts *topo.Server, tmc tmclient.TabletManagerClien logger: logger, ts: ts, tmc: tmc, + vtctld: grpcvtctldserver.NewVtctldServer(ts), } } @@ -64,6 +69,12 @@ func (wr *Wrangler) TabletManagerClient() tmclient.TabletManagerClient { return wr.tmc } +// VtctldServer returns the vtctlservicepb.VtctldServer implementation this +// wrangler is using. +func (wr *Wrangler) VtctldServer() vtctlservicepb.VtctldServer { + return wr.vtctld +} + // SetLogger can be used to change the current logger. Not synchronized, // no calls to this wrangler should be in progress. func (wr *Wrangler) SetLogger(logger logutil.Logger) { diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index db151d3b11d..1a7142ea09e 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -57,6 +57,20 @@ message Keyspace { topodata.Keyspace keyspace = 2; } +message FindAllShardsInKeyspaceRequest { + string keyspace = 1; +} + +message FindAllShardsInKeyspaceResponse { + map shards = 1; +} + +message Shard { + string keyspace = 1; + string name = 2; + topodata.Shard shard = 3; +} + // TableMaterializeSttings contains the settings for one table. message TableMaterializeSettings { string target_table = 1; diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 8b4d2b79c02..ebd82714774 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -31,6 +31,8 @@ service Vtctl { // Service Vtctld exposes gRPC endpoints for each vt command. service Vtctld { + // FindAllShardsInKeyspace returns a map of shard names to shard references for a given keyspace. + rpc FindAllShardsInKeyspace(vtctldata.FindAllShardsInKeyspaceRequest) returns (vtctldata.FindAllShardsInKeyspaceResponse) {}; // GetKeyspace reads the given keyspace from the topo and returns it. rpc GetKeyspace(vtctldata.GetKeyspaceRequest) returns (vtctldata.GetKeyspaceResponse) {}; // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. From 272fd36c2aab8a9ece7151cbe4be209c4f76d1a5 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Tue, 5 Jan 2021 15:48:32 -0800 Subject: [PATCH 04/21] Merge pull request #7238 from tinyspeck/am_vtctldclient_generator [vtctldclient] vtctldclient generator --- Makefile | 3 + go/vt/vtctl/grpcvtctldclient/Makefile | 19 ++ go/vt/vtctl/grpcvtctldclient/client.go | 36 +-- go/vt/vtctl/grpcvtctldclient/client_gen.go | 56 ++++ go/vt/vtctl/grpcvtctldclient/client_test.go | 2 +- go/vt/vtctl/grpcvtctldclient/codegen/main.go | 290 ++++++++++++++++++ .../grpcvtctldclient/codegen/template.go | 63 ++++ 7 files changed, 436 insertions(+), 33 deletions(-) create mode 100644 go/vt/vtctl/grpcvtctldclient/Makefile create mode 100644 go/vt/vtctl/grpcvtctldclient/client_gen.go create mode 100644 go/vt/vtctl/grpcvtctldclient/codegen/main.go create mode 100644 go/vt/vtctl/grpcvtctldclient/codegen/template.go diff --git a/Makefile b/Makefile index d3473f19784..49c3d59b93d 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,9 @@ install-testing: build mkdir -p "$${PREFIX}/web/vtctld2" cp -R web/vtctld2/app "$${PREFIX}/web/vtctld2" +grpcvtctldclient: go/vt/proto/vtctlservice/vtctlservice.pb.go + make -C go/vt/vtctl/grpcvtctldclient + parser: make -C go/vt/sqlparser diff --git a/go/vt/vtctl/grpcvtctldclient/Makefile b/go/vt/vtctl/grpcvtctldclient/Makefile new file mode 100644 index 00000000000..d40d962d709 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldclient/Makefile @@ -0,0 +1,19 @@ +# Copyright 2021 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +MAKEFLAGS = -s + +generate: + go generate ./... + gofmt -w client_gen.go diff --git a/go/vt/vtctl/grpcvtctldclient/client.go b/go/vt/vtctl/grpcvtctldclient/client.go index d313ba0b568..af3e8e07802 100644 --- a/go/vt/vtctl/grpcvtctldclient/client.go +++ b/go/vt/vtctl/grpcvtctldclient/client.go @@ -1,5 +1,5 @@ /* -Copyright 2020 The Vitess Authors. +Copyright 2021 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,17 +19,13 @@ limitations under the License. package grpcvtctldclient import ( - "context" "flag" "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "vitess.io/vitess/go/vt/grpcclient" "vitess.io/vitess/go/vt/vtctl/vtctldclient" - vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" ) @@ -56,6 +52,9 @@ type gRPCVtctldClient struct { c vtctlservicepb.VtctldClient } +//go:generate -command grpcvtctldclient go run ./codegen +//go:generate grpcvtctldclient -out client_gen.go + func gRPCVtctldClientFactory(addr string) (vtctldclient.VtctldClient, error) { opt, err := grpcclient.SecureDialOption(*cert, *key, *ca, *name) if err != nil { @@ -82,33 +81,6 @@ func (client *gRPCVtctldClient) Close() error { return err } -// (TODO:@amason) - This boilerplate should end up the same for all ~70 commands -// .... we should do this with code gen. - -func (client *gRPCVtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldatapb.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.FindAllShardsInKeyspaceResponse, error) { - if client.c == nil { - return nil, status.Error(codes.Unavailable, connClosedMsg) - } - - return client.c.FindAllShardsInKeyspace(ctx, in, opts...) -} - -func (client *gRPCVtctldClient) GetKeyspace(ctx context.Context, in *vtctldatapb.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.GetKeyspaceResponse, error) { - if client.c == nil { - return nil, status.Error(codes.Unavailable, connClosedMsg) - } - - return client.c.GetKeyspace(ctx, in, opts...) -} - -func (client *gRPCVtctldClient) GetKeyspaces(ctx context.Context, in *vtctldatapb.GetKeyspacesRequest, opts ...grpc.CallOption) (*vtctldatapb.GetKeyspacesResponse, error) { - if client.c == nil { - return nil, status.Error(codes.Unavailable, connClosedMsg) - } - - return client.c.GetKeyspaces(ctx, in, opts...) -} - func init() { vtctldclient.Register("grpc", gRPCVtctldClientFactory) } diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go new file mode 100644 index 00000000000..cbe87b15d87 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -0,0 +1,56 @@ +// Code generated by grpcvtctldclient-generator. DO NOT EDIT. + +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package grpcvtctldclient + +import ( + "context" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +// FindAllShardsInKeyspace is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldatapb.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.FindAllShardsInKeyspaceResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.FindAllShardsInKeyspace(ctx, in, opts...) +} + +// GetKeyspace is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetKeyspace(ctx context.Context, in *vtctldatapb.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.GetKeyspaceResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetKeyspace(ctx, in, opts...) +} + +// GetKeyspaces is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetKeyspaces(ctx context.Context, in *vtctldatapb.GetKeyspacesRequest, opts ...grpc.CallOption) (*vtctldatapb.GetKeyspacesResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetKeyspaces(ctx, in, opts...) +} diff --git a/go/vt/vtctl/grpcvtctldclient/client_test.go b/go/vt/vtctl/grpcvtctldclient/client_test.go index 52ff3f7948c..84a8b3b8133 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_test.go +++ b/go/vt/vtctl/grpcvtctldclient/client_test.go @@ -1,5 +1,5 @@ /* -Copyright 2020 The Vitess Authors. +Copyright 2021 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/vtctl/grpcvtctldclient/codegen/main.go b/go/vt/vtctl/grpcvtctldclient/codegen/main.go new file mode 100644 index 00000000000..81a3a7fd759 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldclient/codegen/main.go @@ -0,0 +1,290 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "errors" + "flag" + "fmt" + "go/types" + "io" + "os" + "path/filepath" + "regexp" + "sort" + + "golang.org/x/tools/go/packages" +) + +func main() { // nolint:funlen + source := flag.String("source", "../../proto/vtctlservice", "source package") + typeName := flag.String("type", "VtctldClient", "interface type to implement") + implType := flag.String("impl", "gRPCVtctldClient", "type implementing the interface") + pkgName := flag.String("targetpkg", "grpcvtctldclient", "package name to generate code for") + out := flag.String("out", "", "output destination. leave empty to use stdout") + + flag.Parse() + + if *source == "" { + panic("-source cannot be empty") + } + + if *typeName == "" { + panic("-type cannot be empty") + } + + if *implType == "" { + panic("-impl cannot be empty") + } + + if *pkgName == "" { + panic("-targetpkg cannot be empty") + } + + var output io.Writer = os.Stdout + + if *out != "" { + f, err := os.Create(*out) + if err != nil { + panic(err) + } + + defer f.Close() + output = f + } + + pkg, err := loadPackage(*source) + if err != nil { + panic(err) + } + + iface, err := extractSourceInterface(pkg, *typeName) + if err != nil { + panic(fmt.Errorf("error getting %s in %s: %w", *typeName, *source, err)) + } + + imports := map[string]string{ + "context": "context", + } + importNames := []string{} + funcs := make(map[string]*Func, iface.NumExplicitMethods()) + funcNames := make([]string, iface.NumExplicitMethods()) + + for i := 0; i < iface.NumExplicitMethods(); i++ { + m := iface.ExplicitMethod(i) + funcNames[i] = m.Name() + + sig, ok := m.Type().(*types.Signature) + if !ok { + panic(fmt.Sprintf("could not derive signature from method %s, have %T", m.FullName(), m.Type())) + } + + if sig.Params().Len() != 3 { + panic(fmt.Sprintf("all methods in a grpc client interface should have exactly 3 params; found\n=> %s", sig)) + } + + if sig.Results().Len() != 2 { + panic(fmt.Sprintf("all methods in a grpc client interface should have exactly 2 results; found\n=> %s", sig)) + } + + f := &Func{ + Name: m.Name(), + } + funcs[f.Name] = f + + // The first parameter is always context.Context. The third parameter is + // always a ...grpc.CallOption. + param := sig.Params().At(1) + + localType, localImport, pkgPath, err := extractLocalPointerType(param) + if err != nil { + panic(err) + } + + f.Param.Name = param.Name() + f.Param.Type = "*" + localImport + "." + localType + + if _, ok := imports[localImport]; !ok { + importNames = append(importNames, localImport) + } + + imports[localImport] = pkgPath + + // (TODO|@amason): check which grpc lib CallOption is imported from in + // this interface; it could be either google.golang.org/grpc or + // github.com/golang/protobuf/grpc, although in vitess we currently + // always use the former. + + // The second result is always error. + result := sig.Results().At(0) + + localType, localImport, pkgPath, err = extractLocalPointerType(result) // (TODO|@amason): does not work for streaming rpcs + if err != nil { + panic(err) + } + + f.Result.Name = result.Name() + f.Result.Type = "*" + localImport + "." + localType + + if _, ok := imports[localImport]; !ok { + importNames = append(importNames, localImport) + } + + imports[localImport] = pkgPath + } + + sort.Strings(importNames) + sort.Strings(funcNames) + + def := &ClientInterfaceDef{ + PackageName: *pkgName, + Type: *implType, + } + + for _, name := range importNames { + imp := &Import{ + Path: imports[name], + } + + if filepath.Base(imp.Path) != name { + imp.Alias = name + } + + def.Imports = append(def.Imports, imp) + } + + for _, name := range funcNames { + def.Methods = append(def.Methods, funcs[name]) + } + + if err := tmpl.Execute(output, def); err != nil { + panic(err) + } +} + +// ClientInterfaceDef is a struct providing enough information to generate an +// implementation of a gRPC Client interface. +type ClientInterfaceDef struct { + PackageName string + Type string + Imports []*Import + Methods []*Func +} + +// Import contains the meta information about a Go import. +type Import struct { + Alias string + Path string +} + +// Func is the variable part of a gRPC client interface method (i.e. not the +// context or dialopts arguments, or the error part of the result tuple). +type Func struct { + Name string + Param Param + Result Param +} + +// Param represents an element of either a parameter list or result list. It +// contains an optional name, and a package-local type. This struct exists +// purely to power template execution, which is why the Type field is simply a +// bare string. +type Param struct { + Name string + // locally-qualified type, e.g. "grpc.CallOption", and not "google.golang.org/grpc.CallOption". + Type string +} + +func loadPackage(source string) (*packages.Package, error) { + pkgs, err := packages.Load(&packages.Config{ + Mode: packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo, + }, source) + if err != nil { + return nil, err + } + + if len(pkgs) != 1 { + return nil, errors.New("must specify exactly one package") + } + + pkg := pkgs[0] + if len(pkg.Errors) > 0 { + var err error + + for _, e := range pkg.Errors { + switch err { + case nil: + err = fmt.Errorf("errors loading package %s: %s", source, e.Error()) + default: + err = fmt.Errorf("%w; %s", err, e.Error()) + } + } + + return nil, err + } + + return pkg, nil +} + +func extractSourceInterface(pkg *packages.Package, name string) (*types.Interface, error) { + obj := pkg.Types.Scope().Lookup(name) + if obj == nil { + return nil, fmt.Errorf("no symbol found with name %s", name) + } + + switch t := obj.Type().(type) { + case *types.Named: + iface, ok := t.Underlying().(*types.Interface) + if !ok { + return nil, fmt.Errorf("symbol %s was not an interface but %T", name, t.Underlying()) + } + + return iface, nil + case *types.Interface: + return t, nil + } + + return nil, fmt.Errorf("symbol %s was not an interface but %T", name, obj.Type()) +} + +var vitessProtoRegexp = regexp.MustCompile(`^vitess.io.*/proto/.*`) + +func rewriteProtoImports(pkg *types.Package) string { + if vitessProtoRegexp.MatchString(pkg.Path()) { + return pkg.Name() + "pb" + } + + return pkg.Name() +} + +func extractLocalPointerType(v *types.Var) (name string, localImport string, pkgPath string, err error) { + ptr, ok := v.Type().(*types.Pointer) + if !ok { + return "", "", "", fmt.Errorf("expected a pointer type for %s, got %V", v.Name(), v.Type()) + } + + typ, ok := ptr.Elem().(*types.Named) + if !ok { + return "", "", "", fmt.Errorf("expected an underlying named type for %s, got %V", v.Name(), ptr.Elem()) + } + + name = typ.Obj().Name() + localImport = rewriteProtoImports(typ.Obj().Pkg()) + pkgPath = typ.Obj().Pkg().Path() + + return name, localImport, pkgPath, nil +} diff --git a/go/vt/vtctl/grpcvtctldclient/codegen/template.go b/go/vt/vtctl/grpcvtctldclient/codegen/template.go new file mode 100644 index 00000000000..d0c668bf577 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldclient/codegen/template.go @@ -0,0 +1,63 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import "text/template" + +const tmplStr = `// Code generated by grpcvtctldclient-generator. DO NOT EDIT. + +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package {{ .PackageName }} + +import ( + "context" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + {{ range .Imports -}} + {{ if ne .Alias "" }}{{ .Alias }} {{ end }}"{{ .Path }}" + {{- end }} +) +{{ range .Methods }} +// {{ .Name }} is part of the vtctlservicepb.VtctldClient interface. +func (client *{{ $.Type }}) {{ .Name }}(ctx context.Context, {{ .Param.Name }} {{ .Param.Type }}, opts ...grpc.CallOption) ({{ .Result.Type }}, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.{{ .Name }}(ctx, in, opts...) +} +{{ end }}` + +var tmpl = template.Must(template.New("vtctldclient-generator").Parse(tmplStr)) From 50cf8690909cbf8a77489ded876c2859c5174d30 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Mon, 11 Jan 2021 20:28:00 -0800 Subject: [PATCH 05/21] Merge pull request #7285 from tinyspeck/am_fix_findallshardsinkeyspace [vtctld] Fix accidentally-broken legacy vtctl output format --- go/vt/vtctl/vtctl.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 998fb4c18b6..9d60654a348 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2240,7 +2240,14 @@ func commandFindAllShardsInKeyspace(ctx context.Context, wr *wrangler.Wrangler, return err } - return printJSON(wr.Logger(), result.Shards) + // reformat data into structure of old interface + legacyShardMap := make(map[string]*topodatapb.Shard, len(result.Shards)) + + for _, shard := range result.Shards { + legacyShardMap[shard.Name] = shard.Shard + } + + return printJSON(wr.Logger(), legacyShardMap) } func commandValidate(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { From 5094d2b5de1e2b142aa7b2ef81c1fa0bc42b81bf Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Fri, 15 Jan 2021 21:05:58 +0100 Subject: [PATCH 06/21] Merge pull request #7302 from tinyspeck/am_vtctld_cell_getters [vtctld] Migrate cell getters --- go/cmd/vtctldclient/commands.go | 74 ++++++- go/cmd/vtctldclient/json.go | 61 +++++ go/vt/proto/vtctldata/vtctldata.pb.go | 233 +++++++++++++++++++- go/vt/proto/vtctlservice/vtctlservice.pb.go | 124 ++++++++++- go/vt/vtctl/grpcvtctldclient/client_gen.go | 27 +++ go/vt/vtctl/grpcvtctldserver/server.go | 40 ++++ proto/vtctldata.proto | 22 ++ proto/vtctlservice.proto | 11 +- 8 files changed, 582 insertions(+), 10 deletions(-) create mode 100644 go/cmd/vtctldclient/json.go diff --git a/go/cmd/vtctldclient/commands.go b/go/cmd/vtctldclient/commands.go index 951b04f8679..8603489c6a2 100644 --- a/go/cmd/vtctldclient/commands.go +++ b/go/cmd/vtctldclient/commands.go @@ -17,8 +17,8 @@ limitations under the License. package main import ( - "encoding/json" "fmt" + "strings" "github.com/spf13/cobra" @@ -32,6 +32,21 @@ var ( Args: cobra.ExactArgs(1), RunE: commandFindAllShardsInKeyspace, } + getCellInfoNamesCmd = &cobra.Command{ + Use: "GetCellInfoNames", + Args: cobra.NoArgs, + RunE: commandGetCellInfoNames, + } + getCellInfoCmd = &cobra.Command{ + Use: "GetCellInfo cell", + Args: cobra.ExactArgs(1), + RunE: commandGetCellInfo, + } + getCellsAliasesCmd = &cobra.Command{ + Use: "GetCellsAliases", + Args: cobra.NoArgs, + RunE: commandGetCellsAliases, + } getKeyspaceCmd = &cobra.Command{ Use: "GetKeyspace keyspace", Aliases: []string{"getkeyspace"}, @@ -56,7 +71,7 @@ func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { return err } - data, err := json.Marshal(&resp) + data, err := MarshalJSON(resp) if err != nil { return err } @@ -65,6 +80,51 @@ func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { return nil } +func commandGetCellInfoNames(cmd *cobra.Command, args []string) error { + resp, err := client.GetCellInfoNames(commandCtx, &vtctldatapb.GetCellInfoNamesRequest{}) + if err != nil { + return err + } + + fmt.Printf("%s\n", strings.Join(resp.Names, "\n")) + + return nil +} + +func commandGetCellInfo(cmd *cobra.Command, args []string) error { + cell := cmd.Flags().Arg(0) + resp, err := client.GetCellInfo(commandCtx, &vtctldatapb.GetCellInfoRequest{Cell: cell}) + + if err != nil { + return err + } + + data, err := MarshalJSON(resp.CellInfo) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +func commandGetCellsAliases(cmd *cobra.Command, args []string) error { + resp, err := client.GetCellsAliases(commandCtx, &vtctldatapb.GetCellsAliasesRequest{}) + if err != nil { + return err + } + + data, err := MarshalJSON(resp.Aliases) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + func commandGetKeyspace(cmd *cobra.Command, args []string) error { ks := cmd.Flags().Arg(0) resp, err := client.GetKeyspace(commandCtx, &vtctldatapb.GetKeyspaceRequest{ @@ -86,13 +146,21 @@ func commandGetKeyspaces(cmd *cobra.Command, args []string) error { return err } - fmt.Printf("%+v\n", resp.Keyspaces) + data, err := MarshalJSON(resp.Keyspaces) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) return nil } func init() { rootCmd.AddCommand(findAllShardsInKeyspaceCmd) + rootCmd.AddCommand(getCellInfoNamesCmd) + rootCmd.AddCommand(getCellInfoCmd) + rootCmd.AddCommand(getCellsAliasesCmd) rootCmd.AddCommand(getKeyspaceCmd) rootCmd.AddCommand(getKeyspacesCmd) } diff --git a/go/cmd/vtctldclient/json.go b/go/cmd/vtctldclient/json.go new file mode 100644 index 00000000000..b7cb3eeff0e --- /dev/null +++ b/go/cmd/vtctldclient/json.go @@ -0,0 +1,61 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bytes" + "encoding/json" + "fmt" + + "github.com/golang/protobuf/jsonpb" + "github.com/golang/protobuf/proto" +) + +// MarshalJSON marshals obj to a JSON string. It uses the jsonpb marshaler for +// proto.Message types, with some sensible defaults, and falls back to the +// standard Go marshaler otherwise. In both cases, the marshaled JSON is +// indented with two spaces for readability. +// +// Unfortunately jsonpb only works for types that implement proto.Message, +// either by being a proto message type or by anonymously embedding one, so for +// other types that may have nested struct fields, we still use the standard Go +// marshaler, which will result in different formattings. +func MarshalJSON(obj interface{}) ([]byte, error) { + switch obj := obj.(type) { + case proto.Message: + b := bytes.NewBuffer(nil) + m := jsonpb.Marshaler{ + EnumsAsInts: false, + EmitDefaults: true, + Indent: " ", + OrigName: true, + } + + if err := m.Marshal(b, obj); err != nil { + return nil, fmt.Errorf("jsonpb.Marshal = %v", err) + } + + return b.Bytes(), nil + default: + data, err := json.MarshalIndent(obj, "", " ") + if err != nil { + return nil, fmt.Errorf("json.Marshal = %v", err) + } + + return data, nil + } +} diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index aba0d093fd3..90d7811045a 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -112,6 +112,224 @@ func (m *ExecuteVtctlCommandResponse) GetEvent() *logutil.Event { return nil } +type GetCellInfoNamesRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetCellInfoNamesRequest) Reset() { *m = GetCellInfoNamesRequest{} } +func (m *GetCellInfoNamesRequest) String() string { return proto.CompactTextString(m) } +func (*GetCellInfoNamesRequest) ProtoMessage() {} +func (*GetCellInfoNamesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{2} +} + +func (m *GetCellInfoNamesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetCellInfoNamesRequest.Unmarshal(m, b) +} +func (m *GetCellInfoNamesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetCellInfoNamesRequest.Marshal(b, m, deterministic) +} +func (m *GetCellInfoNamesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetCellInfoNamesRequest.Merge(m, src) +} +func (m *GetCellInfoNamesRequest) XXX_Size() int { + return xxx_messageInfo_GetCellInfoNamesRequest.Size(m) +} +func (m *GetCellInfoNamesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetCellInfoNamesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetCellInfoNamesRequest proto.InternalMessageInfo + +type GetCellInfoNamesResponse struct { + Names []string `protobuf:"bytes,1,rep,name=names,proto3" json:"names,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetCellInfoNamesResponse) Reset() { *m = GetCellInfoNamesResponse{} } +func (m *GetCellInfoNamesResponse) String() string { return proto.CompactTextString(m) } +func (*GetCellInfoNamesResponse) ProtoMessage() {} +func (*GetCellInfoNamesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{3} +} + +func (m *GetCellInfoNamesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetCellInfoNamesResponse.Unmarshal(m, b) +} +func (m *GetCellInfoNamesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetCellInfoNamesResponse.Marshal(b, m, deterministic) +} +func (m *GetCellInfoNamesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetCellInfoNamesResponse.Merge(m, src) +} +func (m *GetCellInfoNamesResponse) XXX_Size() int { + return xxx_messageInfo_GetCellInfoNamesResponse.Size(m) +} +func (m *GetCellInfoNamesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetCellInfoNamesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetCellInfoNamesResponse proto.InternalMessageInfo + +func (m *GetCellInfoNamesResponse) GetNames() []string { + if m != nil { + return m.Names + } + return nil +} + +type GetCellInfoRequest struct { + Cell string `protobuf:"bytes,1,opt,name=cell,proto3" json:"cell,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetCellInfoRequest) Reset() { *m = GetCellInfoRequest{} } +func (m *GetCellInfoRequest) String() string { return proto.CompactTextString(m) } +func (*GetCellInfoRequest) ProtoMessage() {} +func (*GetCellInfoRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{4} +} + +func (m *GetCellInfoRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetCellInfoRequest.Unmarshal(m, b) +} +func (m *GetCellInfoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetCellInfoRequest.Marshal(b, m, deterministic) +} +func (m *GetCellInfoRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetCellInfoRequest.Merge(m, src) +} +func (m *GetCellInfoRequest) XXX_Size() int { + return xxx_messageInfo_GetCellInfoRequest.Size(m) +} +func (m *GetCellInfoRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetCellInfoRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetCellInfoRequest proto.InternalMessageInfo + +func (m *GetCellInfoRequest) GetCell() string { + if m != nil { + return m.Cell + } + return "" +} + +type GetCellInfoResponse struct { + CellInfo *topodata.CellInfo `protobuf:"bytes,1,opt,name=cell_info,json=cellInfo,proto3" json:"cell_info,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetCellInfoResponse) Reset() { *m = GetCellInfoResponse{} } +func (m *GetCellInfoResponse) String() string { return proto.CompactTextString(m) } +func (*GetCellInfoResponse) ProtoMessage() {} +func (*GetCellInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{5} +} + +func (m *GetCellInfoResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetCellInfoResponse.Unmarshal(m, b) +} +func (m *GetCellInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetCellInfoResponse.Marshal(b, m, deterministic) +} +func (m *GetCellInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetCellInfoResponse.Merge(m, src) +} +func (m *GetCellInfoResponse) XXX_Size() int { + return xxx_messageInfo_GetCellInfoResponse.Size(m) +} +func (m *GetCellInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetCellInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetCellInfoResponse proto.InternalMessageInfo + +func (m *GetCellInfoResponse) GetCellInfo() *topodata.CellInfo { + if m != nil { + return m.CellInfo + } + return nil +} + +type GetCellsAliasesRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetCellsAliasesRequest) Reset() { *m = GetCellsAliasesRequest{} } +func (m *GetCellsAliasesRequest) String() string { return proto.CompactTextString(m) } +func (*GetCellsAliasesRequest) ProtoMessage() {} +func (*GetCellsAliasesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{6} +} + +func (m *GetCellsAliasesRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetCellsAliasesRequest.Unmarshal(m, b) +} +func (m *GetCellsAliasesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetCellsAliasesRequest.Marshal(b, m, deterministic) +} +func (m *GetCellsAliasesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetCellsAliasesRequest.Merge(m, src) +} +func (m *GetCellsAliasesRequest) XXX_Size() int { + return xxx_messageInfo_GetCellsAliasesRequest.Size(m) +} +func (m *GetCellsAliasesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetCellsAliasesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetCellsAliasesRequest proto.InternalMessageInfo + +type GetCellsAliasesResponse struct { + Aliases map[string]*topodata.CellsAlias `protobuf:"bytes,1,rep,name=aliases,proto3" json:"aliases,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetCellsAliasesResponse) Reset() { *m = GetCellsAliasesResponse{} } +func (m *GetCellsAliasesResponse) String() string { return proto.CompactTextString(m) } +func (*GetCellsAliasesResponse) ProtoMessage() {} +func (*GetCellsAliasesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{7} +} + +func (m *GetCellsAliasesResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetCellsAliasesResponse.Unmarshal(m, b) +} +func (m *GetCellsAliasesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetCellsAliasesResponse.Marshal(b, m, deterministic) +} +func (m *GetCellsAliasesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetCellsAliasesResponse.Merge(m, src) +} +func (m *GetCellsAliasesResponse) XXX_Size() int { + return xxx_messageInfo_GetCellsAliasesResponse.Size(m) +} +func (m *GetCellsAliasesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetCellsAliasesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetCellsAliasesResponse proto.InternalMessageInfo + +func (m *GetCellsAliasesResponse) GetAliases() map[string]*topodata.CellsAlias { + if m != nil { + return m.Aliases + } + return nil +} + type GetKeyspacesRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -122,7 +340,7 @@ func (m *GetKeyspacesRequest) Reset() { *m = GetKeyspacesRequest{} } func (m *GetKeyspacesRequest) String() string { return proto.CompactTextString(m) } func (*GetKeyspacesRequest) ProtoMessage() {} func (*GetKeyspacesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{2} + return fileDescriptor_f41247b323a1ab2e, []int{8} } func (m *GetKeyspacesRequest) XXX_Unmarshal(b []byte) error { @@ -154,7 +372,7 @@ func (m *GetKeyspacesResponse) Reset() { *m = GetKeyspacesResponse{} } func (m *GetKeyspacesResponse) String() string { return proto.CompactTextString(m) } func (*GetKeyspacesResponse) ProtoMessage() {} func (*GetKeyspacesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{3} + return fileDescriptor_f41247b323a1ab2e, []int{9} } func (m *GetKeyspacesResponse) XXX_Unmarshal(b []byte) error { @@ -193,7 +411,7 @@ func (m *GetKeyspaceRequest) Reset() { *m = GetKeyspaceRequest{} } func (m *GetKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*GetKeyspaceRequest) ProtoMessage() {} func (*GetKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{4} + return fileDescriptor_f41247b323a1ab2e, []int{10} } func (m *GetKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -232,7 +450,7 @@ func (m *GetKeyspaceResponse) Reset() { *m = GetKeyspaceResponse{} } func (m *GetKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*GetKeyspaceResponse) ProtoMessage() {} func (*GetKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{5} + return fileDescriptor_f41247b323a1ab2e, []int{11} } func (m *GetKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -594,6 +812,13 @@ func (m *MaterializeSettings) GetTabletTypes() string { func init() { proto.RegisterType((*ExecuteVtctlCommandRequest)(nil), "vtctldata.ExecuteVtctlCommandRequest") proto.RegisterType((*ExecuteVtctlCommandResponse)(nil), "vtctldata.ExecuteVtctlCommandResponse") + proto.RegisterType((*GetCellInfoNamesRequest)(nil), "vtctldata.GetCellInfoNamesRequest") + proto.RegisterType((*GetCellInfoNamesResponse)(nil), "vtctldata.GetCellInfoNamesResponse") + proto.RegisterType((*GetCellInfoRequest)(nil), "vtctldata.GetCellInfoRequest") + proto.RegisterType((*GetCellInfoResponse)(nil), "vtctldata.GetCellInfoResponse") + proto.RegisterType((*GetCellsAliasesRequest)(nil), "vtctldata.GetCellsAliasesRequest") + proto.RegisterType((*GetCellsAliasesResponse)(nil), "vtctldata.GetCellsAliasesResponse") + proto.RegisterMapType((map[string]*topodata.CellsAlias)(nil), "vtctldata.GetCellsAliasesResponse.AliasesEntry") proto.RegisterType((*GetKeyspacesRequest)(nil), "vtctldata.GetKeyspacesRequest") proto.RegisterType((*GetKeyspacesResponse)(nil), "vtctldata.GetKeyspacesResponse") proto.RegisterType((*GetKeyspaceRequest)(nil), "vtctldata.GetKeyspaceRequest") diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index b22a1288dec..35d17c1efea 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -158,8 +158,17 @@ var _Vtctl_serviceDesc = grpc.ServiceDesc{ // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type VtctldClient interface { - // FindAllShardsInKeyspace returns a map of shard names to shard references for a given keyspace. + // FindAllShardsInKeyspace returns a map of shard names to shard references + // for a given keyspace. FindAllShardsInKeyspace(ctx context.Context, in *vtctldata.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.FindAllShardsInKeyspaceResponse, error) + // GetCellInfoNames returns all the cells for which we have a CellInfo object, + // meaning we have a topology service registered. + GetCellInfoNames(ctx context.Context, in *vtctldata.GetCellInfoNamesRequest, opts ...grpc.CallOption) (*vtctldata.GetCellInfoNamesResponse, error) + // GetCellInfo returns the information for a cell. + GetCellInfo(ctx context.Context, in *vtctldata.GetCellInfoRequest, opts ...grpc.CallOption) (*vtctldata.GetCellInfoResponse, error) + // GetCellsAliases returns a mapping of cell alias to cells identified by that + // alias. + GetCellsAliases(ctx context.Context, in *vtctldata.GetCellsAliasesRequest, opts ...grpc.CallOption) (*vtctldata.GetCellsAliasesResponse, error) // GetKeyspace reads the given keyspace from the topo and returns it. GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. @@ -183,6 +192,33 @@ func (c *vtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldat return out, nil } +func (c *vtctldClient) GetCellInfoNames(ctx context.Context, in *vtctldata.GetCellInfoNamesRequest, opts ...grpc.CallOption) (*vtctldata.GetCellInfoNamesResponse, error) { + out := new(vtctldata.GetCellInfoNamesResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetCellInfoNames", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) GetCellInfo(ctx context.Context, in *vtctldata.GetCellInfoRequest, opts ...grpc.CallOption) (*vtctldata.GetCellInfoResponse, error) { + out := new(vtctldata.GetCellInfoResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetCellInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) GetCellsAliases(ctx context.Context, in *vtctldata.GetCellsAliasesRequest, opts ...grpc.CallOption) (*vtctldata.GetCellsAliasesResponse, error) { + out := new(vtctldata.GetCellsAliasesResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetCellsAliases", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) { out := new(vtctldata.GetKeyspaceResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetKeyspace", in, out, opts...) @@ -203,8 +239,17 @@ func (c *vtctldClient) GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspa // VtctldServer is the server API for Vtctld service. type VtctldServer interface { - // FindAllShardsInKeyspace returns a map of shard names to shard references for a given keyspace. + // FindAllShardsInKeyspace returns a map of shard names to shard references + // for a given keyspace. FindAllShardsInKeyspace(context.Context, *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) + // GetCellInfoNames returns all the cells for which we have a CellInfo object, + // meaning we have a topology service registered. + GetCellInfoNames(context.Context, *vtctldata.GetCellInfoNamesRequest) (*vtctldata.GetCellInfoNamesResponse, error) + // GetCellInfo returns the information for a cell. + GetCellInfo(context.Context, *vtctldata.GetCellInfoRequest) (*vtctldata.GetCellInfoResponse, error) + // GetCellsAliases returns a mapping of cell alias to cells identified by that + // alias. + GetCellsAliases(context.Context, *vtctldata.GetCellsAliasesRequest) (*vtctldata.GetCellsAliasesResponse, error) // GetKeyspace reads the given keyspace from the topo and returns it. GetKeyspace(context.Context, *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. @@ -218,6 +263,15 @@ type UnimplementedVtctldServer struct { func (*UnimplementedVtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method FindAllShardsInKeyspace not implemented") } +func (*UnimplementedVtctldServer) GetCellInfoNames(ctx context.Context, req *vtctldata.GetCellInfoNamesRequest) (*vtctldata.GetCellInfoNamesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCellInfoNames not implemented") +} +func (*UnimplementedVtctldServer) GetCellInfo(ctx context.Context, req *vtctldata.GetCellInfoRequest) (*vtctldata.GetCellInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCellInfo not implemented") +} +func (*UnimplementedVtctldServer) GetCellsAliases(ctx context.Context, req *vtctldata.GetCellsAliasesRequest) (*vtctldata.GetCellsAliasesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCellsAliases not implemented") +} func (*UnimplementedVtctldServer) GetKeyspace(ctx context.Context, req *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetKeyspace not implemented") } @@ -247,6 +301,60 @@ func _Vtctld_FindAllShardsInKeyspace_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _Vtctld_GetCellInfoNames_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetCellInfoNamesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetCellInfoNames(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetCellInfoNames", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetCellInfoNames(ctx, req.(*vtctldata.GetCellInfoNamesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_GetCellInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetCellInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetCellInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetCellInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetCellInfo(ctx, req.(*vtctldata.GetCellInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_GetCellsAliases_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetCellsAliasesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetCellsAliases(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetCellsAliases", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetCellsAliases(ctx, req.(*vtctldata.GetCellsAliasesRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_GetKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.GetKeyspaceRequest) if err := dec(in); err != nil { @@ -291,6 +399,18 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "FindAllShardsInKeyspace", Handler: _Vtctld_FindAllShardsInKeyspace_Handler, }, + { + MethodName: "GetCellInfoNames", + Handler: _Vtctld_GetCellInfoNames_Handler, + }, + { + MethodName: "GetCellInfo", + Handler: _Vtctld_GetCellInfo_Handler, + }, + { + MethodName: "GetCellsAliases", + Handler: _Vtctld_GetCellsAliases_Handler, + }, { MethodName: "GetKeyspace", Handler: _Vtctld_GetKeyspace_Handler, diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index cbe87b15d87..0c600794202 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -37,6 +37,33 @@ func (client *gRPCVtctldClient) FindAllShardsInKeyspace(ctx context.Context, in return client.c.FindAllShardsInKeyspace(ctx, in, opts...) } +// GetCellInfo is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetCellInfo(ctx context.Context, in *vtctldatapb.GetCellInfoRequest, opts ...grpc.CallOption) (*vtctldatapb.GetCellInfoResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetCellInfo(ctx, in, opts...) +} + +// GetCellInfoNames is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetCellInfoNames(ctx context.Context, in *vtctldatapb.GetCellInfoNamesRequest, opts ...grpc.CallOption) (*vtctldatapb.GetCellInfoNamesResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetCellInfoNames(ctx, in, opts...) +} + +// GetCellsAliases is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetCellsAliases(ctx context.Context, in *vtctldatapb.GetCellsAliasesRequest, opts ...grpc.CallOption) (*vtctldatapb.GetCellsAliasesResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetCellsAliases(ctx, in, opts...) +} + // GetKeyspace is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) GetKeyspace(ctx context.Context, in *vtctldatapb.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.GetKeyspaceResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 3814bc62165..04b4f0a1cc1 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -21,9 +21,11 @@ import ( "google.golang.org/grpc" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vterrors" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" + "vitess.io/vitess/go/vt/proto/vtrpc" ) // VtctldServer implements the Vtctld RPC service protocol. @@ -57,6 +59,44 @@ func (s *VtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctlda }, nil } +// GetCellInfoNames is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetCellInfoNames(ctx context.Context, req *vtctldatapb.GetCellInfoNamesRequest) (*vtctldatapb.GetCellInfoNamesResponse, error) { + names, err := s.ts.GetCellInfoNames(ctx) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetCellInfoNamesResponse{Names: names}, nil +} + +// GetCellInfo is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetCellInfo(ctx context.Context, req *vtctldatapb.GetCellInfoRequest) (*vtctldatapb.GetCellInfoResponse, error) { + if req.Cell == "" { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "cell field is required") + } + + // We use a strong read, because users using this command want the latest + // data, and this is user-generated, not used in any automated process. + strongRead := true + ci, err := s.ts.GetCellInfo(ctx, req.Cell, strongRead) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetCellInfoResponse{CellInfo: ci}, nil +} + +// GetCellsAliases is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetCellsAliases(ctx context.Context, req *vtctldatapb.GetCellsAliasesRequest) (*vtctldatapb.GetCellsAliasesResponse, error) { + strongRead := true + aliases, err := s.ts.GetCellsAliases(ctx, strongRead) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetCellsAliasesResponse{Aliases: aliases}, nil +} + // GetKeyspace is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) GetKeyspace(ctx context.Context, req *vtctldatapb.GetKeyspaceRequest) (*vtctldatapb.GetKeyspaceResponse, error) { keyspace, err := s.ts.GetKeyspace(ctx, req.Keyspace) diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 1a7142ea09e..cd553e53c0d 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -37,6 +37,28 @@ message ExecuteVtctlCommandResponse { logutil.Event event = 1; } +message GetCellInfoNamesRequest { +} + +message GetCellInfoNamesResponse { + repeated string names = 1; +} + +message GetCellInfoRequest { + string cell = 1; +} + +message GetCellInfoResponse { + topodata.CellInfo cell_info = 1; +} + +message GetCellsAliasesRequest { +} + +message GetCellsAliasesResponse { + map aliases = 1; +} + message GetKeyspacesRequest { } diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index ebd82714774..4007550f587 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -31,8 +31,17 @@ service Vtctl { // Service Vtctld exposes gRPC endpoints for each vt command. service Vtctld { - // FindAllShardsInKeyspace returns a map of shard names to shard references for a given keyspace. + // FindAllShardsInKeyspace returns a map of shard names to shard references + // for a given keyspace. rpc FindAllShardsInKeyspace(vtctldata.FindAllShardsInKeyspaceRequest) returns (vtctldata.FindAllShardsInKeyspaceResponse) {}; + // GetCellInfoNames returns all the cells for which we have a CellInfo object, + // meaning we have a topology service registered. + rpc GetCellInfoNames(vtctldata.GetCellInfoNamesRequest) returns (vtctldata.GetCellInfoNamesResponse) {}; + // GetCellInfo returns the information for a cell. + rpc GetCellInfo(vtctldata.GetCellInfoRequest) returns (vtctldata.GetCellInfoResponse) {}; + // GetCellsAliases returns a mapping of cell alias to cells identified by that + // alias. + rpc GetCellsAliases(vtctldata.GetCellsAliasesRequest) returns (vtctldata.GetCellsAliasesResponse) {}; // GetKeyspace reads the given keyspace from the topo and returns it. rpc GetKeyspace(vtctldata.GetKeyspaceRequest) returns (vtctldata.GetKeyspaceResponse) {}; // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. From 70eeab5f5fdc8adf8e84af4ac6c2d956d1e6bc40 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Mon, 18 Jan 2021 16:09:56 +0100 Subject: [PATCH 07/21] Merge pull request #7311 from tinyspeck/am_vtctld_tablet_getters [vtctld] migrate tablet getters --- go/cmd/vtctldclient/commands.go | 119 ++++++ go/cmd/vtctldclient/formats.go | 38 ++ go/vt/proto/vtctldata/vtctldata.pb.go | 288 ++++++++++--- go/vt/proto/vtctlservice/vtctlservice.pb.go | 114 ++++- go/vt/vtctl/grpcvtctldclient/client_gen.go | 18 + go/vt/vtctl/grpcvtctldserver/server.go | 107 +++++ go/vt/vtctl/grpcvtctldserver/server_test.go | 393 ++++++++++++++++++ go/vt/vtctl/grpcvtctldserver/testutil/util.go | 100 +++++ proto/vtctldata.proto | 23 + proto/vtctlservice.proto | 4 + 10 files changed, 1141 insertions(+), 63 deletions(-) create mode 100644 go/cmd/vtctldclient/formats.go create mode 100644 go/vt/vtctl/grpcvtctldserver/testutil/util.go diff --git a/go/cmd/vtctldclient/commands.go b/go/cmd/vtctldclient/commands.go index 8603489c6a2..4b720e84378 100644 --- a/go/cmd/vtctldclient/commands.go +++ b/go/cmd/vtctldclient/commands.go @@ -19,9 +19,15 @@ package main import ( "fmt" "strings" + "time" "github.com/spf13/cobra" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -59,6 +65,16 @@ var ( Args: cobra.NoArgs, RunE: commandGetKeyspaces, } + getTabletCmd = &cobra.Command{ + Use: "GetTablet alias", + Args: cobra.ExactArgs(1), + RunE: commandGetTablet, + } + getTabletsCmd = &cobra.Command{ + Use: "GetTablets [--cell $c1, ...] [--keyspace $ks [--shard $shard]]", + Args: cobra.NoArgs, + RunE: commandGetTablets, + } ) func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { @@ -156,11 +172,114 @@ func commandGetKeyspaces(cmd *cobra.Command, args []string) error { return nil } +func commandGetTablet(cmd *cobra.Command, args []string) error { + aliasStr := cmd.Flags().Arg(0) + alias, err := topoproto.ParseTabletAlias(aliasStr) + if err != nil { + return err + } + + resp, err := client.GetTablet(commandCtx, &vtctldatapb.GetTabletRequest{TabletAlias: alias}) + if err != nil { + return err + } + + data, err := MarshalJSON(resp.Tablet) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +var getTabletsArgs = struct { + Cells []string + Keyspace string + Shard string + + Format string +}{} + +func commandGetTablets(cmd *cobra.Command, args []string) error { + format := strings.ToLower(getTabletsArgs.Format) + + switch format { + case "awk", "json": + default: + return fmt.Errorf("invalid output format, got %s", getTabletsArgs.Format) + } + + if getTabletsArgs.Keyspace == "" && getTabletsArgs.Shard != "" { + return fmt.Errorf("--shard (= %s) cannot be passed without also passing --keyspace", getTabletsArgs.Shard) + } + + resp, err := client.GetTablets(commandCtx, &vtctldatapb.GetTabletsRequest{ + Cells: getTabletsArgs.Cells, + Keyspace: getTabletsArgs.Keyspace, + Shard: getTabletsArgs.Shard, + }) + if err != nil { + return err + } + + switch format { + case "awk": + lineFn := func(t *topodatapb.Tablet) string { + ti := topo.TabletInfo{ + Tablet: t, + } + + keyspace := t.Keyspace + if keyspace == "" { + keyspace = "" + } + + shard := t.Shard + if shard == "" { + shard = "" + } + + mtst := "" + // special case for old primary that hasn't been updated in the topo + // yet. + if t.MasterTermStartTime != nil && t.MasterTermStartTime.Seconds > 0 { + mtst = logutil.ProtoToTime(t.MasterTermStartTime).Format(time.RFC3339) + } + + return fmt.Sprintf("%v %v %v %v %v %v %v %v", topoproto.TabletAliasString(t.Alias), keyspace, shard, topoproto.TabletTypeLString(t.Type), ti.Addr(), ti.MysqlAddr(), fmtMapAwkable(t.Tags), mtst) + } + + for _, t := range resp.Tablets { + fmt.Println(lineFn(t)) + } + case "json": + data, err := MarshalJSON(resp.Tablets) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + } + + return nil +} + func init() { rootCmd.AddCommand(findAllShardsInKeyspaceCmd) + rootCmd.AddCommand(getCellInfoNamesCmd) rootCmd.AddCommand(getCellInfoCmd) rootCmd.AddCommand(getCellsAliasesCmd) + rootCmd.AddCommand(getKeyspaceCmd) rootCmd.AddCommand(getKeyspacesCmd) + + rootCmd.AddCommand(getTabletCmd) + getTabletsCmd.Flags().StringSliceVarP(&getTabletsArgs.Cells, "cell", "c", nil, "TODO") + getTabletsCmd.Flags().StringVarP(&getTabletsArgs.Keyspace, "keyspace", "k", "", "TODO") + getTabletsCmd.Flags().StringVarP(&getTabletsArgs.Shard, "shard", "s", "", "TODO") + getTabletsCmd.Flags().StringVar(&getTabletsArgs.Format, "format", "awk", "Output format to use; valid choices are (json, awk)") + rootCmd.AddCommand(getTabletsCmd) } diff --git a/go/cmd/vtctldclient/formats.go b/go/cmd/vtctldclient/formats.go new file mode 100644 index 00000000000..152d6684579 --- /dev/null +++ b/go/cmd/vtctldclient/formats.go @@ -0,0 +1,38 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "fmt" + "sort" + "strings" +) + +func fmtMapAwkable(m map[string]string) string { + pairs := make([]string, len(m)) + i := 0 + + for k, v := range m { + pairs[i] = fmt.Sprintf("%v: %q", k, v) + + i++ + } + + sort.Strings(pairs) + + return "[" + strings.Join(pairs, " ") + "]" +} diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 90d7811045a..4e6762da1f5 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -478,6 +478,183 @@ func (m *GetKeyspaceResponse) GetKeyspace() *Keyspace { return nil } +type GetTabletRequest struct { + TabletAlias *topodata.TabletAlias `protobuf:"bytes,1,opt,name=tablet_alias,json=tabletAlias,proto3" json:"tablet_alias,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetTabletRequest) Reset() { *m = GetTabletRequest{} } +func (m *GetTabletRequest) String() string { return proto.CompactTextString(m) } +func (*GetTabletRequest) ProtoMessage() {} +func (*GetTabletRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{12} +} + +func (m *GetTabletRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetTabletRequest.Unmarshal(m, b) +} +func (m *GetTabletRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetTabletRequest.Marshal(b, m, deterministic) +} +func (m *GetTabletRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetTabletRequest.Merge(m, src) +} +func (m *GetTabletRequest) XXX_Size() int { + return xxx_messageInfo_GetTabletRequest.Size(m) +} +func (m *GetTabletRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetTabletRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetTabletRequest proto.InternalMessageInfo + +func (m *GetTabletRequest) GetTabletAlias() *topodata.TabletAlias { + if m != nil { + return m.TabletAlias + } + return nil +} + +type GetTabletResponse struct { + Tablet *topodata.Tablet `protobuf:"bytes,1,opt,name=tablet,proto3" json:"tablet,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetTabletResponse) Reset() { *m = GetTabletResponse{} } +func (m *GetTabletResponse) String() string { return proto.CompactTextString(m) } +func (*GetTabletResponse) ProtoMessage() {} +func (*GetTabletResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{13} +} + +func (m *GetTabletResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetTabletResponse.Unmarshal(m, b) +} +func (m *GetTabletResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetTabletResponse.Marshal(b, m, deterministic) +} +func (m *GetTabletResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetTabletResponse.Merge(m, src) +} +func (m *GetTabletResponse) XXX_Size() int { + return xxx_messageInfo_GetTabletResponse.Size(m) +} +func (m *GetTabletResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetTabletResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetTabletResponse proto.InternalMessageInfo + +func (m *GetTabletResponse) GetTablet() *topodata.Tablet { + if m != nil { + return m.Tablet + } + return nil +} + +type GetTabletsRequest struct { + // Keyspace is the name of the keyspace to return tablets for. Omit to return + // all tablets. + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + // Shard is the name of the shard to return tablets for. This field is ignored + // if Keyspace is not set. + Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` + // Cells is an optional set of cells to return tablets for. + Cells []string `protobuf:"bytes,3,rep,name=cells,proto3" json:"cells,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetTabletsRequest) Reset() { *m = GetTabletsRequest{} } +func (m *GetTabletsRequest) String() string { return proto.CompactTextString(m) } +func (*GetTabletsRequest) ProtoMessage() {} +func (*GetTabletsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{14} +} + +func (m *GetTabletsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetTabletsRequest.Unmarshal(m, b) +} +func (m *GetTabletsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetTabletsRequest.Marshal(b, m, deterministic) +} +func (m *GetTabletsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetTabletsRequest.Merge(m, src) +} +func (m *GetTabletsRequest) XXX_Size() int { + return xxx_messageInfo_GetTabletsRequest.Size(m) +} +func (m *GetTabletsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetTabletsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetTabletsRequest proto.InternalMessageInfo + +func (m *GetTabletsRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *GetTabletsRequest) GetShard() string { + if m != nil { + return m.Shard + } + return "" +} + +func (m *GetTabletsRequest) GetCells() []string { + if m != nil { + return m.Cells + } + return nil +} + +type GetTabletsResponse struct { + Tablets []*topodata.Tablet `protobuf:"bytes,1,rep,name=tablets,proto3" json:"tablets,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetTabletsResponse) Reset() { *m = GetTabletsResponse{} } +func (m *GetTabletsResponse) String() string { return proto.CompactTextString(m) } +func (*GetTabletsResponse) ProtoMessage() {} +func (*GetTabletsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{15} +} + +func (m *GetTabletsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetTabletsResponse.Unmarshal(m, b) +} +func (m *GetTabletsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetTabletsResponse.Marshal(b, m, deterministic) +} +func (m *GetTabletsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetTabletsResponse.Merge(m, src) +} +func (m *GetTabletsResponse) XXX_Size() int { + return xxx_messageInfo_GetTabletsResponse.Size(m) +} +func (m *GetTabletsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetTabletsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetTabletsResponse proto.InternalMessageInfo + +func (m *GetTabletsResponse) GetTablets() []*topodata.Tablet { + if m != nil { + return m.Tablets + } + return nil +} + type Keyspace struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Keyspace *topodata.Keyspace `protobuf:"bytes,2,opt,name=keyspace,proto3" json:"keyspace,omitempty"` @@ -490,7 +667,7 @@ func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{6} + return fileDescriptor_f41247b323a1ab2e, []int{16} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { @@ -536,7 +713,7 @@ func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInK func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{7} + return fileDescriptor_f41247b323a1ab2e, []int{17} } func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -575,7 +752,7 @@ func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsIn func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{8} + return fileDescriptor_f41247b323a1ab2e, []int{18} } func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -616,7 +793,7 @@ func (m *Shard) Reset() { *m = Shard{} } func (m *Shard) String() string { return proto.CompactTextString(m) } func (*Shard) ProtoMessage() {} func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{9} + return fileDescriptor_f41247b323a1ab2e, []int{19} } func (m *Shard) XXX_Unmarshal(b []byte) error { @@ -676,7 +853,7 @@ func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettin func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } func (*TableMaterializeSettings) ProtoMessage() {} func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{10} + return fileDescriptor_f41247b323a1ab2e, []int{20} } func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -739,7 +916,7 @@ func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } func (*MaterializeSettings) ProtoMessage() {} func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{11} + return fileDescriptor_f41247b323a1ab2e, []int{21} } func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -823,6 +1000,10 @@ func init() { proto.RegisterType((*GetKeyspacesResponse)(nil), "vtctldata.GetKeyspacesResponse") proto.RegisterType((*GetKeyspaceRequest)(nil), "vtctldata.GetKeyspaceRequest") proto.RegisterType((*GetKeyspaceResponse)(nil), "vtctldata.GetKeyspaceResponse") + proto.RegisterType((*GetTabletRequest)(nil), "vtctldata.GetTabletRequest") + proto.RegisterType((*GetTabletResponse)(nil), "vtctldata.GetTabletResponse") + proto.RegisterType((*GetTabletsRequest)(nil), "vtctldata.GetTabletsRequest") + proto.RegisterType((*GetTabletsResponse)(nil), "vtctldata.GetTabletsResponse") proto.RegisterType((*Keyspace)(nil), "vtctldata.Keyspace") proto.RegisterType((*FindAllShardsInKeyspaceRequest)(nil), "vtctldata.FindAllShardsInKeyspaceRequest") proto.RegisterType((*FindAllShardsInKeyspaceResponse)(nil), "vtctldata.FindAllShardsInKeyspaceResponse") @@ -835,45 +1016,58 @@ func init() { func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 629 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xdf, 0x6e, 0xd3, 0x30, - 0x14, 0xc6, 0x95, 0x76, 0x1d, 0xed, 0x29, 0x6d, 0x87, 0x07, 0x52, 0x54, 0x04, 0x94, 0xc0, 0xb6, - 0x4a, 0x48, 0x29, 0x0c, 0x09, 0x21, 0xc4, 0xcd, 0x18, 0x1d, 0x1a, 0x13, 0xbb, 0xc8, 0x26, 0x90, - 0xb8, 0x20, 0xf2, 0x92, 0xb3, 0x12, 0xcd, 0x8d, 0x43, 0x7c, 0xda, 0xad, 0xbc, 0x01, 0x2f, 0xc3, - 0x23, 0xf0, 0x6c, 0x28, 0x76, 0x92, 0x66, 0x68, 0x03, 0x71, 0xe7, 0xfc, 0xce, 0xbf, 0xef, 0x7c, - 0xb6, 0x02, 0xbd, 0x39, 0x05, 0x24, 0x42, 0x4e, 0xdc, 0x4d, 0x52, 0x49, 0x92, 0xb5, 0x4a, 0xd0, - 0xef, 0x08, 0x39, 0x99, 0x51, 0x24, 0x4c, 0xa4, 0xdf, 0x25, 0x99, 0xc8, 0x65, 0xa6, 0xf3, 0x09, - 0xfa, 0xe3, 0x0b, 0x0c, 0x66, 0x84, 0x1f, 0xb3, 0x92, 0x5d, 0x39, 0x9d, 0xf2, 0x38, 0xf4, 0xf0, - 0xdb, 0x0c, 0x15, 0x31, 0x06, 0x2b, 0x3c, 0x9d, 0x28, 0xdb, 0x1a, 0xd4, 0x87, 0x2d, 0x4f, 0x9f, - 0xd9, 0x06, 0x74, 0x79, 0x40, 0x91, 0x8c, 0x7d, 0x8a, 0xa6, 0x28, 0x67, 0x64, 0xd7, 0x06, 0xd6, - 0xb0, 0xee, 0x75, 0x0c, 0x3d, 0x36, 0xd0, 0xd9, 0x85, 0xbb, 0x57, 0x36, 0x56, 0x89, 0x8c, 0x15, - 0xb2, 0xc7, 0xd0, 0xc0, 0x39, 0xc6, 0x64, 0x5b, 0x03, 0x6b, 0xd8, 0xde, 0xee, 0xba, 0x85, 0xcc, - 0x71, 0x46, 0x3d, 0x13, 0x74, 0xee, 0xc0, 0xfa, 0x3b, 0xa4, 0x03, 0x5c, 0xa8, 0x84, 0x07, 0xa8, - 0x72, 0x59, 0xce, 0x3e, 0xdc, 0xbe, 0x8c, 0xf3, 0xa6, 0xcf, 0xa0, 0x75, 0x56, 0x40, 0xad, 0xb9, - 0xbd, 0xbd, 0xee, 0x2e, 0xbd, 0x29, 0x0a, 0xbc, 0x65, 0x96, 0xf3, 0x14, 0x58, 0xa5, 0x55, 0xb1, - 0x77, 0x1f, 0x9a, 0x45, 0x8a, 0x16, 0xd8, 0xf2, 0xca, 0x6f, 0x67, 0xef, 0x92, 0xa6, 0x72, 0xf6, - 0xe8, 0x8f, 0x92, 0x6b, 0x46, 0x2f, 0xfb, 0x1c, 0x42, 0xb3, 0xa0, 0x99, 0xcf, 0x31, 0x9f, 0x16, - 0xb3, 0xf4, 0x99, 0xb9, 0x95, 0x86, 0x35, 0xdd, 0x90, 0xb9, 0xe5, 0xe5, 0x5d, 0xd1, 0xef, 0x35, - 0xdc, 0xdf, 0x8b, 0xe2, 0x70, 0x47, 0x88, 0xa3, 0xaf, 0x3c, 0x0d, 0xd5, 0x7e, 0xfc, 0x3f, 0x5b, - 0xfd, 0xb2, 0xe0, 0xc1, 0xb5, 0xe5, 0xf9, 0x8a, 0x87, 0xb0, 0xaa, 0x74, 0x2c, 0xf7, 0xf6, 0x45, - 0x65, 0xc1, 0x7f, 0xd4, 0xba, 0x26, 0x30, 0x8e, 0x29, 0x5d, 0x78, 0x79, 0x97, 0xfe, 0x01, 0xb4, - 0x2b, 0x98, 0xad, 0x41, 0xfd, 0x0c, 0x17, 0xb9, 0xb2, 0xec, 0xc8, 0x36, 0xa1, 0x31, 0xe7, 0x62, - 0x56, 0xec, 0xbf, 0x56, 0x99, 0xa7, 0x0b, 0x3d, 0x13, 0x7e, 0x55, 0x7b, 0x69, 0x39, 0x5f, 0xa0, - 0xa1, 0xd9, 0xdf, 0xb6, 0x2c, 0x7d, 0xae, 0x55, 0x7c, 0xde, 0x80, 0x86, 0xd6, 0x63, 0xd7, 0xf5, - 0x90, 0xde, 0xd2, 0xe4, 0x7c, 0x86, 0x8e, 0x3a, 0x3f, 0x2c, 0xb0, 0x8f, 0xf9, 0x89, 0xc0, 0x0f, - 0x9c, 0x30, 0x8d, 0xb8, 0x88, 0xbe, 0xe3, 0x11, 0x12, 0x45, 0xf1, 0x44, 0xb1, 0x87, 0x70, 0x93, - 0x78, 0x3a, 0x41, 0xf2, 0x29, 0x4b, 0xc9, 0xe7, 0xb6, 0x0d, 0xd3, 0x55, 0xec, 0x09, 0xdc, 0x52, - 0x72, 0x96, 0x06, 0xe8, 0xe3, 0x45, 0x92, 0xa2, 0x52, 0x91, 0x8c, 0x73, 0x1d, 0x6b, 0x26, 0x30, - 0x2e, 0x39, 0xbb, 0x07, 0x10, 0xa4, 0xc8, 0x09, 0xfd, 0x30, 0x14, 0x5a, 0x58, 0xcb, 0x6b, 0x19, - 0xf2, 0x36, 0x14, 0xce, 0xcf, 0x1a, 0xac, 0x5f, 0x25, 0xa3, 0x0f, 0xcd, 0x73, 0x99, 0x9e, 0x9d, - 0x0a, 0x79, 0x5e, 0xac, 0x5e, 0x7c, 0xb3, 0x2d, 0xe8, 0xe5, 0xf3, 0x2f, 0xbd, 0xaa, 0x96, 0xd7, - 0x35, 0xb8, 0x7c, 0x8b, 0x5b, 0xd0, 0xcb, 0x77, 0x29, 0x13, 0x8d, 0x80, 0xae, 0xc1, 0x65, 0xe2, - 0x26, 0xf4, 0x14, 0xc9, 0xc4, 0xe7, 0xa7, 0x84, 0xa9, 0x1f, 0xc8, 0x64, 0x61, 0xaf, 0x0c, 0xac, - 0x61, 0xd3, 0xeb, 0x64, 0x78, 0x27, 0xa3, 0xbb, 0x32, 0x59, 0xb0, 0xf7, 0xd0, 0xd5, 0xae, 0xf8, - 0x2a, 0xd7, 0x69, 0x37, 0xf4, 0xf3, 0x79, 0x54, 0xb9, 0xce, 0xeb, 0x9c, 0xf5, 0x3a, 0xba, 0xb4, - 0xdc, 0x90, 0xc1, 0x4a, 0x80, 0x42, 0xd8, 0xab, 0xe6, 0x02, 0xb3, 0xb3, 0x31, 0xff, 0x44, 0x64, - 0xe6, 0x2f, 0x12, 0x54, 0xf6, 0x8d, 0xc2, 0xfc, 0x8c, 0x1d, 0x67, 0xe8, 0xcd, 0xf0, 0xf3, 0xe6, - 0x3c, 0x22, 0x54, 0xca, 0x8d, 0xe4, 0xc8, 0x9c, 0x46, 0x13, 0x39, 0x9a, 0xd3, 0x48, 0xff, 0x05, - 0x47, 0xa5, 0x90, 0x93, 0x55, 0x0d, 0x9e, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x2e, 0xa9, 0x4e, - 0xcf, 0x53, 0x05, 0x00, 0x00, + // 844 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x6e, 0xe3, 0x44, + 0x14, 0x96, 0x93, 0x4d, 0x1a, 0x9f, 0x6c, 0x7e, 0xd6, 0xed, 0x82, 0x09, 0x02, 0x82, 0x61, 0xbb, + 0xd1, 0x22, 0x39, 0xa5, 0x48, 0xa8, 0x42, 0x20, 0x51, 0x42, 0x5a, 0x85, 0x42, 0x85, 0xdc, 0x0a, + 0x24, 0x90, 0xb0, 0xa6, 0xce, 0x24, 0x58, 0x9d, 0x78, 0x8c, 0x67, 0x92, 0x36, 0xbc, 0x01, 0x2f, + 0xc3, 0x25, 0x97, 0x3c, 0x1b, 0x9a, 0x3f, 0xdb, 0x69, 0x13, 0x60, 0xef, 0x66, 0xbe, 0xf3, 0xf7, + 0x9d, 0xef, 0xcc, 0xb1, 0xa1, 0xb3, 0xe2, 0x11, 0x27, 0x53, 0xc4, 0x91, 0x9f, 0x66, 0x94, 0x53, + 0xc7, 0xce, 0x81, 0x5e, 0x8b, 0xd0, 0xf9, 0x92, 0xc7, 0x44, 0x59, 0x7a, 0x6d, 0x4e, 0x53, 0x5a, + 0x78, 0x7a, 0x3f, 0x42, 0x6f, 0x7c, 0x8f, 0xa3, 0x25, 0xc7, 0x3f, 0x88, 0x90, 0x11, 0x5d, 0x2c, + 0x50, 0x32, 0x0d, 0xf0, 0x6f, 0x4b, 0xcc, 0xb8, 0xe3, 0xc0, 0x13, 0x94, 0xcd, 0x99, 0x6b, 0xf5, + 0xab, 0x03, 0x3b, 0x90, 0x67, 0xe7, 0x05, 0xb4, 0x51, 0xc4, 0x63, 0x9a, 0x84, 0x3c, 0x5e, 0x60, + 0xba, 0xe4, 0x6e, 0xa5, 0x6f, 0x0d, 0xaa, 0x41, 0x4b, 0xa1, 0xd7, 0x0a, 0xf4, 0x46, 0xf0, 0xf6, + 0xd6, 0xc4, 0x2c, 0xa5, 0x09, 0xc3, 0xce, 0x87, 0x50, 0xc3, 0x2b, 0x9c, 0x70, 0xd7, 0xea, 0x5b, + 0x83, 0xe6, 0x71, 0xdb, 0x37, 0x34, 0xc7, 0x02, 0x0d, 0x94, 0xd1, 0x7b, 0x0b, 0xde, 0x3c, 0xc7, + 0x7c, 0x84, 0x09, 0x99, 0x24, 0x33, 0x7a, 0x89, 0x16, 0x98, 0x69, 0x6a, 0xde, 0x11, 0xb8, 0x8f, + 0x4d, 0x3a, 0xf9, 0x01, 0xd4, 0x12, 0x01, 0x68, 0xde, 0xea, 0xe2, 0x0d, 0xc0, 0x29, 0x45, 0x94, + 0x5a, 0x8c, 0x30, 0x21, 0x92, 0x87, 0x1d, 0xc8, 0xb3, 0x77, 0x06, 0xfb, 0x1b, 0x9e, 0x3a, 0xed, + 0x10, 0x6c, 0x61, 0x0e, 0xe3, 0x64, 0x46, 0x35, 0x6f, 0xc7, 0xcf, 0xf5, 0xcc, 0xdd, 0x1b, 0x91, + 0x3e, 0x79, 0x2e, 0xbc, 0xa1, 0xf3, 0xb0, 0x53, 0x12, 0x23, 0x56, 0xb0, 0xff, 0xcb, 0xca, 0x3b, + 0x2b, 0x4c, 0xba, 0xcc, 0x04, 0xf6, 0x90, 0x82, 0x24, 0xff, 0xe6, 0xf1, 0xd0, 0x2f, 0xe6, 0xbb, + 0x23, 0xc8, 0xd7, 0xf7, 0x71, 0xc2, 0xb3, 0x75, 0x60, 0xe2, 0x7b, 0xdf, 0xc3, 0xd3, 0xb2, 0xc1, + 0xe9, 0x42, 0xf5, 0x16, 0xaf, 0x75, 0xaf, 0xe2, 0xe8, 0xbc, 0x82, 0xda, 0x0a, 0x91, 0x25, 0x96, + 0x43, 0x6c, 0x1e, 0x1f, 0x6c, 0xf6, 0xa3, 0xca, 0x04, 0xca, 0xe5, 0xb3, 0xca, 0x89, 0xe5, 0x3d, + 0x97, 0xd2, 0x5c, 0xe0, 0x35, 0x4b, 0x51, 0x54, 0xf4, 0x33, 0x81, 0x83, 0x4d, 0x58, 0xf7, 0xf2, + 0x31, 0xd8, 0xb7, 0x06, 0xd4, 0xdd, 0xec, 0x97, 0xba, 0x31, 0x01, 0x41, 0xe1, 0xe5, 0x1d, 0xc9, + 0x31, 0xe5, 0x16, 0x3d, 0xa6, 0x1e, 0x34, 0x8c, 0x8b, 0xa6, 0x9f, 0xdf, 0xf5, 0xb8, 0x8a, 0x88, + 0x7c, 0x5c, 0x9b, 0x21, 0x3b, 0x4a, 0x17, 0x79, 0xbe, 0x85, 0xee, 0x39, 0xe6, 0xd7, 0xe8, 0x86, + 0x60, 0x6e, 0xea, 0x9e, 0xc0, 0x53, 0x2e, 0x81, 0x50, 0x6a, 0xaa, 0x13, 0x3d, 0x2f, 0x64, 0x52, + 0xee, 0x4a, 0xa7, 0x26, 0x2f, 0x2e, 0xde, 0x17, 0xf0, 0xac, 0x94, 0x4d, 0x73, 0x1a, 0x40, 0x5d, + 0xf9, 0xe8, 0x44, 0xdd, 0x87, 0x89, 0x02, 0x6d, 0xf7, 0x7e, 0x2e, 0x85, 0xb3, 0xff, 0xa1, 0x82, + 0x78, 0xf4, 0xec, 0x57, 0x94, 0x4d, 0xe5, 0x24, 0xed, 0x40, 0x5d, 0x04, 0x2a, 0x9e, 0x23, 0x73, + 0xab, 0x6a, 0x15, 0xe4, 0xc5, 0xfb, 0x52, 0x6a, 0x9c, 0x27, 0xd7, 0xe4, 0x5e, 0xc1, 0x9e, 0x2a, + 0x6e, 0x46, 0xf5, 0x98, 0x9d, 0x71, 0xf0, 0x2e, 0xa1, 0x61, 0x14, 0x14, 0x2b, 0x24, 0x36, 0xcc, + 0xac, 0x90, 0x38, 0x3b, 0x7e, 0x89, 0x69, 0xe5, 0xe1, 0xaa, 0x6c, 0xd1, 0xfe, 0x73, 0x78, 0xf7, + 0x2c, 0x4e, 0xa6, 0xa7, 0x84, 0x5c, 0x09, 0xde, 0x6c, 0x92, 0xbc, 0xce, 0x0b, 0xf8, 0xdb, 0x82, + 0xf7, 0x76, 0x86, 0xeb, 0xee, 0x2e, 0xa1, 0x2e, 0x25, 0x31, 0xcd, 0x7d, 0x5a, 0x7a, 0x0c, 0xff, + 0x11, 0xeb, 0x2b, 0x83, 0x5a, 0x2e, 0x9d, 0xa5, 0x77, 0x01, 0xcd, 0x12, 0xbc, 0x65, 0xb5, 0x0e, + 0x37, 0x57, 0xab, 0x5b, 0xaa, 0x27, 0x03, 0xcb, 0x6b, 0xf5, 0x0b, 0xd4, 0x24, 0xf6, 0xaf, 0x13, + 0x36, 0x3a, 0x57, 0x4a, 0x3a, 0xbf, 0x30, 0x53, 0xaf, 0xca, 0x22, 0x9d, 0x42, 0x64, 0x5d, 0x43, + 0x5a, 0xbd, 0x3f, 0x2c, 0x70, 0xe5, 0x08, 0xbf, 0x43, 0x1c, 0x67, 0x31, 0x22, 0xf1, 0xef, 0xf8, + 0x0a, 0x73, 0x1e, 0x27, 0x73, 0xe6, 0xbc, 0x2f, 0xde, 0x78, 0x36, 0xc7, 0x3c, 0x94, 0xd3, 0xd5, + 0x75, 0x9b, 0x0a, 0x93, 0x51, 0xce, 0x47, 0xf0, 0x8c, 0xd1, 0x65, 0x16, 0xe1, 0x10, 0xdf, 0xa7, + 0x19, 0x66, 0x2c, 0xa6, 0x89, 0xe6, 0xd1, 0x55, 0x86, 0x71, 0x8e, 0x3b, 0xef, 0x00, 0x44, 0x19, + 0x46, 0x1c, 0x87, 0xd3, 0x29, 0x91, 0xc4, 0xec, 0xc0, 0x56, 0xc8, 0xd7, 0x53, 0xe2, 0xfd, 0x59, + 0x81, 0xfd, 0x6d, 0x34, 0x7a, 0xd0, 0xb8, 0xa3, 0xd9, 0xed, 0x8c, 0xd0, 0x3b, 0xd3, 0xba, 0xb9, + 0x3b, 0x2f, 0xa1, 0xa3, 0xeb, 0x6f, 0xbc, 0x2a, 0x3b, 0x68, 0x2b, 0x38, 0x7f, 0x8b, 0x2f, 0xa1, + 0xa3, 0x7b, 0xc9, 0x1d, 0x15, 0x81, 0xb6, 0x82, 0x73, 0xc7, 0x43, 0xe8, 0x30, 0x4e, 0xd3, 0x10, + 0xcd, 0x38, 0xce, 0xc2, 0x88, 0xa6, 0x6b, 0xf7, 0x49, 0xdf, 0x1a, 0x34, 0x82, 0x96, 0x80, 0x4f, + 0x05, 0x3a, 0xa2, 0xe9, 0xda, 0xf9, 0x06, 0xda, 0x52, 0x95, 0x90, 0x69, 0x9e, 0x6e, 0x4d, 0x3e, + 0x9f, 0x0f, 0x4a, 0xe3, 0xdc, 0xa5, 0x6c, 0xd0, 0x92, 0xa1, 0x79, 0x87, 0xe6, 0x5f, 0x53, 0x2f, + 0xfe, 0x35, 0x4a, 0x7c, 0xf9, 0x81, 0xe1, 0xeb, 0x14, 0x33, 0x77, 0xcf, 0x88, 0x2f, 0xb0, 0x6b, + 0x01, 0x7d, 0x35, 0xf8, 0xe9, 0x70, 0x15, 0x73, 0xcc, 0x98, 0x1f, 0xd3, 0xa1, 0x3a, 0x0d, 0xe7, + 0x74, 0xb8, 0xe2, 0x43, 0xf9, 0x0f, 0x1f, 0xe6, 0x44, 0x6e, 0xea, 0x12, 0xf8, 0xe4, 0x9f, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xcb, 0x2a, 0x06, 0x49, 0x11, 0x08, 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 35d17c1efea..b0e6c73a1f7 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,22 +29,28 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 235 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x2b, 0x49, 0x2e, - 0xc9, 0x29, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, - 0x41, 0x16, 0x93, 0xe2, 0x07, 0xf3, 0x52, 0x12, 0x4b, 0x12, 0x21, 0xd2, 0x46, 0x85, 0x5c, 0xac, - 0x61, 0x20, 0x21, 0xa1, 0x0c, 0x2e, 0x61, 0xd7, 0x8a, 0xd4, 0xe4, 0xd2, 0x92, 0x54, 0x30, 0xdf, - 0x39, 0x3f, 0x37, 0x37, 0x31, 0x2f, 0x45, 0x48, 0x55, 0x0f, 0xa1, 0x03, 0x8b, 0x7c, 0x50, 0x6a, - 0x61, 0x69, 0x6a, 0x71, 0x89, 0x94, 0x1a, 0x21, 0x65, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x4a, - 0x0c, 0x06, 0x8c, 0x46, 0xf3, 0x99, 0xb8, 0xd8, 0xc0, 0x92, 0x29, 0x42, 0x45, 0x5c, 0xe2, 0x6e, - 0x99, 0x79, 0x29, 0x8e, 0x39, 0x39, 0xc1, 0x19, 0x89, 0x45, 0x29, 0xc5, 0x9e, 0x79, 0xde, 0xa9, - 0x95, 0xc5, 0x05, 0x89, 0xc9, 0xa9, 0x42, 0x9a, 0x48, 0x26, 0xe2, 0x50, 0x03, 0xb3, 0x5c, 0x8b, - 0x18, 0xa5, 0x30, 0x07, 0x08, 0xf9, 0x71, 0x71, 0xbb, 0xa7, 0x96, 0xc0, 0xed, 0x91, 0x45, 0xd2, - 0x8c, 0x24, 0x0e, 0x33, 0x5b, 0x0e, 0x97, 0x34, 0xdc, 0xbc, 0x40, 0x2e, 0x1e, 0x24, 0x89, 0x62, - 0x21, 0x1c, 0x3a, 0x8a, 0x61, 0x26, 0xca, 0xe3, 0x94, 0x87, 0x19, 0xe9, 0xa4, 0x1d, 0xa5, 0x59, - 0x96, 0x59, 0x92, 0x5a, 0x5c, 0xac, 0x97, 0x99, 0xaf, 0x0f, 0x61, 0xe9, 0xa7, 0xe7, 0xeb, 0x97, - 0x95, 0xe8, 0x83, 0x23, 0x4d, 0x1f, 0x39, 0x4a, 0x93, 0xd8, 0xc0, 0x62, 0xc6, 0x80, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xd5, 0x49, 0x16, 0xd1, 0xfd, 0x01, 0x00, 0x00, + // 332 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x5f, 0x4b, 0x32, 0x41, + 0x14, 0xc6, 0xdf, 0xf7, 0x42, 0xa1, 0x93, 0x60, 0x9c, 0x2e, 0x02, 0x4b, 0x23, 0xa3, 0xc0, 0x02, + 0x37, 0xec, 0x13, 0x98, 0x94, 0x89, 0x20, 0xf4, 0x87, 0x2e, 0x84, 0x2e, 0xc6, 0xdd, 0x53, 0x2e, + 0x8c, 0x3b, 0xba, 0x67, 0x5c, 0xea, 0xe3, 0xf5, 0xcd, 0xa2, 0xb5, 0x99, 0xb6, 0x6d, 0xc7, 0xba, + 0xdb, 0x3d, 0xbf, 0xe7, 0xfc, 0xe6, 0x61, 0x60, 0x00, 0x13, 0xed, 0x6b, 0xc9, 0x14, 0x27, 0xa1, + 0x4f, 0xed, 0x79, 0xac, 0xb4, 0xc2, 0x4a, 0x76, 0x56, 0xab, 0xa6, 0x7f, 0x81, 0xd0, 0x62, 0x85, + 0x3b, 0x0b, 0x28, 0x3d, 0x7c, 0x8c, 0x70, 0x0a, 0xdb, 0x97, 0x2f, 0xe4, 0x2f, 0x35, 0xa5, 0xff, + 0x3d, 0x35, 0x9b, 0x89, 0x28, 0xc0, 0xa3, 0xf6, 0xd7, 0x46, 0x01, 0xbf, 0xa5, 0xc5, 0x92, 0x58, + 0xd7, 0x8e, 0x7f, 0x8b, 0xf1, 0x5c, 0x45, 0x4c, 0xcd, 0x7f, 0x67, 0xff, 0x3b, 0x6f, 0x25, 0x28, + 0xa7, 0x30, 0xc0, 0x18, 0x76, 0xae, 0xc2, 0x28, 0xe8, 0x4a, 0x79, 0x37, 0x15, 0x71, 0xc0, 0x83, + 0x68, 0x48, 0xaf, 0x3c, 0x17, 0x3e, 0x61, 0x2b, 0x63, 0x74, 0x64, 0xcc, 0xe1, 0x27, 0x7f, 0x89, + 0x9a, 0x02, 0xf8, 0x08, 0x5b, 0x7d, 0xd2, 0x3d, 0x92, 0x72, 0x10, 0x3d, 0xa9, 0x91, 0x98, 0x11, + 0x63, 0x33, 0x63, 0xc8, 0x43, 0x73, 0xca, 0xe1, 0xda, 0x8c, 0xd5, 0x8f, 0x60, 0x33, 0x43, 0xb1, + 0x5e, 0xbc, 0x65, 0xa4, 0x0d, 0x17, 0xb6, 0xbe, 0x31, 0x54, 0x3f, 0x01, 0x77, 0x65, 0x28, 0x98, + 0x18, 0x0f, 0x7e, 0x2e, 0x19, 0x66, 0xbc, 0xcd, 0x75, 0x91, 0x5c, 0x57, 0x7b, 0xe5, 0xb9, 0xae, + 0xf9, 0x6b, 0x6e, 0xb8, 0xb0, 0xf5, 0xdd, 0x40, 0x25, 0x03, 0x18, 0x1d, 0x1b, 0xb6, 0xe5, 0xbe, + 0x93, 0x5b, 0xe5, 0x35, 0x6c, 0xf4, 0x49, 0xdf, 0x8b, 0x89, 0x24, 0x8d, 0xbb, 0xdf, 0xf3, 0xab, + 0xa9, 0x91, 0xed, 0x15, 0x43, 0x6b, 0x1a, 0x02, 0xd8, 0x31, 0x63, 0x61, 0xda, 0x16, 0xab, 0x3b, + 0xa8, 0x91, 0x5d, 0x9c, 0x8e, 0x5b, 0x49, 0xa8, 0x89, 0xb9, 0x1d, 0x2a, 0x6f, 0xf5, 0xe5, 0x3d, + 0x2b, 0x2f, 0xd1, 0x5e, 0xfa, 0xac, 0xbc, 0xec, 0xa3, 0x9b, 0x94, 0xd3, 0xd9, 0xf9, 0x7b, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x5d, 0xff, 0x05, 0xa6, 0x9f, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -173,6 +179,10 @@ type VtctldClient interface { GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspacesRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspacesResponse, error) + // GetTablet returns information about a tablet. + GetTablet(ctx context.Context, in *vtctldata.GetTabletRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletResponse, error) + // GetTablets returns tablets, optionally filtered by keyspace and shard. + GetTablets(ctx context.Context, in *vtctldata.GetTabletsRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletsResponse, error) } type vtctldClient struct { @@ -237,6 +247,24 @@ func (c *vtctldClient) GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspa return out, nil } +func (c *vtctldClient) GetTablet(ctx context.Context, in *vtctldata.GetTabletRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletResponse, error) { + out := new(vtctldata.GetTabletResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetTablet", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) GetTablets(ctx context.Context, in *vtctldata.GetTabletsRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletsResponse, error) { + out := new(vtctldata.GetTabletsResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetTablets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // VtctldServer is the server API for Vtctld service. type VtctldServer interface { // FindAllShardsInKeyspace returns a map of shard names to shard references @@ -254,6 +282,10 @@ type VtctldServer interface { GetKeyspace(context.Context, *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. GetKeyspaces(context.Context, *vtctldata.GetKeyspacesRequest) (*vtctldata.GetKeyspacesResponse, error) + // GetTablet returns information about a tablet. + GetTablet(context.Context, *vtctldata.GetTabletRequest) (*vtctldata.GetTabletResponse, error) + // GetTablets returns tablets, optionally filtered by keyspace and shard. + GetTablets(context.Context, *vtctldata.GetTabletsRequest) (*vtctldata.GetTabletsResponse, error) } // UnimplementedVtctldServer can be embedded to have forward compatible implementations. @@ -278,6 +310,12 @@ func (*UnimplementedVtctldServer) GetKeyspace(ctx context.Context, req *vtctldat func (*UnimplementedVtctldServer) GetKeyspaces(ctx context.Context, req *vtctldata.GetKeyspacesRequest) (*vtctldata.GetKeyspacesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetKeyspaces not implemented") } +func (*UnimplementedVtctldServer) GetTablet(ctx context.Context, req *vtctldata.GetTabletRequest) (*vtctldata.GetTabletResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTablet not implemented") +} +func (*UnimplementedVtctldServer) GetTablets(ctx context.Context, req *vtctldata.GetTabletsRequest) (*vtctldata.GetTabletsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTablets not implemented") +} func RegisterVtctldServer(s *grpc.Server, srv VtctldServer) { s.RegisterService(&_Vtctld_serviceDesc, srv) @@ -391,6 +429,42 @@ func _Vtctld_GetKeyspaces_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _Vtctld_GetTablet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetTabletRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetTablet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetTablet", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetTablet(ctx, req.(*vtctldata.GetTabletRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_GetTablets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetTabletsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetTablets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetTablets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetTablets(ctx, req.(*vtctldata.GetTabletsRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Vtctld_serviceDesc = grpc.ServiceDesc{ ServiceName: "vtctlservice.Vtctld", HandlerType: (*VtctldServer)(nil), @@ -419,6 +493,14 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "GetKeyspaces", Handler: _Vtctld_GetKeyspaces_Handler, }, + { + MethodName: "GetTablet", + Handler: _Vtctld_GetTablet_Handler, + }, + { + MethodName: "GetTablets", + Handler: _Vtctld_GetTablets_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "vtctlservice.proto", diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index 0c600794202..cc8d2b2ce72 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -81,3 +81,21 @@ func (client *gRPCVtctldClient) GetKeyspaces(ctx context.Context, in *vtctldatap return client.c.GetKeyspaces(ctx, in, opts...) } + +// GetTablet is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetTablet(ctx context.Context, in *vtctldatapb.GetTabletRequest, opts ...grpc.CallOption) (*vtctldatapb.GetTabletResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetTablet(ctx, in, opts...) +} + +// GetTablets is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetTablets(ctx context.Context, in *vtctldatapb.GetTabletsRequest, opts ...grpc.CallOption) (*vtctldatapb.GetTabletsResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetTablets(ctx, in, opts...) +} diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 04b4f0a1cc1..c28bceddee3 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -18,11 +18,14 @@ package grpcvtctldserver import ( "context" + "time" "google.golang.org/grpc" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vterrors" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" "vitess.io/vitess/go/vt/proto/vtrpc" @@ -133,6 +136,110 @@ func (s *VtctldServer) GetKeyspaces(ctx context.Context, req *vtctldatapb.GetKey return &vtctldatapb.GetKeyspacesResponse{Keyspaces: keyspaces}, nil } +// GetTablet is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetTablet(ctx context.Context, req *vtctldatapb.GetTabletRequest) (*vtctldatapb.GetTabletResponse, error) { + ti, err := s.ts.GetTablet(ctx, req.TabletAlias) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetTabletResponse{ + Tablet: ti.Tablet, + }, nil +} + +// GetTablets is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetTablets(ctx context.Context, req *vtctldatapb.GetTabletsRequest) (*vtctldatapb.GetTabletsResponse, error) { + // It is possible that an old primary has not yet updated its type in the + // topo. In that case, report its type as UNKNOWN. It used to be MASTER but + // is no longer the serving primary. + adjustTypeForStalePrimary := func(ti *topo.TabletInfo, mtst time.Time) { + if ti.Type == topodatapb.TabletType_MASTER && ti.GetMasterTermStartTime().Before(mtst) { + ti.Tablet.Type = topodatapb.TabletType_UNKNOWN + } + } + + if req.Keyspace != "" && req.Shard != "" { + tabletMap, err := s.ts.GetTabletMapForShard(ctx, req.Keyspace, req.Shard) + if err != nil { + return nil, err + } + + var trueMasterTimestamp time.Time + for _, ti := range tabletMap { + if ti.Type == topodatapb.TabletType_MASTER { + masterTimestamp := ti.GetMasterTermStartTime() + if masterTimestamp.After(trueMasterTimestamp) { + trueMasterTimestamp = masterTimestamp + } + } + } + + tablets := make([]*topodatapb.Tablet, 0, len(tabletMap)) + for _, ti := range tabletMap { + adjustTypeForStalePrimary(ti, trueMasterTimestamp) + tablets = append(tablets, ti.Tablet) + } + + return &vtctldatapb.GetTabletsResponse{Tablets: tablets}, nil + } + + cells := req.Cells + if len(cells) == 0 { + c, err := s.ts.GetKnownCells(ctx) + if err != nil { + return nil, err + } + + cells = c + } + + var allTablets []*topodatapb.Tablet + + for _, cell := range cells { + tablets, err := topotools.GetAllTablets(ctx, s.ts, cell) + if err != nil { + return nil, err + } + + // Collect true master term start times, and optionally filter out any + // tablets by keyspace according to the request. + masterTermStartTimes := map[string]time.Time{} + filteredTablets := make([]*topo.TabletInfo, 0, len(tablets)) + + for _, tablet := range tablets { + if req.Keyspace != "" && tablet.Keyspace != req.Keyspace { + continue + } + + key := tablet.Keyspace + "." + tablet.Shard + if v, ok := masterTermStartTimes[key]; ok { + if tablet.GetMasterTermStartTime().After(v) { + masterTermStartTimes[key] = tablet.GetMasterTermStartTime() + } + } else { + masterTermStartTimes[key] = tablet.GetMasterTermStartTime() + } + + filteredTablets = append(filteredTablets, tablet) + } + + // collect the tablets with adjusted master term start times. they've + // already been filtered by the above loop, so no keyspace filtering + // here. + for _, ti := range filteredTablets { + key := ti.Keyspace + "." + ti.Shard + adjustTypeForStalePrimary(ti, masterTermStartTimes[key]) + + allTablets = append(allTablets, ti.Tablet) + } + } + + return &vtctldatapb.GetTabletsResponse{ + Tablets: allTablets, + }, nil +} + // StartServer registers a VtctldServer for RPCs on the given gRPC server. func StartServer(s *grpc.Server, ts *topo.Server) { vtctlservicepb.RegisterVtctldServer(s, NewVtctldServer(ts)) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index faebf22e610..183daa7e5b9 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -20,11 +20,15 @@ import ( "context" "errors" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" @@ -141,3 +145,392 @@ func TestGetKeyspaces(t *testing.T) { _, err = vtctld.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) assert.Error(t, err) } + +func TestGetTablet(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + vtctld := NewVtctldServer(ts) + + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Hostname: "localhost", + Keyspace: "testkeyspace", + Shard: "-", + Type: topodatapb.TabletType_REPLICA, + } + + testutil.AddTablet(ctx, t, ts, tablet) + + resp, err := vtctld.GetTablet(ctx, &vtctldatapb.GetTabletRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + }) + assert.NoError(t, err) + assert.Equal(t, resp.Tablet, tablet) + + // not found + _, err = vtctld.GetTablet(ctx, &vtctldatapb.GetTabletRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + }) + assert.Error(t, err) +} + +func TestGetTablets(t *testing.T) { + tests := []struct { + name string + cells []string + tablets []*topodatapb.Tablet + req *vtctldatapb.GetTabletsRequest + expected []*topodatapb.Tablet + shouldErr bool + }{ + { + name: "no tablets", + cells: []string{"cell1"}, + tablets: []*topodatapb.Tablet{}, + req: &vtctldatapb.GetTabletsRequest{}, + expected: []*topodatapb.Tablet{}, + shouldErr: false, + }, + { + name: "keyspace and shard filter", + cells: []string{"cell1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Keyspace: "ks1", + Shard: "-80", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Keyspace: "ks1", + Shard: "80-", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 102, + }, + Keyspace: "ks2", + Shard: "-", + }, + }, + req: &vtctldatapb.GetTabletsRequest{ + Keyspace: "ks1", + Shard: "80-", + }, + expected: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Keyspace: "ks1", + Shard: "80-", + }, + }, + shouldErr: false, + }, + { + name: "keyspace filter", + cells: []string{"cell1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Keyspace: "ks1", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Keyspace: "ks1", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 102, + }, + Keyspace: "otherkeyspace", + }, + }, + req: &vtctldatapb.GetTabletsRequest{ + Keyspace: "ks1", + }, + expected: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Keyspace: "ks1", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Keyspace: "ks1", + }, + }, + shouldErr: false, + }, + { + name: "keyspace and shard filter - stale primary", + cells: []string{"cell1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Keyspace: "ks1", + Shard: "-80", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Keyspace: "ks1", + Shard: "80-", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 102, + }, + Keyspace: "ks2", + Shard: "-", + Type: topodatapb.TabletType_MASTER, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)), + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 103, + }, + Keyspace: "ks2", + Shard: "-", + Hostname: "stale.primary", + Type: topodatapb.TabletType_MASTER, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 14, 4, 5, 0, time.UTC)), + }, + }, + req: &vtctldatapb.GetTabletsRequest{ + Keyspace: "ks2", + Shard: "-", + }, + expected: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 102, + }, + Keyspace: "ks2", + Shard: "-", + Type: topodatapb.TabletType_MASTER, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)), + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 103, + }, + Keyspace: "ks2", + Shard: "-", + Hostname: "stale.primary", + Type: topodatapb.TabletType_UNKNOWN, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 14, 4, 5, 0, time.UTC)), + }, + }, + shouldErr: false, + }, + { + name: "stale primary", + cells: []string{"cell1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Keyspace: "ks1", + Shard: "-", + Hostname: "slightly less stale", + Type: topodatapb.TabletType_MASTER, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)), + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Hostname: "stale primary", + Keyspace: "ks1", + Shard: "-", + Type: topodatapb.TabletType_MASTER, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 14, 4, 5, 0, time.UTC)), + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 103, + }, + Hostname: "true primary", + Keyspace: "ks1", + Shard: "-", + Type: topodatapb.TabletType_MASTER, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 16, 4, 5, 0, time.UTC)), + }, + }, + req: &vtctldatapb.GetTabletsRequest{}, + expected: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Keyspace: "ks1", + Shard: "-", + Hostname: "slightly less stale", + Type: topodatapb.TabletType_UNKNOWN, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC)), + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Hostname: "stale primary", + Keyspace: "ks1", + Shard: "-", + Type: topodatapb.TabletType_UNKNOWN, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 14, 4, 5, 0, time.UTC)), + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 103, + }, + Hostname: "true primary", + Keyspace: "ks1", + Shard: "-", + Type: topodatapb.TabletType_MASTER, + MasterTermStartTime: logutil.TimeToProto(time.Date(2006, time.January, 2, 16, 4, 5, 0, time.UTC)), + }, + }, + shouldErr: false, + }, + { + name: "keyspace and shard filter - error", + cells: []string{"cell1"}, + tablets: []*topodatapb.Tablet{}, + req: &vtctldatapb.GetTabletsRequest{ + Keyspace: "ks1", + Shard: "-", + }, + expected: []*topodatapb.Tablet{}, + shouldErr: true, + }, + { + name: "cells filter", + cells: []string{"cell1", "cell2", "cell3"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell2", + Uid: 200, + }, + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell3", + Uid: 300, + }, + }, + }, + req: &vtctldatapb.GetTabletsRequest{ + Cells: []string{"cell1", "cell3"}, + }, + expected: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell3", + Uid: 300, + }, + }, + }, + shouldErr: false, + }, + { + name: "cells filter - error", + cells: []string{"cell1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Keyspace: "ks1", + Shard: "-", + }, + }, + req: &vtctldatapb.GetTabletsRequest{ + Cells: []string{"cell1", "doesnotexist"}, + }, + expected: []*topodatapb.Tablet{}, + shouldErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer(tt.cells...) + vtctld := NewVtctldServer(ts) + + for _, tablet := range tt.tablets { + testutil.AddTablet(ctx, t, ts, tablet) + } + + resp, err := vtctld.GetTablets(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.ElementsMatch(t, tt.expected, resp.Tablets) + }) + } +} diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/util.go b/go/vt/vtctl/grpcvtctldserver/testutil/util.go new file mode 100644 index 00000000000..99928b54936 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldserver/testutil/util.go @@ -0,0 +1,100 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package testutil contains utility functions for writing tests for the +// grpcvtctldserver. +package testutil + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/net/nettest" + "google.golang.org/grpc" + + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vtctl/vtctldclient" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" +) + +// WithTestServer creates a gRPC server listening locally with the given RPC +// implementation, then runs the test func with a client created to point at +// that server. +func WithTestServer( + t *testing.T, + server vtctlservicepb.VtctldServer, + test func(t *testing.T, client vtctldclient.VtctldClient), +) { + lis, err := nettest.NewLocalListener("tcp") + require.NoError(t, err, "cannot create local listener") + + defer lis.Close() + + s := grpc.NewServer() + vtctlservicepb.RegisterVtctldServer(s, server) + + go s.Serve(lis) + defer s.Stop() + + client, err := vtctldclient.New("grpc", lis.Addr().String()) + require.NoError(t, err, "cannot create vtctld client") + + test(t, client) +} + +// AddKeyspace adds a keyspace to a topology, failing a test if that keyspace +// could not be added. It shallow copies the proto struct to prevent XXX_ fields +// from changing in the marshalling. +func AddKeyspace(ctx context.Context, t *testing.T, ts *topo.Server, ks *vtctldatapb.Keyspace) { + in := *ks.Keyspace // take a copy to avoid XXX_ fields changing. + + err := ts.CreateKeyspace(ctx, ks.Name, &in) + require.NoError(t, err) +} + +// AddTablet adds a tablet to the topology, failing a test if that tablet record +// could not be created. It shallow copies to prevent XXX_ fields from changing, +// including nested proto message fields. +// +// AddTablet also optionally adds empty keyspace and shard records to the +// topology, if they are set on the tablet record and they cannot be retrieved +// from the topo server without error. +func AddTablet(ctx context.Context, t *testing.T, ts *topo.Server, tablet *topodatapb.Tablet) { + in := *tablet + alias := *tablet.Alias + in.Alias = &alias + + err := ts.CreateTablet(ctx, &in) + require.NoError(t, err, "CreateTablet(%+v)", &in) + + if tablet.Keyspace != "" { + if _, err := ts.GetKeyspace(ctx, tablet.Keyspace); err != nil { + err := ts.CreateKeyspace(ctx, tablet.Keyspace, &topodatapb.Keyspace{}) + require.NoError(t, err, "CreateKeyspace(%s)", tablet.Keyspace) + } + + if tablet.Shard != "" { + if _, err := ts.GetShard(ctx, tablet.Keyspace, tablet.Shard); err != nil { + err := ts.CreateShard(ctx, tablet.Keyspace, tablet.Shard) + require.NoError(t, err, "CreateShard(%s, %s)", tablet.Keyspace, tablet.Shard) + } + } + } +} diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index cd553e53c0d..a05087216d2 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -74,6 +74,29 @@ message GetKeyspaceResponse { Keyspace keyspace = 1; } +message GetTabletRequest { + topodata.TabletAlias tablet_alias = 1; +} + +message GetTabletResponse { + topodata.Tablet tablet = 1; +} + +message GetTabletsRequest { + // Keyspace is the name of the keyspace to return tablets for. Omit to return + // all tablets. + string keyspace = 1; + // Shard is the name of the shard to return tablets for. This field is ignored + // if Keyspace is not set. + string shard = 2; + // Cells is an optional set of cells to return tablets for. + repeated string cells = 3; +} + +message GetTabletsResponse { + repeated topodata.Tablet tablets = 1; +} + message Keyspace { string name = 1; topodata.Keyspace keyspace = 2; diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 4007550f587..76f76645389 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -46,4 +46,8 @@ service Vtctld { rpc GetKeyspace(vtctldata.GetKeyspaceRequest) returns (vtctldata.GetKeyspaceResponse) {}; // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. rpc GetKeyspaces(vtctldata.GetKeyspacesRequest) returns (vtctldata.GetKeyspacesResponse) {}; + // GetTablet returns information about a tablet. + rpc GetTablet(vtctldata.GetTabletRequest) returns (vtctldata.GetTabletResponse) {}; + // GetTablets returns tablets, optionally filtered by keyspace and shard. + rpc GetTablets(vtctldata.GetTabletsRequest) returns (vtctldata.GetTabletsResponse) {}; } From 91b30ac5919836ef65c5cd8fb750fe5f2833bb06 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Tue, 19 Jan 2021 16:42:25 -0800 Subject: [PATCH 08/21] Merge pull request #7321 from tinyspeck/am_vtctldclient_command_pkg [vtctld] vtctldclient command pkg --- .../vtctldclient/{formats.go => cli/awk.go} | 6 +- go/cmd/vtctldclient/{ => cli}/json.go | 4 +- go/cmd/vtctldclient/commands.go | 285 ------------------ go/cmd/vtctldclient/internal/command/cells.go | 100 ++++++ go/cmd/vtctldclient/internal/command/doc.go | 111 +++++++ .../internal/command/keyspaces.go | 107 +++++++ go/cmd/vtctldclient/internal/command/root.go | 73 +++++ .../vtctldclient/internal/command/tablets.go | 152 ++++++++++ go/cmd/vtctldclient/main.go | 57 +--- 9 files changed, 552 insertions(+), 343 deletions(-) rename go/cmd/vtctldclient/{formats.go => cli/awk.go} (82%) rename go/cmd/vtctldclient/{ => cli}/json.go (96%) delete mode 100644 go/cmd/vtctldclient/commands.go create mode 100644 go/cmd/vtctldclient/internal/command/cells.go create mode 100644 go/cmd/vtctldclient/internal/command/doc.go create mode 100644 go/cmd/vtctldclient/internal/command/keyspaces.go create mode 100644 go/cmd/vtctldclient/internal/command/root.go create mode 100644 go/cmd/vtctldclient/internal/command/tablets.go diff --git a/go/cmd/vtctldclient/formats.go b/go/cmd/vtctldclient/cli/awk.go similarity index 82% rename from go/cmd/vtctldclient/formats.go rename to go/cmd/vtctldclient/cli/awk.go index 152d6684579..7e5f0c5c50e 100644 --- a/go/cmd/vtctldclient/formats.go +++ b/go/cmd/vtctldclient/cli/awk.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package main +package cli import ( "fmt" @@ -22,7 +22,9 @@ import ( "strings" ) -func fmtMapAwkable(m map[string]string) string { +// MarshalMapAWK returns a string representation of a string->string map in an +// AWK-friendly format. +func MarshalMapAWK(m map[string]string) string { pairs := make([]string, len(m)) i := 0 diff --git a/go/cmd/vtctldclient/json.go b/go/cmd/vtctldclient/cli/json.go similarity index 96% rename from go/cmd/vtctldclient/json.go rename to go/cmd/vtctldclient/cli/json.go index b7cb3eeff0e..903ca905b3e 100644 --- a/go/cmd/vtctldclient/json.go +++ b/go/cmd/vtctldclient/cli/json.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package main +package cli import ( "bytes" diff --git a/go/cmd/vtctldclient/commands.go b/go/cmd/vtctldclient/commands.go deleted file mode 100644 index 4b720e84378..00000000000 --- a/go/cmd/vtctldclient/commands.go +++ /dev/null @@ -1,285 +0,0 @@ -/* -Copyright 2020 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "fmt" - "strings" - "time" - - "github.com/spf13/cobra" - - "vitess.io/vitess/go/vt/logutil" - "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/vt/topo/topoproto" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" -) - -var ( - findAllShardsInKeyspaceCmd = &cobra.Command{ - Use: "FindAllShardsInKeyspace keyspace", - Aliases: []string{"findallshardsinkeyspace"}, - Args: cobra.ExactArgs(1), - RunE: commandFindAllShardsInKeyspace, - } - getCellInfoNamesCmd = &cobra.Command{ - Use: "GetCellInfoNames", - Args: cobra.NoArgs, - RunE: commandGetCellInfoNames, - } - getCellInfoCmd = &cobra.Command{ - Use: "GetCellInfo cell", - Args: cobra.ExactArgs(1), - RunE: commandGetCellInfo, - } - getCellsAliasesCmd = &cobra.Command{ - Use: "GetCellsAliases", - Args: cobra.NoArgs, - RunE: commandGetCellsAliases, - } - getKeyspaceCmd = &cobra.Command{ - Use: "GetKeyspace keyspace", - Aliases: []string{"getkeyspace"}, - Args: cobra.ExactArgs(1), - RunE: commandGetKeyspace, - } - getKeyspacesCmd = &cobra.Command{ - Use: "GetKeyspaces", - Aliases: []string{"getkeyspaces"}, - Args: cobra.NoArgs, - RunE: commandGetKeyspaces, - } - getTabletCmd = &cobra.Command{ - Use: "GetTablet alias", - Args: cobra.ExactArgs(1), - RunE: commandGetTablet, - } - getTabletsCmd = &cobra.Command{ - Use: "GetTablets [--cell $c1, ...] [--keyspace $ks [--shard $shard]]", - Args: cobra.NoArgs, - RunE: commandGetTablets, - } -) - -func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { - ks := cmd.Flags().Arg(0) - resp, err := client.FindAllShardsInKeyspace(commandCtx, &vtctldatapb.FindAllShardsInKeyspaceRequest{ - Keyspace: ks, - }) - - if err != nil { - return err - } - - data, err := MarshalJSON(resp) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - return nil -} - -func commandGetCellInfoNames(cmd *cobra.Command, args []string) error { - resp, err := client.GetCellInfoNames(commandCtx, &vtctldatapb.GetCellInfoNamesRequest{}) - if err != nil { - return err - } - - fmt.Printf("%s\n", strings.Join(resp.Names, "\n")) - - return nil -} - -func commandGetCellInfo(cmd *cobra.Command, args []string) error { - cell := cmd.Flags().Arg(0) - resp, err := client.GetCellInfo(commandCtx, &vtctldatapb.GetCellInfoRequest{Cell: cell}) - - if err != nil { - return err - } - - data, err := MarshalJSON(resp.CellInfo) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - - return nil -} - -func commandGetCellsAliases(cmd *cobra.Command, args []string) error { - resp, err := client.GetCellsAliases(commandCtx, &vtctldatapb.GetCellsAliasesRequest{}) - if err != nil { - return err - } - - data, err := MarshalJSON(resp.Aliases) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - - return nil -} - -func commandGetKeyspace(cmd *cobra.Command, args []string) error { - ks := cmd.Flags().Arg(0) - resp, err := client.GetKeyspace(commandCtx, &vtctldatapb.GetKeyspaceRequest{ - Keyspace: ks, - }) - - if err != nil { - return err - } - - fmt.Printf("%+v\n", resp.Keyspace) - - return nil -} - -func commandGetKeyspaces(cmd *cobra.Command, args []string) error { - resp, err := client.GetKeyspaces(commandCtx, &vtctldatapb.GetKeyspacesRequest{}) - if err != nil { - return err - } - - data, err := MarshalJSON(resp.Keyspaces) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - - return nil -} - -func commandGetTablet(cmd *cobra.Command, args []string) error { - aliasStr := cmd.Flags().Arg(0) - alias, err := topoproto.ParseTabletAlias(aliasStr) - if err != nil { - return err - } - - resp, err := client.GetTablet(commandCtx, &vtctldatapb.GetTabletRequest{TabletAlias: alias}) - if err != nil { - return err - } - - data, err := MarshalJSON(resp.Tablet) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - - return nil -} - -var getTabletsArgs = struct { - Cells []string - Keyspace string - Shard string - - Format string -}{} - -func commandGetTablets(cmd *cobra.Command, args []string) error { - format := strings.ToLower(getTabletsArgs.Format) - - switch format { - case "awk", "json": - default: - return fmt.Errorf("invalid output format, got %s", getTabletsArgs.Format) - } - - if getTabletsArgs.Keyspace == "" && getTabletsArgs.Shard != "" { - return fmt.Errorf("--shard (= %s) cannot be passed without also passing --keyspace", getTabletsArgs.Shard) - } - - resp, err := client.GetTablets(commandCtx, &vtctldatapb.GetTabletsRequest{ - Cells: getTabletsArgs.Cells, - Keyspace: getTabletsArgs.Keyspace, - Shard: getTabletsArgs.Shard, - }) - if err != nil { - return err - } - - switch format { - case "awk": - lineFn := func(t *topodatapb.Tablet) string { - ti := topo.TabletInfo{ - Tablet: t, - } - - keyspace := t.Keyspace - if keyspace == "" { - keyspace = "" - } - - shard := t.Shard - if shard == "" { - shard = "" - } - - mtst := "" - // special case for old primary that hasn't been updated in the topo - // yet. - if t.MasterTermStartTime != nil && t.MasterTermStartTime.Seconds > 0 { - mtst = logutil.ProtoToTime(t.MasterTermStartTime).Format(time.RFC3339) - } - - return fmt.Sprintf("%v %v %v %v %v %v %v %v", topoproto.TabletAliasString(t.Alias), keyspace, shard, topoproto.TabletTypeLString(t.Type), ti.Addr(), ti.MysqlAddr(), fmtMapAwkable(t.Tags), mtst) - } - - for _, t := range resp.Tablets { - fmt.Println(lineFn(t)) - } - case "json": - data, err := MarshalJSON(resp.Tablets) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - } - - return nil -} - -func init() { - rootCmd.AddCommand(findAllShardsInKeyspaceCmd) - - rootCmd.AddCommand(getCellInfoNamesCmd) - rootCmd.AddCommand(getCellInfoCmd) - rootCmd.AddCommand(getCellsAliasesCmd) - - rootCmd.AddCommand(getKeyspaceCmd) - rootCmd.AddCommand(getKeyspacesCmd) - - rootCmd.AddCommand(getTabletCmd) - getTabletsCmd.Flags().StringSliceVarP(&getTabletsArgs.Cells, "cell", "c", nil, "TODO") - getTabletsCmd.Flags().StringVarP(&getTabletsArgs.Keyspace, "keyspace", "k", "", "TODO") - getTabletsCmd.Flags().StringVarP(&getTabletsArgs.Shard, "shard", "s", "", "TODO") - getTabletsCmd.Flags().StringVar(&getTabletsArgs.Format, "format", "awk", "Output format to use; valid choices are (json, awk)") - rootCmd.AddCommand(getTabletsCmd) -} diff --git a/go/cmd/vtctldclient/internal/command/cells.go b/go/cmd/vtctldclient/internal/command/cells.go new file mode 100644 index 00000000000..e37709abc44 --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/cells.go @@ -0,0 +1,100 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // GetCellInfoNames makes a GetCellInfoNames gRPC call to a vtctld. + GetCellInfoNames = &cobra.Command{ + Use: "GetCellInfoNames", + Args: cobra.NoArgs, + RunE: commandGetCellInfoNames, + } + // GetCellInfo makes a GetCellInfo gRPC call to a vtctld. + GetCellInfo = &cobra.Command{ + Use: "GetCellInfo cell", + Args: cobra.ExactArgs(1), + RunE: commandGetCellInfo, + } + // GetCellsAliases makes a GetCellsAliases gRPC call to a vtctld. + GetCellsAliases = &cobra.Command{ + Use: "GetCellsAliases", + Args: cobra.NoArgs, + RunE: commandGetCellsAliases, + } +) + +func commandGetCellInfoNames(cmd *cobra.Command, args []string) error { + resp, err := client.GetCellInfoNames(commandCtx, &vtctldatapb.GetCellInfoNamesRequest{}) + if err != nil { + return err + } + + fmt.Printf("%s\n", strings.Join(resp.Names, "\n")) + + return nil +} + +func commandGetCellInfo(cmd *cobra.Command, args []string) error { + cell := cmd.Flags().Arg(0) + resp, err := client.GetCellInfo(commandCtx, &vtctldatapb.GetCellInfoRequest{Cell: cell}) + + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.CellInfo) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +func commandGetCellsAliases(cmd *cobra.Command, args []string) error { + resp, err := client.GetCellsAliases(commandCtx, &vtctldatapb.GetCellsAliasesRequest{}) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.Aliases) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +func init() { + Root.AddCommand(GetCellInfoNames) + Root.AddCommand(GetCellInfo) + Root.AddCommand(GetCellsAliases) +} diff --git a/go/cmd/vtctldclient/internal/command/doc.go b/go/cmd/vtctldclient/internal/command/doc.go new file mode 100644 index 00000000000..57500b0fccd --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/doc.go @@ -0,0 +1,111 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package command contains the commands used by vtctldclient. It is intended only +for use in vtctldclient's main package and entrypoint. The rest of this +documentation is intended for maintainers. + +Commands are grouped into files by the types of resources they interact with ( +e.g. GetTablet, CreateTablet, DeleteTablet, GetTablets) or by what they do (e.g. +PlannedReparentShard, EmergencyReparentShard, InitShardPrimary). Please add the +command to the appropriate existing file, alphabetically, or create a new +grouping if one does not exist. + +The root command lives in root.go, and commands must attach themselves to this +during an init function in order to be reachable from the CLI. root.go also +contains the global variables available to any subcommand that are managed by +the root command's pre- and post-run functions. Commands must not attempt to +manage these, as that may conflict with Root's post-run cleanup actions. All +commands should, at a minimum, use the commandCtx rather than creating their own +context.Background to start, as it contains root tracing spans that would be +lost. + +Commands should not keep their logic in an anonymous function on the +cobra.Command struct, but instead in a separate function that is assigned to +RunE. Commands should strive to keep declaration, function definition, and flag +initialization located as closely together as possible, to make the code easier +to follow and understand (the global variables declared near Root are the +exception here, not the rule). Commands should also prevent individual flag +names from polluting the package namespace. + +A good pattern we have found is to do the following: + package command + + // (imports ...) + + var ( + CreateTablet = &cobra.Command{ + Use: "CreateTablet [options] --keyspace= --shard= ", + Args: cobra.ExactArgs(2), + RunE: commandCreateTablet, + } + GetTablet = &cobra.Command{ + Use: "GetTablet ", + Args: cobra.ExactArgs(1), + RunE: commandGetTablet, + } + ) + + var createTabletOptions = struct { + Opt1 string + Opt2 bool + Keyspace string + Shard string + }{} + + func commandCreateTablet(cmd *cobra.Command, args []string) error { + aliasStr := cmd.Flags().Args(0) + tabletTypeStr := cmd.Flags().Args(1) + + // do stuff with: + // - client + // - commandCtx + // - createTabletOptions + // - aliasStr + // - tabletTypeStr + + return nil + } + + // GetTablet takes no flags, so it needs no anonymous struct to store them + func commandGetTablet(cmd *cobra.Command, args []string) error { + aliasStr := cmd.Flags().Arg(0) + + // do stuff with: + // - client + // - commandCtx + // - aliasStr + + return nil + } + + // finally, hook up all the commands in this file to Root, and add any flags + // to each of those commands + + func init() { + CreateTablet.Flags().StringVar(&createTabletOptions.Opt1, "opt1", "default", "help") + CreateTablet.Flags().BoolVar(&createTabletOptions.Opt2, "opt2", false, "help") + CreateTablet.Flags().StringVarP(&createTabletOptions.Keyspace, "keyspace", "k", "keyspace of tablet") + CreateTablet.MarkFlagRequired("keyspace") + CreateTablet.Flags().StringVarP(&createTabletOptions.Shard, "shard", "s", "shard range of tablet") + CreateTablet.MarkFlagRequired("shard") + Root.AddCommand(CreateTablet) + + Root.AddCommand(GetTablet) + } +*/ +package command diff --git a/go/cmd/vtctldclient/internal/command/keyspaces.go b/go/cmd/vtctldclient/internal/command/keyspaces.go new file mode 100644 index 00000000000..47207d8e443 --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/keyspaces.go @@ -0,0 +1,107 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "fmt" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // FindAllShardsInKeyspace makes a FindAllShardsInKeyspace gRPC call to a vtctld. + FindAllShardsInKeyspace = &cobra.Command{ + Use: "FindAllShardsInKeyspace keyspace", + Aliases: []string{"findallshardsinkeyspace"}, + Args: cobra.ExactArgs(1), + RunE: commandFindAllShardsInKeyspace, + } + // GetKeyspace makes a GetKeyspace gRPC call to a vtctld. + GetKeyspace = &cobra.Command{ + Use: "GetKeyspace keyspace", + Aliases: []string{"getkeyspace"}, + Args: cobra.ExactArgs(1), + RunE: commandGetKeyspace, + } + // GetKeyspaces makes a GetKeyspaces gRPC call to a vtctld. + GetKeyspaces = &cobra.Command{ + Use: "GetKeyspaces", + Aliases: []string{"getkeyspaces"}, + Args: cobra.NoArgs, + RunE: commandGetKeyspaces, + } +) + +func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { + ks := cmd.Flags().Arg(0) + resp, err := client.FindAllShardsInKeyspace(commandCtx, &vtctldatapb.FindAllShardsInKeyspaceRequest{ + Keyspace: ks, + }) + + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + return nil +} + +func commandGetKeyspace(cmd *cobra.Command, args []string) error { + ks := cmd.Flags().Arg(0) + resp, err := client.GetKeyspace(commandCtx, &vtctldatapb.GetKeyspaceRequest{ + Keyspace: ks, + }) + + if err != nil { + return err + } + + fmt.Printf("%+v\n", resp.Keyspace) + + return nil +} + +func commandGetKeyspaces(cmd *cobra.Command, args []string) error { + resp, err := client.GetKeyspaces(commandCtx, &vtctldatapb.GetKeyspacesRequest{}) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.Keyspaces) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +func init() { + Root.AddCommand(FindAllShardsInKeyspace) + Root.AddCommand(GetKeyspace) + Root.AddCommand(GetKeyspaces) +} diff --git a/go/cmd/vtctldclient/internal/command/root.go b/go/cmd/vtctldclient/internal/command/root.go new file mode 100644 index 00000000000..63ef37fe346 --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/root.go @@ -0,0 +1,73 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "context" + "errors" + "io" + "time" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/trace" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/vtctl/vtctldclient" +) + +var ( + client vtctldclient.VtctldClient + traceCloser io.Closer + commandCtx context.Context + commandCancel func() + + server string + actionTimeout time.Duration + + // Root is the main entrypoint to the vtctldclient CLI. + Root = &cobra.Command{ + // We use PersistentPreRun to set up the tracer, grpc client, and + // command context for every command. + PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { + traceCloser = trace.StartTracing("vtctldclient") + if server == "" { + err = errors.New("please specify -server to specify the vtctld server to connect to") + log.Error(err) + return err + } + + client, err = vtctldclient.New("grpc", server) + + commandCtx, commandCancel = context.WithTimeout(context.Background(), actionTimeout) + return err + }, + // Similarly, PersistentPostRun cleans up the resources spawned by + // PersistentPreRun. + PersistentPostRunE: func(cmd *cobra.Command, args []string) error { + commandCancel() + err := client.Close() + trace.LogErrorsWhenClosing(traceCloser) + return err + }, + TraverseChildren: true, + } +) + +func init() { + Root.PersistentFlags().StringVar(&server, "server", "", "server to use for connection") + Root.PersistentFlags().DurationVar(&actionTimeout, "action_timeout", time.Hour, "timeout for the total command") +} diff --git a/go/cmd/vtctldclient/internal/command/tablets.go b/go/cmd/vtctldclient/internal/command/tablets.go new file mode 100644 index 00000000000..1beaaa2751a --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/tablets.go @@ -0,0 +1,152 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "fmt" + "strings" + "time" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // GetTablet makes a GetTablet gRPC call to a vtctld. + GetTablet = &cobra.Command{ + Use: "GetTablet alias", + Args: cobra.ExactArgs(1), + RunE: commandGetTablet, + } + // GetTablets makes a GetTablets gRPC call to a vtctld. + GetTablets = &cobra.Command{ + Use: "GetTablets [--cell $c1, ...] [--keyspace $ks [--shard $shard]]", + Args: cobra.NoArgs, + RunE: commandGetTablets, + } +) + +func commandGetTablet(cmd *cobra.Command, args []string) error { + aliasStr := cmd.Flags().Arg(0) + alias, err := topoproto.ParseTabletAlias(aliasStr) + if err != nil { + return err + } + + resp, err := client.GetTablet(commandCtx, &vtctldatapb.GetTabletRequest{TabletAlias: alias}) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.Tablet) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +var getTabletsOptions = struct { + Cells []string + Keyspace string + Shard string + + Format string +}{} + +func commandGetTablets(cmd *cobra.Command, args []string) error { + format := strings.ToLower(getTabletsOptions.Format) + + switch format { + case "awk", "json": + default: + return fmt.Errorf("invalid output format, got %s", getTabletsOptions.Format) + } + + if getTabletsOptions.Keyspace == "" && getTabletsOptions.Shard != "" { + return fmt.Errorf("--shard (= %s) cannot be passed without also passing --keyspace", getTabletsOptions.Shard) + } + + resp, err := client.GetTablets(commandCtx, &vtctldatapb.GetTabletsRequest{ + Cells: getTabletsOptions.Cells, + Keyspace: getTabletsOptions.Keyspace, + Shard: getTabletsOptions.Shard, + }) + if err != nil { + return err + } + + switch format { + case "awk": + lineFn := func(t *topodatapb.Tablet) string { + ti := topo.TabletInfo{ + Tablet: t, + } + + keyspace := t.Keyspace + if keyspace == "" { + keyspace = "" + } + + shard := t.Shard + if shard == "" { + shard = "" + } + + mtst := "" + // special case for old primary that hasn't been updated in the topo + // yet. + if t.MasterTermStartTime != nil && t.MasterTermStartTime.Seconds > 0 { + mtst = logutil.ProtoToTime(t.MasterTermStartTime).Format(time.RFC3339) + } + + return fmt.Sprintf("%v %v %v %v %v %v %v %v", topoproto.TabletAliasString(t.Alias), keyspace, shard, topoproto.TabletTypeLString(t.Type), ti.Addr(), ti.MysqlAddr(), cli.MarshalMapAWK(t.Tags), mtst) + } + + for _, t := range resp.Tablets { + fmt.Println(lineFn(t)) + } + case "json": + data, err := cli.MarshalJSON(resp.Tablets) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + } + + return nil +} + +func init() { + Root.AddCommand(GetTablet) + + GetTablets.Flags().StringSliceVarP(&getTabletsOptions.Cells, "cell", "c", nil, "list of cells to filter tablets by") + GetTablets.Flags().StringVarP(&getTabletsOptions.Keyspace, "keyspace", "k", "", "keyspace to filter tablets by") + GetTablets.Flags().StringVarP(&getTabletsOptions.Shard, "shard", "s", "", "shard to filter tablets by") + GetTablets.Flags().StringVar(&getTabletsOptions.Format, "format", "awk", "Output format to use; valid choices are (json, awk)") + Root.AddCommand(GetTablets) +} diff --git a/go/cmd/vtctldclient/main.go b/go/cmd/vtctldclient/main.go index f00eee7a410..9086b289b8c 100644 --- a/go/cmd/vtctldclient/main.go +++ b/go/cmd/vtctldclient/main.go @@ -17,70 +17,19 @@ limitations under the License. package main import ( - "context" - "errors" "flag" - "io" "os" - "time" - - "github.com/spf13/cobra" + "vitess.io/vitess/go/cmd/vtctldclient/internal/command" "vitess.io/vitess/go/exit" - "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/vtctl/vtctldclient" -) - -var ( - client vtctldclient.VtctldClient - traceCloser io.Closer - commandCtx context.Context - commandCancel func() - - server string - actionTimeout time.Duration - - // We use cobra to make subcommands easier to manage. And do a hack below - // in main to grab the rest of the flags globally scattered to make sure we - // pick up things like common servenv flags, tracing flags, etc. Refer to - // commands.go for all of the subcommands. - rootCmd = &cobra.Command{ - // We use PersistentPreRun to set up the tracer, grpc client, and - // command context for every command. - PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { - traceCloser = trace.StartTracing("vtctldclient") - if server == "" { - err = errors.New("please specify -server to specify the vtctld server to connect to") - log.Error(err) - return err - } - - client, err = vtctldclient.New("grpc", server) - - commandCtx, commandCancel = context.WithTimeout(context.Background(), actionTimeout) - return err - }, - // Similarly, PersistentPostRun cleans up the resources spawned by - // PersistentPreRun. - PersistentPostRunE: func(cmd *cobra.Command, args []string) error { - commandCancel() - err := client.Close() - trace.LogErrorsWhenClosing(traceCloser) - return err - }, - TraverseChildren: true, - } ) func main() { defer exit.Recover() // Grab all those global flags across the codebase and shove 'em on in. - rootCmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) - // Attach our local flags - rootCmd.PersistentFlags().StringVar(&server, "server", "", "server to use for connection") - rootCmd.PersistentFlags().DurationVar(&actionTimeout, "action_timeout", time.Hour, "timeout for the total command") + command.Root.PersistentFlags().AddGoFlagSet(flag.CommandLine) // hack to get rid of an "ERROR: logging before flag.Parse" args := os.Args[:] @@ -89,7 +38,7 @@ func main() { os.Args = args // back to your regularly scheduled cobra programming - if err := rootCmd.Execute(); err != nil { + if err := command.Root.Execute(); err != nil { log.Error(err) exit.Return(1) } From 0d6a1c02ea7904b6e98e33fb0d84d92c8af18de7 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Thu, 21 Jan 2021 18:03:26 +0100 Subject: [PATCH 09/21] Merge pull request #7334 from tinyspeck/am_vtctld_getsrvvschema [vtctld] Add GetSrvVSchema command --- .../vtctldclient/internal/command/vschemas.go | 60 +++++ go/vt/proto/vtctldata/vtctldata.pb.go | 212 ++++++++++++------ go/vt/proto/vtctlservice/vtctlservice.pb.go | 83 +++++-- go/vt/vtctl/grpcvtctldclient/client_gen.go | 9 + go/vt/vtctl/grpcvtctldserver/server.go | 12 + go/vt/vtctl/grpcvtctldserver/server_test.go | 83 +++++++ proto/vtctldata.proto | 9 + proto/vtctlservice.proto | 2 + 8 files changed, 384 insertions(+), 86 deletions(-) create mode 100644 go/cmd/vtctldclient/internal/command/vschemas.go diff --git a/go/cmd/vtctldclient/internal/command/vschemas.go b/go/cmd/vtctldclient/internal/command/vschemas.go new file mode 100644 index 00000000000..1dae2fdef56 --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/vschemas.go @@ -0,0 +1,60 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "fmt" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // GetSrvVSchema makes a GetSrvVSchema gRPC call to a vtctld. + GetSrvVSchema = &cobra.Command{ + Use: "GetSrvVSchema cell", + Args: cobra.ExactArgs(1), + RunE: commandGetSrvVSchema, + } +) + +func commandGetSrvVSchema(cmd *cobra.Command, args []string) error { + cell := cmd.Flags().Arg(0) + + resp, err := client.GetSrvVSchema(commandCtx, &vtctldatapb.GetSrvVSchemaRequest{ + Cell: cell, + }) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.SrvVSchema) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +func init() { + Root.AddCommand(GetSrvVSchema) +} diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 4e6762da1f5..3a26ea4c933 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -10,6 +10,7 @@ import ( proto "github.com/golang/protobuf/proto" logutil "vitess.io/vitess/go/vt/proto/logutil" topodata "vitess.io/vitess/go/vt/proto/topodata" + vschema "vitess.io/vitess/go/vt/proto/vschema" ) // Reference imports to suppress errors if they are not otherwise used. @@ -478,6 +479,84 @@ func (m *GetKeyspaceResponse) GetKeyspace() *Keyspace { return nil } +type GetSrvVSchemaRequest struct { + Cell string `protobuf:"bytes,1,opt,name=cell,proto3" json:"cell,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetSrvVSchemaRequest) Reset() { *m = GetSrvVSchemaRequest{} } +func (m *GetSrvVSchemaRequest) String() string { return proto.CompactTextString(m) } +func (*GetSrvVSchemaRequest) ProtoMessage() {} +func (*GetSrvVSchemaRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{12} +} + +func (m *GetSrvVSchemaRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetSrvVSchemaRequest.Unmarshal(m, b) +} +func (m *GetSrvVSchemaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetSrvVSchemaRequest.Marshal(b, m, deterministic) +} +func (m *GetSrvVSchemaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSrvVSchemaRequest.Merge(m, src) +} +func (m *GetSrvVSchemaRequest) XXX_Size() int { + return xxx_messageInfo_GetSrvVSchemaRequest.Size(m) +} +func (m *GetSrvVSchemaRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetSrvVSchemaRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSrvVSchemaRequest proto.InternalMessageInfo + +func (m *GetSrvVSchemaRequest) GetCell() string { + if m != nil { + return m.Cell + } + return "" +} + +type GetSrvVSchemaResponse struct { + SrvVSchema *vschema.SrvVSchema `protobuf:"bytes,1,opt,name=srv_v_schema,json=srvVSchema,proto3" json:"srv_v_schema,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetSrvVSchemaResponse) Reset() { *m = GetSrvVSchemaResponse{} } +func (m *GetSrvVSchemaResponse) String() string { return proto.CompactTextString(m) } +func (*GetSrvVSchemaResponse) ProtoMessage() {} +func (*GetSrvVSchemaResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{13} +} + +func (m *GetSrvVSchemaResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetSrvVSchemaResponse.Unmarshal(m, b) +} +func (m *GetSrvVSchemaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetSrvVSchemaResponse.Marshal(b, m, deterministic) +} +func (m *GetSrvVSchemaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSrvVSchemaResponse.Merge(m, src) +} +func (m *GetSrvVSchemaResponse) XXX_Size() int { + return xxx_messageInfo_GetSrvVSchemaResponse.Size(m) +} +func (m *GetSrvVSchemaResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetSrvVSchemaResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSrvVSchemaResponse proto.InternalMessageInfo + +func (m *GetSrvVSchemaResponse) GetSrvVSchema() *vschema.SrvVSchema { + if m != nil { + return m.SrvVSchema + } + return nil +} + type GetTabletRequest struct { TabletAlias *topodata.TabletAlias `protobuf:"bytes,1,opt,name=tablet_alias,json=tabletAlias,proto3" json:"tablet_alias,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -489,7 +568,7 @@ func (m *GetTabletRequest) Reset() { *m = GetTabletRequest{} } func (m *GetTabletRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletRequest) ProtoMessage() {} func (*GetTabletRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{12} + return fileDescriptor_f41247b323a1ab2e, []int{14} } func (m *GetTabletRequest) XXX_Unmarshal(b []byte) error { @@ -528,7 +607,7 @@ func (m *GetTabletResponse) Reset() { *m = GetTabletResponse{} } func (m *GetTabletResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletResponse) ProtoMessage() {} func (*GetTabletResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{13} + return fileDescriptor_f41247b323a1ab2e, []int{15} } func (m *GetTabletResponse) XXX_Unmarshal(b []byte) error { @@ -574,7 +653,7 @@ func (m *GetTabletsRequest) Reset() { *m = GetTabletsRequest{} } func (m *GetTabletsRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletsRequest) ProtoMessage() {} func (*GetTabletsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{14} + return fileDescriptor_f41247b323a1ab2e, []int{16} } func (m *GetTabletsRequest) XXX_Unmarshal(b []byte) error { @@ -627,7 +706,7 @@ func (m *GetTabletsResponse) Reset() { *m = GetTabletsResponse{} } func (m *GetTabletsResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletsResponse) ProtoMessage() {} func (*GetTabletsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{15} + return fileDescriptor_f41247b323a1ab2e, []int{17} } func (m *GetTabletsResponse) XXX_Unmarshal(b []byte) error { @@ -667,7 +746,7 @@ func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{16} + return fileDescriptor_f41247b323a1ab2e, []int{18} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { @@ -713,7 +792,7 @@ func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInK func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{17} + return fileDescriptor_f41247b323a1ab2e, []int{19} } func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -752,7 +831,7 @@ func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsIn func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{18} + return fileDescriptor_f41247b323a1ab2e, []int{20} } func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -793,7 +872,7 @@ func (m *Shard) Reset() { *m = Shard{} } func (m *Shard) String() string { return proto.CompactTextString(m) } func (*Shard) ProtoMessage() {} func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{19} + return fileDescriptor_f41247b323a1ab2e, []int{21} } func (m *Shard) XXX_Unmarshal(b []byte) error { @@ -853,7 +932,7 @@ func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettin func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } func (*TableMaterializeSettings) ProtoMessage() {} func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{20} + return fileDescriptor_f41247b323a1ab2e, []int{22} } func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -916,7 +995,7 @@ func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } func (*MaterializeSettings) ProtoMessage() {} func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{21} + return fileDescriptor_f41247b323a1ab2e, []int{23} } func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -1000,6 +1079,8 @@ func init() { proto.RegisterType((*GetKeyspacesResponse)(nil), "vtctldata.GetKeyspacesResponse") proto.RegisterType((*GetKeyspaceRequest)(nil), "vtctldata.GetKeyspaceRequest") proto.RegisterType((*GetKeyspaceResponse)(nil), "vtctldata.GetKeyspaceResponse") + proto.RegisterType((*GetSrvVSchemaRequest)(nil), "vtctldata.GetSrvVSchemaRequest") + proto.RegisterType((*GetSrvVSchemaResponse)(nil), "vtctldata.GetSrvVSchemaResponse") proto.RegisterType((*GetTabletRequest)(nil), "vtctldata.GetTabletRequest") proto.RegisterType((*GetTabletResponse)(nil), "vtctldata.GetTabletResponse") proto.RegisterType((*GetTabletsRequest)(nil), "vtctldata.GetTabletsRequest") @@ -1016,58 +1097,61 @@ func init() { func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 844 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x6e, 0xe3, 0x44, - 0x14, 0x96, 0x93, 0x4d, 0x1a, 0x9f, 0x6c, 0x7e, 0xd6, 0xed, 0x82, 0x09, 0x02, 0x82, 0x61, 0xbb, - 0xd1, 0x22, 0x39, 0xa5, 0x48, 0xa8, 0x42, 0x20, 0x51, 0x42, 0x5a, 0x85, 0x42, 0x85, 0xdc, 0x0a, - 0x24, 0x90, 0xb0, 0xa6, 0xce, 0x24, 0x58, 0x9d, 0x78, 0x8c, 0x67, 0x92, 0x36, 0xbc, 0x01, 0x2f, - 0xc3, 0x25, 0x97, 0x3c, 0x1b, 0x9a, 0x3f, 0xdb, 0x69, 0x13, 0x60, 0xef, 0x66, 0xbe, 0xf3, 0xf7, - 0x9d, 0xef, 0xcc, 0xb1, 0xa1, 0xb3, 0xe2, 0x11, 0x27, 0x53, 0xc4, 0x91, 0x9f, 0x66, 0x94, 0x53, - 0xc7, 0xce, 0x81, 0x5e, 0x8b, 0xd0, 0xf9, 0x92, 0xc7, 0x44, 0x59, 0x7a, 0x6d, 0x4e, 0x53, 0x5a, - 0x78, 0x7a, 0x3f, 0x42, 0x6f, 0x7c, 0x8f, 0xa3, 0x25, 0xc7, 0x3f, 0x88, 0x90, 0x11, 0x5d, 0x2c, - 0x50, 0x32, 0x0d, 0xf0, 0x6f, 0x4b, 0xcc, 0xb8, 0xe3, 0xc0, 0x13, 0x94, 0xcd, 0x99, 0x6b, 0xf5, - 0xab, 0x03, 0x3b, 0x90, 0x67, 0xe7, 0x05, 0xb4, 0x51, 0xc4, 0x63, 0x9a, 0x84, 0x3c, 0x5e, 0x60, - 0xba, 0xe4, 0x6e, 0xa5, 0x6f, 0x0d, 0xaa, 0x41, 0x4b, 0xa1, 0xd7, 0x0a, 0xf4, 0x46, 0xf0, 0xf6, - 0xd6, 0xc4, 0x2c, 0xa5, 0x09, 0xc3, 0xce, 0x87, 0x50, 0xc3, 0x2b, 0x9c, 0x70, 0xd7, 0xea, 0x5b, - 0x83, 0xe6, 0x71, 0xdb, 0x37, 0x34, 0xc7, 0x02, 0x0d, 0x94, 0xd1, 0x7b, 0x0b, 0xde, 0x3c, 0xc7, - 0x7c, 0x84, 0x09, 0x99, 0x24, 0x33, 0x7a, 0x89, 0x16, 0x98, 0x69, 0x6a, 0xde, 0x11, 0xb8, 0x8f, - 0x4d, 0x3a, 0xf9, 0x01, 0xd4, 0x12, 0x01, 0x68, 0xde, 0xea, 0xe2, 0x0d, 0xc0, 0x29, 0x45, 0x94, - 0x5a, 0x8c, 0x30, 0x21, 0x92, 0x87, 0x1d, 0xc8, 0xb3, 0x77, 0x06, 0xfb, 0x1b, 0x9e, 0x3a, 0xed, - 0x10, 0x6c, 0x61, 0x0e, 0xe3, 0x64, 0x46, 0x35, 0x6f, 0xc7, 0xcf, 0xf5, 0xcc, 0xdd, 0x1b, 0x91, - 0x3e, 0x79, 0x2e, 0xbc, 0xa1, 0xf3, 0xb0, 0x53, 0x12, 0x23, 0x56, 0xb0, 0xff, 0xcb, 0xca, 0x3b, - 0x2b, 0x4c, 0xba, 0xcc, 0x04, 0xf6, 0x90, 0x82, 0x24, 0xff, 0xe6, 0xf1, 0xd0, 0x2f, 0xe6, 0xbb, - 0x23, 0xc8, 0xd7, 0xf7, 0x71, 0xc2, 0xb3, 0x75, 0x60, 0xe2, 0x7b, 0xdf, 0xc3, 0xd3, 0xb2, 0xc1, - 0xe9, 0x42, 0xf5, 0x16, 0xaf, 0x75, 0xaf, 0xe2, 0xe8, 0xbc, 0x82, 0xda, 0x0a, 0x91, 0x25, 0x96, - 0x43, 0x6c, 0x1e, 0x1f, 0x6c, 0xf6, 0xa3, 0xca, 0x04, 0xca, 0xe5, 0xb3, 0xca, 0x89, 0xe5, 0x3d, - 0x97, 0xd2, 0x5c, 0xe0, 0x35, 0x4b, 0x51, 0x54, 0xf4, 0x33, 0x81, 0x83, 0x4d, 0x58, 0xf7, 0xf2, - 0x31, 0xd8, 0xb7, 0x06, 0xd4, 0xdd, 0xec, 0x97, 0xba, 0x31, 0x01, 0x41, 0xe1, 0xe5, 0x1d, 0xc9, - 0x31, 0xe5, 0x16, 0x3d, 0xa6, 0x1e, 0x34, 0x8c, 0x8b, 0xa6, 0x9f, 0xdf, 0xf5, 0xb8, 0x8a, 0x88, - 0x7c, 0x5c, 0x9b, 0x21, 0x3b, 0x4a, 0x17, 0x79, 0xbe, 0x85, 0xee, 0x39, 0xe6, 0xd7, 0xe8, 0x86, - 0x60, 0x6e, 0xea, 0x9e, 0xc0, 0x53, 0x2e, 0x81, 0x50, 0x6a, 0xaa, 0x13, 0x3d, 0x2f, 0x64, 0x52, - 0xee, 0x4a, 0xa7, 0x26, 0x2f, 0x2e, 0xde, 0x17, 0xf0, 0xac, 0x94, 0x4d, 0x73, 0x1a, 0x40, 0x5d, - 0xf9, 0xe8, 0x44, 0xdd, 0x87, 0x89, 0x02, 0x6d, 0xf7, 0x7e, 0x2e, 0x85, 0xb3, 0xff, 0xa1, 0x82, - 0x78, 0xf4, 0xec, 0x57, 0x94, 0x4d, 0xe5, 0x24, 0xed, 0x40, 0x5d, 0x04, 0x2a, 0x9e, 0x23, 0x73, - 0xab, 0x6a, 0x15, 0xe4, 0xc5, 0xfb, 0x52, 0x6a, 0x9c, 0x27, 0xd7, 0xe4, 0x5e, 0xc1, 0x9e, 0x2a, - 0x6e, 0x46, 0xf5, 0x98, 0x9d, 0x71, 0xf0, 0x2e, 0xa1, 0x61, 0x14, 0x14, 0x2b, 0x24, 0x36, 0xcc, - 0xac, 0x90, 0x38, 0x3b, 0x7e, 0x89, 0x69, 0xe5, 0xe1, 0xaa, 0x6c, 0xd1, 0xfe, 0x73, 0x78, 0xf7, - 0x2c, 0x4e, 0xa6, 0xa7, 0x84, 0x5c, 0x09, 0xde, 0x6c, 0x92, 0xbc, 0xce, 0x0b, 0xf8, 0xdb, 0x82, - 0xf7, 0x76, 0x86, 0xeb, 0xee, 0x2e, 0xa1, 0x2e, 0x25, 0x31, 0xcd, 0x7d, 0x5a, 0x7a, 0x0c, 0xff, - 0x11, 0xeb, 0x2b, 0x83, 0x5a, 0x2e, 0x9d, 0xa5, 0x77, 0x01, 0xcd, 0x12, 0xbc, 0x65, 0xb5, 0x0e, - 0x37, 0x57, 0xab, 0x5b, 0xaa, 0x27, 0x03, 0xcb, 0x6b, 0xf5, 0x0b, 0xd4, 0x24, 0xf6, 0xaf, 0x13, - 0x36, 0x3a, 0x57, 0x4a, 0x3a, 0xbf, 0x30, 0x53, 0xaf, 0xca, 0x22, 0x9d, 0x42, 0x64, 0x5d, 0x43, - 0x5a, 0xbd, 0x3f, 0x2c, 0x70, 0xe5, 0x08, 0xbf, 0x43, 0x1c, 0x67, 0x31, 0x22, 0xf1, 0xef, 0xf8, - 0x0a, 0x73, 0x1e, 0x27, 0x73, 0xe6, 0xbc, 0x2f, 0xde, 0x78, 0x36, 0xc7, 0x3c, 0x94, 0xd3, 0xd5, - 0x75, 0x9b, 0x0a, 0x93, 0x51, 0xce, 0x47, 0xf0, 0x8c, 0xd1, 0x65, 0x16, 0xe1, 0x10, 0xdf, 0xa7, - 0x19, 0x66, 0x2c, 0xa6, 0x89, 0xe6, 0xd1, 0x55, 0x86, 0x71, 0x8e, 0x3b, 0xef, 0x00, 0x44, 0x19, - 0x46, 0x1c, 0x87, 0xd3, 0x29, 0x91, 0xc4, 0xec, 0xc0, 0x56, 0xc8, 0xd7, 0x53, 0xe2, 0xfd, 0x59, - 0x81, 0xfd, 0x6d, 0x34, 0x7a, 0xd0, 0xb8, 0xa3, 0xd9, 0xed, 0x8c, 0xd0, 0x3b, 0xd3, 0xba, 0xb9, - 0x3b, 0x2f, 0xa1, 0xa3, 0xeb, 0x6f, 0xbc, 0x2a, 0x3b, 0x68, 0x2b, 0x38, 0x7f, 0x8b, 0x2f, 0xa1, - 0xa3, 0x7b, 0xc9, 0x1d, 0x15, 0x81, 0xb6, 0x82, 0x73, 0xc7, 0x43, 0xe8, 0x30, 0x4e, 0xd3, 0x10, - 0xcd, 0x38, 0xce, 0xc2, 0x88, 0xa6, 0x6b, 0xf7, 0x49, 0xdf, 0x1a, 0x34, 0x82, 0x96, 0x80, 0x4f, - 0x05, 0x3a, 0xa2, 0xe9, 0xda, 0xf9, 0x06, 0xda, 0x52, 0x95, 0x90, 0x69, 0x9e, 0x6e, 0x4d, 0x3e, - 0x9f, 0x0f, 0x4a, 0xe3, 0xdc, 0xa5, 0x6c, 0xd0, 0x92, 0xa1, 0x79, 0x87, 0xe6, 0x5f, 0x53, 0x2f, - 0xfe, 0x35, 0x4a, 0x7c, 0xf9, 0x81, 0xe1, 0xeb, 0x14, 0x33, 0x77, 0xcf, 0x88, 0x2f, 0xb0, 0x6b, - 0x01, 0x7d, 0x35, 0xf8, 0xe9, 0x70, 0x15, 0x73, 0xcc, 0x98, 0x1f, 0xd3, 0xa1, 0x3a, 0x0d, 0xe7, - 0x74, 0xb8, 0xe2, 0x43, 0xf9, 0x0f, 0x1f, 0xe6, 0x44, 0x6e, 0xea, 0x12, 0xf8, 0xe4, 0x9f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xcb, 0x2a, 0x06, 0x49, 0x11, 0x08, 0x00, 0x00, + // 891 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x6e, 0xdc, 0x44, + 0x14, 0x96, 0x77, 0xbb, 0xc9, 0xfa, 0x6c, 0xf6, 0xa7, 0x4e, 0x02, 0xc6, 0x08, 0x08, 0x03, 0x4d, + 0x57, 0x41, 0xf2, 0x96, 0x20, 0x50, 0x85, 0x40, 0x22, 0x84, 0xb4, 0x0a, 0x85, 0x08, 0x39, 0x51, + 0x91, 0x40, 0xc2, 0x9a, 0x7a, 0x27, 0x5b, 0x2b, 0xb3, 0x1e, 0xe3, 0x99, 0x75, 0xbb, 0xbc, 0x01, + 0x2f, 0xc3, 0x25, 0x97, 0x3c, 0x1b, 0x9a, 0x3f, 0xdb, 0x9b, 0xee, 0x16, 0x7a, 0x37, 0xf3, 0x9d, + 0xbf, 0xef, 0x9c, 0x6f, 0x8e, 0x65, 0x18, 0x96, 0x22, 0x11, 0x74, 0x8a, 0x05, 0x0e, 0xf3, 0x82, + 0x09, 0xe6, 0xb9, 0x15, 0x10, 0xf4, 0x29, 0x9b, 0x2d, 0x44, 0x4a, 0xb5, 0x25, 0x18, 0x08, 0x96, + 0xb3, 0xda, 0x33, 0xe8, 0x97, 0x3c, 0x79, 0x4e, 0xe6, 0xe6, 0x8a, 0x7e, 0x86, 0xe0, 0xec, 0x25, + 0x49, 0x16, 0x82, 0x3c, 0x95, 0x19, 0x4e, 0xd9, 0x7c, 0x8e, 0xb3, 0x69, 0x44, 0x7e, 0x5f, 0x10, + 0x2e, 0x3c, 0x0f, 0xee, 0xe0, 0x62, 0xc6, 0x7d, 0xe7, 0xa0, 0x3d, 0x76, 0x23, 0x75, 0xf6, 0xee, + 0xc1, 0x00, 0x27, 0x22, 0x65, 0x59, 0x2c, 0xd2, 0x39, 0x61, 0x0b, 0xe1, 0xb7, 0x0e, 0x9c, 0x71, + 0x3b, 0xea, 0x6b, 0xf4, 0x4a, 0x83, 0xe8, 0x14, 0xde, 0x5d, 0x9b, 0x98, 0xe7, 0x2c, 0xe3, 0xc4, + 0xfb, 0x18, 0x3a, 0xa4, 0x24, 0x99, 0xf0, 0x9d, 0x03, 0x67, 0xdc, 0x3b, 0x1e, 0x84, 0x96, 0xf5, + 0x99, 0x44, 0x23, 0x6d, 0x44, 0xef, 0xc0, 0xdb, 0x8f, 0x89, 0x38, 0x25, 0x94, 0x9e, 0x67, 0xd7, + 0xec, 0x02, 0xcf, 0x09, 0x37, 0xd4, 0xd0, 0x03, 0xf0, 0x5f, 0x35, 0x99, 0xe4, 0x7b, 0xd0, 0xc9, + 0x24, 0x60, 0x78, 0xeb, 0x0b, 0x1a, 0x83, 0xd7, 0x88, 0x68, 0xb4, 0x98, 0x10, 0x4a, 0x15, 0x0f, + 0x37, 0x52, 0x67, 0xf4, 0x08, 0x76, 0x57, 0x3c, 0x4d, 0xda, 0x09, 0xb8, 0xd2, 0x1c, 0xa7, 0xd9, + 0x35, 0x33, 0xbc, 0xbd, 0xb0, 0x1a, 0x6f, 0xe5, 0xde, 0x4d, 0xcc, 0x09, 0xf9, 0xf0, 0x96, 0xc9, + 0xc3, 0x4f, 0x68, 0x8a, 0x79, 0xcd, 0xfe, 0x6f, 0xa7, 0xea, 0xac, 0x36, 0x99, 0x32, 0xe7, 0xb0, + 0x8d, 0x35, 0xa4, 0xf8, 0xf7, 0x8e, 0x27, 0x61, 0x2d, 0xf7, 0x86, 0xa0, 0xd0, 0xdc, 0xcf, 0x32, + 0x51, 0x2c, 0x23, 0x1b, 0x1f, 0xfc, 0x04, 0x3b, 0x4d, 0x83, 0x37, 0x82, 0xf6, 0x0d, 0x59, 0x9a, + 0x5e, 0xe5, 0xd1, 0x3b, 0x82, 0x4e, 0x89, 0xe9, 0x82, 0x28, 0x11, 0x7b, 0xc7, 0x7b, 0xab, 0xfd, + 0xe8, 0x32, 0x91, 0x76, 0xf9, 0xb2, 0xf5, 0xd0, 0x41, 0xfb, 0x6a, 0x34, 0x4f, 0xc8, 0x92, 0xe7, + 0x38, 0xa9, 0xfb, 0x39, 0x87, 0xbd, 0x55, 0xd8, 0xf4, 0xf2, 0x29, 0xb8, 0x37, 0x16, 0x34, 0xdd, + 0xec, 0x36, 0xba, 0xb1, 0x01, 0x51, 0xed, 0x85, 0x1e, 0x28, 0x99, 0x2a, 0x8b, 0x91, 0x29, 0x80, + 0xae, 0x75, 0x31, 0xf4, 0xab, 0xbb, 0x91, 0xab, 0x8e, 0xa8, 0xe4, 0x5a, 0x0d, 0xd9, 0x50, 0xba, + 0xce, 0x73, 0xa4, 0x9a, 0xb8, 0x2c, 0xca, 0xa7, 0x97, 0x6a, 0x45, 0x5e, 0xf7, 0x44, 0x2e, 0x60, + 0xff, 0x96, 0xaf, 0xa9, 0xfa, 0x39, 0xec, 0xf0, 0xa2, 0x8c, 0xcb, 0x58, 0xaf, 0x59, 0x5d, 0xd9, + 0xac, 0x5d, 0x23, 0x04, 0x78, 0x75, 0x46, 0x3f, 0xc0, 0xe8, 0x31, 0x11, 0x57, 0xf8, 0x19, 0x25, + 0xc2, 0xd6, 0x7d, 0x08, 0x3b, 0x42, 0x01, 0xb1, 0xd2, 0xd3, 0xa4, 0xda, 0xaf, 0x25, 0xd2, 0xee, + 0x5a, 0xa3, 0x9e, 0xa8, 0x2f, 0xe8, 0x6b, 0xb8, 0xdb, 0xc8, 0x66, 0x98, 0x8d, 0x61, 0x4b, 0xfb, + 0x98, 0x44, 0xa3, 0xdb, 0x89, 0x22, 0x63, 0x47, 0xbf, 0x36, 0xc2, 0xf9, 0xff, 0x50, 0x40, 0x2e, + 0x1c, 0x7f, 0x8e, 0x8b, 0xa9, 0x7a, 0x45, 0x6e, 0xa4, 0x2f, 0x12, 0x95, 0xb3, 0xe2, 0x7e, 0x5b, + 0xaf, 0xa1, 0xba, 0xa0, 0x6f, 0x94, 0xbe, 0x55, 0x72, 0x43, 0xee, 0x08, 0xb6, 0x75, 0x71, 0xfb, + 0x4c, 0x5e, 0x65, 0x67, 0x1d, 0xd0, 0x05, 0x74, 0xad, 0x7a, 0x52, 0x1b, 0xb9, 0xdd, 0x56, 0x1b, + 0x79, 0xf6, 0xc2, 0x06, 0xd3, 0xd6, 0xed, 0x35, 0x5d, 0xa3, 0xfb, 0x57, 0xf0, 0xfe, 0xa3, 0x34, + 0x9b, 0x9e, 0x50, 0x7a, 0x29, 0x79, 0xf3, 0xf3, 0xec, 0x4d, 0x5e, 0xdf, 0x3f, 0x0e, 0x7c, 0xb0, + 0x31, 0xdc, 0x74, 0x77, 0x01, 0x5b, 0x6a, 0x24, 0xb6, 0xb9, 0x2f, 0x1a, 0x0f, 0xf1, 0x3f, 0x62, + 0x43, 0x6d, 0xd0, 0x8b, 0x6d, 0xb2, 0x04, 0x4f, 0xa0, 0xd7, 0x80, 0xd7, 0xac, 0xf5, 0xe1, 0xea, + 0x5a, 0x8f, 0x1a, 0xf5, 0x54, 0x60, 0x73, 0xa5, 0x7f, 0x83, 0x8e, 0xc2, 0x5e, 0xab, 0xb0, 0x9d, + 0x73, 0xab, 0x31, 0xe7, 0x7b, 0x56, 0xf5, 0xb6, 0x2a, 0x32, 0xac, 0x87, 0x6c, 0x6a, 0x28, 0x2b, + 0xfa, 0xd3, 0x01, 0x5f, 0x49, 0xf8, 0x23, 0x16, 0xa4, 0x48, 0x31, 0x4d, 0xff, 0x20, 0x97, 0x44, + 0x88, 0x34, 0x9b, 0x71, 0xef, 0x43, 0xf9, 0xc6, 0x8b, 0x19, 0x11, 0xb1, 0x52, 0xd7, 0xd4, 0xed, + 0x69, 0x4c, 0x45, 0x79, 0x9f, 0xc0, 0x5d, 0xce, 0x16, 0x45, 0x42, 0x62, 0xf2, 0x32, 0x2f, 0x08, + 0xe7, 0x29, 0xcb, 0x0c, 0x8f, 0x91, 0x36, 0x9c, 0x55, 0xb8, 0xf7, 0x1e, 0x40, 0x52, 0x10, 0x2c, + 0x48, 0x3c, 0x9d, 0x52, 0x45, 0xcc, 0x8d, 0x5c, 0x8d, 0x7c, 0x37, 0xa5, 0xe8, 0xaf, 0x16, 0xec, + 0xae, 0xa3, 0x11, 0x40, 0xf7, 0x05, 0x2b, 0x6e, 0xae, 0x29, 0x7b, 0x61, 0x5b, 0xb7, 0x77, 0xef, + 0x3e, 0x0c, 0x4d, 0xfd, 0x95, 0x57, 0xe5, 0x46, 0x03, 0x0d, 0x57, 0x6f, 0xf1, 0x3e, 0x0c, 0x4d, + 0x2f, 0x95, 0xa3, 0x26, 0x30, 0xd0, 0x70, 0xe5, 0x78, 0x08, 0x43, 0x2e, 0x58, 0x1e, 0xe3, 0x6b, + 0x41, 0x8a, 0x38, 0x61, 0xf9, 0xd2, 0xbf, 0x73, 0xe0, 0x8c, 0xbb, 0x51, 0x5f, 0xc2, 0x27, 0x12, + 0x3d, 0x65, 0xf9, 0xd2, 0xfb, 0x1e, 0x06, 0x6a, 0x2a, 0x31, 0x37, 0x3c, 0xfd, 0x8e, 0x7a, 0x3e, + 0x1f, 0x35, 0xe4, 0xdc, 0x34, 0xd9, 0xa8, 0xaf, 0x42, 0xab, 0x0e, 0xed, 0x47, 0x6c, 0xab, 0xfe, + 0x88, 0xe9, 0xe1, 0xab, 0x0f, 0x8c, 0x58, 0xe6, 0x84, 0xfb, 0xdb, 0x76, 0xf8, 0x12, 0xbb, 0x92, + 0xd0, 0xb7, 0xe3, 0x5f, 0x0e, 0xcb, 0x54, 0x10, 0xce, 0xc3, 0x94, 0x4d, 0xf4, 0x69, 0x32, 0x63, + 0x93, 0x52, 0x4c, 0xd4, 0xff, 0xc3, 0xa4, 0x22, 0xf2, 0x6c, 0x4b, 0x01, 0x9f, 0xfd, 0x1b, 0x00, + 0x00, 0xff, 0xff, 0xc7, 0x5e, 0x26, 0x9e, 0x9c, 0x08, 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index b0e6c73a1f7..313ff74c649 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,28 +29,29 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 332 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x5f, 0x4b, 0x32, 0x41, - 0x14, 0xc6, 0xdf, 0xf7, 0x42, 0xa1, 0x93, 0x60, 0x9c, 0x2e, 0x02, 0x4b, 0x23, 0xa3, 0xc0, 0x02, - 0x37, 0xec, 0x13, 0x98, 0x94, 0x89, 0x20, 0xf4, 0x87, 0x2e, 0x84, 0x2e, 0xc6, 0xdd, 0x53, 0x2e, - 0x8c, 0x3b, 0xba, 0x67, 0x5c, 0xea, 0xe3, 0xf5, 0xcd, 0xa2, 0xb5, 0x99, 0xb6, 0x6d, 0xc7, 0xba, - 0xdb, 0x3d, 0xbf, 0xe7, 0xfc, 0xe6, 0x61, 0x60, 0x00, 0x13, 0xed, 0x6b, 0xc9, 0x14, 0x27, 0xa1, - 0x4f, 0xed, 0x79, 0xac, 0xb4, 0xc2, 0x4a, 0x76, 0x56, 0xab, 0xa6, 0x7f, 0x81, 0xd0, 0x62, 0x85, - 0x3b, 0x0b, 0x28, 0x3d, 0x7c, 0x8c, 0x70, 0x0a, 0xdb, 0x97, 0x2f, 0xe4, 0x2f, 0x35, 0xa5, 0xff, - 0x3d, 0x35, 0x9b, 0x89, 0x28, 0xc0, 0xa3, 0xf6, 0xd7, 0x46, 0x01, 0xbf, 0xa5, 0xc5, 0x92, 0x58, - 0xd7, 0x8e, 0x7f, 0x8b, 0xf1, 0x5c, 0x45, 0x4c, 0xcd, 0x7f, 0x67, 0xff, 0x3b, 0x6f, 0x25, 0x28, - 0xa7, 0x30, 0xc0, 0x18, 0x76, 0xae, 0xc2, 0x28, 0xe8, 0x4a, 0x79, 0x37, 0x15, 0x71, 0xc0, 0x83, - 0x68, 0x48, 0xaf, 0x3c, 0x17, 0x3e, 0x61, 0x2b, 0x63, 0x74, 0x64, 0xcc, 0xe1, 0x27, 0x7f, 0x89, - 0x9a, 0x02, 0xf8, 0x08, 0x5b, 0x7d, 0xd2, 0x3d, 0x92, 0x72, 0x10, 0x3d, 0xa9, 0x91, 0x98, 0x11, - 0x63, 0x33, 0x63, 0xc8, 0x43, 0x73, 0xca, 0xe1, 0xda, 0x8c, 0xd5, 0x8f, 0x60, 0x33, 0x43, 0xb1, - 0x5e, 0xbc, 0x65, 0xa4, 0x0d, 0x17, 0xb6, 0xbe, 0x31, 0x54, 0x3f, 0x01, 0x77, 0x65, 0x28, 0x98, - 0x18, 0x0f, 0x7e, 0x2e, 0x19, 0x66, 0xbc, 0xcd, 0x75, 0x91, 0x5c, 0x57, 0x7b, 0xe5, 0xb9, 0xae, - 0xf9, 0x6b, 0x6e, 0xb8, 0xb0, 0xf5, 0xdd, 0x40, 0x25, 0x03, 0x18, 0x1d, 0x1b, 0xb6, 0xe5, 0xbe, - 0x93, 0x5b, 0xe5, 0x35, 0x6c, 0xf4, 0x49, 0xdf, 0x8b, 0x89, 0x24, 0x8d, 0xbb, 0xdf, 0xf3, 0xab, - 0xa9, 0x91, 0xed, 0x15, 0x43, 0x6b, 0x1a, 0x02, 0xd8, 0x31, 0x63, 0x61, 0xda, 0x16, 0xab, 0x3b, - 0xa8, 0x91, 0x5d, 0x9c, 0x8e, 0x5b, 0x49, 0xa8, 0x89, 0xb9, 0x1d, 0x2a, 0x6f, 0xf5, 0xe5, 0x3d, - 0x2b, 0x2f, 0xd1, 0x5e, 0xfa, 0xac, 0xbc, 0xec, 0xa3, 0x9b, 0x94, 0xd3, 0xd9, 0xf9, 0x7b, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x5d, 0xff, 0x05, 0xa6, 0x9f, 0x03, 0x00, 0x00, + // 352 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xd1, 0x4a, 0x02, 0x41, + 0x14, 0x86, 0xeb, 0x22, 0xa1, 0xc9, 0x30, 0x4e, 0x17, 0x81, 0xa5, 0x95, 0x51, 0x60, 0x81, 0x1b, + 0xf6, 0x04, 0x26, 0x65, 0x22, 0x08, 0xa5, 0x78, 0x21, 0x74, 0x31, 0xee, 0x9e, 0x72, 0x61, 0x76, + 0x47, 0xf7, 0x8c, 0x4b, 0x3d, 0x49, 0xaf, 0x1b, 0xad, 0xcd, 0xb8, 0x6d, 0x3b, 0xd6, 0x9d, 0x7b, + 0xbe, 0xff, 0xff, 0xe6, 0x38, 0x30, 0x0c, 0x62, 0xe5, 0x2a, 0x41, 0x18, 0xc5, 0xbe, 0x8b, 0x8d, + 0x59, 0x24, 0x95, 0x84, 0x62, 0x7a, 0x56, 0x2e, 0x25, 0x5f, 0x1e, 0x57, 0x7c, 0x89, 0x9b, 0x73, + 0xb6, 0x35, 0xfa, 0x1a, 0xc1, 0x94, 0xed, 0xdf, 0xbd, 0xa1, 0xbb, 0x50, 0x98, 0x7c, 0xb7, 0x65, + 0x10, 0xf0, 0xd0, 0x83, 0xf3, 0xc6, 0xaa, 0x91, 0xc3, 0x9f, 0x70, 0xbe, 0x40, 0x52, 0xe5, 0x8b, + 0xbf, 0x62, 0x34, 0x93, 0x21, 0x61, 0x6d, 0xe3, 0x7a, 0xb3, 0xf9, 0x51, 0x60, 0x85, 0x04, 0x7a, + 0x10, 0xb1, 0x83, 0x7b, 0x3f, 0xf4, 0x5a, 0x42, 0x0c, 0xa6, 0x3c, 0xf2, 0xa8, 0x1b, 0xf6, 0xf0, + 0x9d, 0x66, 0xdc, 0x45, 0xa8, 0xa7, 0x8c, 0x96, 0x8c, 0x3e, 0xfc, 0xf2, 0x3f, 0x51, 0xbd, 0x00, + 0x3c, 0xb3, 0xbd, 0x0e, 0xaa, 0x36, 0x0a, 0xd1, 0x0d, 0x5f, 0x64, 0x9f, 0x07, 0x48, 0x50, 0x4b, + 0x19, 0xb2, 0x50, 0x9f, 0x72, 0xb6, 0x36, 0x63, 0xf4, 0x7d, 0xb6, 0x93, 0xa2, 0x50, 0xc9, 0x6f, + 0x69, 0x69, 0xd5, 0x86, 0x8d, 0x6f, 0xcc, 0x4a, 0xdf, 0x80, 0x5a, 0xc2, 0xe7, 0x84, 0x04, 0xa7, + 0xbf, 0x4b, 0x9a, 0x69, 0x6f, 0x6d, 0x5d, 0x24, 0xb3, 0xab, 0xb9, 0xf2, 0xcc, 0xae, 0xd9, 0x6b, + 0xae, 0xda, 0xb0, 0xf1, 0x3d, 0xb2, 0x62, 0x0a, 0x10, 0x58, 0x1a, 0x66, 0xcb, 0x63, 0x2b, 0x37, + 0xca, 0x21, 0xdb, 0xed, 0xa0, 0x1a, 0x44, 0xf1, 0x68, 0xe0, 0x4e, 0x31, 0xe0, 0x90, 0xe9, 0xac, + 0x88, 0x96, 0x9e, 0xd8, 0x03, 0xc6, 0xfa, 0xc0, 0xb6, 0x3b, 0xa8, 0x86, 0x7c, 0x22, 0x50, 0xc1, + 0xe1, 0xcf, 0xc2, 0x72, 0xaa, 0x6d, 0x47, 0xf9, 0xd0, 0x98, 0x7a, 0x8c, 0x99, 0x31, 0x41, 0x6e, + 0xda, 0xfc, 0xdd, 0x8a, 0x85, 0x6a, 0xd9, 0xed, 0xd5, 0xb8, 0x1e, 0xfb, 0x0a, 0x89, 0x1a, 0xbe, + 0x74, 0x96, 0xbf, 0x9c, 0x57, 0xe9, 0xc4, 0xca, 0x49, 0x1e, 0xab, 0x93, 0x7e, 0xca, 0x93, 0x42, + 0x32, 0xbb, 0xf9, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x95, 0x4b, 0x3a, 0x7d, 0xf5, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -179,6 +180,8 @@ type VtctldClient interface { GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspacesRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspacesResponse, error) + // GetSrvVSchema returns a the SrvVSchema for a cell. + GetSrvVSchema(ctx context.Context, in *vtctldata.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSrvVSchemaResponse, error) // GetTablet returns information about a tablet. GetTablet(ctx context.Context, in *vtctldata.GetTabletRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletResponse, error) // GetTablets returns tablets, optionally filtered by keyspace and shard. @@ -247,6 +250,15 @@ func (c *vtctldClient) GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspa return out, nil } +func (c *vtctldClient) GetSrvVSchema(ctx context.Context, in *vtctldata.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSrvVSchemaResponse, error) { + out := new(vtctldata.GetSrvVSchemaResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetSrvVSchema", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) GetTablet(ctx context.Context, in *vtctldata.GetTabletRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletResponse, error) { out := new(vtctldata.GetTabletResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetTablet", in, out, opts...) @@ -282,6 +294,8 @@ type VtctldServer interface { GetKeyspace(context.Context, *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. GetKeyspaces(context.Context, *vtctldata.GetKeyspacesRequest) (*vtctldata.GetKeyspacesResponse, error) + // GetSrvVSchema returns a the SrvVSchema for a cell. + GetSrvVSchema(context.Context, *vtctldata.GetSrvVSchemaRequest) (*vtctldata.GetSrvVSchemaResponse, error) // GetTablet returns information about a tablet. GetTablet(context.Context, *vtctldata.GetTabletRequest) (*vtctldata.GetTabletResponse, error) // GetTablets returns tablets, optionally filtered by keyspace and shard. @@ -310,6 +324,9 @@ func (*UnimplementedVtctldServer) GetKeyspace(ctx context.Context, req *vtctldat func (*UnimplementedVtctldServer) GetKeyspaces(ctx context.Context, req *vtctldata.GetKeyspacesRequest) (*vtctldata.GetKeyspacesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetKeyspaces not implemented") } +func (*UnimplementedVtctldServer) GetSrvVSchema(ctx context.Context, req *vtctldata.GetSrvVSchemaRequest) (*vtctldata.GetSrvVSchemaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSrvVSchema not implemented") +} func (*UnimplementedVtctldServer) GetTablet(ctx context.Context, req *vtctldata.GetTabletRequest) (*vtctldata.GetTabletResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetTablet not implemented") } @@ -429,6 +446,24 @@ func _Vtctld_GetKeyspaces_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _Vtctld_GetSrvVSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetSrvVSchemaRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetSrvVSchema(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetSrvVSchema", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetSrvVSchema(ctx, req.(*vtctldata.GetSrvVSchemaRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_GetTablet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.GetTabletRequest) if err := dec(in); err != nil { @@ -493,6 +528,10 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "GetKeyspaces", Handler: _Vtctld_GetKeyspaces_Handler, }, + { + MethodName: "GetSrvVSchema", + Handler: _Vtctld_GetSrvVSchema_Handler, + }, { MethodName: "GetTablet", Handler: _Vtctld_GetTablet_Handler, diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index cc8d2b2ce72..65b7060ae01 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -82,6 +82,15 @@ func (client *gRPCVtctldClient) GetKeyspaces(ctx context.Context, in *vtctldatap return client.c.GetKeyspaces(ctx, in, opts...) } +// GetSrvVSchema is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetSrvVSchema(ctx context.Context, in *vtctldatapb.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldatapb.GetSrvVSchemaResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetSrvVSchema(ctx, in, opts...) +} + // GetTablet is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) GetTablet(ctx context.Context, in *vtctldatapb.GetTabletRequest, opts ...grpc.CallOption) (*vtctldatapb.GetTabletResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index c28bceddee3..03a0921ecf6 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -136,6 +136,18 @@ func (s *VtctldServer) GetKeyspaces(ctx context.Context, req *vtctldatapb.GetKey return &vtctldatapb.GetKeyspacesResponse{Keyspaces: keyspaces}, nil } +// GetSrvVSchema is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetSrvVSchema(ctx context.Context, req *vtctldatapb.GetSrvVSchemaRequest) (*vtctldatapb.GetSrvVSchemaResponse, error) { + vschema, err := s.ts.GetSrvVSchema(ctx, req.Cell) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetSrvVSchemaResponse{ + SrvVSchema: vschema, + }, nil +} + // GetTablet is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) GetTablet(ctx context.Context, req *vtctldatapb.GetTabletRequest) (*vtctldatapb.GetTabletResponse, error) { ti, err := s.ts.GetTablet(ctx, req.TabletAlias) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 183daa7e5b9..e55b764898b 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -183,6 +184,88 @@ func TestGetTablet(t *testing.T) { assert.Error(t, err) } +func TestGetSrvVSchema(t *testing.T) { + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory("zone1", "zone2") + vtctld := NewVtctldServer(ts) + + zone1SrvVSchema := &vschemapb.SrvVSchema{ + Keyspaces: map[string]*vschemapb.Keyspace{ + "testkeyspace": { + Sharded: true, + RequireExplicitRouting: false, + }, + }, + RoutingRules: &vschemapb.RoutingRules{ + Rules: []*vschemapb.RoutingRule{}, + }, + } + zone2SrvVSchema := &vschemapb.SrvVSchema{ + Keyspaces: map[string]*vschemapb.Keyspace{ + "testkeyspace": { + Sharded: true, + RequireExplicitRouting: false, + }, + "unsharded": { + Sharded: false, + RequireExplicitRouting: false, + }, + }, + RoutingRules: &vschemapb.RoutingRules{ + Rules: []*vschemapb.RoutingRule{}, + }, + } + + err := ts.UpdateSrvVSchema(ctx, "zone1", zone1SrvVSchema) + require.NoError(t, err, "cannot add zone1 srv vschema") + err = ts.UpdateSrvVSchema(ctx, "zone2", zone2SrvVSchema) + require.NoError(t, err, "cannot add zone2 srv vschema") + + expected := &vschemapb.SrvVSchema{ // have to copy our structs because of proto marshal artifacts + Keyspaces: map[string]*vschemapb.Keyspace{ + "testkeyspace": { + Sharded: true, + RequireExplicitRouting: false, + }, + }, + RoutingRules: &vschemapb.RoutingRules{ + Rules: []*vschemapb.RoutingRule{}, + }, + } + resp, err := vtctld.GetSrvVSchema(ctx, &vtctldatapb.GetSrvVSchemaRequest{Cell: "zone1"}) + assert.NoError(t, err) + assert.Equal(t, expected.Keyspaces, resp.SrvVSchema.Keyspaces, "GetSrvVSchema(zone1) mismatch") + assert.ElementsMatch(t, expected.RoutingRules.Rules, resp.SrvVSchema.RoutingRules.Rules, "GetSrvVSchema(zone1) rules mismatch") + + expected = &vschemapb.SrvVSchema{ // have to copy our structs because of proto marshal artifacts + Keyspaces: map[string]*vschemapb.Keyspace{ + "testkeyspace": { + Sharded: true, + RequireExplicitRouting: false, + }, + "unsharded": { + Sharded: false, + RequireExplicitRouting: false, + }, + }, + RoutingRules: &vschemapb.RoutingRules{ + Rules: []*vschemapb.RoutingRule{}, + }, + } + resp, err = vtctld.GetSrvVSchema(ctx, &vtctldatapb.GetSrvVSchemaRequest{Cell: "zone2"}) + assert.NoError(t, err) + assert.Equal(t, expected.Keyspaces, resp.SrvVSchema.Keyspaces, "GetSrvVSchema(zone2) mismatch %+v %+v", zone2SrvVSchema.Keyspaces["testkeyspace"], resp.SrvVSchema.Keyspaces["testkeyspace"]) + assert.ElementsMatch(t, expected.RoutingRules.Rules, resp.SrvVSchema.RoutingRules.Rules, "GetSrvVSchema(zone2) rules mismatch") + + resp, err = vtctld.GetSrvVSchema(ctx, &vtctldatapb.GetSrvVSchemaRequest{Cell: "dne"}) + assert.Error(t, err, "GetSrvVSchema(dne)") + assert.Nil(t, resp, "GetSrvVSchema(dne)") + + topofactory.SetError(assert.AnError) + _, err = vtctld.GetSrvVSchema(ctx, &vtctldatapb.GetSrvVSchemaRequest{Cell: "zone1"}) + assert.Error(t, err) +} + func TestGetTablets(t *testing.T) { tests := []struct { name string diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index a05087216d2..1e18b37f4c1 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -24,6 +24,7 @@ package vtctldata; import "logutil.proto"; import "topodata.proto"; +import "vschema.proto"; // ExecuteVtctlCommandRequest is the payload for ExecuteVtctlCommand. // timeouts are in nanoseconds. @@ -74,6 +75,14 @@ message GetKeyspaceResponse { Keyspace keyspace = 1; } +message GetSrvVSchemaRequest { + string cell = 1; +} + +message GetSrvVSchemaResponse { + vschema.SrvVSchema srv_v_schema = 1; +} + message GetTabletRequest { topodata.TabletAlias tablet_alias = 1; } diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 76f76645389..2ffbdb218de 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -46,6 +46,8 @@ service Vtctld { rpc GetKeyspace(vtctldata.GetKeyspaceRequest) returns (vtctldata.GetKeyspaceResponse) {}; // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. rpc GetKeyspaces(vtctldata.GetKeyspacesRequest) returns (vtctldata.GetKeyspacesResponse) {}; + // GetSrvVSchema returns a the SrvVSchema for a cell. + rpc GetSrvVSchema(vtctldata.GetSrvVSchemaRequest) returns (vtctldata.GetSrvVSchemaResponse) {}; // GetTablet returns information about a tablet. rpc GetTablet(vtctldata.GetTabletRequest) returns (vtctldata.GetTabletResponse) {}; // GetTablets returns tablets, optionally filtered by keyspace and shard. From d05d57f4fb547fce3a03543981073773f4bdb027 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Fri, 22 Jan 2021 22:01:24 +0100 Subject: [PATCH 10/21] Merge pull request #7346 from tinyspeck/am_vtctld_getschema [vtctld] Migrate GetSchema Signed-off-by: Richard Bailey --- go.mod | 1 + .../vtctldclient/internal/command/schema.go | 99 +++++++ go/vt/proto/vtctldata/vtctldata.pb.go | 277 +++++++++++++----- go/vt/proto/vtctlservice/vtctlservice.pb.go | 87 ++++-- go/vt/vtctl/grpcvtctldclient/client_gen.go | 9 + go/vt/vtctl/grpcvtctldserver/server.go | 50 +++- go/vt/vtctl/grpcvtctldserver/server_test.go | 187 ++++++++++++ .../testutil/test_tmclient.go | 64 ++++ go/vt/vtctl/vtctl.go | 14 +- proto/vtctldata.proto | 24 ++ proto/vtctlservice.proto | 3 + 11 files changed, 718 insertions(+), 97 deletions(-) create mode 100644 go/cmd/vtctldclient/internal/command/schema.go create mode 100644 go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go diff --git a/go.mod b/go.mod index 63e23c4803d..4136bb84f46 100644 --- a/go.mod +++ b/go.mod @@ -79,6 +79,7 @@ require ( github.com/satori/go.uuid v1.2.0 // indirect github.com/sjmudd/stopwatch v0.0.0-20170613150411-f380bf8a9be1 github.com/smartystreets/goconvey v1.6.4 // indirect + github.com/spf13/cobra v0.0.5 github.com/stretchr/testify v1.4.0 github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b github.com/tebeka/selenium v0.9.9 diff --git a/go/cmd/vtctldclient/internal/command/schema.go b/go/cmd/vtctldclient/internal/command/schema.go new file mode 100644 index 00000000000..da6493d156e --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/schema.go @@ -0,0 +1,99 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "errors" + "fmt" + "strings" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/topo/topoproto" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +// GetSchema makes a GetSchema gRPC call to a vtctld. +var GetSchema = &cobra.Command{ + Use: "GetSchema [--tables TABLES ...] [--exclude-tables EXCLUDE_TABLES ...] [{--table-names-only | --table-sizes-only}] [--include-views] alias", + Args: cobra.ExactArgs(1), + RunE: commandGetSchema, +} + +var getSchemaOptions = struct { + Tables []string + ExcludeTables []string + IncludeViews bool + TableNamesOnly bool + TableSizesOnly bool +}{} + +func commandGetSchema(cmd *cobra.Command, args []string) error { + if getSchemaOptions.TableNamesOnly && getSchemaOptions.TableSizesOnly { + return errors.New("can only pass one of --table-names-only and --table-sizes-only") + } + + alias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + resp, err := client.GetSchema(commandCtx, &vtctldatapb.GetSchemaRequest{ + TabletAlias: alias, + Tables: getSchemaOptions.Tables, + ExcludeTables: getSchemaOptions.ExcludeTables, + IncludeViews: getSchemaOptions.IncludeViews, + TableNamesOnly: getSchemaOptions.TableNamesOnly, + TableSizesOnly: getSchemaOptions.TableSizesOnly, + }) + if err != nil { + return err + } + + if getSchemaOptions.TableNamesOnly { + names := make([]string, len(resp.Schema.TableDefinitions)) + + for i, td := range resp.Schema.TableDefinitions { + names[i] = td.Name + } + + fmt.Printf("%s\n", strings.Join(names, "\n")) + + return nil + } + + data, err := cli.MarshalJSON(resp.Schema) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +func init() { + GetSchema.Flags().StringSliceVar(&getSchemaOptions.Tables, "tables", nil, "TODO") + GetSchema.Flags().StringSliceVar(&getSchemaOptions.ExcludeTables, "exclude-tables", nil, "TODO") + GetSchema.Flags().BoolVar(&getSchemaOptions.IncludeViews, "include-views", false, "TODO") + GetSchema.Flags().BoolVarP(&getSchemaOptions.TableNamesOnly, "table-names-only", "n", false, "TODO") + GetSchema.Flags().BoolVarP(&getSchemaOptions.TableSizesOnly, "table-sizes-only", "s", false, "TODO") + + Root.AddCommand(GetSchema) +} diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 3a26ea4c933..5bab4dbea03 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -9,6 +9,7 @@ import ( proto "github.com/golang/protobuf/proto" logutil "vitess.io/vitess/go/vt/proto/logutil" + tabletmanagerdata "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodata "vitess.io/vitess/go/vt/proto/topodata" vschema "vitess.io/vitess/go/vt/proto/vschema" ) @@ -479,6 +480,134 @@ func (m *GetKeyspaceResponse) GetKeyspace() *Keyspace { return nil } +type GetSchemaRequest struct { + TabletAlias *topodata.TabletAlias `protobuf:"bytes,1,opt,name=tablet_alias,json=tabletAlias,proto3" json:"tablet_alias,omitempty"` + // Tables is a list of tables for which we should gather information. Each is + // either an exact match, or a regular expression of the form /regexp/. + Tables []string `protobuf:"bytes,2,rep,name=tables,proto3" json:"tables,omitempty"` + // ExcludeTables is a list of tables to exclude from the result. Each is + // either an exact match, or a regular expression of the form /regexp/. + ExcludeTables []string `protobuf:"bytes,3,rep,name=exclude_tables,json=excludeTables,proto3" json:"exclude_tables,omitempty"` + // IncludeViews specifies whether to include views in the result. + IncludeViews bool `protobuf:"varint,4,opt,name=include_views,json=includeViews,proto3" json:"include_views,omitempty"` + // TableNamesOnly specifies whether to limit the results to just table names, + // rather than full schema information for each table. + TableNamesOnly bool `protobuf:"varint,5,opt,name=table_names_only,json=tableNamesOnly,proto3" json:"table_names_only,omitempty"` + // TableSizesOnly specifies whether to limit the results to just table sizes, + // rather than full schema information for each table. It is ignored if + // TableNamesOnly is set to true. + TableSizesOnly bool `protobuf:"varint,6,opt,name=table_sizes_only,json=tableSizesOnly,proto3" json:"table_sizes_only,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetSchemaRequest) Reset() { *m = GetSchemaRequest{} } +func (m *GetSchemaRequest) String() string { return proto.CompactTextString(m) } +func (*GetSchemaRequest) ProtoMessage() {} +func (*GetSchemaRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{12} +} + +func (m *GetSchemaRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetSchemaRequest.Unmarshal(m, b) +} +func (m *GetSchemaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetSchemaRequest.Marshal(b, m, deterministic) +} +func (m *GetSchemaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSchemaRequest.Merge(m, src) +} +func (m *GetSchemaRequest) XXX_Size() int { + return xxx_messageInfo_GetSchemaRequest.Size(m) +} +func (m *GetSchemaRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetSchemaRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSchemaRequest proto.InternalMessageInfo + +func (m *GetSchemaRequest) GetTabletAlias() *topodata.TabletAlias { + if m != nil { + return m.TabletAlias + } + return nil +} + +func (m *GetSchemaRequest) GetTables() []string { + if m != nil { + return m.Tables + } + return nil +} + +func (m *GetSchemaRequest) GetExcludeTables() []string { + if m != nil { + return m.ExcludeTables + } + return nil +} + +func (m *GetSchemaRequest) GetIncludeViews() bool { + if m != nil { + return m.IncludeViews + } + return false +} + +func (m *GetSchemaRequest) GetTableNamesOnly() bool { + if m != nil { + return m.TableNamesOnly + } + return false +} + +func (m *GetSchemaRequest) GetTableSizesOnly() bool { + if m != nil { + return m.TableSizesOnly + } + return false +} + +type GetSchemaResponse struct { + Schema *tabletmanagerdata.SchemaDefinition `protobuf:"bytes,1,opt,name=schema,proto3" json:"schema,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetSchemaResponse) Reset() { *m = GetSchemaResponse{} } +func (m *GetSchemaResponse) String() string { return proto.CompactTextString(m) } +func (*GetSchemaResponse) ProtoMessage() {} +func (*GetSchemaResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{13} +} + +func (m *GetSchemaResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetSchemaResponse.Unmarshal(m, b) +} +func (m *GetSchemaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetSchemaResponse.Marshal(b, m, deterministic) +} +func (m *GetSchemaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSchemaResponse.Merge(m, src) +} +func (m *GetSchemaResponse) XXX_Size() int { + return xxx_messageInfo_GetSchemaResponse.Size(m) +} +func (m *GetSchemaResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetSchemaResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSchemaResponse proto.InternalMessageInfo + +func (m *GetSchemaResponse) GetSchema() *tabletmanagerdata.SchemaDefinition { + if m != nil { + return m.Schema + } + return nil +} + type GetSrvVSchemaRequest struct { Cell string `protobuf:"bytes,1,opt,name=cell,proto3" json:"cell,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -490,7 +619,7 @@ func (m *GetSrvVSchemaRequest) Reset() { *m = GetSrvVSchemaRequest{} } func (m *GetSrvVSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetSrvVSchemaRequest) ProtoMessage() {} func (*GetSrvVSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{12} + return fileDescriptor_f41247b323a1ab2e, []int{14} } func (m *GetSrvVSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -529,7 +658,7 @@ func (m *GetSrvVSchemaResponse) Reset() { *m = GetSrvVSchemaResponse{} } func (m *GetSrvVSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetSrvVSchemaResponse) ProtoMessage() {} func (*GetSrvVSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{13} + return fileDescriptor_f41247b323a1ab2e, []int{15} } func (m *GetSrvVSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -568,7 +697,7 @@ func (m *GetTabletRequest) Reset() { *m = GetTabletRequest{} } func (m *GetTabletRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletRequest) ProtoMessage() {} func (*GetTabletRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{14} + return fileDescriptor_f41247b323a1ab2e, []int{16} } func (m *GetTabletRequest) XXX_Unmarshal(b []byte) error { @@ -607,7 +736,7 @@ func (m *GetTabletResponse) Reset() { *m = GetTabletResponse{} } func (m *GetTabletResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletResponse) ProtoMessage() {} func (*GetTabletResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{15} + return fileDescriptor_f41247b323a1ab2e, []int{17} } func (m *GetTabletResponse) XXX_Unmarshal(b []byte) error { @@ -653,7 +782,7 @@ func (m *GetTabletsRequest) Reset() { *m = GetTabletsRequest{} } func (m *GetTabletsRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletsRequest) ProtoMessage() {} func (*GetTabletsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{16} + return fileDescriptor_f41247b323a1ab2e, []int{18} } func (m *GetTabletsRequest) XXX_Unmarshal(b []byte) error { @@ -706,7 +835,7 @@ func (m *GetTabletsResponse) Reset() { *m = GetTabletsResponse{} } func (m *GetTabletsResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletsResponse) ProtoMessage() {} func (*GetTabletsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{17} + return fileDescriptor_f41247b323a1ab2e, []int{19} } func (m *GetTabletsResponse) XXX_Unmarshal(b []byte) error { @@ -746,7 +875,7 @@ func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{18} + return fileDescriptor_f41247b323a1ab2e, []int{20} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { @@ -792,7 +921,7 @@ func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInK func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{19} + return fileDescriptor_f41247b323a1ab2e, []int{21} } func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -831,7 +960,7 @@ func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsIn func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{20} + return fileDescriptor_f41247b323a1ab2e, []int{22} } func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -872,7 +1001,7 @@ func (m *Shard) Reset() { *m = Shard{} } func (m *Shard) String() string { return proto.CompactTextString(m) } func (*Shard) ProtoMessage() {} func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{21} + return fileDescriptor_f41247b323a1ab2e, []int{23} } func (m *Shard) XXX_Unmarshal(b []byte) error { @@ -932,7 +1061,7 @@ func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettin func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } func (*TableMaterializeSettings) ProtoMessage() {} func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{22} + return fileDescriptor_f41247b323a1ab2e, []int{24} } func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -995,7 +1124,7 @@ func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } func (*MaterializeSettings) ProtoMessage() {} func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{23} + return fileDescriptor_f41247b323a1ab2e, []int{25} } func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -1079,6 +1208,8 @@ func init() { proto.RegisterType((*GetKeyspacesResponse)(nil), "vtctldata.GetKeyspacesResponse") proto.RegisterType((*GetKeyspaceRequest)(nil), "vtctldata.GetKeyspaceRequest") proto.RegisterType((*GetKeyspaceResponse)(nil), "vtctldata.GetKeyspaceResponse") + proto.RegisterType((*GetSchemaRequest)(nil), "vtctldata.GetSchemaRequest") + proto.RegisterType((*GetSchemaResponse)(nil), "vtctldata.GetSchemaResponse") proto.RegisterType((*GetSrvVSchemaRequest)(nil), "vtctldata.GetSrvVSchemaRequest") proto.RegisterType((*GetSrvVSchemaResponse)(nil), "vtctldata.GetSrvVSchemaResponse") proto.RegisterType((*GetTabletRequest)(nil), "vtctldata.GetTabletRequest") @@ -1097,61 +1228,69 @@ func init() { func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 891 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x6e, 0xdc, 0x44, - 0x14, 0x96, 0x77, 0xbb, 0xc9, 0xfa, 0x6c, 0xf6, 0xa7, 0x4e, 0x02, 0xc6, 0x08, 0x08, 0x03, 0x4d, - 0x57, 0x41, 0xf2, 0x96, 0x20, 0x50, 0x85, 0x40, 0x22, 0x84, 0xb4, 0x0a, 0x85, 0x08, 0x39, 0x51, - 0x91, 0x40, 0xc2, 0x9a, 0x7a, 0x27, 0x5b, 0x2b, 0xb3, 0x1e, 0xe3, 0x99, 0x75, 0xbb, 0xbc, 0x01, - 0x2f, 0xc3, 0x25, 0x97, 0x3c, 0x1b, 0x9a, 0x3f, 0xdb, 0x9b, 0xee, 0x16, 0x7a, 0x37, 0xf3, 0x9d, - 0xbf, 0xef, 0x9c, 0x6f, 0x8e, 0x65, 0x18, 0x96, 0x22, 0x11, 0x74, 0x8a, 0x05, 0x0e, 0xf3, 0x82, - 0x09, 0xe6, 0xb9, 0x15, 0x10, 0xf4, 0x29, 0x9b, 0x2d, 0x44, 0x4a, 0xb5, 0x25, 0x18, 0x08, 0x96, - 0xb3, 0xda, 0x33, 0xe8, 0x97, 0x3c, 0x79, 0x4e, 0xe6, 0xe6, 0x8a, 0x7e, 0x86, 0xe0, 0xec, 0x25, - 0x49, 0x16, 0x82, 0x3c, 0x95, 0x19, 0x4e, 0xd9, 0x7c, 0x8e, 0xb3, 0x69, 0x44, 0x7e, 0x5f, 0x10, - 0x2e, 0x3c, 0x0f, 0xee, 0xe0, 0x62, 0xc6, 0x7d, 0xe7, 0xa0, 0x3d, 0x76, 0x23, 0x75, 0xf6, 0xee, - 0xc1, 0x00, 0x27, 0x22, 0x65, 0x59, 0x2c, 0xd2, 0x39, 0x61, 0x0b, 0xe1, 0xb7, 0x0e, 0x9c, 0x71, - 0x3b, 0xea, 0x6b, 0xf4, 0x4a, 0x83, 0xe8, 0x14, 0xde, 0x5d, 0x9b, 0x98, 0xe7, 0x2c, 0xe3, 0xc4, - 0xfb, 0x18, 0x3a, 0xa4, 0x24, 0x99, 0xf0, 0x9d, 0x03, 0x67, 0xdc, 0x3b, 0x1e, 0x84, 0x96, 0xf5, - 0x99, 0x44, 0x23, 0x6d, 0x44, 0xef, 0xc0, 0xdb, 0x8f, 0x89, 0x38, 0x25, 0x94, 0x9e, 0x67, 0xd7, - 0xec, 0x02, 0xcf, 0x09, 0x37, 0xd4, 0xd0, 0x03, 0xf0, 0x5f, 0x35, 0x99, 0xe4, 0x7b, 0xd0, 0xc9, - 0x24, 0x60, 0x78, 0xeb, 0x0b, 0x1a, 0x83, 0xd7, 0x88, 0x68, 0xb4, 0x98, 0x10, 0x4a, 0x15, 0x0f, - 0x37, 0x52, 0x67, 0xf4, 0x08, 0x76, 0x57, 0x3c, 0x4d, 0xda, 0x09, 0xb8, 0xd2, 0x1c, 0xa7, 0xd9, - 0x35, 0x33, 0xbc, 0xbd, 0xb0, 0x1a, 0x6f, 0xe5, 0xde, 0x4d, 0xcc, 0x09, 0xf9, 0xf0, 0x96, 0xc9, - 0xc3, 0x4f, 0x68, 0x8a, 0x79, 0xcd, 0xfe, 0x6f, 0xa7, 0xea, 0xac, 0x36, 0x99, 0x32, 0xe7, 0xb0, - 0x8d, 0x35, 0xa4, 0xf8, 0xf7, 0x8e, 0x27, 0x61, 0x2d, 0xf7, 0x86, 0xa0, 0xd0, 0xdc, 0xcf, 0x32, - 0x51, 0x2c, 0x23, 0x1b, 0x1f, 0xfc, 0x04, 0x3b, 0x4d, 0x83, 0x37, 0x82, 0xf6, 0x0d, 0x59, 0x9a, - 0x5e, 0xe5, 0xd1, 0x3b, 0x82, 0x4e, 0x89, 0xe9, 0x82, 0x28, 0x11, 0x7b, 0xc7, 0x7b, 0xab, 0xfd, - 0xe8, 0x32, 0x91, 0x76, 0xf9, 0xb2, 0xf5, 0xd0, 0x41, 0xfb, 0x6a, 0x34, 0x4f, 0xc8, 0x92, 0xe7, - 0x38, 0xa9, 0xfb, 0x39, 0x87, 0xbd, 0x55, 0xd8, 0xf4, 0xf2, 0x29, 0xb8, 0x37, 0x16, 0x34, 0xdd, - 0xec, 0x36, 0xba, 0xb1, 0x01, 0x51, 0xed, 0x85, 0x1e, 0x28, 0x99, 0x2a, 0x8b, 0x91, 0x29, 0x80, - 0xae, 0x75, 0x31, 0xf4, 0xab, 0xbb, 0x91, 0xab, 0x8e, 0xa8, 0xe4, 0x5a, 0x0d, 0xd9, 0x50, 0xba, - 0xce, 0x73, 0xa4, 0x9a, 0xb8, 0x2c, 0xca, 0xa7, 0x97, 0x6a, 0x45, 0x5e, 0xf7, 0x44, 0x2e, 0x60, - 0xff, 0x96, 0xaf, 0xa9, 0xfa, 0x39, 0xec, 0xf0, 0xa2, 0x8c, 0xcb, 0x58, 0xaf, 0x59, 0x5d, 0xd9, - 0xac, 0x5d, 0x23, 0x04, 0x78, 0x75, 0x46, 0x3f, 0xc0, 0xe8, 0x31, 0x11, 0x57, 0xf8, 0x19, 0x25, - 0xc2, 0xd6, 0x7d, 0x08, 0x3b, 0x42, 0x01, 0xb1, 0xd2, 0xd3, 0xa4, 0xda, 0xaf, 0x25, 0xd2, 0xee, - 0x5a, 0xa3, 0x9e, 0xa8, 0x2f, 0xe8, 0x6b, 0xb8, 0xdb, 0xc8, 0x66, 0x98, 0x8d, 0x61, 0x4b, 0xfb, - 0x98, 0x44, 0xa3, 0xdb, 0x89, 0x22, 0x63, 0x47, 0xbf, 0x36, 0xc2, 0xf9, 0xff, 0x50, 0x40, 0x2e, - 0x1c, 0x7f, 0x8e, 0x8b, 0xa9, 0x7a, 0x45, 0x6e, 0xa4, 0x2f, 0x12, 0x95, 0xb3, 0xe2, 0x7e, 0x5b, - 0xaf, 0xa1, 0xba, 0xa0, 0x6f, 0x94, 0xbe, 0x55, 0x72, 0x43, 0xee, 0x08, 0xb6, 0x75, 0x71, 0xfb, - 0x4c, 0x5e, 0x65, 0x67, 0x1d, 0xd0, 0x05, 0x74, 0xad, 0x7a, 0x52, 0x1b, 0xb9, 0xdd, 0x56, 0x1b, - 0x79, 0xf6, 0xc2, 0x06, 0xd3, 0xd6, 0xed, 0x35, 0x5d, 0xa3, 0xfb, 0x57, 0xf0, 0xfe, 0xa3, 0x34, - 0x9b, 0x9e, 0x50, 0x7a, 0x29, 0x79, 0xf3, 0xf3, 0xec, 0x4d, 0x5e, 0xdf, 0x3f, 0x0e, 0x7c, 0xb0, - 0x31, 0xdc, 0x74, 0x77, 0x01, 0x5b, 0x6a, 0x24, 0xb6, 0xb9, 0x2f, 0x1a, 0x0f, 0xf1, 0x3f, 0x62, - 0x43, 0x6d, 0xd0, 0x8b, 0x6d, 0xb2, 0x04, 0x4f, 0xa0, 0xd7, 0x80, 0xd7, 0xac, 0xf5, 0xe1, 0xea, - 0x5a, 0x8f, 0x1a, 0xf5, 0x54, 0x60, 0x73, 0xa5, 0x7f, 0x83, 0x8e, 0xc2, 0x5e, 0xab, 0xb0, 0x9d, - 0x73, 0xab, 0x31, 0xe7, 0x7b, 0x56, 0xf5, 0xb6, 0x2a, 0x32, 0xac, 0x87, 0x6c, 0x6a, 0x28, 0x2b, - 0xfa, 0xd3, 0x01, 0x5f, 0x49, 0xf8, 0x23, 0x16, 0xa4, 0x48, 0x31, 0x4d, 0xff, 0x20, 0x97, 0x44, - 0x88, 0x34, 0x9b, 0x71, 0xef, 0x43, 0xf9, 0xc6, 0x8b, 0x19, 0x11, 0xb1, 0x52, 0xd7, 0xd4, 0xed, - 0x69, 0x4c, 0x45, 0x79, 0x9f, 0xc0, 0x5d, 0xce, 0x16, 0x45, 0x42, 0x62, 0xf2, 0x32, 0x2f, 0x08, - 0xe7, 0x29, 0xcb, 0x0c, 0x8f, 0x91, 0x36, 0x9c, 0x55, 0xb8, 0xf7, 0x1e, 0x40, 0x52, 0x10, 0x2c, - 0x48, 0x3c, 0x9d, 0x52, 0x45, 0xcc, 0x8d, 0x5c, 0x8d, 0x7c, 0x37, 0xa5, 0xe8, 0xaf, 0x16, 0xec, - 0xae, 0xa3, 0x11, 0x40, 0xf7, 0x05, 0x2b, 0x6e, 0xae, 0x29, 0x7b, 0x61, 0x5b, 0xb7, 0x77, 0xef, - 0x3e, 0x0c, 0x4d, 0xfd, 0x95, 0x57, 0xe5, 0x46, 0x03, 0x0d, 0x57, 0x6f, 0xf1, 0x3e, 0x0c, 0x4d, - 0x2f, 0x95, 0xa3, 0x26, 0x30, 0xd0, 0x70, 0xe5, 0x78, 0x08, 0x43, 0x2e, 0x58, 0x1e, 0xe3, 0x6b, - 0x41, 0x8a, 0x38, 0x61, 0xf9, 0xd2, 0xbf, 0x73, 0xe0, 0x8c, 0xbb, 0x51, 0x5f, 0xc2, 0x27, 0x12, - 0x3d, 0x65, 0xf9, 0xd2, 0xfb, 0x1e, 0x06, 0x6a, 0x2a, 0x31, 0x37, 0x3c, 0xfd, 0x8e, 0x7a, 0x3e, - 0x1f, 0x35, 0xe4, 0xdc, 0x34, 0xd9, 0xa8, 0xaf, 0x42, 0xab, 0x0e, 0xed, 0x47, 0x6c, 0xab, 0xfe, - 0x88, 0xe9, 0xe1, 0xab, 0x0f, 0x8c, 0x58, 0xe6, 0x84, 0xfb, 0xdb, 0x76, 0xf8, 0x12, 0xbb, 0x92, - 0xd0, 0xb7, 0xe3, 0x5f, 0x0e, 0xcb, 0x54, 0x10, 0xce, 0xc3, 0x94, 0x4d, 0xf4, 0x69, 0x32, 0x63, - 0x93, 0x52, 0x4c, 0xd4, 0xff, 0xc3, 0xa4, 0x22, 0xf2, 0x6c, 0x4b, 0x01, 0x9f, 0xfd, 0x1b, 0x00, - 0x00, 0xff, 0xff, 0xc7, 0x5e, 0x26, 0x9e, 0x9c, 0x08, 0x00, 0x00, + // 1022 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5b, 0x6f, 0xe3, 0x44, + 0x14, 0x56, 0x92, 0x4d, 0x36, 0x39, 0x69, 0x2e, 0xeb, 0xb6, 0xbb, 0x26, 0x08, 0x28, 0x2e, 0xdb, + 0x8d, 0x8a, 0xe4, 0x2c, 0x45, 0xa0, 0x15, 0x17, 0x89, 0xd2, 0xed, 0xae, 0xca, 0x42, 0x59, 0x39, + 0x55, 0x91, 0x40, 0xc2, 0xf2, 0x3a, 0x93, 0xac, 0xd5, 0x89, 0xc7, 0x78, 0x26, 0x6e, 0xb3, 0xcf, + 0xbc, 0xf0, 0x67, 0x78, 0xe4, 0x91, 0xdf, 0x86, 0x66, 0xe6, 0x8c, 0xed, 0xb4, 0x29, 0x17, 0xf1, + 0xe6, 0xf3, 0x9d, 0xcb, 0x7c, 0xe7, 0x2a, 0x43, 0x2f, 0x13, 0xa1, 0xa0, 0x93, 0x40, 0x04, 0x6e, + 0x92, 0x32, 0xc1, 0xac, 0x56, 0x0e, 0x0c, 0x3a, 0x94, 0xcd, 0x16, 0x22, 0xa2, 0x5a, 0x33, 0x78, + 0x20, 0x82, 0x57, 0x94, 0x88, 0x79, 0x10, 0x07, 0x33, 0x92, 0x16, 0x2e, 0x83, 0xae, 0x60, 0x09, + 0x2b, 0xc9, 0x9d, 0x8c, 0x87, 0xaf, 0xc9, 0x1c, 0x45, 0xe7, 0x07, 0x18, 0x1c, 0x5f, 0x91, 0x70, + 0x21, 0xc8, 0xb9, 0x0c, 0x7d, 0xc4, 0xe6, 0xf3, 0x20, 0x9e, 0x78, 0xe4, 0x97, 0x05, 0xe1, 0xc2, + 0xb2, 0xe0, 0x4e, 0x90, 0xce, 0xb8, 0x5d, 0xd9, 0xa9, 0x0d, 0x5b, 0x9e, 0xfa, 0xb6, 0x1e, 0x42, + 0x37, 0x08, 0x45, 0xc4, 0x62, 0x5f, 0x44, 0x73, 0xc2, 0x16, 0xc2, 0xae, 0xee, 0x54, 0x86, 0x35, + 0xaf, 0xa3, 0xd1, 0x33, 0x0d, 0x3a, 0x47, 0xf0, 0xf6, 0xda, 0xc0, 0x3c, 0x61, 0x31, 0x27, 0xd6, + 0x07, 0x50, 0x27, 0x19, 0x89, 0x85, 0x5d, 0xd9, 0xa9, 0x0c, 0xdb, 0x07, 0x5d, 0xd7, 0xa4, 0x73, + 0x2c, 0x51, 0x4f, 0x2b, 0x9d, 0xb7, 0xe0, 0xc1, 0x73, 0x22, 0x8e, 0x08, 0xa5, 0x27, 0xf1, 0x94, + 0x9d, 0x06, 0x73, 0xc2, 0x91, 0x9a, 0xf3, 0x18, 0xec, 0x9b, 0x2a, 0x0c, 0xbe, 0x05, 0xf5, 0x58, + 0x02, 0xc8, 0x5b, 0x0b, 0xce, 0x10, 0xac, 0x92, 0x47, 0x29, 0xc5, 0x90, 0x50, 0xaa, 0x78, 0xb4, + 0x3c, 0xf5, 0xed, 0x3c, 0x83, 0xcd, 0x15, 0x4b, 0x0c, 0x3b, 0x82, 0x96, 0x54, 0xfb, 0x51, 0x3c, + 0x65, 0xc8, 0xdb, 0x72, 0xf3, 0xf2, 0xe6, 0xe6, 0xcd, 0x10, 0xbf, 0x1c, 0x1b, 0xee, 0x63, 0x1c, + 0x7e, 0x48, 0xa3, 0x80, 0x17, 0xec, 0xff, 0xa8, 0xe4, 0x99, 0x15, 0x2a, 0x7c, 0xe6, 0x04, 0xee, + 0x06, 0x1a, 0x52, 0xfc, 0xdb, 0x07, 0x23, 0xb7, 0x98, 0x83, 0x5b, 0x9c, 0x5c, 0x94, 0x8f, 0x63, + 0x91, 0x2e, 0x3d, 0xe3, 0x3f, 0x78, 0x09, 0x1b, 0x65, 0x85, 0xd5, 0x87, 0xda, 0x05, 0x59, 0x62, + 0xae, 0xf2, 0xd3, 0xda, 0x87, 0x7a, 0x16, 0xd0, 0x05, 0x51, 0x4d, 0x6c, 0x1f, 0x6c, 0xad, 0xe6, + 0xa3, 0x9f, 0xf1, 0xb4, 0xc9, 0x67, 0xd5, 0x27, 0x15, 0x67, 0x5b, 0x95, 0xe6, 0x05, 0x59, 0xf2, + 0x24, 0x08, 0x8b, 0x7c, 0x4e, 0x60, 0x6b, 0x15, 0xc6, 0x5c, 0x3e, 0x82, 0xd6, 0x85, 0x01, 0x31, + 0x9b, 0xcd, 0x52, 0x36, 0xc6, 0xc1, 0x2b, 0xac, 0x9c, 0xc7, 0xaa, 0x4d, 0xb9, 0x06, 0xdb, 0x34, + 0x80, 0xa6, 0x31, 0x41, 0xfa, 0xb9, 0x8c, 0xed, 0x2a, 0x3c, 0xf2, 0x76, 0xad, 0xba, 0xdc, 0xf2, + 0x74, 0x11, 0xe7, 0xd7, 0x2a, 0xf4, 0x9f, 0x13, 0x31, 0x56, 0xfb, 0x61, 0x1e, 0x7e, 0x02, 0x1b, + 0x7a, 0xb5, 0x7c, 0x55, 0x54, 0x8c, 0xb4, 0x5d, 0xd4, 0xe9, 0x4c, 0x69, 0x75, 0xa1, 0xda, 0xa2, + 0x10, 0xac, 0xfb, 0xd0, 0x50, 0x22, 0xb7, 0xab, 0x6a, 0x0c, 0x51, 0x92, 0x0b, 0x44, 0xae, 0x42, + 0xba, 0x98, 0x10, 0x1f, 0xf5, 0x35, 0xa5, 0xef, 0x20, 0x7a, 0xa6, 0xcd, 0x76, 0xa1, 0x13, 0xc5, + 0xda, 0x2c, 0x8b, 0xc8, 0x25, 0xb7, 0xef, 0xec, 0x54, 0x86, 0x4d, 0x6f, 0x03, 0xc1, 0x73, 0x89, + 0x59, 0x43, 0xe8, 0xab, 0x18, 0xbe, 0x1a, 0x71, 0x9f, 0xc5, 0x74, 0x69, 0xd7, 0x95, 0x5d, 0x57, + 0xe1, 0x6a, 0x2f, 0xbe, 0x8f, 0xe9, 0xb2, 0xb0, 0xe4, 0xd1, 0x1b, 0x63, 0xd9, 0x28, 0x59, 0x8e, + 0x25, 0x2c, 0x2d, 0x9d, 0x97, 0x70, 0xaf, 0x54, 0x05, 0x2c, 0xe6, 0xe7, 0xd0, 0xd0, 0x77, 0x03, + 0x0b, 0xb0, 0xeb, 0xde, 0x3c, 0x38, 0xda, 0xe5, 0x29, 0x99, 0x46, 0x71, 0x24, 0x4f, 0x81, 0x87, + 0x2e, 0xce, 0xbe, 0x9a, 0x8e, 0x71, 0x9a, 0x9d, 0xaf, 0xd6, 0x76, 0xdd, 0xee, 0x9d, 0xc2, 0xf6, + 0x35, 0x5b, 0x64, 0xf0, 0x09, 0x6c, 0xf0, 0x34, 0xf3, 0x33, 0x7f, 0x85, 0xc7, 0xa6, 0x6b, 0xee, + 0x59, 0xc9, 0x05, 0x78, 0xfe, 0xed, 0x7c, 0xab, 0x7a, 0xaa, 0x9b, 0xf4, 0xbf, 0x7b, 0xea, 0x7c, + 0xa9, 0x6a, 0x63, 0xa2, 0x21, 0xb3, 0x21, 0x36, 0xda, 0x1c, 0xb3, 0xfe, 0xf5, 0x40, 0xd8, 0x7a, + 0xe1, 0xfc, 0x54, 0x72, 0xe7, 0xff, 0x62, 0xb4, 0xe5, 0x25, 0xe3, 0xaf, 0x83, 0x74, 0xa2, 0xd6, + 0xb3, 0xe5, 0x69, 0x41, 0xa2, 0xb2, 0x56, 0x66, 0x70, 0xb4, 0xe0, 0x7c, 0xa5, 0x16, 0x27, 0x0f, + 0x8e, 0xe4, 0xf6, 0xe1, 0xae, 0x7e, 0xdc, 0xec, 0xdf, 0x4d, 0x76, 0xc6, 0xc0, 0x39, 0x85, 0xa6, + 0x59, 0x0b, 0xd9, 0x1b, 0x39, 0x53, 0xa6, 0x37, 0xf2, 0xdb, 0x72, 0x4b, 0x4c, 0xab, 0xd7, 0xef, + 0xdf, 0x9a, 0x85, 0xfa, 0x02, 0xde, 0x7d, 0x16, 0xc5, 0x93, 0x43, 0x4a, 0xc7, 0x92, 0x37, 0x3f, + 0x89, 0xff, 0xcb, 0x5a, 0xff, 0x59, 0x81, 0xf7, 0x6e, 0x75, 0xc7, 0xec, 0x4e, 0xa1, 0xa1, 0x4a, + 0x62, 0x92, 0xfb, 0xb4, 0xb4, 0xe1, 0xff, 0xe0, 0xeb, 0x6a, 0x85, 0xbe, 0x98, 0x18, 0x65, 0xf0, + 0x02, 0xda, 0x25, 0x78, 0xcd, 0xbd, 0xdc, 0x5b, 0xbd, 0x97, 0xfd, 0xd2, 0x7b, 0xca, 0xb1, 0x7c, + 0x2b, 0x7f, 0x86, 0xba, 0xc2, 0xfe, 0xb6, 0xc3, 0xa6, 0xce, 0xd5, 0x52, 0x9d, 0x1f, 0x9a, 0xae, + 0xd7, 0xd4, 0x23, 0xbd, 0xa2, 0xc8, 0xf8, 0x86, 0xd2, 0x3a, 0xbf, 0x55, 0xc0, 0x56, 0x2d, 0xfc, + 0x2e, 0x10, 0x24, 0x8d, 0x02, 0x1a, 0xbd, 0x21, 0x63, 0x22, 0x44, 0x14, 0xcf, 0xb8, 0xf5, 0xbe, + 0x9c, 0xf1, 0x74, 0x46, 0x84, 0x3e, 0x32, 0xf8, 0x6e, 0x5b, 0x63, 0xca, 0xcb, 0xfa, 0x10, 0xee, + 0x71, 0xb6, 0x48, 0x43, 0xe2, 0x93, 0xab, 0x24, 0x25, 0x9c, 0x47, 0x2c, 0x46, 0x1e, 0x7d, 0xad, + 0x38, 0xce, 0x71, 0xeb, 0x1d, 0x80, 0x30, 0x25, 0x81, 0x20, 0xfe, 0x64, 0x42, 0x15, 0xb1, 0x96, + 0xd7, 0xd2, 0xc8, 0xd3, 0x09, 0x75, 0x7e, 0xaf, 0xc2, 0xe6, 0x3a, 0x1a, 0x03, 0x68, 0x5e, 0xb2, + 0xf4, 0x62, 0x4a, 0xd9, 0xa5, 0x49, 0xdd, 0xc8, 0xd6, 0x23, 0xe8, 0xe1, 0xfb, 0x2b, 0x53, 0xd5, + 0xf2, 0xba, 0x1a, 0xce, 0x67, 0xf1, 0x11, 0xf4, 0x30, 0x97, 0xdc, 0x50, 0x13, 0xe8, 0x6a, 0x38, + 0x37, 0xdc, 0x83, 0x1e, 0x17, 0x2c, 0xf1, 0x83, 0xa9, 0x20, 0xa9, 0x1f, 0xb2, 0x64, 0x89, 0x57, + 0xb3, 0x23, 0xe1, 0x43, 0x89, 0x1e, 0xb1, 0x64, 0x69, 0x7d, 0x03, 0x5d, 0x3c, 0x86, 0xc8, 0xd3, + 0xae, 0xab, 0xf1, 0xd9, 0x2d, 0xb5, 0xf3, 0xb6, 0xca, 0x7a, 0x1d, 0x7d, 0x2f, 0x4d, 0x86, 0xe6, + 0x88, 0x35, 0x8a, 0x23, 0xa6, 0x8b, 0xaf, 0x0e, 0x8c, 0x58, 0x26, 0x84, 0xdb, 0x77, 0x4d, 0xf1, + 0x25, 0x76, 0x26, 0xa1, 0xaf, 0x87, 0x3f, 0xee, 0x65, 0x91, 0x20, 0x9c, 0xbb, 0x11, 0x1b, 0xe9, + 0xaf, 0xd1, 0x8c, 0x8d, 0x32, 0x31, 0x52, 0x3f, 0x66, 0xa3, 0x9c, 0xc8, 0xab, 0x86, 0x02, 0x3e, + 0xfe, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xed, 0x8c, 0xe6, 0x02, 0x0e, 0x0a, 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 313ff74c649..5f22024bc5a 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,29 +29,30 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 352 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xd1, 0x4a, 0x02, 0x41, - 0x14, 0x86, 0xeb, 0x22, 0xa1, 0xc9, 0x30, 0x4e, 0x17, 0x81, 0xa5, 0x95, 0x51, 0x60, 0x81, 0x1b, - 0xf6, 0x04, 0x26, 0x65, 0x22, 0x08, 0xa5, 0x78, 0x21, 0x74, 0x31, 0xee, 0x9e, 0x72, 0x61, 0x76, - 0x47, 0xf7, 0x8c, 0x4b, 0x3d, 0x49, 0xaf, 0x1b, 0xad, 0xcd, 0xb8, 0x6d, 0x3b, 0xd6, 0x9d, 0x7b, - 0xbe, 0xff, 0xff, 0xe6, 0x38, 0x30, 0x0c, 0x62, 0xe5, 0x2a, 0x41, 0x18, 0xc5, 0xbe, 0x8b, 0x8d, - 0x59, 0x24, 0x95, 0x84, 0x62, 0x7a, 0x56, 0x2e, 0x25, 0x5f, 0x1e, 0x57, 0x7c, 0x89, 0x9b, 0x73, - 0xb6, 0x35, 0xfa, 0x1a, 0xc1, 0x94, 0xed, 0xdf, 0xbd, 0xa1, 0xbb, 0x50, 0x98, 0x7c, 0xb7, 0x65, - 0x10, 0xf0, 0xd0, 0x83, 0xf3, 0xc6, 0xaa, 0x91, 0xc3, 0x9f, 0x70, 0xbe, 0x40, 0x52, 0xe5, 0x8b, - 0xbf, 0x62, 0x34, 0x93, 0x21, 0x61, 0x6d, 0xe3, 0x7a, 0xb3, 0xf9, 0x51, 0x60, 0x85, 0x04, 0x7a, - 0x10, 0xb1, 0x83, 0x7b, 0x3f, 0xf4, 0x5a, 0x42, 0x0c, 0xa6, 0x3c, 0xf2, 0xa8, 0x1b, 0xf6, 0xf0, - 0x9d, 0x66, 0xdc, 0x45, 0xa8, 0xa7, 0x8c, 0x96, 0x8c, 0x3e, 0xfc, 0xf2, 0x3f, 0x51, 0xbd, 0x00, - 0x3c, 0xb3, 0xbd, 0x0e, 0xaa, 0x36, 0x0a, 0xd1, 0x0d, 0x5f, 0x64, 0x9f, 0x07, 0x48, 0x50, 0x4b, - 0x19, 0xb2, 0x50, 0x9f, 0x72, 0xb6, 0x36, 0x63, 0xf4, 0x7d, 0xb6, 0x93, 0xa2, 0x50, 0xc9, 0x6f, - 0x69, 0x69, 0xd5, 0x86, 0x8d, 0x6f, 0xcc, 0x4a, 0xdf, 0x80, 0x5a, 0xc2, 0xe7, 0x84, 0x04, 0xa7, - 0xbf, 0x4b, 0x9a, 0x69, 0x6f, 0x6d, 0x5d, 0x24, 0xb3, 0xab, 0xb9, 0xf2, 0xcc, 0xae, 0xd9, 0x6b, - 0xae, 0xda, 0xb0, 0xf1, 0x3d, 0xb2, 0x62, 0x0a, 0x10, 0x58, 0x1a, 0x66, 0xcb, 0x63, 0x2b, 0x37, - 0xca, 0x21, 0xdb, 0xed, 0xa0, 0x1a, 0x44, 0xf1, 0x68, 0xe0, 0x4e, 0x31, 0xe0, 0x90, 0xe9, 0xac, - 0x88, 0x96, 0x9e, 0xd8, 0x03, 0xc6, 0xfa, 0xc0, 0xb6, 0x3b, 0xa8, 0x86, 0x7c, 0x22, 0x50, 0xc1, - 0xe1, 0xcf, 0xc2, 0x72, 0xaa, 0x6d, 0x47, 0xf9, 0xd0, 0x98, 0x7a, 0x8c, 0x99, 0x31, 0x41, 0x6e, - 0xda, 0xfc, 0xdd, 0x8a, 0x85, 0x6a, 0xd9, 0xed, 0xd5, 0xb8, 0x1e, 0xfb, 0x0a, 0x89, 0x1a, 0xbe, - 0x74, 0x96, 0xbf, 0x9c, 0x57, 0xe9, 0xc4, 0xca, 0x49, 0x1e, 0xab, 0x93, 0x7e, 0xca, 0x93, 0x42, - 0x32, 0xbb, 0xf9, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x95, 0x4b, 0x3a, 0x7d, 0xf5, 0x03, 0x00, 0x00, + // 362 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xd1, 0x4a, 0x02, 0x41, + 0x14, 0x86, 0xeb, 0x22, 0xa1, 0xc9, 0x30, 0xa6, 0x8b, 0xc0, 0xd2, 0xca, 0x28, 0xb0, 0xc0, 0x0d, + 0x7b, 0x02, 0x93, 0x32, 0x11, 0x84, 0x52, 0xbc, 0x10, 0xba, 0x18, 0x77, 0x4f, 0xb9, 0x30, 0xbb, + 0xa3, 0x7b, 0xc6, 0xa5, 0x1e, 0xb7, 0x37, 0x09, 0x77, 0x9d, 0x71, 0x9b, 0x76, 0xac, 0x3b, 0xe7, + 0x7c, 0xff, 0xf9, 0xe6, 0x67, 0xc0, 0x25, 0x34, 0x96, 0xae, 0xe4, 0x08, 0x51, 0xec, 0xbb, 0xd0, + 0x98, 0x45, 0x42, 0x0a, 0x5a, 0xcc, 0xce, 0xca, 0xa5, 0xe4, 0xe4, 0x31, 0xc9, 0x52, 0xdc, 0x9c, + 0x93, 0x9d, 0xd1, 0x72, 0x44, 0xa7, 0xe4, 0xf0, 0xe1, 0x03, 0xdc, 0x85, 0x84, 0xe4, 0xdc, 0x16, + 0x41, 0xc0, 0x42, 0x8f, 0x5e, 0x36, 0xd6, 0x1b, 0x39, 0xfc, 0x05, 0xe6, 0x0b, 0x40, 0x59, 0xbe, + 0xfa, 0x2b, 0x86, 0x33, 0x11, 0x22, 0xd4, 0xb6, 0x6e, 0xb7, 0x9b, 0x5f, 0x05, 0x52, 0x48, 0xa0, + 0x47, 0x23, 0x72, 0xf4, 0xe8, 0x87, 0x5e, 0x8b, 0xf3, 0xc1, 0x94, 0x45, 0x1e, 0x76, 0xc3, 0x1e, + 0x7c, 0xe2, 0x8c, 0xb9, 0x40, 0xeb, 0x19, 0xa3, 0x25, 0xa3, 0x2e, 0xbf, 0xfe, 0x4f, 0x54, 0x15, + 0xa0, 0xaf, 0xe4, 0xa0, 0x03, 0xb2, 0x0d, 0x9c, 0x77, 0xc3, 0x37, 0xd1, 0x67, 0x01, 0x20, 0xad, + 0x65, 0x0c, 0x26, 0x54, 0xb7, 0x5c, 0x6c, 0xcc, 0x68, 0x7d, 0x9f, 0xec, 0x65, 0x28, 0xad, 0xe4, + 0x6f, 0x29, 0x69, 0xd5, 0x86, 0xb5, 0x6f, 0x4c, 0x4a, 0x2b, 0x80, 0x2d, 0xee, 0x33, 0x04, 0xa4, + 0xe7, 0xbf, 0x97, 0x14, 0x53, 0xde, 0xda, 0xa6, 0x88, 0xd1, 0x55, 0x3f, 0xb9, 0xd1, 0xd5, 0x7c, + 0xe6, 0xaa, 0x0d, 0x6b, 0xdf, 0x33, 0x29, 0x66, 0x00, 0x52, 0xcb, 0x86, 0x6e, 0x79, 0x6a, 0xe5, + 0x5a, 0xf9, 0x44, 0x76, 0x3b, 0x20, 0x07, 0xee, 0x14, 0x02, 0x46, 0x8f, 0x7f, 0xe6, 0xd3, 0xa9, + 0x92, 0x9d, 0xe4, 0x43, 0x6d, 0x1a, 0x92, 0xfd, 0xe5, 0x38, 0x8a, 0x47, 0x2b, 0x9b, 0x71, 0xfb, + 0x9a, 0x28, 0xe3, 0x99, 0x3d, 0x60, 0xf4, 0x1b, 0xb2, 0x09, 0x07, 0x69, 0xf6, 0x4b, 0xa7, 0x96, + 0x7e, 0x0a, 0x6a, 0x53, 0x8f, 0x10, 0x3d, 0x46, 0x9a, 0x9b, 0xd6, 0x0f, 0x57, 0xb1, 0x50, 0x25, + 0xbb, 0xbf, 0x19, 0xd7, 0x63, 0x5f, 0x02, 0x62, 0xc3, 0x17, 0x4e, 0xfa, 0xcb, 0x79, 0x17, 0x4e, + 0x2c, 0x9d, 0xe4, 0x6f, 0xef, 0x64, 0x3f, 0x0a, 0x93, 0x42, 0x32, 0xbb, 0xfb, 0x0e, 0x00, 0x00, + 0xff, 0xff, 0x19, 0x7f, 0xf4, 0xe7, 0x3f, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -180,6 +181,9 @@ type VtctldClient interface { GetKeyspace(ctx context.Context, in *vtctldata.GetKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspacesRequest, opts ...grpc.CallOption) (*vtctldata.GetKeyspacesResponse, error) + // GetSchema returns the schema for a tablet, or just the schema for the + // specified tables in that tablet. + GetSchema(ctx context.Context, in *vtctldata.GetSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSchemaResponse, error) // GetSrvVSchema returns a the SrvVSchema for a cell. GetSrvVSchema(ctx context.Context, in *vtctldata.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSrvVSchemaResponse, error) // GetTablet returns information about a tablet. @@ -250,6 +254,15 @@ func (c *vtctldClient) GetKeyspaces(ctx context.Context, in *vtctldata.GetKeyspa return out, nil } +func (c *vtctldClient) GetSchema(ctx context.Context, in *vtctldata.GetSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSchemaResponse, error) { + out := new(vtctldata.GetSchemaResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetSchema", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) GetSrvVSchema(ctx context.Context, in *vtctldata.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSrvVSchemaResponse, error) { out := new(vtctldata.GetSrvVSchemaResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetSrvVSchema", in, out, opts...) @@ -294,6 +307,9 @@ type VtctldServer interface { GetKeyspace(context.Context, *vtctldata.GetKeyspaceRequest) (*vtctldata.GetKeyspaceResponse, error) // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. GetKeyspaces(context.Context, *vtctldata.GetKeyspacesRequest) (*vtctldata.GetKeyspacesResponse, error) + // GetSchema returns the schema for a tablet, or just the schema for the + // specified tables in that tablet. + GetSchema(context.Context, *vtctldata.GetSchemaRequest) (*vtctldata.GetSchemaResponse, error) // GetSrvVSchema returns a the SrvVSchema for a cell. GetSrvVSchema(context.Context, *vtctldata.GetSrvVSchemaRequest) (*vtctldata.GetSrvVSchemaResponse, error) // GetTablet returns information about a tablet. @@ -324,6 +340,9 @@ func (*UnimplementedVtctldServer) GetKeyspace(ctx context.Context, req *vtctldat func (*UnimplementedVtctldServer) GetKeyspaces(ctx context.Context, req *vtctldata.GetKeyspacesRequest) (*vtctldata.GetKeyspacesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetKeyspaces not implemented") } +func (*UnimplementedVtctldServer) GetSchema(ctx context.Context, req *vtctldata.GetSchemaRequest) (*vtctldata.GetSchemaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSchema not implemented") +} func (*UnimplementedVtctldServer) GetSrvVSchema(ctx context.Context, req *vtctldata.GetSrvVSchemaRequest) (*vtctldata.GetSrvVSchemaResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSrvVSchema not implemented") } @@ -446,6 +465,24 @@ func _Vtctld_GetKeyspaces_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _Vtctld_GetSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetSchemaRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetSchema(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetSchema", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetSchema(ctx, req.(*vtctldata.GetSchemaRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_GetSrvVSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.GetSrvVSchemaRequest) if err := dec(in); err != nil { @@ -528,6 +565,10 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "GetKeyspaces", Handler: _Vtctld_GetKeyspaces_Handler, }, + { + MethodName: "GetSchema", + Handler: _Vtctld_GetSchema_Handler, + }, { MethodName: "GetSrvVSchema", Handler: _Vtctld_GetSrvVSchema_Handler, diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index 65b7060ae01..d82f5ae262f 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -82,6 +82,15 @@ func (client *gRPCVtctldClient) GetKeyspaces(ctx context.Context, in *vtctldatap return client.c.GetKeyspaces(ctx, in, opts...) } +// GetSchema is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetSchema(ctx context.Context, in *vtctldatapb.GetSchemaRequest, opts ...grpc.CallOption) (*vtctldatapb.GetSchemaResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetSchema(ctx, in, opts...) +} + // GetSrvVSchema is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) GetSrvVSchema(ctx context.Context, in *vtctldatapb.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldatapb.GetSrvVSchemaResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 03a0921ecf6..cbef9733ab6 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -18,13 +18,16 @@ package grpcvtctldserver import ( "context" + "fmt" "time" "google.golang.org/grpc" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/tmclient" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" @@ -33,12 +36,13 @@ import ( // VtctldServer implements the Vtctld RPC service protocol. type VtctldServer struct { - ts *topo.Server + ts *topo.Server + tmc tmclient.TabletManagerClient } // NewVtctldServer returns a new VtctldServer for the given topo server. func NewVtctldServer(ts *topo.Server) *VtctldServer { - return &VtctldServer{ts: ts} + return &VtctldServer{ts: ts, tmc: tmclient.NewTabletManagerClient()} } // FindAllShardsInKeyspace is part of the vtctlservicepb.VtctldServer interface. @@ -136,6 +140,48 @@ func (s *VtctldServer) GetKeyspaces(ctx context.Context, req *vtctldatapb.GetKey return &vtctldatapb.GetKeyspacesResponse{Keyspaces: keyspaces}, nil } +// GetSchema is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetSchema(ctx context.Context, req *vtctldatapb.GetSchemaRequest) (*vtctldatapb.GetSchemaResponse, error) { + tablet, err := s.ts.GetTablet(ctx, req.TabletAlias) + if err != nil { + return nil, fmt.Errorf("GetTablet(%v) failed: %w", req.TabletAlias, err) + } + + sd, err := s.tmc.GetSchema(ctx, tablet.Tablet, req.Tables, req.ExcludeTables, req.IncludeViews) + if err != nil { + return nil, fmt.Errorf("GetSchema(%v, %v, %v, %v) failed: %w", tablet.Tablet, req.Tables, req.ExcludeTables, req.IncludeViews, err) + } + + if req.TableNamesOnly { + nameTds := make([]*tabletmanagerdatapb.TableDefinition, len(sd.TableDefinitions)) + + for i, td := range sd.TableDefinitions { + nameTds[i] = &tabletmanagerdatapb.TableDefinition{ + Name: td.Name, + } + } + + sd.TableDefinitions = nameTds + } else if req.TableSizesOnly { + sizeTds := make([]*tabletmanagerdatapb.TableDefinition, len(sd.TableDefinitions)) + + for i, td := range sd.TableDefinitions { + sizeTds[i] = &tabletmanagerdatapb.TableDefinition{ + Name: td.Name, + Type: td.Type, + RowCount: td.RowCount, + DataLength: td.DataLength, + } + } + + sd.TableDefinitions = sizeTds + } + + return &vtctldatapb.GetSchemaResponse{ + Schema: sd, + }, nil +} + // GetSrvVSchema is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) GetSrvVSchema(ctx context.Context, req *vtctldatapb.GetSrvVSchemaRequest) (*vtctldatapb.GetSrvVSchemaResponse, error) { vschema, err := s.ts.GetSrvVSchema(ctx, req.Cell) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index e55b764898b..bff3ac4e430 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -28,13 +28,21 @@ import ( "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" + "vitess.io/vitess/go/vt/vttablet/tmclient" + querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) +func init() { + *tmclient.TabletManagerProtocol = testutil.TabletManagerClientProtocol +} + func TestFindAllShardsInKeyspace(t *testing.T) { ctx := context.Background() ts := memorytopo.NewServer("cell1") @@ -184,6 +192,185 @@ func TestGetTablet(t *testing.T) { assert.Error(t, err) } +func TestGetSchema(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("zone1") + vtctld := NewVtctldServer(ts) + + validAlias := &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + } + testutil.AddTablet(ctx, t, ts, &topodatapb.Tablet{ + Alias: validAlias, + }) + otherAlias := &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + } + testutil.AddTablet(ctx, t, ts, &topodatapb.Tablet{ + Alias: otherAlias, + }) + + // we need to run this on each test case or they will pollute each other + setupSchema := func() { + testutil.TabletManagerClient.Schemas[topoproto.TabletAliasString(validAlias)] = &tabletmanagerdatapb.SchemaDefinition{ + DatabaseSchema: "CREATE DATABASE vt_testkeyspace", + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Schema: `CREATE TABLE t1 ( + id int(11) not null, + PRIMARY KEY (id) +);`, + Type: "BASE", + Columns: []string{"id"}, + DataLength: 100, + RowCount: 50, + Fields: []*querypb.Field{ + { + Name: "id", + Type: querypb.Type_INT32, + }, + }, + }, + }, + } + } + + tests := []*struct { + name string + req *vtctldatapb.GetSchemaRequest + expected *vtctldatapb.GetSchemaResponse + shouldErr bool + }{ + { + name: "normal path", + req: &vtctldatapb.GetSchemaRequest{ + TabletAlias: validAlias, + }, + expected: &vtctldatapb.GetSchemaResponse{ + Schema: &tabletmanagerdatapb.SchemaDefinition{ + DatabaseSchema: "CREATE DATABASE vt_testkeyspace", + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Schema: `CREATE TABLE t1 ( + id int(11) not null, + PRIMARY KEY (id) +);`, + Type: "BASE", + Columns: []string{"id"}, + DataLength: 100, + RowCount: 50, + Fields: []*querypb.Field{ + { + Name: "id", + Type: querypb.Type_INT32, + }, + }, + }, + }, + }, + }, + shouldErr: false, + }, + { + name: "table names only", + req: &vtctldatapb.GetSchemaRequest{ + TabletAlias: validAlias, + TableNamesOnly: true, + }, + expected: &vtctldatapb.GetSchemaResponse{ + Schema: &tabletmanagerdatapb.SchemaDefinition{ + DatabaseSchema: "CREATE DATABASE vt_testkeyspace", + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + }, + }, + }, + }, + shouldErr: false, + }, + { + name: "table sizes only", + req: &vtctldatapb.GetSchemaRequest{ + TabletAlias: validAlias, + TableSizesOnly: true, + }, + expected: &vtctldatapb.GetSchemaResponse{ + Schema: &tabletmanagerdatapb.SchemaDefinition{ + DatabaseSchema: "CREATE DATABASE vt_testkeyspace", + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Type: "BASE", + DataLength: 100, + RowCount: 50, + }, + }, + }, + }, + shouldErr: false, + }, + { + name: "table names take precedence over table sizes", + req: &vtctldatapb.GetSchemaRequest{ + TabletAlias: validAlias, + TableNamesOnly: true, + TableSizesOnly: true, + }, + expected: &vtctldatapb.GetSchemaResponse{ + Schema: &tabletmanagerdatapb.SchemaDefinition{ + DatabaseSchema: "CREATE DATABASE vt_testkeyspace", + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + }, + }, + }, + }, + shouldErr: false, + }, + // error cases + { + name: "no tablet", + req: &vtctldatapb.GetSchemaRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "notfound", + Uid: 100, + }, + }, + expected: nil, + shouldErr: true, + }, + { + name: "no schema", + req: &vtctldatapb.GetSchemaRequest{ + TabletAlias: otherAlias, + }, + expected: nil, + shouldErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + setupSchema() + + resp, err := vtctld.GetSchema(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, resp) + }) + } +} + func TestGetSrvVSchema(t *testing.T) { ctx := context.Background() ts, topofactory := memorytopo.NewServerAndFactory("zone1", "zone2") diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go new file mode 100644 index 00000000000..facaaf4f5bc --- /dev/null +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go @@ -0,0 +1,64 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import ( + "context" + "fmt" + + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vttablet/tmclient" + + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +// TestTabletManagerClient implements the tmclient.TabletManagerClient for +// testing. It allows users to mock various tmclient methods. +type TestTabletManagerClient struct { + tmclient.TabletManagerClient + Schemas map[string]*tabletmanagerdatapb.SchemaDefinition +} + +// GetSchema is part of the tmclient.TabletManagerClient interface. +func (c *TestTabletManagerClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tablets []string, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { + key := topoproto.TabletAliasString(tablet.Alias) + + schema, ok := c.Schemas[key] + if !ok { + return nil, fmt.Errorf("no schemas for %s", key) + } + + return schema, nil +} + +// TabletManagerClientProtocol is the protocol this package registers its client +// test implementation under. Users should set *tmclient.TabletManagerProtocol +// to this value before use. +const TabletManagerClientProtocol = "grpcvtctldserver.testutil" + +// TabletManagerClient is the singleton test client instance. It is public and +// singleton to allow tests to mutate and verify its state. +var TabletManagerClient = &TestTabletManagerClient{ + Schemas: map[string]*tabletmanagerdatapb.SchemaDefinition{}, +} + +func init() { + tmclient.RegisterTabletManagerClientFactory(TabletManagerClientProtocol, func() tmclient.TabletManagerClient { + return TabletManagerClient + }) +} diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 9d60654a348..1671e33f063 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2330,17 +2330,25 @@ func commandGetSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag excludeTableArray = strings.Split(*excludeTables, ",") } - sd, err := wr.GetSchema(ctx, tabletAlias, tableArray, excludeTableArray, *includeViews) + resp, err := wr.VtctldServer().GetSchema(ctx, &vtctldatapb.GetSchemaRequest{ + TabletAlias: tabletAlias, + Tables: tableArray, + ExcludeTables: excludeTableArray, + IncludeViews: *includeViews, + TableNamesOnly: *tableNamesOnly, + }) if err != nil { return err } + if *tableNamesOnly { - for _, td := range sd.TableDefinitions { + for _, td := range resp.Schema.TableDefinitions { wr.Logger().Printf("%v\n", td.Name) } return nil } - return printJSON(wr.Logger(), sd) + + return printJSON(wr.Logger(), resp.Schema) } func commandReloadSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 1e18b37f4c1..f17041cf296 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -23,6 +23,7 @@ option go_package = "vitess.io/vitess/go/vt/proto/vtctldata"; package vtctldata; import "logutil.proto"; +import "tabletmanagerdata.proto"; import "topodata.proto"; import "vschema.proto"; @@ -75,6 +76,29 @@ message GetKeyspaceResponse { Keyspace keyspace = 1; } +message GetSchemaRequest { + topodata.TabletAlias tablet_alias = 1; + // Tables is a list of tables for which we should gather information. Each is + // either an exact match, or a regular expression of the form /regexp/. + repeated string tables = 2; + // ExcludeTables is a list of tables to exclude from the result. Each is + // either an exact match, or a regular expression of the form /regexp/. + repeated string exclude_tables = 3; + // IncludeViews specifies whether to include views in the result. + bool include_views = 4; + // TableNamesOnly specifies whether to limit the results to just table names, + // rather than full schema information for each table. + bool table_names_only = 5; + // TableSizesOnly specifies whether to limit the results to just table sizes, + // rather than full schema information for each table. It is ignored if + // TableNamesOnly is set to true. + bool table_sizes_only = 6; +} + +message GetSchemaResponse { + tabletmanagerdata.SchemaDefinition schema = 1; +} + message GetSrvVSchemaRequest { string cell = 1; } diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 2ffbdb218de..69acb88f181 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -46,6 +46,9 @@ service Vtctld { rpc GetKeyspace(vtctldata.GetKeyspaceRequest) returns (vtctldata.GetKeyspaceResponse) {}; // GetKeyspaces returns the keyspace struct of all keyspaces in the topo. rpc GetKeyspaces(vtctldata.GetKeyspacesRequest) returns (vtctldata.GetKeyspacesResponse) {}; + // GetSchema returns the schema for a tablet, or just the schema for the + // specified tables in that tablet. + rpc GetSchema(vtctldata.GetSchemaRequest) returns (vtctldata.GetSchemaResponse) {}; // GetSrvVSchema returns a the SrvVSchema for a cell. rpc GetSrvVSchema(vtctldata.GetSrvVSchemaRequest) returns (vtctldata.GetSrvVSchemaResponse) {}; // GetTablet returns information about a tablet. From 73fa04899f5c8520d6b526eff8bf98310c4d59b3 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Sat, 23 Jan 2021 23:21:21 +0100 Subject: [PATCH 11/21] Merge pull request #7352 from tinyspeck/am_vtctld_listbackups [vtctld] Migrate ListBackups as GetBackups in new vtctld server --- .../vtctldclient/internal/command/backups.go | 59 ++++ go/vt/mysqlctl/mysqlctlproto/backup.go | 31 ++ go/vt/mysqlctl/mysqlctlproto/doc.go | 21 ++ go/vt/proto/mysqlctl/mysqlctl.pb.go | 97 +++++-- go/vt/proto/vtctldata/vtctldata.pb.go | 270 ++++++++++++------ go/vt/proto/vtctlservice/vtctlservice.pb.go | 88 ++++-- go/vt/vtctl/grpcvtctldclient/client_gen.go | 9 + go/vt/vtctl/grpcvtctldserver/server.go | 30 ++ go/vt/vtctl/grpcvtctldserver/server_test.go | 55 ++++ .../testutil/test_backupstorage.go | 92 ++++++ .../testutil/test_tmclient.go | 8 +- proto/mysqlctl.proto | 6 + proto/vtctldata.proto | 10 + proto/vtctlservice.proto | 2 + 14 files changed, 638 insertions(+), 140 deletions(-) create mode 100644 go/cmd/vtctldclient/internal/command/backups.go create mode 100644 go/vt/mysqlctl/mysqlctlproto/backup.go create mode 100644 go/vt/mysqlctl/mysqlctlproto/doc.go create mode 100644 go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go diff --git a/go/cmd/vtctldclient/internal/command/backups.go b/go/cmd/vtctldclient/internal/command/backups.go new file mode 100644 index 00000000000..3b1fea947d2 --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/backups.go @@ -0,0 +1,59 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +// GetBackups makes a GetBackups gRPC call to a vtctld. +var GetBackups = &cobra.Command{ + Use: "GetBackups keyspace shard", + Args: cobra.ExactArgs(2), + RunE: commandGetBackups, +} + +func commandGetBackups(cmd *cobra.Command, args []string) error { + keyspace := cmd.Flags().Arg(0) + shard := cmd.Flags().Arg(1) + + resp, err := client.GetBackups(commandCtx, &vtctldatapb.GetBackupsRequest{ + Keyspace: keyspace, + Shard: shard, + }) + if err != nil { + return err + } + + names := make([]string, len(resp.Backups)) + for i, b := range resp.Backups { + names[i] = b.Name + } + + fmt.Printf("%s\n", strings.Join(names, "\n")) + + return nil +} + +func init() { + Root.AddCommand(GetBackups) +} diff --git a/go/vt/mysqlctl/mysqlctlproto/backup.go b/go/vt/mysqlctl/mysqlctlproto/backup.go new file mode 100644 index 00000000000..6fa2755b441 --- /dev/null +++ b/go/vt/mysqlctl/mysqlctlproto/backup.go @@ -0,0 +1,31 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package mysqlctlproto + +import ( + "vitess.io/vitess/go/vt/mysqlctl/backupstorage" + + mysqlctlpb "vitess.io/vitess/go/vt/proto/mysqlctl" +) + +// BackupHandleToProto returns a BackupInfo proto from a BackupHandle. +func BackupHandleToProto(bh backupstorage.BackupHandle) *mysqlctlpb.BackupInfo { + return &mysqlctlpb.BackupInfo{ + Name: bh.Name(), + Directory: bh.Directory(), + } +} diff --git a/go/vt/mysqlctl/mysqlctlproto/doc.go b/go/vt/mysqlctl/mysqlctlproto/doc.go new file mode 100644 index 00000000000..cf77ea853ff --- /dev/null +++ b/go/vt/mysqlctl/mysqlctlproto/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package mysqlctlproto provides utility functions for working with data +structures in mysqlctl.proto. +*/ +package mysqlctlproto diff --git a/go/vt/proto/mysqlctl/mysqlctl.pb.go b/go/vt/proto/mysqlctl/mysqlctl.pb.go index 2b80a9971d9..f7c1b3af765 100644 --- a/go/vt/proto/mysqlctl/mysqlctl.pb.go +++ b/go/vt/proto/mysqlctl/mysqlctl.pb.go @@ -351,6 +351,54 @@ func (m *RefreshConfigResponse) XXX_DiscardUnknown() { var xxx_messageInfo_RefreshConfigResponse proto.InternalMessageInfo +// BackupInfo is the read-only attributes of a mysqlctl/backupstorage.BackupHandle. +type BackupInfo struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Directory string `protobuf:"bytes,2,opt,name=directory,proto3" json:"directory,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BackupInfo) Reset() { *m = BackupInfo{} } +func (m *BackupInfo) String() string { return proto.CompactTextString(m) } +func (*BackupInfo) ProtoMessage() {} +func (*BackupInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_cd8c110e42f9cbb9, []int{10} +} + +func (m *BackupInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BackupInfo.Unmarshal(m, b) +} +func (m *BackupInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BackupInfo.Marshal(b, m, deterministic) +} +func (m *BackupInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_BackupInfo.Merge(m, src) +} +func (m *BackupInfo) XXX_Size() int { + return xxx_messageInfo_BackupInfo.Size(m) +} +func (m *BackupInfo) XXX_DiscardUnknown() { + xxx_messageInfo_BackupInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_BackupInfo proto.InternalMessageInfo + +func (m *BackupInfo) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *BackupInfo) GetDirectory() string { + if m != nil { + return m.Directory + } + return "" +} + func init() { proto.RegisterType((*StartRequest)(nil), "mysqlctl.StartRequest") proto.RegisterType((*StartResponse)(nil), "mysqlctl.StartResponse") @@ -362,34 +410,37 @@ func init() { proto.RegisterType((*ReinitConfigResponse)(nil), "mysqlctl.ReinitConfigResponse") proto.RegisterType((*RefreshConfigRequest)(nil), "mysqlctl.RefreshConfigRequest") proto.RegisterType((*RefreshConfigResponse)(nil), "mysqlctl.RefreshConfigResponse") + proto.RegisterType((*BackupInfo)(nil), "mysqlctl.BackupInfo") } func init() { proto.RegisterFile("mysqlctl.proto", fileDescriptor_cd8c110e42f9cbb9) } var fileDescriptor_cd8c110e42f9cbb9 = []byte{ - // 339 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x4d, 0x4f, 0xfa, 0x30, - 0x1c, 0xc7, 0xff, 0x84, 0xfc, 0xcd, 0xfc, 0x09, 0xce, 0x54, 0x79, 0x6a, 0xa2, 0xe0, 0x12, 0x95, - 0x13, 0x4d, 0xf4, 0xa4, 0x37, 0x25, 0xf1, 0x66, 0x4c, 0x4a, 0x4c, 0x8c, 0x17, 0x32, 0xa5, 0x8c, - 0x26, 0xb8, 0x42, 0x5b, 0x20, 0xbe, 0x05, 0x5f, 0xb5, 0xb1, 0x6b, 0xc7, 0xc6, 0xc0, 0xdb, 0xfa, - 0x7d, 0x6a, 0xf6, 0xd9, 0xe0, 0xf0, 0xf3, 0x4b, 0xcd, 0xa7, 0x1f, 0x7a, 0xda, 0x9b, 0x49, 0xa1, - 0x05, 0xf2, 0xdc, 0x39, 0x20, 0x50, 0x19, 0xe8, 0x50, 0x6a, 0xca, 0xe6, 0x0b, 0xa6, 0x34, 0x6a, - 0xc3, 0x81, 0xf1, 0x46, 0xc3, 0x50, 0x46, 0xaa, 0x59, 0xea, 0x94, 0xbb, 0xfb, 0x14, 0x12, 0xe9, - 0x5e, 0x46, 0x2a, 0xf0, 0xa1, 0x6a, 0x0b, 0x6a, 0x26, 0x62, 0xc5, 0x82, 0x5b, 0xf0, 0x07, 0x93, - 0x85, 0x1e, 0x89, 0x55, 0xec, 0x46, 0x2e, 0xc1, 0x5f, 0x85, 0x5c, 0x0f, 0xc7, 0x42, 0x0e, 0x93, - 0x6a, 0xb3, 0xd4, 0x29, 0x75, 0x3d, 0x5a, 0xfd, 0x95, 0x1f, 0x85, 0x7c, 0x32, 0x62, 0x80, 0xe0, - 0x68, 0x5d, 0xb5, 0x73, 0x4d, 0xa8, 0xd3, 0x45, 0x6c, 0x02, 0x2f, 0xb3, 0x48, 0x86, 0x23, 0x66, - 0x57, 0x83, 0x16, 0x34, 0x0a, 0x8e, 0x2d, 0xd5, 0xe0, 0x98, 0x32, 0x1e, 0x73, 0xdd, 0x17, 0xf1, - 0x98, 0x47, 0xae, 0x51, 0x87, 0x93, 0xbc, 0x6c, 0xe3, 0x46, 0x1f, 0x4b, 0xa6, 0x26, 0xf9, 0x7c, - 0x03, 0x6a, 0x1b, 0x7a, 0x52, 0xb8, 0xfe, 0x2e, 0x83, 0x67, 0x2e, 0xee, 0xeb, 0x29, 0xba, 0x83, - 0xff, 0x86, 0x00, 0xaa, 0xf7, 0x52, 0xac, 0x59, 0x86, 0xb8, 0x51, 0xd0, 0xed, 0xbd, 0xff, 0x50, - 0x1f, 0x3c, 0xf7, 0xc6, 0xa8, 0x95, 0x89, 0xe5, 0x01, 0x62, 0xbc, 0xcd, 0x4a, 0x47, 0x5e, 0xc1, - 0xdf, 0x00, 0x81, 0x3a, 0xeb, 0xc2, 0x76, 0x7a, 0xf8, 0xfc, 0x8f, 0x44, 0xba, 0xfc, 0x0c, 0x95, - 0x2c, 0x30, 0x74, 0x9a, 0x29, 0x15, 0xf9, 0xe2, 0xb3, 0x5d, 0x76, 0x3a, 0x48, 0xa1, 0x9a, 0x23, - 0x8a, 0x72, 0x95, 0xe2, 0x27, 0xc0, 0xed, 0x9d, 0xbe, 0xdb, 0x7c, 0xb8, 0x7a, 0xbb, 0x58, 0x72, - 0xcd, 0x94, 0xea, 0x71, 0x41, 0x92, 0x27, 0x12, 0x09, 0xb2, 0xd4, 0xc4, 0xfc, 0xdc, 0xc4, 0x0d, - 0xbc, 0xef, 0x99, 0xf3, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb8, 0xe2, 0x15, 0x86, 0xfe, - 0x02, 0x00, 0x00, + // 376 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x53, 0xdf, 0x4b, 0xc2, 0x40, + 0x1c, 0xcf, 0xac, 0x98, 0xdf, 0xb4, 0xc5, 0x95, 0x3a, 0x47, 0xa5, 0x0d, 0x2a, 0x9f, 0x1c, 0xd4, + 0x53, 0x3d, 0x04, 0x29, 0x04, 0x3d, 0x44, 0x30, 0x09, 0xa2, 0x17, 0x59, 0xee, 0x36, 0x47, 0xba, + 0x9b, 0x77, 0x37, 0xc5, 0x7f, 0xa1, 0xbf, 0x3a, 0x3a, 0x6f, 0x73, 0x73, 0xda, 0xdb, 0xdd, 0xe7, + 0x17, 0xb7, 0xcf, 0x87, 0xc1, 0xd1, 0x64, 0xc1, 0xa6, 0xe3, 0x21, 0x1f, 0x77, 0x42, 0x4a, 0x38, + 0x41, 0x4a, 0x7c, 0x37, 0x4c, 0x28, 0xf7, 0xb9, 0x4d, 0xb9, 0x85, 0xa7, 0x11, 0x66, 0x1c, 0x35, + 0xe1, 0x50, 0x70, 0xce, 0xc0, 0xa6, 0x1e, 0xd3, 0x0a, 0xad, 0x62, 0xbb, 0x64, 0xc1, 0x12, 0x7a, + 0xa2, 0x1e, 0x33, 0x54, 0xa8, 0x48, 0x03, 0x0b, 0x49, 0xc0, 0xb0, 0x71, 0x0f, 0x6a, 0x7f, 0x14, + 0x71, 0x87, 0xcc, 0x83, 0x38, 0xe4, 0x1a, 0xd4, 0xb9, 0xed, 0xf3, 0x81, 0x4b, 0xe8, 0x60, 0x69, + 0xd5, 0x0a, 0xad, 0x42, 0x5b, 0xb1, 0x2a, 0x7f, 0xf0, 0x33, 0xa1, 0xaf, 0x02, 0x34, 0x10, 0x1c, + 0xaf, 0xac, 0x32, 0x4e, 0x83, 0x9a, 0x15, 0x05, 0x42, 0xf0, 0x1e, 0x7a, 0xd4, 0x76, 0xb0, 0x4c, + 0x35, 0x1a, 0x50, 0xcf, 0x31, 0xd2, 0x54, 0x85, 0x13, 0x0b, 0xfb, 0x81, 0xcf, 0x7b, 0x24, 0x70, + 0x7d, 0x2f, 0x76, 0xd4, 0xe0, 0x34, 0x0b, 0x4b, 0xb9, 0xc0, 0x5d, 0x8a, 0xd9, 0x28, 0xab, 0xaf, + 0x43, 0x75, 0x0d, 0x97, 0x86, 0x47, 0x80, 0xae, 0x3d, 0xfc, 0x8e, 0xc2, 0x97, 0xc0, 0x25, 0x08, + 0xc1, 0x5e, 0x60, 0x4f, 0xb0, 0xf8, 0xa6, 0x92, 0x25, 0xce, 0xe8, 0x0c, 0x4a, 0x8e, 0x4f, 0xf1, + 0x90, 0x13, 0xba, 0xd0, 0x76, 0x05, 0xb1, 0x02, 0x6e, 0x7f, 0x8a, 0xa0, 0x88, 0x87, 0xf7, 0xf8, + 0x18, 0x3d, 0xc0, 0xbe, 0x68, 0x10, 0xd5, 0x3a, 0xc9, 0x2c, 0xe9, 0x0d, 0xf4, 0x7a, 0x0e, 0x97, + 0xcf, 0xd8, 0x41, 0x3d, 0x50, 0xe2, 0xc6, 0x50, 0x23, 0x25, 0xcb, 0x0e, 0xa0, 0xeb, 0x9b, 0xa8, + 0x24, 0xe4, 0x03, 0xd4, 0xb5, 0x22, 0x51, 0x6b, 0x65, 0xd8, 0xdc, 0xbe, 0x7e, 0xf9, 0x8f, 0x22, + 0x49, 0x7e, 0x83, 0x72, 0xba, 0x70, 0x74, 0x9e, 0x32, 0xe5, 0xf7, 0xd1, 0x2f, 0xb6, 0xd1, 0x49, + 0xa0, 0x05, 0x95, 0xcc, 0x22, 0x28, 0x63, 0xc9, 0x4f, 0xa8, 0x37, 0xb7, 0xf2, 0x71, 0x66, 0xf7, + 0xe6, 0xf3, 0x6a, 0xe6, 0x73, 0xcc, 0x58, 0xc7, 0x27, 0xe6, 0xf2, 0x64, 0x7a, 0xc4, 0x9c, 0x71, + 0x53, 0xfc, 0x1c, 0x66, 0x1c, 0xf0, 0x75, 0x20, 0xee, 0x77, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, + 0xd3, 0x4f, 0x5c, 0x33, 0x3e, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 5bab4dbea03..73307d4733b 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -9,6 +9,7 @@ import ( proto "github.com/golang/protobuf/proto" logutil "vitess.io/vitess/go/vt/proto/logutil" + mysqlctl "vitess.io/vitess/go/vt/proto/mysqlctl" tabletmanagerdata "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodata "vitess.io/vitess/go/vt/proto/topodata" vschema "vitess.io/vitess/go/vt/proto/vschema" @@ -114,6 +115,92 @@ func (m *ExecuteVtctlCommandResponse) GetEvent() *logutil.Event { return nil } +type GetBackupsRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetBackupsRequest) Reset() { *m = GetBackupsRequest{} } +func (m *GetBackupsRequest) String() string { return proto.CompactTextString(m) } +func (*GetBackupsRequest) ProtoMessage() {} +func (*GetBackupsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{2} +} + +func (m *GetBackupsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetBackupsRequest.Unmarshal(m, b) +} +func (m *GetBackupsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetBackupsRequest.Marshal(b, m, deterministic) +} +func (m *GetBackupsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetBackupsRequest.Merge(m, src) +} +func (m *GetBackupsRequest) XXX_Size() int { + return xxx_messageInfo_GetBackupsRequest.Size(m) +} +func (m *GetBackupsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetBackupsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetBackupsRequest proto.InternalMessageInfo + +func (m *GetBackupsRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *GetBackupsRequest) GetShard() string { + if m != nil { + return m.Shard + } + return "" +} + +type GetBackupsResponse struct { + Backups []*mysqlctl.BackupInfo `protobuf:"bytes,1,rep,name=backups,proto3" json:"backups,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetBackupsResponse) Reset() { *m = GetBackupsResponse{} } +func (m *GetBackupsResponse) String() string { return proto.CompactTextString(m) } +func (*GetBackupsResponse) ProtoMessage() {} +func (*GetBackupsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{3} +} + +func (m *GetBackupsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetBackupsResponse.Unmarshal(m, b) +} +func (m *GetBackupsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetBackupsResponse.Marshal(b, m, deterministic) +} +func (m *GetBackupsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetBackupsResponse.Merge(m, src) +} +func (m *GetBackupsResponse) XXX_Size() int { + return xxx_messageInfo_GetBackupsResponse.Size(m) +} +func (m *GetBackupsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetBackupsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetBackupsResponse proto.InternalMessageInfo + +func (m *GetBackupsResponse) GetBackups() []*mysqlctl.BackupInfo { + if m != nil { + return m.Backups + } + return nil +} + type GetCellInfoNamesRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -124,7 +211,7 @@ func (m *GetCellInfoNamesRequest) Reset() { *m = GetCellInfoNamesRequest func (m *GetCellInfoNamesRequest) String() string { return proto.CompactTextString(m) } func (*GetCellInfoNamesRequest) ProtoMessage() {} func (*GetCellInfoNamesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{2} + return fileDescriptor_f41247b323a1ab2e, []int{4} } func (m *GetCellInfoNamesRequest) XXX_Unmarshal(b []byte) error { @@ -156,7 +243,7 @@ func (m *GetCellInfoNamesResponse) Reset() { *m = GetCellInfoNamesRespon func (m *GetCellInfoNamesResponse) String() string { return proto.CompactTextString(m) } func (*GetCellInfoNamesResponse) ProtoMessage() {} func (*GetCellInfoNamesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{3} + return fileDescriptor_f41247b323a1ab2e, []int{5} } func (m *GetCellInfoNamesResponse) XXX_Unmarshal(b []byte) error { @@ -195,7 +282,7 @@ func (m *GetCellInfoRequest) Reset() { *m = GetCellInfoRequest{} } func (m *GetCellInfoRequest) String() string { return proto.CompactTextString(m) } func (*GetCellInfoRequest) ProtoMessage() {} func (*GetCellInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{4} + return fileDescriptor_f41247b323a1ab2e, []int{6} } func (m *GetCellInfoRequest) XXX_Unmarshal(b []byte) error { @@ -234,7 +321,7 @@ func (m *GetCellInfoResponse) Reset() { *m = GetCellInfoResponse{} } func (m *GetCellInfoResponse) String() string { return proto.CompactTextString(m) } func (*GetCellInfoResponse) ProtoMessage() {} func (*GetCellInfoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{5} + return fileDescriptor_f41247b323a1ab2e, []int{7} } func (m *GetCellInfoResponse) XXX_Unmarshal(b []byte) error { @@ -272,7 +359,7 @@ func (m *GetCellsAliasesRequest) Reset() { *m = GetCellsAliasesRequest{} func (m *GetCellsAliasesRequest) String() string { return proto.CompactTextString(m) } func (*GetCellsAliasesRequest) ProtoMessage() {} func (*GetCellsAliasesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{6} + return fileDescriptor_f41247b323a1ab2e, []int{8} } func (m *GetCellsAliasesRequest) XXX_Unmarshal(b []byte) error { @@ -304,7 +391,7 @@ func (m *GetCellsAliasesResponse) Reset() { *m = GetCellsAliasesResponse func (m *GetCellsAliasesResponse) String() string { return proto.CompactTextString(m) } func (*GetCellsAliasesResponse) ProtoMessage() {} func (*GetCellsAliasesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{7} + return fileDescriptor_f41247b323a1ab2e, []int{9} } func (m *GetCellsAliasesResponse) XXX_Unmarshal(b []byte) error { @@ -342,7 +429,7 @@ func (m *GetKeyspacesRequest) Reset() { *m = GetKeyspacesRequest{} } func (m *GetKeyspacesRequest) String() string { return proto.CompactTextString(m) } func (*GetKeyspacesRequest) ProtoMessage() {} func (*GetKeyspacesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{8} + return fileDescriptor_f41247b323a1ab2e, []int{10} } func (m *GetKeyspacesRequest) XXX_Unmarshal(b []byte) error { @@ -374,7 +461,7 @@ func (m *GetKeyspacesResponse) Reset() { *m = GetKeyspacesResponse{} } func (m *GetKeyspacesResponse) String() string { return proto.CompactTextString(m) } func (*GetKeyspacesResponse) ProtoMessage() {} func (*GetKeyspacesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{9} + return fileDescriptor_f41247b323a1ab2e, []int{11} } func (m *GetKeyspacesResponse) XXX_Unmarshal(b []byte) error { @@ -413,7 +500,7 @@ func (m *GetKeyspaceRequest) Reset() { *m = GetKeyspaceRequest{} } func (m *GetKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*GetKeyspaceRequest) ProtoMessage() {} func (*GetKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{10} + return fileDescriptor_f41247b323a1ab2e, []int{12} } func (m *GetKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -452,7 +539,7 @@ func (m *GetKeyspaceResponse) Reset() { *m = GetKeyspaceResponse{} } func (m *GetKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*GetKeyspaceResponse) ProtoMessage() {} func (*GetKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{11} + return fileDescriptor_f41247b323a1ab2e, []int{13} } func (m *GetKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -506,7 +593,7 @@ func (m *GetSchemaRequest) Reset() { *m = GetSchemaRequest{} } func (m *GetSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetSchemaRequest) ProtoMessage() {} func (*GetSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{12} + return fileDescriptor_f41247b323a1ab2e, []int{14} } func (m *GetSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -580,7 +667,7 @@ func (m *GetSchemaResponse) Reset() { *m = GetSchemaResponse{} } func (m *GetSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetSchemaResponse) ProtoMessage() {} func (*GetSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{13} + return fileDescriptor_f41247b323a1ab2e, []int{15} } func (m *GetSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -619,7 +706,7 @@ func (m *GetSrvVSchemaRequest) Reset() { *m = GetSrvVSchemaRequest{} } func (m *GetSrvVSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetSrvVSchemaRequest) ProtoMessage() {} func (*GetSrvVSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{14} + return fileDescriptor_f41247b323a1ab2e, []int{16} } func (m *GetSrvVSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -658,7 +745,7 @@ func (m *GetSrvVSchemaResponse) Reset() { *m = GetSrvVSchemaResponse{} } func (m *GetSrvVSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetSrvVSchemaResponse) ProtoMessage() {} func (*GetSrvVSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{15} + return fileDescriptor_f41247b323a1ab2e, []int{17} } func (m *GetSrvVSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -697,7 +784,7 @@ func (m *GetTabletRequest) Reset() { *m = GetTabletRequest{} } func (m *GetTabletRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletRequest) ProtoMessage() {} func (*GetTabletRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{16} + return fileDescriptor_f41247b323a1ab2e, []int{18} } func (m *GetTabletRequest) XXX_Unmarshal(b []byte) error { @@ -736,7 +823,7 @@ func (m *GetTabletResponse) Reset() { *m = GetTabletResponse{} } func (m *GetTabletResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletResponse) ProtoMessage() {} func (*GetTabletResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{17} + return fileDescriptor_f41247b323a1ab2e, []int{19} } func (m *GetTabletResponse) XXX_Unmarshal(b []byte) error { @@ -782,7 +869,7 @@ func (m *GetTabletsRequest) Reset() { *m = GetTabletsRequest{} } func (m *GetTabletsRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletsRequest) ProtoMessage() {} func (*GetTabletsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{18} + return fileDescriptor_f41247b323a1ab2e, []int{20} } func (m *GetTabletsRequest) XXX_Unmarshal(b []byte) error { @@ -835,7 +922,7 @@ func (m *GetTabletsResponse) Reset() { *m = GetTabletsResponse{} } func (m *GetTabletsResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletsResponse) ProtoMessage() {} func (*GetTabletsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{19} + return fileDescriptor_f41247b323a1ab2e, []int{21} } func (m *GetTabletsResponse) XXX_Unmarshal(b []byte) error { @@ -875,7 +962,7 @@ func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{20} + return fileDescriptor_f41247b323a1ab2e, []int{22} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { @@ -921,7 +1008,7 @@ func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInK func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{21} + return fileDescriptor_f41247b323a1ab2e, []int{23} } func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -960,7 +1047,7 @@ func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsIn func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{22} + return fileDescriptor_f41247b323a1ab2e, []int{24} } func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -1001,7 +1088,7 @@ func (m *Shard) Reset() { *m = Shard{} } func (m *Shard) String() string { return proto.CompactTextString(m) } func (*Shard) ProtoMessage() {} func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{23} + return fileDescriptor_f41247b323a1ab2e, []int{25} } func (m *Shard) XXX_Unmarshal(b []byte) error { @@ -1061,7 +1148,7 @@ func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettin func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } func (*TableMaterializeSettings) ProtoMessage() {} func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{24} + return fileDescriptor_f41247b323a1ab2e, []int{26} } func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -1124,7 +1211,7 @@ func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } func (*MaterializeSettings) ProtoMessage() {} func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{25} + return fileDescriptor_f41247b323a1ab2e, []int{27} } func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -1197,6 +1284,8 @@ func (m *MaterializeSettings) GetTabletTypes() string { func init() { proto.RegisterType((*ExecuteVtctlCommandRequest)(nil), "vtctldata.ExecuteVtctlCommandRequest") proto.RegisterType((*ExecuteVtctlCommandResponse)(nil), "vtctldata.ExecuteVtctlCommandResponse") + proto.RegisterType((*GetBackupsRequest)(nil), "vtctldata.GetBackupsRequest") + proto.RegisterType((*GetBackupsResponse)(nil), "vtctldata.GetBackupsResponse") proto.RegisterType((*GetCellInfoNamesRequest)(nil), "vtctldata.GetCellInfoNamesRequest") proto.RegisterType((*GetCellInfoNamesResponse)(nil), "vtctldata.GetCellInfoNamesResponse") proto.RegisterType((*GetCellInfoRequest)(nil), "vtctldata.GetCellInfoRequest") @@ -1228,69 +1317,72 @@ func init() { func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 1022 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5b, 0x6f, 0xe3, 0x44, - 0x14, 0x56, 0x92, 0x4d, 0x36, 0x39, 0x69, 0x2e, 0xeb, 0xb6, 0xbb, 0x26, 0x08, 0x28, 0x2e, 0xdb, - 0x8d, 0x8a, 0xe4, 0x2c, 0x45, 0xa0, 0x15, 0x17, 0x89, 0xd2, 0xed, 0xae, 0xca, 0x42, 0x59, 0x39, - 0x55, 0x91, 0x40, 0xc2, 0xf2, 0x3a, 0x93, 0xac, 0xd5, 0x89, 0xc7, 0x78, 0x26, 0x6e, 0xb3, 0xcf, - 0xbc, 0xf0, 0x67, 0x78, 0xe4, 0x91, 0xdf, 0x86, 0x66, 0xe6, 0x8c, 0xed, 0xb4, 0x29, 0x17, 0xf1, - 0xe6, 0xf3, 0x9d, 0xcb, 0x7c, 0xe7, 0x2a, 0x43, 0x2f, 0x13, 0xa1, 0xa0, 0x93, 0x40, 0x04, 0x6e, - 0x92, 0x32, 0xc1, 0xac, 0x56, 0x0e, 0x0c, 0x3a, 0x94, 0xcd, 0x16, 0x22, 0xa2, 0x5a, 0x33, 0x78, - 0x20, 0x82, 0x57, 0x94, 0x88, 0x79, 0x10, 0x07, 0x33, 0x92, 0x16, 0x2e, 0x83, 0xae, 0x60, 0x09, - 0x2b, 0xc9, 0x9d, 0x8c, 0x87, 0xaf, 0xc9, 0x1c, 0x45, 0xe7, 0x07, 0x18, 0x1c, 0x5f, 0x91, 0x70, - 0x21, 0xc8, 0xb9, 0x0c, 0x7d, 0xc4, 0xe6, 0xf3, 0x20, 0x9e, 0x78, 0xe4, 0x97, 0x05, 0xe1, 0xc2, - 0xb2, 0xe0, 0x4e, 0x90, 0xce, 0xb8, 0x5d, 0xd9, 0xa9, 0x0d, 0x5b, 0x9e, 0xfa, 0xb6, 0x1e, 0x42, - 0x37, 0x08, 0x45, 0xc4, 0x62, 0x5f, 0x44, 0x73, 0xc2, 0x16, 0xc2, 0xae, 0xee, 0x54, 0x86, 0x35, - 0xaf, 0xa3, 0xd1, 0x33, 0x0d, 0x3a, 0x47, 0xf0, 0xf6, 0xda, 0xc0, 0x3c, 0x61, 0x31, 0x27, 0xd6, - 0x07, 0x50, 0x27, 0x19, 0x89, 0x85, 0x5d, 0xd9, 0xa9, 0x0c, 0xdb, 0x07, 0x5d, 0xd7, 0xa4, 0x73, - 0x2c, 0x51, 0x4f, 0x2b, 0x9d, 0xb7, 0xe0, 0xc1, 0x73, 0x22, 0x8e, 0x08, 0xa5, 0x27, 0xf1, 0x94, - 0x9d, 0x06, 0x73, 0xc2, 0x91, 0x9a, 0xf3, 0x18, 0xec, 0x9b, 0x2a, 0x0c, 0xbe, 0x05, 0xf5, 0x58, - 0x02, 0xc8, 0x5b, 0x0b, 0xce, 0x10, 0xac, 0x92, 0x47, 0x29, 0xc5, 0x90, 0x50, 0xaa, 0x78, 0xb4, - 0x3c, 0xf5, 0xed, 0x3c, 0x83, 0xcd, 0x15, 0x4b, 0x0c, 0x3b, 0x82, 0x96, 0x54, 0xfb, 0x51, 0x3c, - 0x65, 0xc8, 0xdb, 0x72, 0xf3, 0xf2, 0xe6, 0xe6, 0xcd, 0x10, 0xbf, 0x1c, 0x1b, 0xee, 0x63, 0x1c, - 0x7e, 0x48, 0xa3, 0x80, 0x17, 0xec, 0xff, 0xa8, 0xe4, 0x99, 0x15, 0x2a, 0x7c, 0xe6, 0x04, 0xee, - 0x06, 0x1a, 0x52, 0xfc, 0xdb, 0x07, 0x23, 0xb7, 0x98, 0x83, 0x5b, 0x9c, 0x5c, 0x94, 0x8f, 0x63, - 0x91, 0x2e, 0x3d, 0xe3, 0x3f, 0x78, 0x09, 0x1b, 0x65, 0x85, 0xd5, 0x87, 0xda, 0x05, 0x59, 0x62, - 0xae, 0xf2, 0xd3, 0xda, 0x87, 0x7a, 0x16, 0xd0, 0x05, 0x51, 0x4d, 0x6c, 0x1f, 0x6c, 0xad, 0xe6, - 0xa3, 0x9f, 0xf1, 0xb4, 0xc9, 0x67, 0xd5, 0x27, 0x15, 0x67, 0x5b, 0x95, 0xe6, 0x05, 0x59, 0xf2, - 0x24, 0x08, 0x8b, 0x7c, 0x4e, 0x60, 0x6b, 0x15, 0xc6, 0x5c, 0x3e, 0x82, 0xd6, 0x85, 0x01, 0x31, - 0x9b, 0xcd, 0x52, 0x36, 0xc6, 0xc1, 0x2b, 0xac, 0x9c, 0xc7, 0xaa, 0x4d, 0xb9, 0x06, 0xdb, 0x34, - 0x80, 0xa6, 0x31, 0x41, 0xfa, 0xb9, 0x8c, 0xed, 0x2a, 0x3c, 0xf2, 0x76, 0xad, 0xba, 0xdc, 0xf2, - 0x74, 0x11, 0xe7, 0xd7, 0x2a, 0xf4, 0x9f, 0x13, 0x31, 0x56, 0xfb, 0x61, 0x1e, 0x7e, 0x02, 0x1b, - 0x7a, 0xb5, 0x7c, 0x55, 0x54, 0x8c, 0xb4, 0x5d, 0xd4, 0xe9, 0x4c, 0x69, 0x75, 0xa1, 0xda, 0xa2, - 0x10, 0xac, 0xfb, 0xd0, 0x50, 0x22, 0xb7, 0xab, 0x6a, 0x0c, 0x51, 0x92, 0x0b, 0x44, 0xae, 0x42, - 0xba, 0x98, 0x10, 0x1f, 0xf5, 0x35, 0xa5, 0xef, 0x20, 0x7a, 0xa6, 0xcd, 0x76, 0xa1, 0x13, 0xc5, - 0xda, 0x2c, 0x8b, 0xc8, 0x25, 0xb7, 0xef, 0xec, 0x54, 0x86, 0x4d, 0x6f, 0x03, 0xc1, 0x73, 0x89, - 0x59, 0x43, 0xe8, 0xab, 0x18, 0xbe, 0x1a, 0x71, 0x9f, 0xc5, 0x74, 0x69, 0xd7, 0x95, 0x5d, 0x57, - 0xe1, 0x6a, 0x2f, 0xbe, 0x8f, 0xe9, 0xb2, 0xb0, 0xe4, 0xd1, 0x1b, 0x63, 0xd9, 0x28, 0x59, 0x8e, - 0x25, 0x2c, 0x2d, 0x9d, 0x97, 0x70, 0xaf, 0x54, 0x05, 0x2c, 0xe6, 0xe7, 0xd0, 0xd0, 0x77, 0x03, - 0x0b, 0xb0, 0xeb, 0xde, 0x3c, 0x38, 0xda, 0xe5, 0x29, 0x99, 0x46, 0x71, 0x24, 0x4f, 0x81, 0x87, - 0x2e, 0xce, 0xbe, 0x9a, 0x8e, 0x71, 0x9a, 0x9d, 0xaf, 0xd6, 0x76, 0xdd, 0xee, 0x9d, 0xc2, 0xf6, - 0x35, 0x5b, 0x64, 0xf0, 0x09, 0x6c, 0xf0, 0x34, 0xf3, 0x33, 0x7f, 0x85, 0xc7, 0xa6, 0x6b, 0xee, - 0x59, 0xc9, 0x05, 0x78, 0xfe, 0xed, 0x7c, 0xab, 0x7a, 0xaa, 0x9b, 0xf4, 0xbf, 0x7b, 0xea, 0x7c, - 0xa9, 0x6a, 0x63, 0xa2, 0x21, 0xb3, 0x21, 0x36, 0xda, 0x1c, 0xb3, 0xfe, 0xf5, 0x40, 0xd8, 0x7a, - 0xe1, 0xfc, 0x54, 0x72, 0xe7, 0xff, 0x62, 0xb4, 0xe5, 0x25, 0xe3, 0xaf, 0x83, 0x74, 0xa2, 0xd6, - 0xb3, 0xe5, 0x69, 0x41, 0xa2, 0xb2, 0x56, 0x66, 0x70, 0xb4, 0xe0, 0x7c, 0xa5, 0x16, 0x27, 0x0f, - 0x8e, 0xe4, 0xf6, 0xe1, 0xae, 0x7e, 0xdc, 0xec, 0xdf, 0x4d, 0x76, 0xc6, 0xc0, 0x39, 0x85, 0xa6, - 0x59, 0x0b, 0xd9, 0x1b, 0x39, 0x53, 0xa6, 0x37, 0xf2, 0xdb, 0x72, 0x4b, 0x4c, 0xab, 0xd7, 0xef, - 0xdf, 0x9a, 0x85, 0xfa, 0x02, 0xde, 0x7d, 0x16, 0xc5, 0x93, 0x43, 0x4a, 0xc7, 0x92, 0x37, 0x3f, - 0x89, 0xff, 0xcb, 0x5a, 0xff, 0x59, 0x81, 0xf7, 0x6e, 0x75, 0xc7, 0xec, 0x4e, 0xa1, 0xa1, 0x4a, - 0x62, 0x92, 0xfb, 0xb4, 0xb4, 0xe1, 0xff, 0xe0, 0xeb, 0x6a, 0x85, 0xbe, 0x98, 0x18, 0x65, 0xf0, - 0x02, 0xda, 0x25, 0x78, 0xcd, 0xbd, 0xdc, 0x5b, 0xbd, 0x97, 0xfd, 0xd2, 0x7b, 0xca, 0xb1, 0x7c, - 0x2b, 0x7f, 0x86, 0xba, 0xc2, 0xfe, 0xb6, 0xc3, 0xa6, 0xce, 0xd5, 0x52, 0x9d, 0x1f, 0x9a, 0xae, - 0xd7, 0xd4, 0x23, 0xbd, 0xa2, 0xc8, 0xf8, 0x86, 0xd2, 0x3a, 0xbf, 0x55, 0xc0, 0x56, 0x2d, 0xfc, - 0x2e, 0x10, 0x24, 0x8d, 0x02, 0x1a, 0xbd, 0x21, 0x63, 0x22, 0x44, 0x14, 0xcf, 0xb8, 0xf5, 0xbe, - 0x9c, 0xf1, 0x74, 0x46, 0x84, 0x3e, 0x32, 0xf8, 0x6e, 0x5b, 0x63, 0xca, 0xcb, 0xfa, 0x10, 0xee, - 0x71, 0xb6, 0x48, 0x43, 0xe2, 0x93, 0xab, 0x24, 0x25, 0x9c, 0x47, 0x2c, 0x46, 0x1e, 0x7d, 0xad, - 0x38, 0xce, 0x71, 0xeb, 0x1d, 0x80, 0x30, 0x25, 0x81, 0x20, 0xfe, 0x64, 0x42, 0x15, 0xb1, 0x96, - 0xd7, 0xd2, 0xc8, 0xd3, 0x09, 0x75, 0x7e, 0xaf, 0xc2, 0xe6, 0x3a, 0x1a, 0x03, 0x68, 0x5e, 0xb2, - 0xf4, 0x62, 0x4a, 0xd9, 0xa5, 0x49, 0xdd, 0xc8, 0xd6, 0x23, 0xe8, 0xe1, 0xfb, 0x2b, 0x53, 0xd5, - 0xf2, 0xba, 0x1a, 0xce, 0x67, 0xf1, 0x11, 0xf4, 0x30, 0x97, 0xdc, 0x50, 0x13, 0xe8, 0x6a, 0x38, - 0x37, 0xdc, 0x83, 0x1e, 0x17, 0x2c, 0xf1, 0x83, 0xa9, 0x20, 0xa9, 0x1f, 0xb2, 0x64, 0x89, 0x57, - 0xb3, 0x23, 0xe1, 0x43, 0x89, 0x1e, 0xb1, 0x64, 0x69, 0x7d, 0x03, 0x5d, 0x3c, 0x86, 0xc8, 0xd3, - 0xae, 0xab, 0xf1, 0xd9, 0x2d, 0xb5, 0xf3, 0xb6, 0xca, 0x7a, 0x1d, 0x7d, 0x2f, 0x4d, 0x86, 0xe6, - 0x88, 0x35, 0x8a, 0x23, 0xa6, 0x8b, 0xaf, 0x0e, 0x8c, 0x58, 0x26, 0x84, 0xdb, 0x77, 0x4d, 0xf1, - 0x25, 0x76, 0x26, 0xa1, 0xaf, 0x87, 0x3f, 0xee, 0x65, 0x91, 0x20, 0x9c, 0xbb, 0x11, 0x1b, 0xe9, - 0xaf, 0xd1, 0x8c, 0x8d, 0x32, 0x31, 0x52, 0x3f, 0x66, 0xa3, 0x9c, 0xc8, 0xab, 0x86, 0x02, 0x3e, - 0xfe, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xed, 0x8c, 0xe6, 0x02, 0x0e, 0x0a, 0x00, 0x00, + // 1071 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5d, 0x6f, 0x1b, 0x45, + 0x17, 0x96, 0x9d, 0xda, 0x89, 0x4f, 0xe2, 0x8f, 0x6e, 0x92, 0x76, 0x5f, 0xbf, 0x02, 0xc2, 0x86, + 0xa6, 0x56, 0x90, 0xd6, 0xa5, 0x08, 0x54, 0xf1, 0x21, 0x91, 0x26, 0x6e, 0x14, 0x0a, 0xa1, 0x5a, + 0x47, 0x41, 0x02, 0x89, 0xd5, 0x66, 0x3d, 0x76, 0x57, 0x19, 0xef, 0x6c, 0x77, 0xc6, 0x9b, 0xb8, + 0xd7, 0xdc, 0xf0, 0x67, 0xb8, 0xe4, 0x92, 0xdf, 0x86, 0x66, 0xe6, 0xcc, 0xee, 0x3a, 0x71, 0xa8, + 0x80, 0xbb, 0x3d, 0xcf, 0xf9, 0x7e, 0xce, 0x99, 0x63, 0x43, 0x3b, 0x13, 0xa1, 0xa0, 0xa3, 0x40, + 0x04, 0x6e, 0x92, 0x32, 0xc1, 0xac, 0x46, 0x0e, 0x74, 0x9b, 0x94, 0x4d, 0x66, 0x22, 0xa2, 0x5a, + 0xd3, 0x6d, 0x4d, 0xe7, 0xfc, 0x0d, 0x0d, 0x85, 0x91, 0x1f, 0x8a, 0xe0, 0x82, 0x12, 0x31, 0x0d, + 0xe2, 0x60, 0x42, 0xd2, 0x22, 0x44, 0xb7, 0x25, 0x58, 0xc2, 0x4a, 0x72, 0x33, 0xe3, 0xe1, 0x6b, + 0x32, 0x45, 0xd1, 0xf9, 0x11, 0xba, 0x83, 0x6b, 0x12, 0xce, 0x04, 0x39, 0x97, 0xa9, 0x0e, 0xd9, + 0x74, 0x1a, 0xc4, 0x23, 0x8f, 0xbc, 0x99, 0x11, 0x2e, 0x2c, 0x0b, 0xee, 0x05, 0xe9, 0x84, 0xdb, + 0x95, 0x9d, 0x95, 0x5e, 0xc3, 0x53, 0xdf, 0xd6, 0x23, 0x68, 0x05, 0xa1, 0x88, 0x58, 0xec, 0x8b, + 0x68, 0x4a, 0xd8, 0x4c, 0xd8, 0xd5, 0x9d, 0x4a, 0x6f, 0xc5, 0x6b, 0x6a, 0xf4, 0x4c, 0x83, 0xce, + 0x21, 0xfc, 0x7f, 0x69, 0x60, 0x9e, 0xb0, 0x98, 0x13, 0xeb, 0x23, 0xa8, 0x91, 0x8c, 0xc4, 0xc2, + 0xae, 0xec, 0x54, 0x7a, 0xeb, 0x4f, 0x5b, 0xae, 0x69, 0x6f, 0x20, 0x51, 0x4f, 0x2b, 0x9d, 0x01, + 0xdc, 0x3f, 0x26, 0xe2, 0x79, 0x10, 0x5e, 0xce, 0x12, 0x6e, 0x8a, 0xea, 0xc2, 0xda, 0x25, 0x99, + 0xf3, 0x24, 0x08, 0x89, 0xf2, 0x6e, 0x78, 0xb9, 0x6c, 0x6d, 0x41, 0x8d, 0xbf, 0x0e, 0xd2, 0x91, + 0xaa, 0xa9, 0xe1, 0x69, 0xc1, 0x39, 0x02, 0xab, 0x1c, 0x06, 0x4b, 0x70, 0x61, 0xf5, 0x42, 0x43, + 0xaa, 0xbf, 0xf5, 0xa7, 0x5b, 0x6e, 0x4e, 0xaa, 0xb6, 0x3d, 0x89, 0xc7, 0xcc, 0x33, 0x46, 0xce, + 0xff, 0xe0, 0xe1, 0x31, 0x11, 0x87, 0x84, 0x52, 0x89, 0x9f, 0x06, 0x53, 0x62, 0x4a, 0x72, 0x9e, + 0x80, 0x7d, 0x5b, 0x85, 0x69, 0xb6, 0xa0, 0x16, 0x4b, 0x00, 0x49, 0xd4, 0x82, 0xd3, 0x53, 0x25, + 0x19, 0x8f, 0x12, 0xdf, 0x21, 0xa1, 0x14, 0xdb, 0x52, 0xdf, 0xce, 0x0b, 0xd8, 0x5c, 0xb0, 0xc4, + 0xb0, 0x7d, 0x68, 0x48, 0xb5, 0x1f, 0xc5, 0x63, 0x86, 0x24, 0x5a, 0x6e, 0x3e, 0xeb, 0xdc, 0x7c, + 0x2d, 0xc4, 0x2f, 0xc7, 0x86, 0x07, 0x18, 0x87, 0x1f, 0xd0, 0x28, 0xe0, 0x45, 0xf5, 0x7f, 0x54, + 0xf2, 0xce, 0x0a, 0x15, 0xa6, 0x39, 0x81, 0xd5, 0x40, 0x43, 0x48, 0x52, 0xdf, 0x2d, 0x96, 0xf4, + 0x0e, 0x27, 0x17, 0xe5, 0x41, 0x2c, 0xd2, 0xb9, 0x67, 0xfc, 0xbb, 0xaf, 0x60, 0xa3, 0xac, 0xb0, + 0x3a, 0xb0, 0x72, 0x49, 0xe6, 0xd8, 0xab, 0xfc, 0xb4, 0xf6, 0xa1, 0x96, 0x05, 0x74, 0x46, 0xd4, + 0xf4, 0xe4, 0x3c, 0x16, 0xfa, 0xd1, 0x69, 0x3c, 0x6d, 0xf2, 0x45, 0xf5, 0x59, 0xc5, 0xd9, 0x56, + 0xd4, 0xbc, 0xc4, 0xe1, 0xe7, 0xfd, 0x9c, 0xc0, 0xd6, 0x22, 0x8c, 0xbd, 0x7c, 0x02, 0x0d, 0xb3, + 0x28, 0xa6, 0x9b, 0xcd, 0x52, 0x37, 0xc6, 0xc1, 0x2b, 0xac, 0x9c, 0x27, 0x6a, 0x4c, 0xb9, 0xe6, + 0xdd, 0x1b, 0x88, 0xe3, 0x2a, 0x3c, 0xf2, 0x71, 0x2d, 0xba, 0xdc, 0x91, 0xba, 0x88, 0xf3, 0x6b, + 0x15, 0x3a, 0xc7, 0x44, 0x0c, 0xd5, 0x63, 0x35, 0x89, 0x9f, 0xc1, 0x86, 0x7e, 0xe7, 0xbe, 0x22, + 0x15, 0x23, 0x6d, 0x17, 0x3c, 0x9d, 0x29, 0xad, 0x26, 0x6a, 0x5d, 0x14, 0x82, 0xf5, 0x00, 0xea, + 0x4a, 0xe4, 0x76, 0x55, 0xad, 0x21, 0x4a, 0xf2, 0x35, 0x93, 0xeb, 0x90, 0xce, 0x46, 0xc4, 0x47, + 0xfd, 0x8a, 0xd2, 0x37, 0x11, 0x3d, 0xd3, 0x66, 0xbb, 0xd0, 0x8c, 0x62, 0x6d, 0x96, 0x45, 0xe4, + 0x8a, 0xdb, 0xf7, 0x76, 0x2a, 0xbd, 0x35, 0x6f, 0x03, 0xc1, 0x73, 0x89, 0x59, 0x3d, 0xe8, 0xa8, + 0x18, 0xbe, 0x5a, 0x71, 0x9f, 0xc5, 0x74, 0x6e, 0xd7, 0x94, 0x5d, 0x4b, 0xe1, 0xea, 0x5d, 0xfc, + 0x10, 0xd3, 0x79, 0x61, 0xc9, 0xa3, 0xb7, 0xc6, 0xb2, 0x5e, 0xb2, 0x1c, 0x4a, 0x58, 0x5a, 0x3a, + 0xaf, 0xd4, 0x05, 0x30, 0x2c, 0x20, 0x99, 0x5f, 0x42, 0x5d, 0x1f, 0x31, 0x24, 0x60, 0xd7, 0xbd, + 0x7d, 0xfd, 0xb4, 0xcb, 0x11, 0x19, 0x47, 0x71, 0x24, 0xef, 0x92, 0x87, 0x2e, 0xce, 0xbe, 0xda, + 0x8e, 0x61, 0x9a, 0x9d, 0x2f, 0x72, 0xbb, 0xec, 0xed, 0x9d, 0xc2, 0xf6, 0x0d, 0x5b, 0xac, 0xe0, + 0x33, 0xd8, 0xe0, 0x69, 0xe6, 0x67, 0xfe, 0x42, 0x1d, 0x9b, 0xae, 0x39, 0xae, 0x25, 0x17, 0xe0, + 0xf9, 0xb7, 0xf3, 0x9d, 0x9a, 0xa9, 0x1e, 0xd2, 0x7f, 0x9e, 0xa9, 0xf3, 0xb5, 0xe2, 0xc6, 0x44, + 0xc3, 0xca, 0x7a, 0x38, 0x68, 0x73, 0x59, 0x3b, 0x37, 0x03, 0xe1, 0xe8, 0x85, 0xf3, 0x73, 0xc9, + 0xfd, 0xdf, 0x1f, 0x57, 0x89, 0x4a, 0xae, 0xcc, 0xe2, 0x68, 0xc1, 0xf9, 0x46, 0x3d, 0x9c, 0x3c, + 0x38, 0x16, 0xb7, 0x0f, 0xab, 0x3a, 0xb9, 0x79, 0x7f, 0xb7, 0xab, 0x33, 0x06, 0xce, 0x29, 0xac, + 0x99, 0x67, 0x21, 0x67, 0x23, 0x77, 0xca, 0xcc, 0x46, 0x7e, 0x5b, 0x6e, 0xa9, 0xd2, 0xea, 0xcd, + 0xfb, 0xb7, 0xe4, 0x41, 0x7d, 0x05, 0xef, 0xbf, 0x88, 0xe2, 0xd1, 0x01, 0xa5, 0x43, 0x59, 0x37, + 0x3f, 0x89, 0xff, 0xc9, 0xb3, 0xfe, 0xb3, 0x02, 0x1f, 0xdc, 0xe9, 0x8e, 0xdd, 0x9d, 0x42, 0x5d, + 0x51, 0x62, 0x9a, 0xfb, 0xbc, 0xf4, 0xc2, 0xdf, 0xe1, 0xeb, 0x6a, 0x85, 0xbe, 0x98, 0x18, 0xa5, + 0xfb, 0x12, 0xd6, 0x4b, 0xf0, 0x92, 0x7b, 0xb9, 0xb7, 0x78, 0x2f, 0x3b, 0xa5, 0x7c, 0xca, 0xb1, + 0x7c, 0x2b, 0x7f, 0x81, 0x9a, 0xc2, 0xfe, 0x76, 0xc2, 0x86, 0xe7, 0x6a, 0x89, 0xe7, 0x47, 0x66, + 0xea, 0x2b, 0x2a, 0x49, 0xbb, 0x20, 0x19, 0x73, 0xe8, 0xdf, 0xd8, 0xdf, 0x2a, 0x60, 0xab, 0x11, + 0x7e, 0x1f, 0x08, 0x92, 0x46, 0x01, 0x8d, 0xde, 0x92, 0x21, 0x11, 0x22, 0x8a, 0x27, 0xdc, 0xfa, + 0x50, 0xee, 0x78, 0x3a, 0x21, 0x42, 0x1f, 0x19, 0xcc, 0xbb, 0xae, 0x31, 0xe5, 0x65, 0x7d, 0x0c, + 0xf7, 0x39, 0x9b, 0xa5, 0x21, 0xf1, 0xc9, 0x75, 0x92, 0x12, 0xce, 0x23, 0x16, 0x63, 0x1d, 0x1d, + 0xad, 0x18, 0xe4, 0xb8, 0xf5, 0x1e, 0x40, 0x98, 0x92, 0x40, 0x10, 0x7f, 0x34, 0xa2, 0xaa, 0xb0, + 0x86, 0xd7, 0xd0, 0xc8, 0xd1, 0x88, 0x3a, 0xbf, 0x57, 0x61, 0x73, 0x59, 0x19, 0x5d, 0x58, 0xbb, + 0x62, 0xe9, 0xe5, 0x98, 0xb2, 0x2b, 0xd3, 0xba, 0x91, 0xad, 0xc7, 0xd0, 0xc6, 0xfc, 0x0b, 0x5b, + 0xd5, 0xf0, 0x5a, 0x1a, 0xce, 0x77, 0xf1, 0x31, 0xb4, 0xb1, 0x97, 0xdc, 0x50, 0x17, 0xd0, 0xd2, + 0x70, 0x6e, 0xb8, 0x07, 0x6d, 0x2e, 0x58, 0xe2, 0x07, 0x63, 0x41, 0x52, 0x3f, 0x64, 0xc9, 0x1c, + 0xaf, 0x66, 0x53, 0xc2, 0x07, 0x12, 0x3d, 0x64, 0xc9, 0xdc, 0xfa, 0x16, 0x5a, 0x78, 0x0c, 0xb1, + 0x4e, 0xbb, 0xa6, 0xd6, 0x67, 0xb7, 0x34, 0xce, 0xbb, 0x98, 0xf5, 0x9a, 0xfa, 0x5e, 0x9a, 0x0e, + 0xcd, 0x11, 0xab, 0x17, 0x47, 0x4c, 0x93, 0xaf, 0x0e, 0x8c, 0x98, 0x27, 0x84, 0xdb, 0xab, 0x86, + 0x7c, 0x89, 0x9d, 0x49, 0xe8, 0x79, 0xef, 0xa7, 0xbd, 0x2c, 0x12, 0x84, 0x73, 0x37, 0x62, 0x7d, + 0xfd, 0xd5, 0x9f, 0xb0, 0x7e, 0x26, 0xfa, 0xea, 0x5f, 0x62, 0x3f, 0x2f, 0xe4, 0xa2, 0xae, 0x80, + 0x4f, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x07, 0x33, 0x99, 0x59, 0xab, 0x0a, 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 5f22024bc5a..c76446f657d 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,30 +29,32 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 362 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xd1, 0x4a, 0x02, 0x41, - 0x14, 0x86, 0xeb, 0x22, 0xa1, 0xc9, 0x30, 0xa6, 0x8b, 0xc0, 0xd2, 0xca, 0x28, 0xb0, 0xc0, 0x0d, - 0x7b, 0x02, 0x93, 0x32, 0x11, 0x84, 0x52, 0xbc, 0x10, 0xba, 0x18, 0x77, 0x4f, 0xb9, 0x30, 0xbb, - 0xa3, 0x7b, 0xc6, 0xa5, 0x1e, 0xb7, 0x37, 0x09, 0x77, 0x9d, 0x71, 0x9b, 0x76, 0xac, 0x3b, 0xe7, - 0x7c, 0xff, 0xf9, 0xe6, 0x67, 0xc0, 0x25, 0x34, 0x96, 0xae, 0xe4, 0x08, 0x51, 0xec, 0xbb, 0xd0, - 0x98, 0x45, 0x42, 0x0a, 0x5a, 0xcc, 0xce, 0xca, 0xa5, 0xe4, 0xe4, 0x31, 0xc9, 0x52, 0xdc, 0x9c, - 0x93, 0x9d, 0xd1, 0x72, 0x44, 0xa7, 0xe4, 0xf0, 0xe1, 0x03, 0xdc, 0x85, 0x84, 0xe4, 0xdc, 0x16, - 0x41, 0xc0, 0x42, 0x8f, 0x5e, 0x36, 0xd6, 0x1b, 0x39, 0xfc, 0x05, 0xe6, 0x0b, 0x40, 0x59, 0xbe, - 0xfa, 0x2b, 0x86, 0x33, 0x11, 0x22, 0xd4, 0xb6, 0x6e, 0xb7, 0x9b, 0x5f, 0x05, 0x52, 0x48, 0xa0, - 0x47, 0x23, 0x72, 0xf4, 0xe8, 0x87, 0x5e, 0x8b, 0xf3, 0xc1, 0x94, 0x45, 0x1e, 0x76, 0xc3, 0x1e, - 0x7c, 0xe2, 0x8c, 0xb9, 0x40, 0xeb, 0x19, 0xa3, 0x25, 0xa3, 0x2e, 0xbf, 0xfe, 0x4f, 0x54, 0x15, - 0xa0, 0xaf, 0xe4, 0xa0, 0x03, 0xb2, 0x0d, 0x9c, 0x77, 0xc3, 0x37, 0xd1, 0x67, 0x01, 0x20, 0xad, - 0x65, 0x0c, 0x26, 0x54, 0xb7, 0x5c, 0x6c, 0xcc, 0x68, 0x7d, 0x9f, 0xec, 0x65, 0x28, 0xad, 0xe4, - 0x6f, 0x29, 0x69, 0xd5, 0x86, 0xb5, 0x6f, 0x4c, 0x4a, 0x2b, 0x80, 0x2d, 0xee, 0x33, 0x04, 0xa4, - 0xe7, 0xbf, 0x97, 0x14, 0x53, 0xde, 0xda, 0xa6, 0x88, 0xd1, 0x55, 0x3f, 0xb9, 0xd1, 0xd5, 0x7c, - 0xe6, 0xaa, 0x0d, 0x6b, 0xdf, 0x33, 0x29, 0x66, 0x00, 0x52, 0xcb, 0x86, 0x6e, 0x79, 0x6a, 0xe5, - 0x5a, 0xf9, 0x44, 0x76, 0x3b, 0x20, 0x07, 0xee, 0x14, 0x02, 0x46, 0x8f, 0x7f, 0xe6, 0xd3, 0xa9, - 0x92, 0x9d, 0xe4, 0x43, 0x6d, 0x1a, 0x92, 0xfd, 0xe5, 0x38, 0x8a, 0x47, 0x2b, 0x9b, 0x71, 0xfb, - 0x9a, 0x28, 0xe3, 0x99, 0x3d, 0x60, 0xf4, 0x1b, 0xb2, 0x09, 0x07, 0x69, 0xf6, 0x4b, 0xa7, 0x96, - 0x7e, 0x0a, 0x6a, 0x53, 0x8f, 0x10, 0x3d, 0x46, 0x9a, 0x9b, 0xd6, 0x0f, 0x57, 0xb1, 0x50, 0x25, - 0xbb, 0xbf, 0x19, 0xd7, 0x63, 0x5f, 0x02, 0x62, 0xc3, 0x17, 0x4e, 0xfa, 0xcb, 0x79, 0x17, 0x4e, - 0x2c, 0x9d, 0xe4, 0x6f, 0xef, 0x64, 0x3f, 0x0a, 0x93, 0x42, 0x32, 0xbb, 0xfb, 0x0e, 0x00, 0x00, - 0xff, 0xff, 0x19, 0x7f, 0xf4, 0xe7, 0x3f, 0x04, 0x00, 0x00, + // 385 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xc1, 0x4e, 0xea, 0x40, + 0x14, 0x86, 0xef, 0x5d, 0x5c, 0x6e, 0x1c, 0x31, 0x98, 0x71, 0x61, 0x82, 0x80, 0x8a, 0xd1, 0x04, + 0x4d, 0xa8, 0xc1, 0x27, 0x00, 0xa2, 0x48, 0x48, 0x48, 0x14, 0xc2, 0x82, 0xc4, 0xc5, 0xd0, 0x1e, + 0xa5, 0xb1, 0xed, 0x94, 0x9e, 0xa1, 0xd1, 0x97, 0xf2, 0x19, 0x0d, 0x2d, 0x33, 0x94, 0x81, 0x41, + 0x77, 0xed, 0xff, 0x9d, 0xf3, 0xf5, 0x4f, 0x3a, 0x19, 0x42, 0x63, 0x61, 0x0b, 0x0f, 0x21, 0x8a, + 0x5d, 0x1b, 0xea, 0x61, 0xc4, 0x05, 0xa7, 0xf9, 0x6c, 0x56, 0x2c, 0x24, 0x6f, 0x0e, 0x13, 0x2c, + 0xc5, 0x8d, 0x19, 0xf9, 0x37, 0x5a, 0x44, 0x74, 0x4a, 0x8e, 0xee, 0x3f, 0xc0, 0x9e, 0x0b, 0x48, + 0xde, 0xdb, 0xdc, 0xf7, 0x59, 0xe0, 0xd0, 0xcb, 0xfa, 0x6a, 0x63, 0x0b, 0x7f, 0x86, 0xd9, 0x1c, + 0x50, 0x14, 0xaf, 0x7e, 0x1a, 0xc3, 0x90, 0x07, 0x08, 0xd5, 0x3f, 0xb7, 0x7f, 0x1b, 0x5f, 0xff, + 0x49, 0x2e, 0x81, 0x0e, 0x8d, 0xc8, 0xf1, 0x83, 0x1b, 0x38, 0x4d, 0xcf, 0x1b, 0x4c, 0x59, 0xe4, + 0x60, 0x37, 0xe8, 0xc1, 0x27, 0x86, 0xcc, 0x06, 0x5a, 0xcb, 0x18, 0x0d, 0x33, 0xf2, 0xe3, 0xd7, + 0xbf, 0x19, 0x95, 0x05, 0x68, 0x8f, 0x90, 0x0e, 0x88, 0x16, 0xb3, 0xdf, 0xe7, 0x21, 0xd2, 0x52, + 0x66, 0x77, 0x15, 0x4b, 0x73, 0xd9, 0x40, 0x95, 0xec, 0x85, 0x1c, 0x76, 0x40, 0xb4, 0xc1, 0xf3, + 0xba, 0xc1, 0x2b, 0xef, 0x33, 0x1f, 0x90, 0x56, 0xd7, 0x97, 0xd6, 0xa0, 0x14, 0x5f, 0xec, 0x9c, + 0x51, 0xfa, 0x3e, 0xd9, 0xcf, 0x50, 0x5a, 0xde, 0xbe, 0x25, 0xa5, 0x15, 0x13, 0x56, 0xbe, 0x31, + 0x29, 0x2c, 0x01, 0x36, 0x3d, 0x97, 0x21, 0x20, 0x3d, 0xdf, 0x5c, 0x92, 0x4c, 0x7a, 0xab, 0xbb, + 0x46, 0xb4, 0xae, 0xea, 0xff, 0x69, 0x5d, 0xf5, 0x7f, 0x56, 0x31, 0x61, 0xe5, 0x7b, 0x22, 0xf9, + 0x0c, 0x40, 0x6a, 0xd8, 0x50, 0x2d, 0x4f, 0x8d, 0x5c, 0x29, 0x1f, 0xc9, 0x5e, 0x07, 0xc4, 0xc0, + 0x9e, 0x82, 0xcf, 0xe8, 0xc9, 0xfa, 0x7c, 0x9a, 0x4a, 0x59, 0x69, 0x3b, 0x54, 0xa6, 0x21, 0x39, + 0x58, 0xc4, 0x51, 0x3c, 0x5a, 0xda, 0xb4, 0xaf, 0xaf, 0x88, 0x34, 0x9e, 0x99, 0x07, 0xb4, 0x7e, + 0x43, 0x36, 0xf1, 0x40, 0xe8, 0xfd, 0xd2, 0xd4, 0xd0, 0x4f, 0x42, 0xed, 0x90, 0xa7, 0xf1, 0xc6, + 0x21, 0x5f, 0xc6, 0x86, 0x43, 0xae, 0xa8, 0x94, 0xb5, 0x6e, 0xc6, 0xb5, 0xd8, 0x15, 0x80, 0x58, + 0x77, 0xb9, 0x95, 0x3e, 0x59, 0x6f, 0xdc, 0x8a, 0x85, 0x95, 0xdc, 0x21, 0x56, 0xf6, 0x86, 0x99, + 0xe4, 0x92, 0xec, 0xee, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x78, 0x06, 0x02, 0xde, 0x8c, 0x04, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -169,6 +171,8 @@ type VtctldClient interface { // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. FindAllShardsInKeyspace(ctx context.Context, in *vtctldata.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.FindAllShardsInKeyspaceResponse, error) + // GetBackups returns all the backups for a shard. + GetBackups(ctx context.Context, in *vtctldata.GetBackupsRequest, opts ...grpc.CallOption) (*vtctldata.GetBackupsResponse, error) // GetCellInfoNames returns all the cells for which we have a CellInfo object, // meaning we have a topology service registered. GetCellInfoNames(ctx context.Context, in *vtctldata.GetCellInfoNamesRequest, opts ...grpc.CallOption) (*vtctldata.GetCellInfoNamesResponse, error) @@ -209,6 +213,15 @@ func (c *vtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldat return out, nil } +func (c *vtctldClient) GetBackups(ctx context.Context, in *vtctldata.GetBackupsRequest, opts ...grpc.CallOption) (*vtctldata.GetBackupsResponse, error) { + out := new(vtctldata.GetBackupsResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetBackups", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) GetCellInfoNames(ctx context.Context, in *vtctldata.GetCellInfoNamesRequest, opts ...grpc.CallOption) (*vtctldata.GetCellInfoNamesResponse, error) { out := new(vtctldata.GetCellInfoNamesResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetCellInfoNames", in, out, opts...) @@ -295,6 +308,8 @@ type VtctldServer interface { // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. FindAllShardsInKeyspace(context.Context, *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) + // GetBackups returns all the backups for a shard. + GetBackups(context.Context, *vtctldata.GetBackupsRequest) (*vtctldata.GetBackupsResponse, error) // GetCellInfoNames returns all the cells for which we have a CellInfo object, // meaning we have a topology service registered. GetCellInfoNames(context.Context, *vtctldata.GetCellInfoNamesRequest) (*vtctldata.GetCellInfoNamesResponse, error) @@ -325,6 +340,9 @@ type UnimplementedVtctldServer struct { func (*UnimplementedVtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method FindAllShardsInKeyspace not implemented") } +func (*UnimplementedVtctldServer) GetBackups(ctx context.Context, req *vtctldata.GetBackupsRequest) (*vtctldata.GetBackupsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBackups not implemented") +} func (*UnimplementedVtctldServer) GetCellInfoNames(ctx context.Context, req *vtctldata.GetCellInfoNamesRequest) (*vtctldata.GetCellInfoNamesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetCellInfoNames not implemented") } @@ -375,6 +393,24 @@ func _Vtctld_FindAllShardsInKeyspace_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _Vtctld_GetBackups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetBackupsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetBackups(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetBackups", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetBackups(ctx, req.(*vtctldata.GetBackupsRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_GetCellInfoNames_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.GetCellInfoNamesRequest) if err := dec(in); err != nil { @@ -545,6 +581,10 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "FindAllShardsInKeyspace", Handler: _Vtctld_FindAllShardsInKeyspace_Handler, }, + { + MethodName: "GetBackups", + Handler: _Vtctld_GetBackups_Handler, + }, { MethodName: "GetCellInfoNames", Handler: _Vtctld_GetCellInfoNames_Handler, diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index d82f5ae262f..994124545d1 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -37,6 +37,15 @@ func (client *gRPCVtctldClient) FindAllShardsInKeyspace(ctx context.Context, in return client.c.FindAllShardsInKeyspace(ctx, in, opts...) } +// GetBackups is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetBackups(ctx context.Context, in *vtctldatapb.GetBackupsRequest, opts ...grpc.CallOption) (*vtctldatapb.GetBackupsResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetBackups(ctx, in, opts...) +} + // GetCellInfo is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) GetCellInfo(ctx context.Context, in *vtctldatapb.GetCellInfoRequest, opts ...grpc.CallOption) (*vtctldatapb.GetCellInfoResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index cbef9733ab6..28db37f564f 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -19,14 +19,18 @@ package grpcvtctldserver import ( "context" "fmt" + "path/filepath" "time" "google.golang.org/grpc" + "vitess.io/vitess/go/vt/mysqlctl/backupstorage" + "vitess.io/vitess/go/vt/mysqlctl/mysqlctlproto" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tmclient" + mysqlctlpb "vitess.io/vitess/go/vt/proto/mysqlctl" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" @@ -66,6 +70,32 @@ func (s *VtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctlda }, nil } +// GetBackups is part of the vtctldservicepb.VtctldServer interface. +func (s *VtctldServer) GetBackups(ctx context.Context, req *vtctldatapb.GetBackupsRequest) (*vtctldatapb.GetBackupsResponse, error) { + bs, err := backupstorage.GetBackupStorage() + if err != nil { + return nil, err + } + + defer bs.Close() + + bucket := filepath.Join(req.Keyspace, req.Shard) + bhs, err := bs.ListBackups(ctx, bucket) + if err != nil { + return nil, err + } + + resp := &vtctldatapb.GetBackupsResponse{ + Backups: make([]*mysqlctlpb.BackupInfo, len(bhs)), + } + + for i, bh := range bhs { + resp.Backups[i] = mysqlctlproto.BackupHandleToProto(bh) + } + + return resp, nil +} + // GetCellInfoNames is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) GetCellInfoNames(ctx context.Context, req *vtctldatapb.GetCellInfoNamesRequest) (*vtctldatapb.GetCellInfoNamesResponse, error) { names, err := s.ts.GetCellInfoNames(ctx) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index bff3ac4e430..af2cf77ebe5 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -26,12 +26,14 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" "vitess.io/vitess/go/vt/vttablet/tmclient" + mysqlctlpb "vitess.io/vitess/go/vt/proto/mysqlctl" querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -41,6 +43,7 @@ import ( func init() { *tmclient.TabletManagerProtocol = testutil.TabletManagerClientProtocol + *backupstorage.BackupStorageImplementation = testutil.BackupStorageImplementation } func TestFindAllShardsInKeyspace(t *testing.T) { @@ -82,6 +85,58 @@ func TestFindAllShardsInKeyspace(t *testing.T) { assert.Error(t, err) } +func TestGetBackups(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer() + vtctld := NewVtctldServer(ts) + + testutil.BackupStorage.Backups = map[string][]string{ + "testkeyspace/-": {"backup1", "backup2"}, + } + + expected := &vtctldatapb.GetBackupsResponse{ + Backups: []*mysqlctlpb.BackupInfo{ + { + Directory: "testkeyspace/-", + Name: "backup1", + }, + { + Directory: "testkeyspace/-", + Name: "backup2", + }, + }, + } + + resp, err := vtctld.GetBackups(ctx, &vtctldatapb.GetBackupsRequest{ + Keyspace: "testkeyspace", + Shard: "-", + }) + assert.NoError(t, err) + assert.Equal(t, expected, resp) + + t.Run("no backupstorage", func(t *testing.T) { + *backupstorage.BackupStorageImplementation = "doesnotexist" + defer func() { *backupstorage.BackupStorageImplementation = testutil.BackupStorageImplementation }() + + _, err := vtctld.GetBackups(ctx, &vtctldatapb.GetBackupsRequest{ + Keyspace: "testkeyspace", + Shard: "-", + }) + assert.Error(t, err) + }) + + t.Run("listbackups error", func(t *testing.T) { + testutil.BackupStorage.ListBackupsError = assert.AnError + defer func() { testutil.BackupStorage.ListBackupsError = nil }() + + _, err := vtctld.GetBackups(ctx, &vtctldatapb.GetBackupsRequest{ + Keyspace: "testkeyspace", + Shard: "-", + }) + assert.Error(t, err) + }) +} + func TestGetKeyspace(t *testing.T) { ctx := context.Background() ts := memorytopo.NewServer("cell1") diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go new file mode 100644 index 00000000000..a871cbfdbf7 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_backupstorage.go @@ -0,0 +1,92 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import ( + "context" + "sort" + + "vitess.io/vitess/go/vt/mysqlctl/backupstorage" +) + +type backupStorage struct { + backupstorage.BackupStorage + + // Backups is a mapping of directory to list of backup names stored in that + // directory. + Backups map[string][]string + // ListBackupsError is returned from ListBackups when it is non-nil. + ListBackupsError error +} + +// ListBackups is part of the backupstorage.BackupStorage interface. +func (bs *backupStorage) ListBackups(ctx context.Context, dir string) ([]backupstorage.BackupHandle, error) { + if bs.ListBackupsError != nil { + return nil, bs.ListBackupsError + } + + handles := []backupstorage.BackupHandle{} + + for k, v := range bs.Backups { + if k == dir { + for _, name := range v { + handles = append(handles, &backupHandle{directory: k, name: name}) + } + } + } + + sort.Sort(handlesByName(handles)) + + return handles, nil +} + +// Close is part of the backupstorage.BackupStorage interface. +func (bs *backupStorage) Close() error { return nil } + +// backupHandle implements a subset of the backupstorage.backupHandle interface. +type backupHandle struct { + backupstorage.BackupHandle + + directory string + name string +} + +func (bh *backupHandle) Directory() string { return bh.directory } +func (bh *backupHandle) Name() string { return bh.name } + +// handlesByName implements the sort interface for backup handles by Name(). +type handlesByName []backupstorage.BackupHandle + +func (a handlesByName) Len() int { return len(a) } +func (a handlesByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a handlesByName) Less(i, j int) bool { return a[i].Name() < a[j].Name() } + +// BackupStorageImplementation is the name this package registers its test +// backupstorage.BackupStorage implementation as. Users should set +// *backupstorage.BackupStorageImplementation to this value before use. +const BackupStorageImplementation = "grpcvtctldserver.testutil" + +// BackupStorage is the singleton test backupstorage.BackupStorage intastnce. It +// is public and singleton to allow tests to both mutate and assert against its +// state. +var BackupStorage = &backupStorage{ + Backups: map[string][]string{}, +} + +func init() { + backupstorage.BackupStorageMap[BackupStorageImplementation] = BackupStorage +} diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go index facaaf4f5bc..938e71e9595 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go @@ -27,15 +27,15 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) -// TestTabletManagerClient implements the tmclient.TabletManagerClient for +// tabletManagerClient implements the tmclient.TabletManagerClient for // testing. It allows users to mock various tmclient methods. -type TestTabletManagerClient struct { +type tabletManagerClient struct { tmclient.TabletManagerClient Schemas map[string]*tabletmanagerdatapb.SchemaDefinition } // GetSchema is part of the tmclient.TabletManagerClient interface. -func (c *TestTabletManagerClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tablets []string, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { +func (c *tabletManagerClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tablets []string, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { key := topoproto.TabletAliasString(tablet.Alias) schema, ok := c.Schemas[key] @@ -53,7 +53,7 @@ const TabletManagerClientProtocol = "grpcvtctldserver.testutil" // TabletManagerClient is the singleton test client instance. It is public and // singleton to allow tests to mutate and verify its state. -var TabletManagerClient = &TestTabletManagerClient{ +var TabletManagerClient = &tabletManagerClient{ Schemas: map[string]*tabletmanagerdatapb.SchemaDefinition{}, } diff --git a/proto/mysqlctl.proto b/proto/mysqlctl.proto index 274f82e74c6..adcd921d004 100644 --- a/proto/mysqlctl.proto +++ b/proto/mysqlctl.proto @@ -54,3 +54,9 @@ service MysqlCtl { rpc ReinitConfig(ReinitConfigRequest) returns (ReinitConfigResponse) {}; rpc RefreshConfig(RefreshConfigRequest) returns (RefreshConfigResponse) {}; } + +// BackupInfo is the read-only attributes of a mysqlctl/backupstorage.BackupHandle. +message BackupInfo { + string name = 1; + string directory = 2; +} diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index f17041cf296..c8fe5a5decd 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -23,6 +23,7 @@ option go_package = "vitess.io/vitess/go/vt/proto/vtctldata"; package vtctldata; import "logutil.proto"; +import "mysqlctl.proto"; import "tabletmanagerdata.proto"; import "topodata.proto"; import "vschema.proto"; @@ -39,6 +40,15 @@ message ExecuteVtctlCommandResponse { logutil.Event event = 1; } +message GetBackupsRequest { + string keyspace = 1; + string shard = 2; +} + +message GetBackupsResponse { + repeated mysqlctl.BackupInfo backups = 1; +} + message GetCellInfoNamesRequest { } diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 69acb88f181..8ca3f581b21 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -34,6 +34,8 @@ service Vtctld { // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. rpc FindAllShardsInKeyspace(vtctldata.FindAllShardsInKeyspaceRequest) returns (vtctldata.FindAllShardsInKeyspaceResponse) {}; + // GetBackups returns all the backups for a shard. + rpc GetBackups(vtctldata.GetBackupsRequest) returns (vtctldata.GetBackupsResponse) {}; // GetCellInfoNames returns all the cells for which we have a CellInfo object, // meaning we have a topology service registered. rpc GetCellInfoNames(vtctldata.GetCellInfoNamesRequest) returns (vtctldata.GetCellInfoNamesResponse) {}; From b7b5a2d0cca974e96a842f6cd9086dc2b2bcbd39 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Sun, 24 Jan 2021 10:05:09 +0100 Subject: [PATCH 12/21] Merge pull request #7360 from tinyspeck/am_vtctld_getvschema [vtctld] Migrate GetVSchema to VtctldServer --- .../vtctldclient/internal/command/vschemas.go | 27 ++ go/vt/proto/vtctldata/vtctldata.pb.go | 230 ++++++++++++------ go/vt/proto/vtctlservice/vtctlservice.pb.go | 90 +++++-- go/vt/vtctl/grpcvtctldclient/client_gen.go | 9 + go/vt/vtctl/grpcvtctldserver/server.go | 12 + go/vt/vtctl/grpcvtctldserver/server_test.go | 40 +++ proto/vtctldata.proto | 8 + proto/vtctlservice.proto | 2 + 8 files changed, 318 insertions(+), 100 deletions(-) diff --git a/go/cmd/vtctldclient/internal/command/vschemas.go b/go/cmd/vtctldclient/internal/command/vschemas.go index 1dae2fdef56..1c5e848e6d2 100644 --- a/go/cmd/vtctldclient/internal/command/vschemas.go +++ b/go/cmd/vtctldclient/internal/command/vschemas.go @@ -33,6 +33,12 @@ var ( Args: cobra.ExactArgs(1), RunE: commandGetSrvVSchema, } + // GetVSchema makes a GetVSchema gRPC call to a vtctld. + GetVSchema = &cobra.Command{ + Use: "GetVSchema keyspace", + Args: cobra.ExactArgs(1), + RunE: commandGetVSchema, + } ) func commandGetSrvVSchema(cmd *cobra.Command, args []string) error { @@ -55,6 +61,27 @@ func commandGetSrvVSchema(cmd *cobra.Command, args []string) error { return nil } +func commandGetVSchema(cmd *cobra.Command, args []string) error { + keyspace := cmd.Flags().Arg(0) + + resp, err := client.GetVSchema(commandCtx, &vtctldatapb.GetVSchemaRequest{ + Keyspace: keyspace, + }) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.VSchema) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + func init() { Root.AddCommand(GetSrvVSchema) + Root.AddCommand(GetVSchema) } diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 73307d4733b..5b42a77c754 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -950,6 +950,84 @@ func (m *GetTabletsResponse) GetTablets() []*topodata.Tablet { return nil } +type GetVSchemaRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetVSchemaRequest) Reset() { *m = GetVSchemaRequest{} } +func (m *GetVSchemaRequest) String() string { return proto.CompactTextString(m) } +func (*GetVSchemaRequest) ProtoMessage() {} +func (*GetVSchemaRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{22} +} + +func (m *GetVSchemaRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetVSchemaRequest.Unmarshal(m, b) +} +func (m *GetVSchemaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetVSchemaRequest.Marshal(b, m, deterministic) +} +func (m *GetVSchemaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetVSchemaRequest.Merge(m, src) +} +func (m *GetVSchemaRequest) XXX_Size() int { + return xxx_messageInfo_GetVSchemaRequest.Size(m) +} +func (m *GetVSchemaRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetVSchemaRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetVSchemaRequest proto.InternalMessageInfo + +func (m *GetVSchemaRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +type GetVSchemaResponse struct { + VSchema *vschema.Keyspace `protobuf:"bytes,1,opt,name=v_schema,json=vSchema,proto3" json:"v_schema,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetVSchemaResponse) Reset() { *m = GetVSchemaResponse{} } +func (m *GetVSchemaResponse) String() string { return proto.CompactTextString(m) } +func (*GetVSchemaResponse) ProtoMessage() {} +func (*GetVSchemaResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{23} +} + +func (m *GetVSchemaResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetVSchemaResponse.Unmarshal(m, b) +} +func (m *GetVSchemaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetVSchemaResponse.Marshal(b, m, deterministic) +} +func (m *GetVSchemaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetVSchemaResponse.Merge(m, src) +} +func (m *GetVSchemaResponse) XXX_Size() int { + return xxx_messageInfo_GetVSchemaResponse.Size(m) +} +func (m *GetVSchemaResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetVSchemaResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetVSchemaResponse proto.InternalMessageInfo + +func (m *GetVSchemaResponse) GetVSchema() *vschema.Keyspace { + if m != nil { + return m.VSchema + } + return nil +} + type Keyspace struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Keyspace *topodata.Keyspace `protobuf:"bytes,2,opt,name=keyspace,proto3" json:"keyspace,omitempty"` @@ -962,7 +1040,7 @@ func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{22} + return fileDescriptor_f41247b323a1ab2e, []int{24} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { @@ -1008,7 +1086,7 @@ func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInK func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{23} + return fileDescriptor_f41247b323a1ab2e, []int{25} } func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -1047,7 +1125,7 @@ func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsIn func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{24} + return fileDescriptor_f41247b323a1ab2e, []int{26} } func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -1088,7 +1166,7 @@ func (m *Shard) Reset() { *m = Shard{} } func (m *Shard) String() string { return proto.CompactTextString(m) } func (*Shard) ProtoMessage() {} func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{25} + return fileDescriptor_f41247b323a1ab2e, []int{27} } func (m *Shard) XXX_Unmarshal(b []byte) error { @@ -1148,7 +1226,7 @@ func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettin func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } func (*TableMaterializeSettings) ProtoMessage() {} func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{26} + return fileDescriptor_f41247b323a1ab2e, []int{28} } func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -1211,7 +1289,7 @@ func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } func (*MaterializeSettings) ProtoMessage() {} func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{27} + return fileDescriptor_f41247b323a1ab2e, []int{29} } func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -1305,6 +1383,8 @@ func init() { proto.RegisterType((*GetTabletResponse)(nil), "vtctldata.GetTabletResponse") proto.RegisterType((*GetTabletsRequest)(nil), "vtctldata.GetTabletsRequest") proto.RegisterType((*GetTabletsResponse)(nil), "vtctldata.GetTabletsResponse") + proto.RegisterType((*GetVSchemaRequest)(nil), "vtctldata.GetVSchemaRequest") + proto.RegisterType((*GetVSchemaResponse)(nil), "vtctldata.GetVSchemaResponse") proto.RegisterType((*Keyspace)(nil), "vtctldata.Keyspace") proto.RegisterType((*FindAllShardsInKeyspaceRequest)(nil), "vtctldata.FindAllShardsInKeyspaceRequest") proto.RegisterType((*FindAllShardsInKeyspaceResponse)(nil), "vtctldata.FindAllShardsInKeyspaceResponse") @@ -1317,72 +1397,74 @@ func init() { func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 1071 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5d, 0x6f, 0x1b, 0x45, - 0x17, 0x96, 0x9d, 0xda, 0x89, 0x4f, 0xe2, 0x8f, 0x6e, 0x92, 0x76, 0x5f, 0xbf, 0x02, 0xc2, 0x86, - 0xa6, 0x56, 0x90, 0xd6, 0xa5, 0x08, 0x54, 0xf1, 0x21, 0x91, 0x26, 0x6e, 0x14, 0x0a, 0xa1, 0x5a, - 0x47, 0x41, 0x02, 0x89, 0xd5, 0x66, 0x3d, 0x76, 0x57, 0x19, 0xef, 0x6c, 0x77, 0xc6, 0x9b, 0xb8, - 0xd7, 0xdc, 0xf0, 0x67, 0xb8, 0xe4, 0x92, 0xdf, 0x86, 0x66, 0xe6, 0xcc, 0xee, 0x3a, 0x71, 0xa8, - 0x80, 0xbb, 0x3d, 0xcf, 0xf9, 0x7e, 0xce, 0x99, 0x63, 0x43, 0x3b, 0x13, 0xa1, 0xa0, 0xa3, 0x40, - 0x04, 0x6e, 0x92, 0x32, 0xc1, 0xac, 0x46, 0x0e, 0x74, 0x9b, 0x94, 0x4d, 0x66, 0x22, 0xa2, 0x5a, - 0xd3, 0x6d, 0x4d, 0xe7, 0xfc, 0x0d, 0x0d, 0x85, 0x91, 0x1f, 0x8a, 0xe0, 0x82, 0x12, 0x31, 0x0d, - 0xe2, 0x60, 0x42, 0xd2, 0x22, 0x44, 0xb7, 0x25, 0x58, 0xc2, 0x4a, 0x72, 0x33, 0xe3, 0xe1, 0x6b, - 0x32, 0x45, 0xd1, 0xf9, 0x11, 0xba, 0x83, 0x6b, 0x12, 0xce, 0x04, 0x39, 0x97, 0xa9, 0x0e, 0xd9, - 0x74, 0x1a, 0xc4, 0x23, 0x8f, 0xbc, 0x99, 0x11, 0x2e, 0x2c, 0x0b, 0xee, 0x05, 0xe9, 0x84, 0xdb, - 0x95, 0x9d, 0x95, 0x5e, 0xc3, 0x53, 0xdf, 0xd6, 0x23, 0x68, 0x05, 0xa1, 0x88, 0x58, 0xec, 0x8b, - 0x68, 0x4a, 0xd8, 0x4c, 0xd8, 0xd5, 0x9d, 0x4a, 0x6f, 0xc5, 0x6b, 0x6a, 0xf4, 0x4c, 0x83, 0xce, - 0x21, 0xfc, 0x7f, 0x69, 0x60, 0x9e, 0xb0, 0x98, 0x13, 0xeb, 0x23, 0xa8, 0x91, 0x8c, 0xc4, 0xc2, - 0xae, 0xec, 0x54, 0x7a, 0xeb, 0x4f, 0x5b, 0xae, 0x69, 0x6f, 0x20, 0x51, 0x4f, 0x2b, 0x9d, 0x01, - 0xdc, 0x3f, 0x26, 0xe2, 0x79, 0x10, 0x5e, 0xce, 0x12, 0x6e, 0x8a, 0xea, 0xc2, 0xda, 0x25, 0x99, - 0xf3, 0x24, 0x08, 0x89, 0xf2, 0x6e, 0x78, 0xb9, 0x6c, 0x6d, 0x41, 0x8d, 0xbf, 0x0e, 0xd2, 0x91, - 0xaa, 0xa9, 0xe1, 0x69, 0xc1, 0x39, 0x02, 0xab, 0x1c, 0x06, 0x4b, 0x70, 0x61, 0xf5, 0x42, 0x43, - 0xaa, 0xbf, 0xf5, 0xa7, 0x5b, 0x6e, 0x4e, 0xaa, 0xb6, 0x3d, 0x89, 0xc7, 0xcc, 0x33, 0x46, 0xce, - 0xff, 0xe0, 0xe1, 0x31, 0x11, 0x87, 0x84, 0x52, 0x89, 0x9f, 0x06, 0x53, 0x62, 0x4a, 0x72, 0x9e, - 0x80, 0x7d, 0x5b, 0x85, 0x69, 0xb6, 0xa0, 0x16, 0x4b, 0x00, 0x49, 0xd4, 0x82, 0xd3, 0x53, 0x25, - 0x19, 0x8f, 0x12, 0xdf, 0x21, 0xa1, 0x14, 0xdb, 0x52, 0xdf, 0xce, 0x0b, 0xd8, 0x5c, 0xb0, 0xc4, - 0xb0, 0x7d, 0x68, 0x48, 0xb5, 0x1f, 0xc5, 0x63, 0x86, 0x24, 0x5a, 0x6e, 0x3e, 0xeb, 0xdc, 0x7c, - 0x2d, 0xc4, 0x2f, 0xc7, 0x86, 0x07, 0x18, 0x87, 0x1f, 0xd0, 0x28, 0xe0, 0x45, 0xf5, 0x7f, 0x54, - 0xf2, 0xce, 0x0a, 0x15, 0xa6, 0x39, 0x81, 0xd5, 0x40, 0x43, 0x48, 0x52, 0xdf, 0x2d, 0x96, 0xf4, - 0x0e, 0x27, 0x17, 0xe5, 0x41, 0x2c, 0xd2, 0xb9, 0x67, 0xfc, 0xbb, 0xaf, 0x60, 0xa3, 0xac, 0xb0, - 0x3a, 0xb0, 0x72, 0x49, 0xe6, 0xd8, 0xab, 0xfc, 0xb4, 0xf6, 0xa1, 0x96, 0x05, 0x74, 0x46, 0xd4, - 0xf4, 0xe4, 0x3c, 0x16, 0xfa, 0xd1, 0x69, 0x3c, 0x6d, 0xf2, 0x45, 0xf5, 0x59, 0xc5, 0xd9, 0x56, - 0xd4, 0xbc, 0xc4, 0xe1, 0xe7, 0xfd, 0x9c, 0xc0, 0xd6, 0x22, 0x8c, 0xbd, 0x7c, 0x02, 0x0d, 0xb3, - 0x28, 0xa6, 0x9b, 0xcd, 0x52, 0x37, 0xc6, 0xc1, 0x2b, 0xac, 0x9c, 0x27, 0x6a, 0x4c, 0xb9, 0xe6, - 0xdd, 0x1b, 0x88, 0xe3, 0x2a, 0x3c, 0xf2, 0x71, 0x2d, 0xba, 0xdc, 0x91, 0xba, 0x88, 0xf3, 0x6b, - 0x15, 0x3a, 0xc7, 0x44, 0x0c, 0xd5, 0x63, 0x35, 0x89, 0x9f, 0xc1, 0x86, 0x7e, 0xe7, 0xbe, 0x22, - 0x15, 0x23, 0x6d, 0x17, 0x3c, 0x9d, 0x29, 0xad, 0x26, 0x6a, 0x5d, 0x14, 0x82, 0xf5, 0x00, 0xea, - 0x4a, 0xe4, 0x76, 0x55, 0xad, 0x21, 0x4a, 0xf2, 0x35, 0x93, 0xeb, 0x90, 0xce, 0x46, 0xc4, 0x47, - 0xfd, 0x8a, 0xd2, 0x37, 0x11, 0x3d, 0xd3, 0x66, 0xbb, 0xd0, 0x8c, 0x62, 0x6d, 0x96, 0x45, 0xe4, - 0x8a, 0xdb, 0xf7, 0x76, 0x2a, 0xbd, 0x35, 0x6f, 0x03, 0xc1, 0x73, 0x89, 0x59, 0x3d, 0xe8, 0xa8, - 0x18, 0xbe, 0x5a, 0x71, 0x9f, 0xc5, 0x74, 0x6e, 0xd7, 0x94, 0x5d, 0x4b, 0xe1, 0xea, 0x5d, 0xfc, - 0x10, 0xd3, 0x79, 0x61, 0xc9, 0xa3, 0xb7, 0xc6, 0xb2, 0x5e, 0xb2, 0x1c, 0x4a, 0x58, 0x5a, 0x3a, - 0xaf, 0xd4, 0x05, 0x30, 0x2c, 0x20, 0x99, 0x5f, 0x42, 0x5d, 0x1f, 0x31, 0x24, 0x60, 0xd7, 0xbd, - 0x7d, 0xfd, 0xb4, 0xcb, 0x11, 0x19, 0x47, 0x71, 0x24, 0xef, 0x92, 0x87, 0x2e, 0xce, 0xbe, 0xda, - 0x8e, 0x61, 0x9a, 0x9d, 0x2f, 0x72, 0xbb, 0xec, 0xed, 0x9d, 0xc2, 0xf6, 0x0d, 0x5b, 0xac, 0xe0, - 0x33, 0xd8, 0xe0, 0x69, 0xe6, 0x67, 0xfe, 0x42, 0x1d, 0x9b, 0xae, 0x39, 0xae, 0x25, 0x17, 0xe0, - 0xf9, 0xb7, 0xf3, 0x9d, 0x9a, 0xa9, 0x1e, 0xd2, 0x7f, 0x9e, 0xa9, 0xf3, 0xb5, 0xe2, 0xc6, 0x44, - 0xc3, 0xca, 0x7a, 0x38, 0x68, 0x73, 0x59, 0x3b, 0x37, 0x03, 0xe1, 0xe8, 0x85, 0xf3, 0x73, 0xc9, - 0xfd, 0xdf, 0x1f, 0x57, 0x89, 0x4a, 0xae, 0xcc, 0xe2, 0x68, 0xc1, 0xf9, 0x46, 0x3d, 0x9c, 0x3c, - 0x38, 0x16, 0xb7, 0x0f, 0xab, 0x3a, 0xb9, 0x79, 0x7f, 0xb7, 0xab, 0x33, 0x06, 0xce, 0x29, 0xac, - 0x99, 0x67, 0x21, 0x67, 0x23, 0x77, 0xca, 0xcc, 0x46, 0x7e, 0x5b, 0x6e, 0xa9, 0xd2, 0xea, 0xcd, - 0xfb, 0xb7, 0xe4, 0x41, 0x7d, 0x05, 0xef, 0xbf, 0x88, 0xe2, 0xd1, 0x01, 0xa5, 0x43, 0x59, 0x37, - 0x3f, 0x89, 0xff, 0xc9, 0xb3, 0xfe, 0xb3, 0x02, 0x1f, 0xdc, 0xe9, 0x8e, 0xdd, 0x9d, 0x42, 0x5d, - 0x51, 0x62, 0x9a, 0xfb, 0xbc, 0xf4, 0xc2, 0xdf, 0xe1, 0xeb, 0x6a, 0x85, 0xbe, 0x98, 0x18, 0xa5, - 0xfb, 0x12, 0xd6, 0x4b, 0xf0, 0x92, 0x7b, 0xb9, 0xb7, 0x78, 0x2f, 0x3b, 0xa5, 0x7c, 0xca, 0xb1, - 0x7c, 0x2b, 0x7f, 0x81, 0x9a, 0xc2, 0xfe, 0x76, 0xc2, 0x86, 0xe7, 0x6a, 0x89, 0xe7, 0x47, 0x66, - 0xea, 0x2b, 0x2a, 0x49, 0xbb, 0x20, 0x19, 0x73, 0xe8, 0xdf, 0xd8, 0xdf, 0x2a, 0x60, 0xab, 0x11, - 0x7e, 0x1f, 0x08, 0x92, 0x46, 0x01, 0x8d, 0xde, 0x92, 0x21, 0x11, 0x22, 0x8a, 0x27, 0xdc, 0xfa, - 0x50, 0xee, 0x78, 0x3a, 0x21, 0x42, 0x1f, 0x19, 0xcc, 0xbb, 0xae, 0x31, 0xe5, 0x65, 0x7d, 0x0c, - 0xf7, 0x39, 0x9b, 0xa5, 0x21, 0xf1, 0xc9, 0x75, 0x92, 0x12, 0xce, 0x23, 0x16, 0x63, 0x1d, 0x1d, - 0xad, 0x18, 0xe4, 0xb8, 0xf5, 0x1e, 0x40, 0x98, 0x92, 0x40, 0x10, 0x7f, 0x34, 0xa2, 0xaa, 0xb0, - 0x86, 0xd7, 0xd0, 0xc8, 0xd1, 0x88, 0x3a, 0xbf, 0x57, 0x61, 0x73, 0x59, 0x19, 0x5d, 0x58, 0xbb, - 0x62, 0xe9, 0xe5, 0x98, 0xb2, 0x2b, 0xd3, 0xba, 0x91, 0xad, 0xc7, 0xd0, 0xc6, 0xfc, 0x0b, 0x5b, - 0xd5, 0xf0, 0x5a, 0x1a, 0xce, 0x77, 0xf1, 0x31, 0xb4, 0xb1, 0x97, 0xdc, 0x50, 0x17, 0xd0, 0xd2, - 0x70, 0x6e, 0xb8, 0x07, 0x6d, 0x2e, 0x58, 0xe2, 0x07, 0x63, 0x41, 0x52, 0x3f, 0x64, 0xc9, 0x1c, - 0xaf, 0x66, 0x53, 0xc2, 0x07, 0x12, 0x3d, 0x64, 0xc9, 0xdc, 0xfa, 0x16, 0x5a, 0x78, 0x0c, 0xb1, - 0x4e, 0xbb, 0xa6, 0xd6, 0x67, 0xb7, 0x34, 0xce, 0xbb, 0x98, 0xf5, 0x9a, 0xfa, 0x5e, 0x9a, 0x0e, - 0xcd, 0x11, 0xab, 0x17, 0x47, 0x4c, 0x93, 0xaf, 0x0e, 0x8c, 0x98, 0x27, 0x84, 0xdb, 0xab, 0x86, - 0x7c, 0x89, 0x9d, 0x49, 0xe8, 0x79, 0xef, 0xa7, 0xbd, 0x2c, 0x12, 0x84, 0x73, 0x37, 0x62, 0x7d, - 0xfd, 0xd5, 0x9f, 0xb0, 0x7e, 0x26, 0xfa, 0xea, 0x5f, 0x62, 0x3f, 0x2f, 0xe4, 0xa2, 0xae, 0x80, - 0x4f, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x07, 0x33, 0x99, 0x59, 0xab, 0x0a, 0x00, 0x00, + // 1097 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xdd, 0x6f, 0xdb, 0x54, + 0x14, 0x57, 0xd2, 0x25, 0x4d, 0x4e, 0x9b, 0x34, 0x75, 0xdb, 0xcd, 0x04, 0x01, 0xc5, 0x65, 0x5d, + 0x54, 0x90, 0x33, 0x86, 0x40, 0x13, 0x1f, 0x12, 0xfd, 0x5a, 0x55, 0x06, 0x65, 0x72, 0xab, 0x22, + 0x81, 0x84, 0xe5, 0x3a, 0xb7, 0x99, 0xd5, 0x1b, 0x5f, 0xcf, 0xf7, 0xc6, 0x6d, 0xf6, 0xcc, 0x0b, + 0xff, 0x0c, 0x8f, 0x3c, 0xf2, 0xb7, 0xa1, 0x7b, 0xef, 0xb9, 0xb6, 0x93, 0xa6, 0x9b, 0x60, 0x6f, + 0x3e, 0xbf, 0xf3, 0xfd, 0x3b, 0xe7, 0x9e, 0x04, 0x56, 0x32, 0x11, 0x0a, 0x3a, 0x08, 0x44, 0xe0, + 0x26, 0x29, 0x13, 0xcc, 0x6a, 0xe6, 0x40, 0xb7, 0x45, 0xd9, 0x70, 0x2c, 0x22, 0xaa, 0x35, 0xdd, + 0xf6, 0x68, 0xc2, 0x5f, 0xd1, 0x50, 0x18, 0xf9, 0x81, 0x08, 0x2e, 0x28, 0x11, 0xa3, 0x20, 0x0e, + 0x86, 0x24, 0x2d, 0x42, 0x74, 0xdb, 0x82, 0x25, 0xac, 0x24, 0xb7, 0x32, 0x1e, 0xbe, 0x24, 0x23, + 0x14, 0x9d, 0x5f, 0xa0, 0x7b, 0x78, 0x43, 0xc2, 0xb1, 0x20, 0xe7, 0x32, 0xd5, 0x3e, 0x1b, 0x8d, + 0x82, 0x78, 0xe0, 0x91, 0x57, 0x63, 0xc2, 0x85, 0x65, 0xc1, 0xbd, 0x20, 0x1d, 0x72, 0xbb, 0xb2, + 0xb9, 0xd0, 0x6b, 0x7a, 0xea, 0xdb, 0x7a, 0x08, 0xed, 0x20, 0x14, 0x11, 0x8b, 0x7d, 0x11, 0x8d, + 0x08, 0x1b, 0x0b, 0xbb, 0xba, 0x59, 0xe9, 0x2d, 0x78, 0x2d, 0x8d, 0x9e, 0x69, 0xd0, 0xd9, 0x87, + 0xf7, 0xe7, 0x06, 0xe6, 0x09, 0x8b, 0x39, 0xb1, 0x3e, 0x81, 0x1a, 0xc9, 0x48, 0x2c, 0xec, 0xca, + 0x66, 0xa5, 0xb7, 0xf4, 0xa4, 0xed, 0x9a, 0xf6, 0x0e, 0x25, 0xea, 0x69, 0xa5, 0x73, 0x08, 0xab, + 0x47, 0x44, 0xec, 0x05, 0xe1, 0xd5, 0x38, 0xe1, 0xa6, 0xa8, 0x2e, 0x34, 0xae, 0xc8, 0x84, 0x27, + 0x41, 0x48, 0x94, 0x77, 0xd3, 0xcb, 0x65, 0x6b, 0x1d, 0x6a, 0xfc, 0x65, 0x90, 0x0e, 0x54, 0x4d, + 0x4d, 0x4f, 0x0b, 0xce, 0x01, 0x58, 0xe5, 0x30, 0x58, 0x82, 0x0b, 0x8b, 0x17, 0x1a, 0x52, 0xfd, + 0x2d, 0x3d, 0x59, 0x77, 0x73, 0x52, 0xb5, 0xed, 0x71, 0x7c, 0xc9, 0x3c, 0x63, 0xe4, 0xbc, 0x07, + 0x0f, 0x8e, 0x88, 0xd8, 0x27, 0x94, 0x4a, 0xfc, 0x24, 0x18, 0x11, 0x53, 0x92, 0xf3, 0x18, 0xec, + 0xdb, 0x2a, 0x4c, 0xb3, 0x0e, 0xb5, 0x58, 0x02, 0x48, 0xa2, 0x16, 0x9c, 0x9e, 0x2a, 0xc9, 0x78, + 0x94, 0xf8, 0x0e, 0x09, 0xa5, 0xd8, 0x96, 0xfa, 0x76, 0x9e, 0xc1, 0xda, 0x94, 0x25, 0x86, 0xed, + 0x43, 0x53, 0xaa, 0xfd, 0x28, 0xbe, 0x64, 0x48, 0xa2, 0xe5, 0xe6, 0xb3, 0xce, 0xcd, 0x1b, 0x21, + 0x7e, 0x39, 0x36, 0xdc, 0xc7, 0x38, 0x7c, 0x97, 0x46, 0x01, 0x2f, 0xaa, 0xff, 0xbb, 0x92, 0x77, + 0x56, 0xa8, 0x30, 0xcd, 0x31, 0x2c, 0x06, 0x1a, 0x42, 0x92, 0xfa, 0x6e, 0xb1, 0xa4, 0x77, 0x38, + 0xb9, 0x28, 0x1f, 0xc6, 0x22, 0x9d, 0x78, 0xc6, 0xbf, 0xfb, 0x02, 0x96, 0xcb, 0x0a, 0xab, 0x03, + 0x0b, 0x57, 0x64, 0x82, 0xbd, 0xca, 0x4f, 0x6b, 0x07, 0x6a, 0x59, 0x40, 0xc7, 0x44, 0x4d, 0x4f, + 0xce, 0x63, 0xaa, 0x1f, 0x9d, 0xc6, 0xd3, 0x26, 0x5f, 0x57, 0x9f, 0x56, 0x9c, 0x0d, 0x45, 0xcd, + 0x73, 0x1c, 0x7e, 0xde, 0xcf, 0x31, 0xac, 0x4f, 0xc3, 0xd8, 0xcb, 0xe7, 0xd0, 0x34, 0x8b, 0x62, + 0xba, 0x59, 0x2b, 0x75, 0x63, 0x1c, 0xbc, 0xc2, 0xca, 0x79, 0xac, 0xc6, 0x94, 0x6b, 0xde, 0xbe, + 0x81, 0x38, 0xae, 0xc2, 0x23, 0x1f, 0xd7, 0xb4, 0xcb, 0x1d, 0xa9, 0x8b, 0x38, 0x7f, 0x54, 0xa1, + 0x73, 0x44, 0xc4, 0xa9, 0x7a, 0xac, 0x26, 0xf1, 0x53, 0x58, 0xd6, 0xef, 0xdc, 0x57, 0xa4, 0x62, + 0xa4, 0x8d, 0x82, 0xa7, 0x33, 0xa5, 0xd5, 0x44, 0x2d, 0x89, 0x42, 0xb0, 0xee, 0x43, 0x5d, 0x89, + 0xdc, 0xae, 0xaa, 0x35, 0x44, 0x49, 0xbe, 0x66, 0x72, 0x13, 0xd2, 0xf1, 0x80, 0xf8, 0xa8, 0x5f, + 0x50, 0xfa, 0x16, 0xa2, 0x67, 0xda, 0x6c, 0x0b, 0x5a, 0x51, 0xac, 0xcd, 0xb2, 0x88, 0x5c, 0x73, + 0xfb, 0xde, 0x66, 0xa5, 0xd7, 0xf0, 0x96, 0x11, 0x3c, 0x97, 0x98, 0xd5, 0x83, 0x8e, 0x8a, 0xe1, + 0xab, 0x15, 0xf7, 0x59, 0x4c, 0x27, 0x76, 0x4d, 0xd9, 0xb5, 0x15, 0xae, 0xde, 0xc5, 0xcf, 0x31, + 0x9d, 0x14, 0x96, 0x3c, 0x7a, 0x6d, 0x2c, 0xeb, 0x25, 0xcb, 0x53, 0x09, 0x4b, 0x4b, 0xe7, 0x85, + 0xba, 0x00, 0x86, 0x05, 0x24, 0xf3, 0x1b, 0xa8, 0xeb, 0x23, 0x86, 0x04, 0x6c, 0xb9, 0xb7, 0xaf, + 0x9f, 0x76, 0x39, 0x20, 0x97, 0x51, 0x1c, 0xc9, 0xbb, 0xe4, 0xa1, 0x8b, 0xb3, 0xa3, 0xb6, 0xe3, + 0x34, 0xcd, 0xce, 0xa7, 0xb9, 0x9d, 0xf7, 0xf6, 0x4e, 0x60, 0x63, 0xc6, 0x16, 0x2b, 0xf8, 0x12, + 0x96, 0x79, 0x9a, 0xf9, 0x99, 0x3f, 0x55, 0xc7, 0x9a, 0x6b, 0x8e, 0x6b, 0xc9, 0x05, 0x78, 0xfe, + 0xed, 0xfc, 0xa8, 0x66, 0xaa, 0x87, 0xf4, 0xce, 0x33, 0x75, 0xbe, 0x53, 0xdc, 0x98, 0x68, 0x58, + 0x59, 0x0f, 0x07, 0x6d, 0x2e, 0x6b, 0x67, 0x36, 0x10, 0x8e, 0x5e, 0x38, 0xbf, 0x95, 0xdc, 0xff, + 0xff, 0x71, 0x95, 0xa8, 0xe4, 0xca, 0x2c, 0x8e, 0x16, 0x9c, 0xef, 0xd5, 0xc3, 0xc9, 0x83, 0x63, + 0x71, 0x3b, 0xb0, 0xa8, 0x93, 0x9b, 0xf7, 0x77, 0xbb, 0x3a, 0x63, 0xe0, 0xf4, 0x55, 0x79, 0x33, + 0x43, 0x7a, 0xd3, 0xcb, 0xdb, 0x53, 0x29, 0x67, 0x27, 0xf5, 0x19, 0x34, 0x66, 0xa6, 0xb4, 0x9a, + 0x4f, 0x29, 0x7f, 0x76, 0x8b, 0x19, 0x0e, 0xe8, 0x04, 0x1a, 0x06, 0x94, 0x0b, 0x21, 0x17, 0xd9, + 0x2c, 0x84, 0xfc, 0xb6, 0xdc, 0x52, 0xfe, 0xea, 0xec, 0xd1, 0x9d, 0xf3, 0x8a, 0xbf, 0x85, 0x0f, + 0x9f, 0x45, 0xf1, 0x60, 0x97, 0xd2, 0x53, 0x49, 0x16, 0x3f, 0x8e, 0xff, 0xcb, 0x2d, 0xf9, 0xa7, + 0x02, 0x1f, 0xdd, 0xe9, 0x8e, 0xfd, 0x9d, 0x40, 0x5d, 0xcd, 0xc1, 0x30, 0xfa, 0x55, 0xe9, 0xac, + 0xbc, 0xc5, 0xd7, 0xd5, 0x0a, 0x7d, 0xa6, 0x31, 0x4a, 0xf7, 0x39, 0x2c, 0x95, 0xe0, 0x39, 0x47, + 0x7a, 0x7b, 0xfa, 0x48, 0x77, 0x4a, 0xf9, 0x94, 0x63, 0xf9, 0x40, 0xff, 0x0e, 0x35, 0x85, 0xbd, + 0x71, 0xad, 0x0c, 0xcf, 0xd5, 0x12, 0xcf, 0x0f, 0xcd, 0xaa, 0x2d, 0xa8, 0x24, 0x2b, 0x05, 0xc9, + 0x98, 0x43, 0xff, 0xb0, 0xff, 0x59, 0x01, 0x5b, 0xed, 0xcd, 0x4f, 0x81, 0x20, 0x69, 0x14, 0xd0, + 0xe8, 0x35, 0x39, 0x25, 0x42, 0x44, 0xf1, 0x90, 0x5b, 0x1f, 0xcb, 0x87, 0x95, 0x0e, 0x89, 0xd0, + 0x97, 0x0d, 0xf3, 0x2e, 0x69, 0x4c, 0x79, 0x59, 0x9f, 0xc2, 0x2a, 0x67, 0xe3, 0x34, 0x24, 0x3e, + 0xb9, 0x49, 0x52, 0xc2, 0x79, 0xc4, 0x62, 0xac, 0xa3, 0xa3, 0x15, 0x87, 0x39, 0x6e, 0x7d, 0x00, + 0x10, 0xa6, 0x24, 0x10, 0xc4, 0x1f, 0x0c, 0xa8, 0x2a, 0xac, 0xe9, 0x35, 0x35, 0x72, 0x30, 0xa0, + 0xce, 0x5f, 0x55, 0x58, 0x9b, 0x57, 0x46, 0x17, 0x1a, 0xd7, 0x2c, 0xbd, 0xba, 0xa4, 0xec, 0xda, + 0xb4, 0x6e, 0x64, 0xeb, 0x11, 0xac, 0x60, 0xfe, 0xa9, 0xad, 0x6a, 0x7a, 0x6d, 0x0d, 0xe7, 0xbb, + 0xf8, 0x08, 0x56, 0xb0, 0x97, 0xdc, 0x50, 0x17, 0xd0, 0xd6, 0x70, 0x6e, 0xb8, 0x0d, 0x2b, 0x5c, + 0xb0, 0xc4, 0x0f, 0x2e, 0x05, 0x49, 0xfd, 0x90, 0x25, 0x13, 0x3c, 0xd5, 0x2d, 0x09, 0xef, 0x4a, + 0x74, 0x9f, 0x25, 0x13, 0xeb, 0x07, 0x68, 0xe3, 0x05, 0xc6, 0x3a, 0xed, 0x9a, 0x5a, 0x9f, 0xad, + 0xd2, 0x38, 0xef, 0x62, 0xd6, 0x6b, 0xe9, 0x23, 0x6d, 0x3a, 0x34, 0x97, 0xb3, 0x5e, 0x5c, 0x4e, + 0x4d, 0xbe, 0xba, 0x6a, 0x62, 0x92, 0x10, 0x6e, 0x2f, 0x1a, 0xf2, 0x25, 0x76, 0x26, 0xa1, 0xbd, + 0xde, 0xaf, 0xdb, 0x59, 0x24, 0x08, 0xe7, 0x6e, 0xc4, 0xfa, 0xfa, 0xab, 0x3f, 0x64, 0xfd, 0x4c, + 0xf4, 0xd5, 0x5f, 0xd3, 0x7e, 0x5e, 0xc8, 0x45, 0x5d, 0x01, 0x5f, 0xfc, 0x1b, 0x00, 0x00, 0xff, + 0xff, 0x66, 0x2a, 0x0a, 0x0a, 0x20, 0x0b, 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index c76446f657d..6dd54ce6e4f 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,32 +29,32 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 385 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xc1, 0x4e, 0xea, 0x40, - 0x14, 0x86, 0xef, 0x5d, 0x5c, 0x6e, 0x1c, 0x31, 0x98, 0x71, 0x61, 0x82, 0x80, 0x8a, 0xd1, 0x04, - 0x4d, 0xa8, 0xc1, 0x27, 0x00, 0xa2, 0x48, 0x48, 0x48, 0x14, 0xc2, 0x82, 0xc4, 0xc5, 0xd0, 0x1e, - 0xa5, 0xb1, 0xed, 0x94, 0x9e, 0xa1, 0xd1, 0x97, 0xf2, 0x19, 0x0d, 0x2d, 0x33, 0x94, 0x81, 0x41, - 0x77, 0xed, 0xff, 0x9d, 0xf3, 0xf5, 0x4f, 0x3a, 0x19, 0x42, 0x63, 0x61, 0x0b, 0x0f, 0x21, 0x8a, - 0x5d, 0x1b, 0xea, 0x61, 0xc4, 0x05, 0xa7, 0xf9, 0x6c, 0x56, 0x2c, 0x24, 0x6f, 0x0e, 0x13, 0x2c, - 0xc5, 0x8d, 0x19, 0xf9, 0x37, 0x5a, 0x44, 0x74, 0x4a, 0x8e, 0xee, 0x3f, 0xc0, 0x9e, 0x0b, 0x48, - 0xde, 0xdb, 0xdc, 0xf7, 0x59, 0xe0, 0xd0, 0xcb, 0xfa, 0x6a, 0x63, 0x0b, 0x7f, 0x86, 0xd9, 0x1c, - 0x50, 0x14, 0xaf, 0x7e, 0x1a, 0xc3, 0x90, 0x07, 0x08, 0xd5, 0x3f, 0xb7, 0x7f, 0x1b, 0x5f, 0xff, - 0x49, 0x2e, 0x81, 0x0e, 0x8d, 0xc8, 0xf1, 0x83, 0x1b, 0x38, 0x4d, 0xcf, 0x1b, 0x4c, 0x59, 0xe4, - 0x60, 0x37, 0xe8, 0xc1, 0x27, 0x86, 0xcc, 0x06, 0x5a, 0xcb, 0x18, 0x0d, 0x33, 0xf2, 0xe3, 0xd7, - 0xbf, 0x19, 0x95, 0x05, 0x68, 0x8f, 0x90, 0x0e, 0x88, 0x16, 0xb3, 0xdf, 0xe7, 0x21, 0xd2, 0x52, - 0x66, 0x77, 0x15, 0x4b, 0x73, 0xd9, 0x40, 0x95, 0xec, 0x85, 0x1c, 0x76, 0x40, 0xb4, 0xc1, 0xf3, - 0xba, 0xc1, 0x2b, 0xef, 0x33, 0x1f, 0x90, 0x56, 0xd7, 0x97, 0xd6, 0xa0, 0x14, 0x5f, 0xec, 0x9c, - 0x51, 0xfa, 0x3e, 0xd9, 0xcf, 0x50, 0x5a, 0xde, 0xbe, 0x25, 0xa5, 0x15, 0x13, 0x56, 0xbe, 0x31, - 0x29, 0x2c, 0x01, 0x36, 0x3d, 0x97, 0x21, 0x20, 0x3d, 0xdf, 0x5c, 0x92, 0x4c, 0x7a, 0xab, 0xbb, - 0x46, 0xb4, 0xae, 0xea, 0xff, 0x69, 0x5d, 0xf5, 0x7f, 0x56, 0x31, 0x61, 0xe5, 0x7b, 0x22, 0xf9, - 0x0c, 0x40, 0x6a, 0xd8, 0x50, 0x2d, 0x4f, 0x8d, 0x5c, 0x29, 0x1f, 0xc9, 0x5e, 0x07, 0xc4, 0xc0, - 0x9e, 0x82, 0xcf, 0xe8, 0xc9, 0xfa, 0x7c, 0x9a, 0x4a, 0x59, 0x69, 0x3b, 0x54, 0xa6, 0x21, 0x39, - 0x58, 0xc4, 0x51, 0x3c, 0x5a, 0xda, 0xb4, 0xaf, 0xaf, 0x88, 0x34, 0x9e, 0x99, 0x07, 0xb4, 0x7e, - 0x43, 0x36, 0xf1, 0x40, 0xe8, 0xfd, 0xd2, 0xd4, 0xd0, 0x4f, 0x42, 0xed, 0x90, 0xa7, 0xf1, 0xc6, - 0x21, 0x5f, 0xc6, 0x86, 0x43, 0xae, 0xa8, 0x94, 0xb5, 0x6e, 0xc6, 0xb5, 0xd8, 0x15, 0x80, 0x58, - 0x77, 0xb9, 0x95, 0x3e, 0x59, 0x6f, 0xdc, 0x8a, 0x85, 0x95, 0xdc, 0x21, 0x56, 0xf6, 0x86, 0x99, - 0xe4, 0x92, 0xec, 0xee, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x78, 0x06, 0x02, 0xde, 0x8c, 0x04, 0x00, - 0x00, + // 395 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0x51, 0x4f, 0xea, 0x30, + 0x14, 0xc7, 0xef, 0x7d, 0xb8, 0xdc, 0x58, 0x31, 0x98, 0xfa, 0x60, 0x82, 0x80, 0x8a, 0xd1, 0x04, + 0x4d, 0x98, 0xc1, 0x4f, 0x00, 0x44, 0x91, 0x90, 0x90, 0x28, 0x84, 0x07, 0x12, 0x1f, 0xca, 0x76, + 0x94, 0xc5, 0x6d, 0x1d, 0x3b, 0x65, 0xd1, 0xcf, 0xee, 0x8b, 0x61, 0xa3, 0x65, 0x14, 0x8a, 0xbe, + 0x6d, 0xff, 0xdf, 0x39, 0xbf, 0x9e, 0xa6, 0x4d, 0x09, 0x8d, 0x85, 0x2d, 0x3c, 0x84, 0x28, 0x76, + 0x6d, 0xa8, 0x87, 0x11, 0x17, 0x9c, 0xe6, 0xb3, 0x59, 0xb1, 0x90, 0xfc, 0x39, 0x4c, 0xb0, 0x14, + 0x37, 0x66, 0xe4, 0xdf, 0x68, 0x11, 0xd1, 0x29, 0x39, 0xba, 0xff, 0x00, 0x7b, 0x2e, 0x20, 0xf9, + 0x6f, 0x73, 0xdf, 0x67, 0x81, 0x43, 0x2f, 0xeb, 0xab, 0x8e, 0x2d, 0xfc, 0x19, 0x66, 0x73, 0x40, + 0x51, 0xbc, 0xfa, 0xa9, 0x0c, 0x43, 0x1e, 0x20, 0x54, 0xff, 0xdc, 0xfe, 0x6d, 0x7c, 0xfd, 0x27, + 0xb9, 0x04, 0x3a, 0x34, 0x22, 0xc7, 0x0f, 0x6e, 0xe0, 0x34, 0x3d, 0x6f, 0x30, 0x65, 0x91, 0x83, + 0xdd, 0xa0, 0x07, 0x9f, 0x18, 0x32, 0x1b, 0x68, 0x2d, 0x63, 0x34, 0xd4, 0xc8, 0xc5, 0xaf, 0x7f, + 0x53, 0x2a, 0x07, 0xa0, 0x3d, 0x42, 0x3a, 0x20, 0x5a, 0xcc, 0x7e, 0x9f, 0x87, 0x48, 0x4b, 0x99, + 0xde, 0x55, 0x2c, 0xcd, 0x65, 0x03, 0x55, 0xb2, 0x17, 0x72, 0xd8, 0x01, 0xd1, 0x06, 0xcf, 0xeb, + 0x06, 0xaf, 0xbc, 0xcf, 0x7c, 0x40, 0x5a, 0x5d, 0x6f, 0x5a, 0x83, 0x52, 0x7c, 0xb1, 0xb3, 0x46, + 0xe9, 0xfb, 0x64, 0x3f, 0x43, 0x69, 0x79, 0x7b, 0x97, 0x94, 0x56, 0x4c, 0x58, 0xf9, 0xc6, 0xa4, + 0xb0, 0x04, 0xd8, 0xf4, 0x5c, 0x86, 0x80, 0xf4, 0x7c, 0xb3, 0x49, 0x32, 0xe9, 0xad, 0xee, 0x2a, + 0xd1, 0x66, 0x55, 0xe7, 0xa7, 0xcd, 0xaa, 0x9f, 0x59, 0xc5, 0x84, 0x95, 0xef, 0x89, 0xe4, 0x33, + 0x00, 0xa9, 0xa1, 0x43, 0x4d, 0x79, 0x6a, 0xe4, 0x4a, 0xf9, 0x48, 0xf6, 0x3a, 0x20, 0x06, 0xf6, + 0x14, 0x7c, 0x46, 0x4f, 0xd6, 0xeb, 0xd3, 0x54, 0xca, 0x4a, 0xdb, 0xa1, 0x32, 0x0d, 0xc9, 0xc1, + 0x22, 0x8e, 0xe2, 0xd1, 0xd2, 0xa6, 0xad, 0xbe, 0x22, 0xd2, 0x78, 0x66, 0x2e, 0xd0, 0xe6, 0x1b, + 0xb2, 0x89, 0x07, 0x42, 0x9f, 0x2f, 0x4d, 0x0d, 0xf3, 0x49, 0xa8, 0x5d, 0xf2, 0x34, 0xde, 0xb8, + 0xe4, 0xcb, 0xd8, 0x70, 0xc9, 0x15, 0xd5, 0x64, 0x72, 0xa7, 0x9a, 0x4c, 0xdb, 0x66, 0xd9, 0x40, + 0xa5, 0xac, 0x75, 0x33, 0xae, 0xc5, 0xae, 0x00, 0xc4, 0xba, 0xcb, 0xad, 0xf4, 0xcb, 0x7a, 0xe3, + 0x56, 0x2c, 0xac, 0xe4, 0x41, 0xb2, 0xb2, 0xcf, 0xd5, 0x24, 0x97, 0x64, 0x77, 0xdf, 0x01, 0x00, + 0x00, 0xff, 0xff, 0xd1, 0x33, 0xf9, 0x95, 0xd9, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -194,6 +194,8 @@ type VtctldClient interface { GetTablet(ctx context.Context, in *vtctldata.GetTabletRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletResponse, error) // GetTablets returns tablets, optionally filtered by keyspace and shard. GetTablets(ctx context.Context, in *vtctldata.GetTabletsRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletsResponse, error) + // GetVSchema returns the vschema for a keyspace. + GetVSchema(ctx context.Context, in *vtctldata.GetVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetVSchemaResponse, error) } type vtctldClient struct { @@ -303,6 +305,15 @@ func (c *vtctldClient) GetTablets(ctx context.Context, in *vtctldata.GetTabletsR return out, nil } +func (c *vtctldClient) GetVSchema(ctx context.Context, in *vtctldata.GetVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetVSchemaResponse, error) { + out := new(vtctldata.GetVSchemaResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetVSchema", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // VtctldServer is the server API for Vtctld service. type VtctldServer interface { // FindAllShardsInKeyspace returns a map of shard names to shard references @@ -331,6 +342,8 @@ type VtctldServer interface { GetTablet(context.Context, *vtctldata.GetTabletRequest) (*vtctldata.GetTabletResponse, error) // GetTablets returns tablets, optionally filtered by keyspace and shard. GetTablets(context.Context, *vtctldata.GetTabletsRequest) (*vtctldata.GetTabletsResponse, error) + // GetVSchema returns the vschema for a keyspace. + GetVSchema(context.Context, *vtctldata.GetVSchemaRequest) (*vtctldata.GetVSchemaResponse, error) } // UnimplementedVtctldServer can be embedded to have forward compatible implementations. @@ -370,6 +383,9 @@ func (*UnimplementedVtctldServer) GetTablet(ctx context.Context, req *vtctldata. func (*UnimplementedVtctldServer) GetTablets(ctx context.Context, req *vtctldata.GetTabletsRequest) (*vtctldata.GetTabletsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetTablets not implemented") } +func (*UnimplementedVtctldServer) GetVSchema(ctx context.Context, req *vtctldata.GetVSchemaRequest) (*vtctldata.GetVSchemaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetVSchema not implemented") +} func RegisterVtctldServer(s *grpc.Server, srv VtctldServer) { s.RegisterService(&_Vtctld_serviceDesc, srv) @@ -573,6 +589,24 @@ func _Vtctld_GetTablets_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Vtctld_GetVSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetVSchemaRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetVSchema(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetVSchema", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetVSchema(ctx, req.(*vtctldata.GetVSchemaRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Vtctld_serviceDesc = grpc.ServiceDesc{ ServiceName: "vtctlservice.Vtctld", HandlerType: (*VtctldServer)(nil), @@ -621,6 +655,10 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "GetTablets", Handler: _Vtctld_GetTablets_Handler, }, + { + MethodName: "GetVSchema", + Handler: _Vtctld_GetVSchema_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "vtctlservice.proto", diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index 994124545d1..ed32a09c69f 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -126,3 +126,12 @@ func (client *gRPCVtctldClient) GetTablets(ctx context.Context, in *vtctldatapb. return client.c.GetTablets(ctx, in, opts...) } + +// GetVSchema is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetVSchema(ctx context.Context, in *vtctldatapb.GetVSchemaRequest, opts ...grpc.CallOption) (*vtctldatapb.GetVSchemaResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetVSchema(ctx, in, opts...) +} diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 28db37f564f..96245825f3b 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -328,6 +328,18 @@ func (s *VtctldServer) GetTablets(ctx context.Context, req *vtctldatapb.GetTable }, nil } +// GetVSchema is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetVSchema(ctx context.Context, req *vtctldatapb.GetVSchemaRequest) (*vtctldatapb.GetVSchemaResponse, error) { + vschema, err := s.ts.GetVSchema(ctx, req.Keyspace) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetVSchemaResponse{ + VSchema: vschema, + }, nil +} + // StartServer registers a VtctldServer for RPCs on the given gRPC server. func StartServer(s *grpc.Server, ts *topo.Server) { vtctlservicepb.RegisterVtctldServer(s, NewVtctldServer(ts)) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index af2cf77ebe5..4bcb2e12b99 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -859,3 +859,43 @@ func TestGetTablets(t *testing.T) { }) } } + +func TestGetVSchema(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("zone1") + vtctld := NewVtctldServer(ts) + + err := ts.SaveVSchema(ctx, "testkeyspace", &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "v1": { + Type: "hash", + }, + }, + }) + require.NoError(t, err) + + expected := &vtctldatapb.GetVSchemaResponse{ + VSchema: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "v1": { + Type: "hash", + }, + }, + }, + } + + resp, err := vtctld.GetVSchema(ctx, &vtctldatapb.GetVSchemaRequest{ + Keyspace: "testkeyspace", + }) + assert.NoError(t, err) + assert.Equal(t, expected, resp) + + t.Run("not found", func(t *testing.T) { + _, err := vtctld.GetVSchema(ctx, &vtctldatapb.GetVSchemaRequest{ + Keyspace: "doesnotexist", + }) + assert.Error(t, err) + }) +} diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index c8fe5a5decd..69c6f561488 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -140,6 +140,14 @@ message GetTabletsResponse { repeated topodata.Tablet tablets = 1; } +message GetVSchemaRequest { + string keyspace = 1; +} + +message GetVSchemaResponse { + vschema.Keyspace v_schema = 1; +} + message Keyspace { string name = 1; topodata.Keyspace keyspace = 2; diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 8ca3f581b21..bcf94e9aa98 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -57,4 +57,6 @@ service Vtctld { rpc GetTablet(vtctldata.GetTabletRequest) returns (vtctldata.GetTabletResponse) {}; // GetTablets returns tablets, optionally filtered by keyspace and shard. rpc GetTablets(vtctldata.GetTabletsRequest) returns (vtctldata.GetTabletsResponse) {}; + // GetVSchema returns the vschema for a keyspace. + rpc GetVSchema(vtctldata.GetVSchemaRequest) returns (vtctldata.GetVSchemaResponse) {}; } From 3b4410ee6a1e4dfe7351defbad76a9dea6ca101f Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Thu, 4 Feb 2021 23:28:20 +0100 Subject: [PATCH 13/21] Merge pull request #7395 from tinyspeck/am_vtctld_manage_topo [vtctld] Migrate topo management RPCs Signed-off-by: Richard Bailey --- go/cmd/vtctldclient/cli/awk.go | 33 + go/cmd/vtctldclient/cli/pflag.go | 93 + go/cmd/vtctldclient/cli/shards.go | 43 + go/cmd/vtctldclient/cli/tablets.go | 40 + .../internal/command/keyspaces.go | 171 ++ .../vtctldclient/internal/command/shards.go | 182 ++ .../vtctldclient/internal/command/tablets.go | 110 +- go/vt/key/key.go | 12 +- go/vt/proto/binlogdata/binlogdata.pb.go | 3 - go/vt/proto/vtctldata/vtctldata.pb.go | 1196 +++++++- go/vt/proto/vtctlservice/vtctlservice.pb.go | 434 ++- go/vt/topo/tablet.go | 18 + go/vt/topo/topoproto/keyspace.go | 12 +- go/vt/topotools/tablet.go | 38 + go/vt/vtctl/grpcvtctldclient/client_gen.go | 81 + go/vt/vtctl/grpcvtctldserver/server.go | 303 ++ go/vt/vtctl/grpcvtctldserver/server_test.go | 2433 +++++++++++++++++ .../testutil/proto_compare.go | 46 + .../testutil/test_tmclient.go | 16 + go/vt/vtctl/grpcvtctldserver/testutil/util.go | 57 + go/vt/vtctl/grpcvtctldserver/topo.go | 292 ++ go/vt/vtctl/vtctl.go | 23 +- go/vt/wrangler/tablet.go | 19 +- proto/vtctldata.proto | 153 ++ proto/vtctlservice.proto | 33 + 25 files changed, 5646 insertions(+), 195 deletions(-) create mode 100644 go/cmd/vtctldclient/cli/pflag.go create mode 100644 go/cmd/vtctldclient/cli/shards.go create mode 100644 go/cmd/vtctldclient/cli/tablets.go create mode 100644 go/cmd/vtctldclient/internal/command/shards.go create mode 100644 go/vt/vtctl/grpcvtctldserver/testutil/proto_compare.go create mode 100644 go/vt/vtctl/grpcvtctldserver/topo.go diff --git a/go/cmd/vtctldclient/cli/awk.go b/go/cmd/vtctldclient/cli/awk.go index 7e5f0c5c50e..2789fec2e6d 100644 --- a/go/cmd/vtctldclient/cli/awk.go +++ b/go/cmd/vtctldclient/cli/awk.go @@ -20,6 +20,13 @@ import ( "fmt" "sort" "strings" + "time" + + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) // MarshalMapAWK returns a string representation of a string->string map in an @@ -38,3 +45,29 @@ func MarshalMapAWK(m map[string]string) string { return "[" + strings.Join(pairs, " ") + "]" } + +// MarshalTabletAWK marshals a tablet into an AWK-friendly line. +func MarshalTabletAWK(t *topodatapb.Tablet) string { + ti := topo.TabletInfo{ + Tablet: t, + } + + keyspace := t.Keyspace + if keyspace == "" { + keyspace = "" + } + + shard := t.Shard + if shard == "" { + shard = "" + } + + mtst := "" + // special case for old primary that hasn't been updated in the topo + // yet. + if t.MasterTermStartTime != nil && t.MasterTermStartTime.Seconds > 0 { + mtst = logutil.ProtoToTime(t.MasterTermStartTime).Format(time.RFC3339) + } + + return fmt.Sprintf("%v %v %v %v %v %v %v %v", topoproto.TabletAliasString(t.Alias), keyspace, shard, topoproto.TabletTypeLString(t.Type), ti.Addr(), ti.MysqlAddr(), MarshalMapAWK(t.Tags), mtst) +} diff --git a/go/cmd/vtctldclient/cli/pflag.go b/go/cmd/vtctldclient/cli/pflag.go new file mode 100644 index 00000000000..8a364be8d86 --- /dev/null +++ b/go/cmd/vtctldclient/cli/pflag.go @@ -0,0 +1,93 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cli + +import ( + "github.com/spf13/pflag" + + "vitess.io/vitess/go/flagutil" + "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/topo/topoproto" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +// StringMapValue augments flagutil.StringMapValue so it can be used as a +// pflag.Value. +type StringMapValue struct { + flagutil.StringMapValue +} + +// Type is part of the pflag.Value interface. +func (v *StringMapValue) Type() string { + return "cli.StringMapValue" +} + +// KeyspaceIDTypeFlag adds the pflag.Value interface to a +// topodatapb.KeyspaceIdType. +type KeyspaceIDTypeFlag topodatapb.KeyspaceIdType + +var _ pflag.Value = (*KeyspaceIDTypeFlag)(nil) + +// Set is part of the pflag.Value interface. +func (v *KeyspaceIDTypeFlag) Set(arg string) error { + t, err := key.ParseKeyspaceIDType(arg) + if err != nil { + return err + } + + *v = KeyspaceIDTypeFlag(t) + + return nil +} + +// String is part of the pflag.Value interface. +func (v *KeyspaceIDTypeFlag) String() string { + return key.KeyspaceIDTypeString(topodatapb.KeyspaceIdType(*v)) +} + +// Type is part of the pflag.Value interface. +func (v *KeyspaceIDTypeFlag) Type() string { + return "cli.KeyspaceIdTypeFlag" +} + +// KeyspaceTypeFlag adds the pflag.Value interface to a topodatapb.KeyspaceType. +type KeyspaceTypeFlag topodatapb.KeyspaceType + +var _ pflag.Value = (*KeyspaceTypeFlag)(nil) + +// Set is part of the pflag.Value interface. +func (v *KeyspaceTypeFlag) Set(arg string) error { + kt, err := topoproto.ParseKeyspaceType(arg) + if err != nil { + return err + } + + *v = KeyspaceTypeFlag(kt) + + return nil +} + +// String is part of the pflag.Value interface. +func (v *KeyspaceTypeFlag) String() string { + return topoproto.KeyspaceTypeString(topodatapb.KeyspaceType(*v)) +} + +// Type is part of the pflag.Value interface. +func (v *KeyspaceTypeFlag) Type() string { + return "cli.KeyspaceTypeFlag" +} diff --git a/go/cmd/vtctldclient/cli/shards.go b/go/cmd/vtctldclient/cli/shards.go new file mode 100644 index 00000000000..b71dc2741df --- /dev/null +++ b/go/cmd/vtctldclient/cli/shards.go @@ -0,0 +1,43 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cli + +import ( + "vitess.io/vitess/go/vt/topo/topoproto" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +// ParseKeyspaceShards takes a list of positional arguments and converts them to +// vtctldatapb.Shard objects. +func ParseKeyspaceShards(args []string) ([]*vtctldatapb.Shard, error) { + shards := make([]*vtctldatapb.Shard, 0, len(args)) + + for _, arg := range args { + keyspace, shard, err := topoproto.ParseKeyspaceShard(arg) + if err != nil { + return nil, err + } + + shards = append(shards, &vtctldatapb.Shard{ + Keyspace: keyspace, + Name: shard, + }) + } + + return shards, nil +} diff --git a/go/cmd/vtctldclient/cli/tablets.go b/go/cmd/vtctldclient/cli/tablets.go new file mode 100644 index 00000000000..a2962c42b45 --- /dev/null +++ b/go/cmd/vtctldclient/cli/tablets.go @@ -0,0 +1,40 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cli + +import ( + "vitess.io/vitess/go/vt/topo/topoproto" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +// TabletAliasesFromPosArgs takes a list of positional (non-flag) arguments and +// converts them to tablet aliases. +func TabletAliasesFromPosArgs(args []string) ([]*topodatapb.TabletAlias, error) { + aliases := make([]*topodatapb.TabletAlias, 0, len(args)) + + for _, arg := range args { + alias, err := topoproto.ParseTabletAlias(arg) + if err != nil { + return nil, err + } + + aliases = append(aliases, alias) + } + + return aliases, nil +} diff --git a/go/cmd/vtctldclient/internal/command/keyspaces.go b/go/cmd/vtctldclient/internal/command/keyspaces.go index 47207d8e443..0f3ec9fcc1d 100644 --- a/go/cmd/vtctldclient/internal/command/keyspaces.go +++ b/go/cmd/vtctldclient/internal/command/keyspaces.go @@ -17,16 +17,34 @@ limitations under the License. package command import ( + "errors" "fmt" + "time" "github.com/spf13/cobra" "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + "vitess.io/vitess/go/vt/proto/vttime" ) var ( + // CreateKeyspace makes a CreateKeyspace gRPC call to a vtctld. + CreateKeyspace = &cobra.Command{ + Use: "CreateKeyspace KEYSPACE_NAME [--force] [--sharding-column-name NAME --sharding-column-type TYPE] [--base-keyspace KEYSPACE --snapshot-timestamp TIME] [--served-from DB_TYPE:KEYSPACE ...]", + Args: cobra.ExactArgs(1), + RunE: commandCreateKeyspace, + } + // DeleteKeyspace makes a DeleteKeyspace gRPC call to a vtctld. + DeleteKeyspace = &cobra.Command{ + Use: "DeleteKeyspace KEYSPACE_NAME", + Args: cobra.ExactArgs(1), + RunE: commandDeleteKeyspace, + } // FindAllShardsInKeyspace makes a FindAllShardsInKeyspace gRPC call to a vtctld. FindAllShardsInKeyspace = &cobra.Command{ Use: "FindAllShardsInKeyspace keyspace", @@ -48,8 +66,119 @@ var ( Args: cobra.NoArgs, RunE: commandGetKeyspaces, } + // RemoveKeyspaceCell makes a RemoveKeyspaceCell gRPC call to a vtctld. + RemoveKeyspaceCell = &cobra.Command{ + Use: "RemoveKeyspaceCell ", + Args: cobra.ExactArgs(2), + RunE: commandRemoveKeyspaceCell, + } ) +var createKeyspaceOptions = struct { + Force bool + AllowEmptyVSchema bool + + ShardingColumnName string + ShardingColumnType cli.KeyspaceIDTypeFlag + + ServedFromsMap cli.StringMapValue + + KeyspaceType cli.KeyspaceTypeFlag + BaseKeyspace string + SnapshotTimestamp string +}{ + KeyspaceType: cli.KeyspaceTypeFlag(topodatapb.KeyspaceType_NORMAL), +} + +func commandCreateKeyspace(cmd *cobra.Command, args []string) error { + name := cmd.Flags().Arg(0) + + switch topodatapb.KeyspaceType(createKeyspaceOptions.KeyspaceType) { + case topodatapb.KeyspaceType_NORMAL, topodatapb.KeyspaceType_SNAPSHOT: + default: + return fmt.Errorf("invalid keyspace type passed to --type: %v", createKeyspaceOptions.KeyspaceType) + } + + var snapshotTime *vttime.Time + if topodatapb.KeyspaceType(createKeyspaceOptions.KeyspaceType) == topodatapb.KeyspaceType_SNAPSHOT { + if createKeyspaceOptions.BaseKeyspace == "" { + return errors.New("--base-keyspace is required for a snapshot keyspace") + } + + if createKeyspaceOptions.SnapshotTimestamp == "" { + return errors.New("--snapshot-timestamp is required for a snapshot keyspace") + } + + t, err := time.Parse(time.RFC3339, createKeyspaceOptions.SnapshotTimestamp) + if err != nil { + return fmt.Errorf("cannot parse --snapshot-timestamp as RFC3339: %w", err) + } + + if now := time.Now(); t.After(now) { + return fmt.Errorf("--snapshot-time cannot be in the future; snapshot = %v, now = %v", t, now) + } + + snapshotTime = logutil.TimeToProto(t) + } + + req := &vtctldatapb.CreateKeyspaceRequest{ + Name: name, + Force: createKeyspaceOptions.Force, + AllowEmptyVSchema: createKeyspaceOptions.AllowEmptyVSchema, + ShardingColumnName: createKeyspaceOptions.ShardingColumnName, + ShardingColumnType: topodatapb.KeyspaceIdType(createKeyspaceOptions.ShardingColumnType), + Type: topodatapb.KeyspaceType(createKeyspaceOptions.KeyspaceType), + BaseKeyspace: createKeyspaceOptions.BaseKeyspace, + SnapshotTime: snapshotTime, + } + + for n, v := range createKeyspaceOptions.ServedFromsMap.StringMapValue { + tt, err := topo.ParseServingTabletType(n) + if err != nil { + return err + } + + req.ServedFroms = append(req.ServedFroms, &topodatapb.Keyspace_ServedFrom{ + TabletType: tt, + Keyspace: v, + }) + } + + resp, err := client.CreateKeyspace(commandCtx, req) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.Keyspace) + if err != nil { + return err + } + + fmt.Printf("Successfully created keyspace %s. Result:\n%s\n", name, data) + + return nil +} + +var deleteKeyspaceOptions = struct { + Recursive bool +}{} + +func commandDeleteKeyspace(cmd *cobra.Command, args []string) error { + ks := cmd.Flags().Arg(0) + + _, err := client.DeleteKeyspace(commandCtx, &vtctldatapb.DeleteKeyspaceRequest{ + Keyspace: ks, + Recursive: deleteKeyspaceOptions.Recursive, + }) + if err != nil { + return fmt.Errorf("DeleteKeyspace(%v) error: %w; please check the topo", ks, err) + } + + fmt.Printf("Successfully deleted keyspace %v.\n", ks) + + return nil +} + func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { ks := cmd.Flags().Arg(0) resp, err := client.FindAllShardsInKeyspace(commandCtx, &vtctldatapb.FindAllShardsInKeyspaceRequest{ @@ -100,8 +229,50 @@ func commandGetKeyspaces(cmd *cobra.Command, args []string) error { return nil } +var removeKeyspaceCellOptions = struct { + Force bool + Recursive bool +}{} + +func commandRemoveKeyspaceCell(cmd *cobra.Command, args []string) error { + keyspace := cmd.Flags().Arg(0) + cell := cmd.Flags().Arg(1) + + _, err := client.RemoveKeyspaceCell(commandCtx, &vtctldatapb.RemoveKeyspaceCellRequest{ + Keyspace: keyspace, + Cell: cell, + Force: removeKeyspaceCellOptions.Force, + Recursive: removeKeyspaceCellOptions.Recursive, + }) + + if err != nil { + return err + } + + fmt.Printf("Successfully removed keyspace %s from cell %s\n", keyspace, cell) + + return nil +} + func init() { + CreateKeyspace.Flags().BoolVarP(&createKeyspaceOptions.Force, "force", "f", false, "Proceeds even if the keyspace already exists. Does not overwrite the existing keyspace record") + CreateKeyspace.Flags().BoolVarP(&createKeyspaceOptions.AllowEmptyVSchema, "allow-empty-vschema", "e", false, "Allows a new keyspace to have no vschema") + CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.ShardingColumnName, "sharding-column-name", "", "The column name to use for sharding operations") + CreateKeyspace.Flags().Var(&createKeyspaceOptions.ShardingColumnType, "sharding-column-type", "The type of the column to use for sharding operations") + CreateKeyspace.Flags().Var(&createKeyspaceOptions.ServedFromsMap, "served-from", "TODO") + CreateKeyspace.Flags().Var(&createKeyspaceOptions.KeyspaceType, "type", "The type of the keyspace") + CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.BaseKeyspace, "base-keyspace", "", "The base keyspace for a snapshot keyspace.") + CreateKeyspace.Flags().StringVar(&createKeyspaceOptions.SnapshotTimestamp, "snapshot-timestamp", "", "The snapshot time for a snapshot keyspace, as a timestamp in RFC3339 format.") + Root.AddCommand(CreateKeyspace) + + DeleteKeyspace.Flags().BoolVarP(&deleteKeyspaceOptions.Recursive, "recursive", "r", false, "Recursively delete all shards in the keyspace, and all tablets in those shards.") + Root.AddCommand(DeleteKeyspace) + Root.AddCommand(FindAllShardsInKeyspace) Root.AddCommand(GetKeyspace) Root.AddCommand(GetKeyspaces) + + RemoveKeyspaceCell.Flags().BoolVarP(&removeKeyspaceCellOptions.Force, "force", "f", false, "Proceed even if the cell's topology server cannot be reached. The assumption is that you turned down the entire cell, and just need to update the global topo data.") + RemoveKeyspaceCell.Flags().BoolVarP(&removeKeyspaceCellOptions.Recursive, "recursive", "r", false, "Also delete all tablets in that cell beloning to the specified keyspace.") + Root.AddCommand(RemoveKeyspaceCell) } diff --git a/go/cmd/vtctldclient/internal/command/shards.go b/go/cmd/vtctldclient/internal/command/shards.go new file mode 100644 index 00000000000..029e9be97fd --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/shards.go @@ -0,0 +1,182 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "fmt" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/topo/topoproto" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // CreateShard makes a CreateShard gRPC request to a vtctld. + CreateShard = &cobra.Command{ + Use: "CreateShard ", + Args: cobra.ExactArgs(1), + RunE: commandCreateShard, + } + // DeleteShards makes a DeleteShards gRPC request to a vtctld. + DeleteShards = &cobra.Command{ + Use: "DeleteShards [ ...]", + Args: cobra.MinimumNArgs(1), + RunE: commandDeleteShards, + } + // GetShard makes a GetShard gRPC request to a vtctld. + GetShard = &cobra.Command{ + Use: "GetShard ", + Args: cobra.ExactArgs(1), + RunE: commandGetShard, + } + // RemoveShardCell makes a RemoveShardCell gRPC request to a vtctld. + RemoveShardCell = &cobra.Command{ + Use: "RemoveShardCell ", + Args: cobra.ExactArgs(2), + RunE: commandRemoveShardCell, + } +) + +var createShardOptions = struct { + Force bool + IncludeParent bool +}{} + +func commandCreateShard(cmd *cobra.Command, args []string) error { + keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + resp, err := client.CreateShard(commandCtx, &vtctldatapb.CreateShardRequest{ + Keyspace: keyspace, + ShardName: shard, + Force: createShardOptions.Force, + IncludeParent: createShardOptions.IncludeParent, + }) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +var deleteShardsOptions = struct { + Recursive bool + EvenIfServing bool +}{} + +func commandDeleteShards(cmd *cobra.Command, args []string) error { + shards, err := cli.ParseKeyspaceShards(cmd.Flags().Args()) + if err != nil { + return err + } + + _, err = client.DeleteShards(commandCtx, &vtctldatapb.DeleteShardsRequest{ + Shards: shards, + EvenIfServing: deleteShardsOptions.EvenIfServing, + Recursive: deleteShardsOptions.Recursive, + }) + + if err != nil { + return fmt.Errorf("%w: while deleting %d shards; please inspect the topo", err, len(shards)) + } + + fmt.Printf("Successfully deleted %d shards\n", len(shards)) + + return nil +} + +func commandGetShard(cmd *cobra.Command, args []string) error { + keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + resp, err := client.GetShard(commandCtx, &vtctldatapb.GetShardRequest{ + Keyspace: keyspace, + ShardName: shard, + }) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.Shard) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +var removeShardCellOptions = struct { + Force bool + Recursive bool +}{} + +func commandRemoveShardCell(cmd *cobra.Command, args []string) error { + keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + cell := cmd.Flags().Arg(1) + + _, err = client.RemoveShardCell(commandCtx, &vtctldatapb.RemoveShardCellRequest{ + Keyspace: keyspace, + ShardName: shard, + Cell: cell, + Force: removeShardCellOptions.Force, + Recursive: removeShardCellOptions.Recursive, + }) + + if err != nil { + return err + } + + fmt.Printf("Successfully removed cell %v from shard %s/%s\n", cell, keyspace, shard) + + return nil +} + +func init() { + CreateShard.Flags().BoolVarP(&createShardOptions.Force, "force", "f", false, "") + CreateShard.Flags().BoolVarP(&createShardOptions.IncludeParent, "include-parent", "p", false, "") + Root.AddCommand(CreateShard) + + DeleteShards.Flags().BoolVarP(&deleteShardsOptions.Recursive, "recursive", "r", false, "Also delete all tablets belonging to the shard. This is required to delete a non-empty shard.") + DeleteShards.Flags().BoolVarP(&deleteShardsOptions.EvenIfServing, "even-if-serving", "f", false, "Remove the shard even if it is serving. Use with caution.") + Root.AddCommand(DeleteShards) + + Root.AddCommand(GetShard) + + RemoveShardCell.Flags().BoolVarP(&removeShardCellOptions.Force, "force", "f", false, "Proceed even if the cell's topology server cannot be reached. The assumption is that you turned down the entire cell, and just need to update the global topo data.") + RemoveShardCell.Flags().BoolVarP(&removeShardCellOptions.Recursive, "recursive", "r", false, "Also delete all tablets in that cell beloning to the specified shard.") + Root.AddCommand(RemoveShardCell) +} diff --git a/go/cmd/vtctldclient/internal/command/tablets.go b/go/cmd/vtctldclient/internal/command/tablets.go index 1beaaa2751a..5b56ff38d32 100644 --- a/go/cmd/vtctldclient/internal/command/tablets.go +++ b/go/cmd/vtctldclient/internal/command/tablets.go @@ -19,20 +19,28 @@ package command import ( "fmt" "strings" - "time" "github.com/spf13/cobra" "vitess.io/vitess/go/cmd/vtctldclient/cli" - "vitess.io/vitess/go/vt/logutil" - "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) var ( + // ChangeTabletType makes a ChangeTabletType gRPC call to a vtctld. + ChangeTabletType = &cobra.Command{ + Use: "ChangeTabletType [--dry-run] TABLET_ALIAS TABLET_TYPE", + Args: cobra.ExactArgs(2), + RunE: commandChangeTabletType, + } + // DeleteTablets makes a DeleteTablets gRPC call to a vtctld. + DeleteTablets = &cobra.Command{ + Use: "DeleteTablets TABLET_ALIAS [ TABLET_ALIAS ... ]", + Args: cobra.MinimumNArgs(1), + RunE: commandDeleteTablets, + } // GetTablet makes a GetTablet gRPC call to a vtctld. GetTablet = &cobra.Command{ Use: "GetTablet alias", @@ -47,6 +55,67 @@ var ( } ) +var changeTabletTypeOptions = struct { + DryRun bool +}{} + +func commandChangeTabletType(cmd *cobra.Command, args []string) error { + aliasStr := cmd.Flags().Arg(0) + typeStr := cmd.Flags().Arg(1) + + alias, err := topoproto.ParseTabletAlias(aliasStr) + if err != nil { + return err + } + + newType, err := topoproto.ParseTabletType(typeStr) + if err != nil { + return err + } + + resp, err := client.ChangeTabletType(commandCtx, &vtctldatapb.ChangeTabletTypeRequest{ + TabletAlias: alias, + DbType: newType, + DryRun: changeTabletTypeOptions.DryRun, + }) + if err != nil { + return err + } + + if resp.WasDryRun { + fmt.Println("--- DRY RUN ---") + } + + fmt.Printf("- %v\n", cli.MarshalTabletAWK(resp.BeforeTablet)) + fmt.Printf("+ %v\n", cli.MarshalTabletAWK(resp.AfterTablet)) + + return nil +} + +var deleteTabletsOptions = struct { + AllowPrimary bool +}{} + +func commandDeleteTablets(cmd *cobra.Command, args []string) error { + aliases, err := cli.TabletAliasesFromPosArgs(cmd.Flags().Args()) + if err != nil { + return err + } + + _, err = client.DeleteTablets(commandCtx, &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: aliases, + AllowPrimary: deleteTabletsOptions.AllowPrimary, + }) + + if err != nil { + return fmt.Errorf("%w: while deleting %d tablets; please inspect the topo", err, len(aliases)) + } + + fmt.Printf("Successfully deleted %d tablets\n", len(aliases)) + + return nil +} + func commandGetTablet(cmd *cobra.Command, args []string) error { aliasStr := cmd.Flags().Arg(0) alias, err := topoproto.ParseTabletAlias(aliasStr) @@ -101,33 +170,8 @@ func commandGetTablets(cmd *cobra.Command, args []string) error { switch format { case "awk": - lineFn := func(t *topodatapb.Tablet) string { - ti := topo.TabletInfo{ - Tablet: t, - } - - keyspace := t.Keyspace - if keyspace == "" { - keyspace = "" - } - - shard := t.Shard - if shard == "" { - shard = "" - } - - mtst := "" - // special case for old primary that hasn't been updated in the topo - // yet. - if t.MasterTermStartTime != nil && t.MasterTermStartTime.Seconds > 0 { - mtst = logutil.ProtoToTime(t.MasterTermStartTime).Format(time.RFC3339) - } - - return fmt.Sprintf("%v %v %v %v %v %v %v %v", topoproto.TabletAliasString(t.Alias), keyspace, shard, topoproto.TabletTypeLString(t.Type), ti.Addr(), ti.MysqlAddr(), cli.MarshalMapAWK(t.Tags), mtst) - } - for _, t := range resp.Tablets { - fmt.Println(lineFn(t)) + fmt.Println(cli.MarshalTabletAWK(t)) } case "json": data, err := cli.MarshalJSON(resp.Tablets) @@ -142,6 +186,12 @@ func commandGetTablets(cmd *cobra.Command, args []string) error { } func init() { + ChangeTabletType.Flags().BoolVarP(&changeTabletTypeOptions.DryRun, "dry-run", "d", false, "Shows the proposed change without actually executing it") + Root.AddCommand(ChangeTabletType) + + DeleteTablets.Flags().BoolVarP(&deleteTabletsOptions.AllowPrimary, "allow-primary", "p", false, "Allow the primary tablet of a shard to be deleted. Use with caution.") + Root.AddCommand(DeleteTablets) + Root.AddCommand(GetTablet) GetTablets.Flags().StringSliceVarP(&getTabletsOptions.Cells, "cell", "c", nil, "list of cells to filter tablets by") diff --git a/go/vt/key/key.go b/go/vt/key/key.go index 98143a1ff13..858e64406cf 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -62,6 +62,16 @@ func ParseKeyspaceIDType(param string) (topodatapb.KeyspaceIdType, error) { return topodatapb.KeyspaceIdType(value), nil } +// KeyspaceIDTypeString returns the string representation of a keyspace id type. +func KeyspaceIDTypeString(id topodatapb.KeyspaceIdType) string { + s, ok := topodatapb.KeyspaceIdType_name[int32(id)] + if !ok { + return KeyspaceIDTypeString(topodatapb.KeyspaceIdType_UNSET) + } + + return s +} + // // KeyRange helper methods // @@ -185,7 +195,7 @@ func KeyRangeEqual(left, right *topodatapb.KeyRange) bool { bytes.Equal(left.End, right.End) } -// KeyRangeStartEqual returns true if right's keyrange start is _after_ left's start +// KeyRangeStartSmaller returns true if right's keyrange start is _after_ left's start func KeyRangeStartSmaller(left, right *topodatapb.KeyRange) bool { if left == nil { return right != nil diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index 5df50ab9dc0..75a2108d406 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -1383,9 +1383,6 @@ func (m *VEvent) GetJournal() *Journal { func (m *VEvent) GetDml() string { if m != nil { - if m.Statement != "" { - return m.Statement - } return m.Dml } return "" diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 5b42a77c754..0180e99e138 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -13,6 +13,7 @@ import ( tabletmanagerdata "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodata "vitess.io/vitess/go/vt/proto/topodata" vschema "vitess.io/vitess/go/vt/proto/vschema" + vttime "vitess.io/vitess/go/vt/proto/vttime" ) // Reference imports to suppress errors if they are not otherwise used. @@ -115,6 +116,657 @@ func (m *ExecuteVtctlCommandResponse) GetEvent() *logutil.Event { return nil } +type ChangeTabletTypeRequest struct { + TabletAlias *topodata.TabletAlias `protobuf:"bytes,1,opt,name=tablet_alias,json=tabletAlias,proto3" json:"tablet_alias,omitempty"` + DbType topodata.TabletType `protobuf:"varint,2,opt,name=db_type,json=dbType,proto3,enum=topodata.TabletType" json:"db_type,omitempty"` + DryRun bool `protobuf:"varint,3,opt,name=dry_run,json=dryRun,proto3" json:"dry_run,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ChangeTabletTypeRequest) Reset() { *m = ChangeTabletTypeRequest{} } +func (m *ChangeTabletTypeRequest) String() string { return proto.CompactTextString(m) } +func (*ChangeTabletTypeRequest) ProtoMessage() {} +func (*ChangeTabletTypeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{2} +} + +func (m *ChangeTabletTypeRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ChangeTabletTypeRequest.Unmarshal(m, b) +} +func (m *ChangeTabletTypeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ChangeTabletTypeRequest.Marshal(b, m, deterministic) +} +func (m *ChangeTabletTypeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangeTabletTypeRequest.Merge(m, src) +} +func (m *ChangeTabletTypeRequest) XXX_Size() int { + return xxx_messageInfo_ChangeTabletTypeRequest.Size(m) +} +func (m *ChangeTabletTypeRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ChangeTabletTypeRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ChangeTabletTypeRequest proto.InternalMessageInfo + +func (m *ChangeTabletTypeRequest) GetTabletAlias() *topodata.TabletAlias { + if m != nil { + return m.TabletAlias + } + return nil +} + +func (m *ChangeTabletTypeRequest) GetDbType() topodata.TabletType { + if m != nil { + return m.DbType + } + return topodata.TabletType_UNKNOWN +} + +func (m *ChangeTabletTypeRequest) GetDryRun() bool { + if m != nil { + return m.DryRun + } + return false +} + +type ChangeTabletTypeResponse struct { + BeforeTablet *topodata.Tablet `protobuf:"bytes,1,opt,name=before_tablet,json=beforeTablet,proto3" json:"before_tablet,omitempty"` + AfterTablet *topodata.Tablet `protobuf:"bytes,2,opt,name=after_tablet,json=afterTablet,proto3" json:"after_tablet,omitempty"` + WasDryRun bool `protobuf:"varint,3,opt,name=was_dry_run,json=wasDryRun,proto3" json:"was_dry_run,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ChangeTabletTypeResponse) Reset() { *m = ChangeTabletTypeResponse{} } +func (m *ChangeTabletTypeResponse) String() string { return proto.CompactTextString(m) } +func (*ChangeTabletTypeResponse) ProtoMessage() {} +func (*ChangeTabletTypeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{3} +} + +func (m *ChangeTabletTypeResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ChangeTabletTypeResponse.Unmarshal(m, b) +} +func (m *ChangeTabletTypeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ChangeTabletTypeResponse.Marshal(b, m, deterministic) +} +func (m *ChangeTabletTypeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangeTabletTypeResponse.Merge(m, src) +} +func (m *ChangeTabletTypeResponse) XXX_Size() int { + return xxx_messageInfo_ChangeTabletTypeResponse.Size(m) +} +func (m *ChangeTabletTypeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ChangeTabletTypeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ChangeTabletTypeResponse proto.InternalMessageInfo + +func (m *ChangeTabletTypeResponse) GetBeforeTablet() *topodata.Tablet { + if m != nil { + return m.BeforeTablet + } + return nil +} + +func (m *ChangeTabletTypeResponse) GetAfterTablet() *topodata.Tablet { + if m != nil { + return m.AfterTablet + } + return nil +} + +func (m *ChangeTabletTypeResponse) GetWasDryRun() bool { + if m != nil { + return m.WasDryRun + } + return false +} + +type CreateKeyspaceRequest struct { + // Name is the name of the keyspace. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Force proceeds with the request even if the keyspace already exists. + Force bool `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"` + // AllowEmptyVSchema allows a keyspace to be created with no vschema. + AllowEmptyVSchema bool `protobuf:"varint,3,opt,name=allow_empty_v_schema,json=allowEmptyVSchema,proto3" json:"allow_empty_v_schema,omitempty"` + // ShardingColumnName specifies the column to use for sharding operations. + ShardingColumnName string `protobuf:"bytes,4,opt,name=sharding_column_name,json=shardingColumnName,proto3" json:"sharding_column_name,omitempty"` + // ShardingColumnType specifies the type of the column to use for sharding + // operations. + ShardingColumnType topodata.KeyspaceIdType `protobuf:"varint,5,opt,name=sharding_column_type,json=shardingColumnType,proto3,enum=topodata.KeyspaceIdType" json:"sharding_column_type,omitempty"` + // ServedFroms specifies a set of db_type:keyspace pairs used to serve + // traffic for the keyspace. + ServedFroms []*topodata.Keyspace_ServedFrom `protobuf:"bytes,6,rep,name=served_froms,json=servedFroms,proto3" json:"served_froms,omitempty"` + // Type is the type of the keyspace to create. + Type topodata.KeyspaceType `protobuf:"varint,7,opt,name=type,proto3,enum=topodata.KeyspaceType" json:"type,omitempty"` + // BaseKeyspace specifies the base keyspace for SNAPSHOT keyspaces. It is + // required to create a SNAPSHOT keyspace. + BaseKeyspace string `protobuf:"bytes,8,opt,name=base_keyspace,json=baseKeyspace,proto3" json:"base_keyspace,omitempty"` + // SnapshotTime specifies the snapshot time for this keyspace. It is required + // to create a SNAPSHOT keyspace. + SnapshotTime *vttime.Time `protobuf:"bytes,9,opt,name=snapshot_time,json=snapshotTime,proto3" json:"snapshot_time,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateKeyspaceRequest) Reset() { *m = CreateKeyspaceRequest{} } +func (m *CreateKeyspaceRequest) String() string { return proto.CompactTextString(m) } +func (*CreateKeyspaceRequest) ProtoMessage() {} +func (*CreateKeyspaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{4} +} + +func (m *CreateKeyspaceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateKeyspaceRequest.Unmarshal(m, b) +} +func (m *CreateKeyspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateKeyspaceRequest.Marshal(b, m, deterministic) +} +func (m *CreateKeyspaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateKeyspaceRequest.Merge(m, src) +} +func (m *CreateKeyspaceRequest) XXX_Size() int { + return xxx_messageInfo_CreateKeyspaceRequest.Size(m) +} +func (m *CreateKeyspaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CreateKeyspaceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateKeyspaceRequest proto.InternalMessageInfo + +func (m *CreateKeyspaceRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *CreateKeyspaceRequest) GetForce() bool { + if m != nil { + return m.Force + } + return false +} + +func (m *CreateKeyspaceRequest) GetAllowEmptyVSchema() bool { + if m != nil { + return m.AllowEmptyVSchema + } + return false +} + +func (m *CreateKeyspaceRequest) GetShardingColumnName() string { + if m != nil { + return m.ShardingColumnName + } + return "" +} + +func (m *CreateKeyspaceRequest) GetShardingColumnType() topodata.KeyspaceIdType { + if m != nil { + return m.ShardingColumnType + } + return topodata.KeyspaceIdType_UNSET +} + +func (m *CreateKeyspaceRequest) GetServedFroms() []*topodata.Keyspace_ServedFrom { + if m != nil { + return m.ServedFroms + } + return nil +} + +func (m *CreateKeyspaceRequest) GetType() topodata.KeyspaceType { + if m != nil { + return m.Type + } + return topodata.KeyspaceType_NORMAL +} + +func (m *CreateKeyspaceRequest) GetBaseKeyspace() string { + if m != nil { + return m.BaseKeyspace + } + return "" +} + +func (m *CreateKeyspaceRequest) GetSnapshotTime() *vttime.Time { + if m != nil { + return m.SnapshotTime + } + return nil +} + +type CreateKeyspaceResponse struct { + // Keyspace is the newly-created keyspace. + Keyspace *Keyspace `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateKeyspaceResponse) Reset() { *m = CreateKeyspaceResponse{} } +func (m *CreateKeyspaceResponse) String() string { return proto.CompactTextString(m) } +func (*CreateKeyspaceResponse) ProtoMessage() {} +func (*CreateKeyspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{5} +} + +func (m *CreateKeyspaceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateKeyspaceResponse.Unmarshal(m, b) +} +func (m *CreateKeyspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateKeyspaceResponse.Marshal(b, m, deterministic) +} +func (m *CreateKeyspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateKeyspaceResponse.Merge(m, src) +} +func (m *CreateKeyspaceResponse) XXX_Size() int { + return xxx_messageInfo_CreateKeyspaceResponse.Size(m) +} +func (m *CreateKeyspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CreateKeyspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateKeyspaceResponse proto.InternalMessageInfo + +func (m *CreateKeyspaceResponse) GetKeyspace() *Keyspace { + if m != nil { + return m.Keyspace + } + return nil +} + +type CreateShardRequest struct { + // Keyspace is the name of the keyspace to create the shard in. + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + // ShardName is the name of the shard to create. E.g. "-" or "-80". + ShardName string `protobuf:"bytes,2,opt,name=shard_name,json=shardName,proto3" json:"shard_name,omitempty"` + // Force treats an attempt to create a shard that already exists as a + // non-error. + Force bool `protobuf:"varint,3,opt,name=force,proto3" json:"force,omitempty"` + // IncludeParent creates the parent keyspace as an empty BASE keyspace, if it + // doesn't already exist. + IncludeParent bool `protobuf:"varint,4,opt,name=include_parent,json=includeParent,proto3" json:"include_parent,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateShardRequest) Reset() { *m = CreateShardRequest{} } +func (m *CreateShardRequest) String() string { return proto.CompactTextString(m) } +func (*CreateShardRequest) ProtoMessage() {} +func (*CreateShardRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{6} +} + +func (m *CreateShardRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateShardRequest.Unmarshal(m, b) +} +func (m *CreateShardRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateShardRequest.Marshal(b, m, deterministic) +} +func (m *CreateShardRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateShardRequest.Merge(m, src) +} +func (m *CreateShardRequest) XXX_Size() int { + return xxx_messageInfo_CreateShardRequest.Size(m) +} +func (m *CreateShardRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CreateShardRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateShardRequest proto.InternalMessageInfo + +func (m *CreateShardRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *CreateShardRequest) GetShardName() string { + if m != nil { + return m.ShardName + } + return "" +} + +func (m *CreateShardRequest) GetForce() bool { + if m != nil { + return m.Force + } + return false +} + +func (m *CreateShardRequest) GetIncludeParent() bool { + if m != nil { + return m.IncludeParent + } + return false +} + +type CreateShardResponse struct { + // Keyspace is the created keyspace. It is set only if IncludeParent was + // specified in the request and the parent keyspace needed to be created. + Keyspace *Keyspace `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + // Shard is the newly-created shard object. + Shard *Shard `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` + // ShardAlreadyExists is set if Force was specified in the request and the + // shard already existed. + ShardAlreadyExists bool `protobuf:"varint,3,opt,name=shard_already_exists,json=shardAlreadyExists,proto3" json:"shard_already_exists,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateShardResponse) Reset() { *m = CreateShardResponse{} } +func (m *CreateShardResponse) String() string { return proto.CompactTextString(m) } +func (*CreateShardResponse) ProtoMessage() {} +func (*CreateShardResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{7} +} + +func (m *CreateShardResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateShardResponse.Unmarshal(m, b) +} +func (m *CreateShardResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateShardResponse.Marshal(b, m, deterministic) +} +func (m *CreateShardResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateShardResponse.Merge(m, src) +} +func (m *CreateShardResponse) XXX_Size() int { + return xxx_messageInfo_CreateShardResponse.Size(m) +} +func (m *CreateShardResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CreateShardResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateShardResponse proto.InternalMessageInfo + +func (m *CreateShardResponse) GetKeyspace() *Keyspace { + if m != nil { + return m.Keyspace + } + return nil +} + +func (m *CreateShardResponse) GetShard() *Shard { + if m != nil { + return m.Shard + } + return nil +} + +func (m *CreateShardResponse) GetShardAlreadyExists() bool { + if m != nil { + return m.ShardAlreadyExists + } + return false +} + +type DeleteKeyspaceRequest struct { + // Keyspace is the name of the keyspace to delete. + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + // Recursive causes all shards in the keyspace to be recursively deleted + // before deleting the keyspace. It is an error to call DeleteKeyspace on a + // non-empty keyspace without also specifying Recursive. + Recursive bool `protobuf:"varint,2,opt,name=recursive,proto3" json:"recursive,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteKeyspaceRequest) Reset() { *m = DeleteKeyspaceRequest{} } +func (m *DeleteKeyspaceRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteKeyspaceRequest) ProtoMessage() {} +func (*DeleteKeyspaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{8} +} + +func (m *DeleteKeyspaceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteKeyspaceRequest.Unmarshal(m, b) +} +func (m *DeleteKeyspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteKeyspaceRequest.Marshal(b, m, deterministic) +} +func (m *DeleteKeyspaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteKeyspaceRequest.Merge(m, src) +} +func (m *DeleteKeyspaceRequest) XXX_Size() int { + return xxx_messageInfo_DeleteKeyspaceRequest.Size(m) +} +func (m *DeleteKeyspaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteKeyspaceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteKeyspaceRequest proto.InternalMessageInfo + +func (m *DeleteKeyspaceRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *DeleteKeyspaceRequest) GetRecursive() bool { + if m != nil { + return m.Recursive + } + return false +} + +type DeleteKeyspaceResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteKeyspaceResponse) Reset() { *m = DeleteKeyspaceResponse{} } +func (m *DeleteKeyspaceResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteKeyspaceResponse) ProtoMessage() {} +func (*DeleteKeyspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{9} +} + +func (m *DeleteKeyspaceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteKeyspaceResponse.Unmarshal(m, b) +} +func (m *DeleteKeyspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteKeyspaceResponse.Marshal(b, m, deterministic) +} +func (m *DeleteKeyspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteKeyspaceResponse.Merge(m, src) +} +func (m *DeleteKeyspaceResponse) XXX_Size() int { + return xxx_messageInfo_DeleteKeyspaceResponse.Size(m) +} +func (m *DeleteKeyspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteKeyspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteKeyspaceResponse proto.InternalMessageInfo + +type DeleteShardsRequest struct { + // Shards is the list of shards to delete. The nested topodatapb.Shard field + // is not required for DeleteShard, but the Keyspace and Shard fields are. + Shards []*Shard `protobuf:"bytes,1,rep,name=shards,proto3" json:"shards,omitempty"` + // Recursive also deletes all tablets belonging to the shard(s). It is an + // error to call DeleteShard on a non-empty shard without also specificying + // Recursive. + Recursive bool `protobuf:"varint,2,opt,name=recursive,proto3" json:"recursive,omitempty"` + // EvenIfServing allows a shard to be deleted even if it is serving, which is + // normally an error. Use with caution. + EvenIfServing bool `protobuf:"varint,4,opt,name=even_if_serving,json=evenIfServing,proto3" json:"even_if_serving,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteShardsRequest) Reset() { *m = DeleteShardsRequest{} } +func (m *DeleteShardsRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteShardsRequest) ProtoMessage() {} +func (*DeleteShardsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{10} +} + +func (m *DeleteShardsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteShardsRequest.Unmarshal(m, b) +} +func (m *DeleteShardsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteShardsRequest.Marshal(b, m, deterministic) +} +func (m *DeleteShardsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteShardsRequest.Merge(m, src) +} +func (m *DeleteShardsRequest) XXX_Size() int { + return xxx_messageInfo_DeleteShardsRequest.Size(m) +} +func (m *DeleteShardsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteShardsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteShardsRequest proto.InternalMessageInfo + +func (m *DeleteShardsRequest) GetShards() []*Shard { + if m != nil { + return m.Shards + } + return nil +} + +func (m *DeleteShardsRequest) GetRecursive() bool { + if m != nil { + return m.Recursive + } + return false +} + +func (m *DeleteShardsRequest) GetEvenIfServing() bool { + if m != nil { + return m.EvenIfServing + } + return false +} + +type DeleteShardsResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteShardsResponse) Reset() { *m = DeleteShardsResponse{} } +func (m *DeleteShardsResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteShardsResponse) ProtoMessage() {} +func (*DeleteShardsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{11} +} + +func (m *DeleteShardsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteShardsResponse.Unmarshal(m, b) +} +func (m *DeleteShardsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteShardsResponse.Marshal(b, m, deterministic) +} +func (m *DeleteShardsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteShardsResponse.Merge(m, src) +} +func (m *DeleteShardsResponse) XXX_Size() int { + return xxx_messageInfo_DeleteShardsResponse.Size(m) +} +func (m *DeleteShardsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteShardsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteShardsResponse proto.InternalMessageInfo + +type DeleteTabletsRequest struct { + // TabletAliases is the list of tablets to delete. + TabletAliases []*topodata.TabletAlias `protobuf:"bytes,1,rep,name=tablet_aliases,json=tabletAliases,proto3" json:"tablet_aliases,omitempty"` + // AllowPrimary allows for the master/primary tablet of a shard to be deleted. + // Use with caution. + AllowPrimary bool `protobuf:"varint,2,opt,name=allow_primary,json=allowPrimary,proto3" json:"allow_primary,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteTabletsRequest) Reset() { *m = DeleteTabletsRequest{} } +func (m *DeleteTabletsRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteTabletsRequest) ProtoMessage() {} +func (*DeleteTabletsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{12} +} + +func (m *DeleteTabletsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteTabletsRequest.Unmarshal(m, b) +} +func (m *DeleteTabletsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteTabletsRequest.Marshal(b, m, deterministic) +} +func (m *DeleteTabletsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteTabletsRequest.Merge(m, src) +} +func (m *DeleteTabletsRequest) XXX_Size() int { + return xxx_messageInfo_DeleteTabletsRequest.Size(m) +} +func (m *DeleteTabletsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteTabletsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteTabletsRequest proto.InternalMessageInfo + +func (m *DeleteTabletsRequest) GetTabletAliases() []*topodata.TabletAlias { + if m != nil { + return m.TabletAliases + } + return nil +} + +func (m *DeleteTabletsRequest) GetAllowPrimary() bool { + if m != nil { + return m.AllowPrimary + } + return false +} + +type DeleteTabletsResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteTabletsResponse) Reset() { *m = DeleteTabletsResponse{} } +func (m *DeleteTabletsResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteTabletsResponse) ProtoMessage() {} +func (*DeleteTabletsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{13} +} + +func (m *DeleteTabletsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteTabletsResponse.Unmarshal(m, b) +} +func (m *DeleteTabletsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteTabletsResponse.Marshal(b, m, deterministic) +} +func (m *DeleteTabletsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteTabletsResponse.Merge(m, src) +} +func (m *DeleteTabletsResponse) XXX_Size() int { + return xxx_messageInfo_DeleteTabletsResponse.Size(m) +} +func (m *DeleteTabletsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteTabletsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteTabletsResponse proto.InternalMessageInfo + type GetBackupsRequest struct { Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` @@ -127,7 +779,7 @@ func (m *GetBackupsRequest) Reset() { *m = GetBackupsRequest{} } func (m *GetBackupsRequest) String() string { return proto.CompactTextString(m) } func (*GetBackupsRequest) ProtoMessage() {} func (*GetBackupsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{2} + return fileDescriptor_f41247b323a1ab2e, []int{14} } func (m *GetBackupsRequest) XXX_Unmarshal(b []byte) error { @@ -173,7 +825,7 @@ func (m *GetBackupsResponse) Reset() { *m = GetBackupsResponse{} } func (m *GetBackupsResponse) String() string { return proto.CompactTextString(m) } func (*GetBackupsResponse) ProtoMessage() {} func (*GetBackupsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{3} + return fileDescriptor_f41247b323a1ab2e, []int{15} } func (m *GetBackupsResponse) XXX_Unmarshal(b []byte) error { @@ -211,7 +863,7 @@ func (m *GetCellInfoNamesRequest) Reset() { *m = GetCellInfoNamesRequest func (m *GetCellInfoNamesRequest) String() string { return proto.CompactTextString(m) } func (*GetCellInfoNamesRequest) ProtoMessage() {} func (*GetCellInfoNamesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{4} + return fileDescriptor_f41247b323a1ab2e, []int{16} } func (m *GetCellInfoNamesRequest) XXX_Unmarshal(b []byte) error { @@ -243,7 +895,7 @@ func (m *GetCellInfoNamesResponse) Reset() { *m = GetCellInfoNamesRespon func (m *GetCellInfoNamesResponse) String() string { return proto.CompactTextString(m) } func (*GetCellInfoNamesResponse) ProtoMessage() {} func (*GetCellInfoNamesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{5} + return fileDescriptor_f41247b323a1ab2e, []int{17} } func (m *GetCellInfoNamesResponse) XXX_Unmarshal(b []byte) error { @@ -282,7 +934,7 @@ func (m *GetCellInfoRequest) Reset() { *m = GetCellInfoRequest{} } func (m *GetCellInfoRequest) String() string { return proto.CompactTextString(m) } func (*GetCellInfoRequest) ProtoMessage() {} func (*GetCellInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{6} + return fileDescriptor_f41247b323a1ab2e, []int{18} } func (m *GetCellInfoRequest) XXX_Unmarshal(b []byte) error { @@ -321,7 +973,7 @@ func (m *GetCellInfoResponse) Reset() { *m = GetCellInfoResponse{} } func (m *GetCellInfoResponse) String() string { return proto.CompactTextString(m) } func (*GetCellInfoResponse) ProtoMessage() {} func (*GetCellInfoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{7} + return fileDescriptor_f41247b323a1ab2e, []int{19} } func (m *GetCellInfoResponse) XXX_Unmarshal(b []byte) error { @@ -359,7 +1011,7 @@ func (m *GetCellsAliasesRequest) Reset() { *m = GetCellsAliasesRequest{} func (m *GetCellsAliasesRequest) String() string { return proto.CompactTextString(m) } func (*GetCellsAliasesRequest) ProtoMessage() {} func (*GetCellsAliasesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{8} + return fileDescriptor_f41247b323a1ab2e, []int{20} } func (m *GetCellsAliasesRequest) XXX_Unmarshal(b []byte) error { @@ -391,7 +1043,7 @@ func (m *GetCellsAliasesResponse) Reset() { *m = GetCellsAliasesResponse func (m *GetCellsAliasesResponse) String() string { return proto.CompactTextString(m) } func (*GetCellsAliasesResponse) ProtoMessage() {} func (*GetCellsAliasesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{9} + return fileDescriptor_f41247b323a1ab2e, []int{21} } func (m *GetCellsAliasesResponse) XXX_Unmarshal(b []byte) error { @@ -429,7 +1081,7 @@ func (m *GetKeyspacesRequest) Reset() { *m = GetKeyspacesRequest{} } func (m *GetKeyspacesRequest) String() string { return proto.CompactTextString(m) } func (*GetKeyspacesRequest) ProtoMessage() {} func (*GetKeyspacesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{10} + return fileDescriptor_f41247b323a1ab2e, []int{22} } func (m *GetKeyspacesRequest) XXX_Unmarshal(b []byte) error { @@ -461,7 +1113,7 @@ func (m *GetKeyspacesResponse) Reset() { *m = GetKeyspacesResponse{} } func (m *GetKeyspacesResponse) String() string { return proto.CompactTextString(m) } func (*GetKeyspacesResponse) ProtoMessage() {} func (*GetKeyspacesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{11} + return fileDescriptor_f41247b323a1ab2e, []int{23} } func (m *GetKeyspacesResponse) XXX_Unmarshal(b []byte) error { @@ -500,7 +1152,7 @@ func (m *GetKeyspaceRequest) Reset() { *m = GetKeyspaceRequest{} } func (m *GetKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*GetKeyspaceRequest) ProtoMessage() {} func (*GetKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{12} + return fileDescriptor_f41247b323a1ab2e, []int{24} } func (m *GetKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -539,7 +1191,7 @@ func (m *GetKeyspaceResponse) Reset() { *m = GetKeyspaceResponse{} } func (m *GetKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*GetKeyspaceResponse) ProtoMessage() {} func (*GetKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{13} + return fileDescriptor_f41247b323a1ab2e, []int{25} } func (m *GetKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -593,7 +1245,7 @@ func (m *GetSchemaRequest) Reset() { *m = GetSchemaRequest{} } func (m *GetSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetSchemaRequest) ProtoMessage() {} func (*GetSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{14} + return fileDescriptor_f41247b323a1ab2e, []int{26} } func (m *GetSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -667,7 +1319,7 @@ func (m *GetSchemaResponse) Reset() { *m = GetSchemaResponse{} } func (m *GetSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetSchemaResponse) ProtoMessage() {} func (*GetSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{15} + return fileDescriptor_f41247b323a1ab2e, []int{27} } func (m *GetSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -695,6 +1347,92 @@ func (m *GetSchemaResponse) GetSchema() *tabletmanagerdata.SchemaDefinition { return nil } +type GetShardRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + ShardName string `protobuf:"bytes,2,opt,name=shard_name,json=shardName,proto3" json:"shard_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetShardRequest) Reset() { *m = GetShardRequest{} } +func (m *GetShardRequest) String() string { return proto.CompactTextString(m) } +func (*GetShardRequest) ProtoMessage() {} +func (*GetShardRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{28} +} + +func (m *GetShardRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetShardRequest.Unmarshal(m, b) +} +func (m *GetShardRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetShardRequest.Marshal(b, m, deterministic) +} +func (m *GetShardRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetShardRequest.Merge(m, src) +} +func (m *GetShardRequest) XXX_Size() int { + return xxx_messageInfo_GetShardRequest.Size(m) +} +func (m *GetShardRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetShardRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetShardRequest proto.InternalMessageInfo + +func (m *GetShardRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *GetShardRequest) GetShardName() string { + if m != nil { + return m.ShardName + } + return "" +} + +type GetShardResponse struct { + Shard *Shard `protobuf:"bytes,1,opt,name=shard,proto3" json:"shard,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetShardResponse) Reset() { *m = GetShardResponse{} } +func (m *GetShardResponse) String() string { return proto.CompactTextString(m) } +func (*GetShardResponse) ProtoMessage() {} +func (*GetShardResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{29} +} + +func (m *GetShardResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetShardResponse.Unmarshal(m, b) +} +func (m *GetShardResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetShardResponse.Marshal(b, m, deterministic) +} +func (m *GetShardResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetShardResponse.Merge(m, src) +} +func (m *GetShardResponse) XXX_Size() int { + return xxx_messageInfo_GetShardResponse.Size(m) +} +func (m *GetShardResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetShardResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetShardResponse proto.InternalMessageInfo + +func (m *GetShardResponse) GetShard() *Shard { + if m != nil { + return m.Shard + } + return nil +} + type GetSrvVSchemaRequest struct { Cell string `protobuf:"bytes,1,opt,name=cell,proto3" json:"cell,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -706,7 +1444,7 @@ func (m *GetSrvVSchemaRequest) Reset() { *m = GetSrvVSchemaRequest{} } func (m *GetSrvVSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetSrvVSchemaRequest) ProtoMessage() {} func (*GetSrvVSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{16} + return fileDescriptor_f41247b323a1ab2e, []int{30} } func (m *GetSrvVSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -745,7 +1483,7 @@ func (m *GetSrvVSchemaResponse) Reset() { *m = GetSrvVSchemaResponse{} } func (m *GetSrvVSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetSrvVSchemaResponse) ProtoMessage() {} func (*GetSrvVSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{17} + return fileDescriptor_f41247b323a1ab2e, []int{31} } func (m *GetSrvVSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -784,7 +1522,7 @@ func (m *GetTabletRequest) Reset() { *m = GetTabletRequest{} } func (m *GetTabletRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletRequest) ProtoMessage() {} func (*GetTabletRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{18} + return fileDescriptor_f41247b323a1ab2e, []int{32} } func (m *GetTabletRequest) XXX_Unmarshal(b []byte) error { @@ -823,7 +1561,7 @@ func (m *GetTabletResponse) Reset() { *m = GetTabletResponse{} } func (m *GetTabletResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletResponse) ProtoMessage() {} func (*GetTabletResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{19} + return fileDescriptor_f41247b323a1ab2e, []int{33} } func (m *GetTabletResponse) XXX_Unmarshal(b []byte) error { @@ -869,7 +1607,7 @@ func (m *GetTabletsRequest) Reset() { *m = GetTabletsRequest{} } func (m *GetTabletsRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletsRequest) ProtoMessage() {} func (*GetTabletsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{20} + return fileDescriptor_f41247b323a1ab2e, []int{34} } func (m *GetTabletsRequest) XXX_Unmarshal(b []byte) error { @@ -922,7 +1660,7 @@ func (m *GetTabletsResponse) Reset() { *m = GetTabletsResponse{} } func (m *GetTabletsResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletsResponse) ProtoMessage() {} func (*GetTabletsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{21} + return fileDescriptor_f41247b323a1ab2e, []int{35} } func (m *GetTabletsResponse) XXX_Unmarshal(b []byte) error { @@ -961,7 +1699,7 @@ func (m *GetVSchemaRequest) Reset() { *m = GetVSchemaRequest{} } func (m *GetVSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetVSchemaRequest) ProtoMessage() {} func (*GetVSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{22} + return fileDescriptor_f41247b323a1ab2e, []int{36} } func (m *GetVSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -1000,7 +1738,7 @@ func (m *GetVSchemaResponse) Reset() { *m = GetVSchemaResponse{} } func (m *GetVSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetVSchemaResponse) ProtoMessage() {} func (*GetVSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{23} + return fileDescriptor_f41247b323a1ab2e, []int{37} } func (m *GetVSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -1028,6 +1766,212 @@ func (m *GetVSchemaResponse) GetVSchema() *vschema.Keyspace { return nil } +type RemoveKeyspaceCellRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Cell string `protobuf:"bytes,2,opt,name=cell,proto3" json:"cell,omitempty"` + // Force proceeds even if the cell's topology server cannot be reached. This + // should only be set if a cell has been shut down entirely, and the global + // topology data just needs to be updated. + Force bool `protobuf:"varint,3,opt,name=force,proto3" json:"force,omitempty"` + // Recursive also deletes all tablets in that cell belonging to the specified + // keyspace. + Recursive bool `protobuf:"varint,4,opt,name=recursive,proto3" json:"recursive,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RemoveKeyspaceCellRequest) Reset() { *m = RemoveKeyspaceCellRequest{} } +func (m *RemoveKeyspaceCellRequest) String() string { return proto.CompactTextString(m) } +func (*RemoveKeyspaceCellRequest) ProtoMessage() {} +func (*RemoveKeyspaceCellRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{38} +} + +func (m *RemoveKeyspaceCellRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RemoveKeyspaceCellRequest.Unmarshal(m, b) +} +func (m *RemoveKeyspaceCellRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RemoveKeyspaceCellRequest.Marshal(b, m, deterministic) +} +func (m *RemoveKeyspaceCellRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RemoveKeyspaceCellRequest.Merge(m, src) +} +func (m *RemoveKeyspaceCellRequest) XXX_Size() int { + return xxx_messageInfo_RemoveKeyspaceCellRequest.Size(m) +} +func (m *RemoveKeyspaceCellRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RemoveKeyspaceCellRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_RemoveKeyspaceCellRequest proto.InternalMessageInfo + +func (m *RemoveKeyspaceCellRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *RemoveKeyspaceCellRequest) GetCell() string { + if m != nil { + return m.Cell + } + return "" +} + +func (m *RemoveKeyspaceCellRequest) GetForce() bool { + if m != nil { + return m.Force + } + return false +} + +func (m *RemoveKeyspaceCellRequest) GetRecursive() bool { + if m != nil { + return m.Recursive + } + return false +} + +type RemoveKeyspaceCellResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RemoveKeyspaceCellResponse) Reset() { *m = RemoveKeyspaceCellResponse{} } +func (m *RemoveKeyspaceCellResponse) String() string { return proto.CompactTextString(m) } +func (*RemoveKeyspaceCellResponse) ProtoMessage() {} +func (*RemoveKeyspaceCellResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{39} +} + +func (m *RemoveKeyspaceCellResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RemoveKeyspaceCellResponse.Unmarshal(m, b) +} +func (m *RemoveKeyspaceCellResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RemoveKeyspaceCellResponse.Marshal(b, m, deterministic) +} +func (m *RemoveKeyspaceCellResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RemoveKeyspaceCellResponse.Merge(m, src) +} +func (m *RemoveKeyspaceCellResponse) XXX_Size() int { + return xxx_messageInfo_RemoveKeyspaceCellResponse.Size(m) +} +func (m *RemoveKeyspaceCellResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RemoveKeyspaceCellResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RemoveKeyspaceCellResponse proto.InternalMessageInfo + +type RemoveShardCellRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + ShardName string `protobuf:"bytes,2,opt,name=shard_name,json=shardName,proto3" json:"shard_name,omitempty"` + Cell string `protobuf:"bytes,3,opt,name=cell,proto3" json:"cell,omitempty"` + // Force proceeds even if the cell's topology server cannot be reached. This + // should only be set if a cell has been shut down entirely, and the global + // topology data just needs to be updated. + Force bool `protobuf:"varint,4,opt,name=force,proto3" json:"force,omitempty"` + // Recursive also deletes all tablets in that cell belonging to the specified + // keyspace and shard. + Recursive bool `protobuf:"varint,5,opt,name=recursive,proto3" json:"recursive,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RemoveShardCellRequest) Reset() { *m = RemoveShardCellRequest{} } +func (m *RemoveShardCellRequest) String() string { return proto.CompactTextString(m) } +func (*RemoveShardCellRequest) ProtoMessage() {} +func (*RemoveShardCellRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{40} +} + +func (m *RemoveShardCellRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RemoveShardCellRequest.Unmarshal(m, b) +} +func (m *RemoveShardCellRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RemoveShardCellRequest.Marshal(b, m, deterministic) +} +func (m *RemoveShardCellRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RemoveShardCellRequest.Merge(m, src) +} +func (m *RemoveShardCellRequest) XXX_Size() int { + return xxx_messageInfo_RemoveShardCellRequest.Size(m) +} +func (m *RemoveShardCellRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RemoveShardCellRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_RemoveShardCellRequest proto.InternalMessageInfo + +func (m *RemoveShardCellRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *RemoveShardCellRequest) GetShardName() string { + if m != nil { + return m.ShardName + } + return "" +} + +func (m *RemoveShardCellRequest) GetCell() string { + if m != nil { + return m.Cell + } + return "" +} + +func (m *RemoveShardCellRequest) GetForce() bool { + if m != nil { + return m.Force + } + return false +} + +func (m *RemoveShardCellRequest) GetRecursive() bool { + if m != nil { + return m.Recursive + } + return false +} + +type RemoveShardCellResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RemoveShardCellResponse) Reset() { *m = RemoveShardCellResponse{} } +func (m *RemoveShardCellResponse) String() string { return proto.CompactTextString(m) } +func (*RemoveShardCellResponse) ProtoMessage() {} +func (*RemoveShardCellResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{41} +} + +func (m *RemoveShardCellResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RemoveShardCellResponse.Unmarshal(m, b) +} +func (m *RemoveShardCellResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RemoveShardCellResponse.Marshal(b, m, deterministic) +} +func (m *RemoveShardCellResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RemoveShardCellResponse.Merge(m, src) +} +func (m *RemoveShardCellResponse) XXX_Size() int { + return xxx_messageInfo_RemoveShardCellResponse.Size(m) +} +func (m *RemoveShardCellResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RemoveShardCellResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RemoveShardCellResponse proto.InternalMessageInfo + type Keyspace struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Keyspace *topodata.Keyspace `protobuf:"bytes,2,opt,name=keyspace,proto3" json:"keyspace,omitempty"` @@ -1040,7 +1984,7 @@ func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{24} + return fileDescriptor_f41247b323a1ab2e, []int{42} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { @@ -1086,7 +2030,7 @@ func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInK func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{25} + return fileDescriptor_f41247b323a1ab2e, []int{43} } func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -1125,7 +2069,7 @@ func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsIn func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{26} + return fileDescriptor_f41247b323a1ab2e, []int{44} } func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -1166,7 +2110,7 @@ func (m *Shard) Reset() { *m = Shard{} } func (m *Shard) String() string { return proto.CompactTextString(m) } func (*Shard) ProtoMessage() {} func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{27} + return fileDescriptor_f41247b323a1ab2e, []int{45} } func (m *Shard) XXX_Unmarshal(b []byte) error { @@ -1226,7 +2170,7 @@ func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettin func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } func (*TableMaterializeSettings) ProtoMessage() {} func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{28} + return fileDescriptor_f41247b323a1ab2e, []int{46} } func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -1289,7 +2233,7 @@ func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } func (*MaterializeSettings) ProtoMessage() {} func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{29} + return fileDescriptor_f41247b323a1ab2e, []int{47} } func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { @@ -1362,6 +2306,18 @@ func (m *MaterializeSettings) GetTabletTypes() string { func init() { proto.RegisterType((*ExecuteVtctlCommandRequest)(nil), "vtctldata.ExecuteVtctlCommandRequest") proto.RegisterType((*ExecuteVtctlCommandResponse)(nil), "vtctldata.ExecuteVtctlCommandResponse") + proto.RegisterType((*ChangeTabletTypeRequest)(nil), "vtctldata.ChangeTabletTypeRequest") + proto.RegisterType((*ChangeTabletTypeResponse)(nil), "vtctldata.ChangeTabletTypeResponse") + proto.RegisterType((*CreateKeyspaceRequest)(nil), "vtctldata.CreateKeyspaceRequest") + proto.RegisterType((*CreateKeyspaceResponse)(nil), "vtctldata.CreateKeyspaceResponse") + proto.RegisterType((*CreateShardRequest)(nil), "vtctldata.CreateShardRequest") + proto.RegisterType((*CreateShardResponse)(nil), "vtctldata.CreateShardResponse") + proto.RegisterType((*DeleteKeyspaceRequest)(nil), "vtctldata.DeleteKeyspaceRequest") + proto.RegisterType((*DeleteKeyspaceResponse)(nil), "vtctldata.DeleteKeyspaceResponse") + proto.RegisterType((*DeleteShardsRequest)(nil), "vtctldata.DeleteShardsRequest") + proto.RegisterType((*DeleteShardsResponse)(nil), "vtctldata.DeleteShardsResponse") + proto.RegisterType((*DeleteTabletsRequest)(nil), "vtctldata.DeleteTabletsRequest") + proto.RegisterType((*DeleteTabletsResponse)(nil), "vtctldata.DeleteTabletsResponse") proto.RegisterType((*GetBackupsRequest)(nil), "vtctldata.GetBackupsRequest") proto.RegisterType((*GetBackupsResponse)(nil), "vtctldata.GetBackupsResponse") proto.RegisterType((*GetCellInfoNamesRequest)(nil), "vtctldata.GetCellInfoNamesRequest") @@ -1377,6 +2333,8 @@ func init() { proto.RegisterType((*GetKeyspaceResponse)(nil), "vtctldata.GetKeyspaceResponse") proto.RegisterType((*GetSchemaRequest)(nil), "vtctldata.GetSchemaRequest") proto.RegisterType((*GetSchemaResponse)(nil), "vtctldata.GetSchemaResponse") + proto.RegisterType((*GetShardRequest)(nil), "vtctldata.GetShardRequest") + proto.RegisterType((*GetShardResponse)(nil), "vtctldata.GetShardResponse") proto.RegisterType((*GetSrvVSchemaRequest)(nil), "vtctldata.GetSrvVSchemaRequest") proto.RegisterType((*GetSrvVSchemaResponse)(nil), "vtctldata.GetSrvVSchemaResponse") proto.RegisterType((*GetTabletRequest)(nil), "vtctldata.GetTabletRequest") @@ -1385,6 +2343,10 @@ func init() { proto.RegisterType((*GetTabletsResponse)(nil), "vtctldata.GetTabletsResponse") proto.RegisterType((*GetVSchemaRequest)(nil), "vtctldata.GetVSchemaRequest") proto.RegisterType((*GetVSchemaResponse)(nil), "vtctldata.GetVSchemaResponse") + proto.RegisterType((*RemoveKeyspaceCellRequest)(nil), "vtctldata.RemoveKeyspaceCellRequest") + proto.RegisterType((*RemoveKeyspaceCellResponse)(nil), "vtctldata.RemoveKeyspaceCellResponse") + proto.RegisterType((*RemoveShardCellRequest)(nil), "vtctldata.RemoveShardCellRequest") + proto.RegisterType((*RemoveShardCellResponse)(nil), "vtctldata.RemoveShardCellResponse") proto.RegisterType((*Keyspace)(nil), "vtctldata.Keyspace") proto.RegisterType((*FindAllShardsInKeyspaceRequest)(nil), "vtctldata.FindAllShardsInKeyspaceRequest") proto.RegisterType((*FindAllShardsInKeyspaceResponse)(nil), "vtctldata.FindAllShardsInKeyspaceResponse") @@ -1397,74 +2359,112 @@ func init() { func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 1097 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xdd, 0x6f, 0xdb, 0x54, - 0x14, 0x57, 0xd2, 0x25, 0x4d, 0x4e, 0x9b, 0x34, 0x75, 0xdb, 0xcd, 0x04, 0x01, 0xc5, 0x65, 0x5d, - 0x54, 0x90, 0x33, 0x86, 0x40, 0x13, 0x1f, 0x12, 0xfd, 0x5a, 0x55, 0x06, 0x65, 0x72, 0xab, 0x22, - 0x81, 0x84, 0xe5, 0x3a, 0xb7, 0x99, 0xd5, 0x1b, 0x5f, 0xcf, 0xf7, 0xc6, 0x6d, 0xf6, 0xcc, 0x0b, - 0xff, 0x0c, 0x8f, 0x3c, 0xf2, 0xb7, 0xa1, 0x7b, 0xef, 0xb9, 0xb6, 0x93, 0xa6, 0x9b, 0x60, 0x6f, - 0x3e, 0xbf, 0xf3, 0xfd, 0x3b, 0xe7, 0x9e, 0x04, 0x56, 0x32, 0x11, 0x0a, 0x3a, 0x08, 0x44, 0xe0, - 0x26, 0x29, 0x13, 0xcc, 0x6a, 0xe6, 0x40, 0xb7, 0x45, 0xd9, 0x70, 0x2c, 0x22, 0xaa, 0x35, 0xdd, - 0xf6, 0x68, 0xc2, 0x5f, 0xd1, 0x50, 0x18, 0xf9, 0x81, 0x08, 0x2e, 0x28, 0x11, 0xa3, 0x20, 0x0e, - 0x86, 0x24, 0x2d, 0x42, 0x74, 0xdb, 0x82, 0x25, 0xac, 0x24, 0xb7, 0x32, 0x1e, 0xbe, 0x24, 0x23, - 0x14, 0x9d, 0x5f, 0xa0, 0x7b, 0x78, 0x43, 0xc2, 0xb1, 0x20, 0xe7, 0x32, 0xd5, 0x3e, 0x1b, 0x8d, - 0x82, 0x78, 0xe0, 0x91, 0x57, 0x63, 0xc2, 0x85, 0x65, 0xc1, 0xbd, 0x20, 0x1d, 0x72, 0xbb, 0xb2, - 0xb9, 0xd0, 0x6b, 0x7a, 0xea, 0xdb, 0x7a, 0x08, 0xed, 0x20, 0x14, 0x11, 0x8b, 0x7d, 0x11, 0x8d, - 0x08, 0x1b, 0x0b, 0xbb, 0xba, 0x59, 0xe9, 0x2d, 0x78, 0x2d, 0x8d, 0x9e, 0x69, 0xd0, 0xd9, 0x87, - 0xf7, 0xe7, 0x06, 0xe6, 0x09, 0x8b, 0x39, 0xb1, 0x3e, 0x81, 0x1a, 0xc9, 0x48, 0x2c, 0xec, 0xca, - 0x66, 0xa5, 0xb7, 0xf4, 0xa4, 0xed, 0x9a, 0xf6, 0x0e, 0x25, 0xea, 0x69, 0xa5, 0x73, 0x08, 0xab, - 0x47, 0x44, 0xec, 0x05, 0xe1, 0xd5, 0x38, 0xe1, 0xa6, 0xa8, 0x2e, 0x34, 0xae, 0xc8, 0x84, 0x27, - 0x41, 0x48, 0x94, 0x77, 0xd3, 0xcb, 0x65, 0x6b, 0x1d, 0x6a, 0xfc, 0x65, 0x90, 0x0e, 0x54, 0x4d, - 0x4d, 0x4f, 0x0b, 0xce, 0x01, 0x58, 0xe5, 0x30, 0x58, 0x82, 0x0b, 0x8b, 0x17, 0x1a, 0x52, 0xfd, - 0x2d, 0x3d, 0x59, 0x77, 0x73, 0x52, 0xb5, 0xed, 0x71, 0x7c, 0xc9, 0x3c, 0x63, 0xe4, 0xbc, 0x07, - 0x0f, 0x8e, 0x88, 0xd8, 0x27, 0x94, 0x4a, 0xfc, 0x24, 0x18, 0x11, 0x53, 0x92, 0xf3, 0x18, 0xec, - 0xdb, 0x2a, 0x4c, 0xb3, 0x0e, 0xb5, 0x58, 0x02, 0x48, 0xa2, 0x16, 0x9c, 0x9e, 0x2a, 0xc9, 0x78, - 0x94, 0xf8, 0x0e, 0x09, 0xa5, 0xd8, 0x96, 0xfa, 0x76, 0x9e, 0xc1, 0xda, 0x94, 0x25, 0x86, 0xed, - 0x43, 0x53, 0xaa, 0xfd, 0x28, 0xbe, 0x64, 0x48, 0xa2, 0xe5, 0xe6, 0xb3, 0xce, 0xcd, 0x1b, 0x21, - 0x7e, 0x39, 0x36, 0xdc, 0xc7, 0x38, 0x7c, 0x97, 0x46, 0x01, 0x2f, 0xaa, 0xff, 0xbb, 0x92, 0x77, - 0x56, 0xa8, 0x30, 0xcd, 0x31, 0x2c, 0x06, 0x1a, 0x42, 0x92, 0xfa, 0x6e, 0xb1, 0xa4, 0x77, 0x38, - 0xb9, 0x28, 0x1f, 0xc6, 0x22, 0x9d, 0x78, 0xc6, 0xbf, 0xfb, 0x02, 0x96, 0xcb, 0x0a, 0xab, 0x03, - 0x0b, 0x57, 0x64, 0x82, 0xbd, 0xca, 0x4f, 0x6b, 0x07, 0x6a, 0x59, 0x40, 0xc7, 0x44, 0x4d, 0x4f, - 0xce, 0x63, 0xaa, 0x1f, 0x9d, 0xc6, 0xd3, 0x26, 0x5f, 0x57, 0x9f, 0x56, 0x9c, 0x0d, 0x45, 0xcd, - 0x73, 0x1c, 0x7e, 0xde, 0xcf, 0x31, 0xac, 0x4f, 0xc3, 0xd8, 0xcb, 0xe7, 0xd0, 0x34, 0x8b, 0x62, - 0xba, 0x59, 0x2b, 0x75, 0x63, 0x1c, 0xbc, 0xc2, 0xca, 0x79, 0xac, 0xc6, 0x94, 0x6b, 0xde, 0xbe, - 0x81, 0x38, 0xae, 0xc2, 0x23, 0x1f, 0xd7, 0xb4, 0xcb, 0x1d, 0xa9, 0x8b, 0x38, 0x7f, 0x54, 0xa1, - 0x73, 0x44, 0xc4, 0xa9, 0x7a, 0xac, 0x26, 0xf1, 0x53, 0x58, 0xd6, 0xef, 0xdc, 0x57, 0xa4, 0x62, - 0xa4, 0x8d, 0x82, 0xa7, 0x33, 0xa5, 0xd5, 0x44, 0x2d, 0x89, 0x42, 0xb0, 0xee, 0x43, 0x5d, 0x89, - 0xdc, 0xae, 0xaa, 0x35, 0x44, 0x49, 0xbe, 0x66, 0x72, 0x13, 0xd2, 0xf1, 0x80, 0xf8, 0xa8, 0x5f, - 0x50, 0xfa, 0x16, 0xa2, 0x67, 0xda, 0x6c, 0x0b, 0x5a, 0x51, 0xac, 0xcd, 0xb2, 0x88, 0x5c, 0x73, - 0xfb, 0xde, 0x66, 0xa5, 0xd7, 0xf0, 0x96, 0x11, 0x3c, 0x97, 0x98, 0xd5, 0x83, 0x8e, 0x8a, 0xe1, - 0xab, 0x15, 0xf7, 0x59, 0x4c, 0x27, 0x76, 0x4d, 0xd9, 0xb5, 0x15, 0xae, 0xde, 0xc5, 0xcf, 0x31, - 0x9d, 0x14, 0x96, 0x3c, 0x7a, 0x6d, 0x2c, 0xeb, 0x25, 0xcb, 0x53, 0x09, 0x4b, 0x4b, 0xe7, 0x85, - 0xba, 0x00, 0x86, 0x05, 0x24, 0xf3, 0x1b, 0xa8, 0xeb, 0x23, 0x86, 0x04, 0x6c, 0xb9, 0xb7, 0xaf, - 0x9f, 0x76, 0x39, 0x20, 0x97, 0x51, 0x1c, 0xc9, 0xbb, 0xe4, 0xa1, 0x8b, 0xb3, 0xa3, 0xb6, 0xe3, - 0x34, 0xcd, 0xce, 0xa7, 0xb9, 0x9d, 0xf7, 0xf6, 0x4e, 0x60, 0x63, 0xc6, 0x16, 0x2b, 0xf8, 0x12, - 0x96, 0x79, 0x9a, 0xf9, 0x99, 0x3f, 0x55, 0xc7, 0x9a, 0x6b, 0x8e, 0x6b, 0xc9, 0x05, 0x78, 0xfe, - 0xed, 0xfc, 0xa8, 0x66, 0xaa, 0x87, 0xf4, 0xce, 0x33, 0x75, 0xbe, 0x53, 0xdc, 0x98, 0x68, 0x58, - 0x59, 0x0f, 0x07, 0x6d, 0x2e, 0x6b, 0x67, 0x36, 0x10, 0x8e, 0x5e, 0x38, 0xbf, 0x95, 0xdc, 0xff, - 0xff, 0x71, 0x95, 0xa8, 0xe4, 0xca, 0x2c, 0x8e, 0x16, 0x9c, 0xef, 0xd5, 0xc3, 0xc9, 0x83, 0x63, - 0x71, 0x3b, 0xb0, 0xa8, 0x93, 0x9b, 0xf7, 0x77, 0xbb, 0x3a, 0x63, 0xe0, 0xf4, 0x55, 0x79, 0x33, - 0x43, 0x7a, 0xd3, 0xcb, 0xdb, 0x53, 0x29, 0x67, 0x27, 0xf5, 0x19, 0x34, 0x66, 0xa6, 0xb4, 0x9a, - 0x4f, 0x29, 0x7f, 0x76, 0x8b, 0x19, 0x0e, 0xe8, 0x04, 0x1a, 0x06, 0x94, 0x0b, 0x21, 0x17, 0xd9, - 0x2c, 0x84, 0xfc, 0xb6, 0xdc, 0x52, 0xfe, 0xea, 0xec, 0xd1, 0x9d, 0xf3, 0x8a, 0xbf, 0x85, 0x0f, - 0x9f, 0x45, 0xf1, 0x60, 0x97, 0xd2, 0x53, 0x49, 0x16, 0x3f, 0x8e, 0xff, 0xcb, 0x2d, 0xf9, 0xa7, - 0x02, 0x1f, 0xdd, 0xe9, 0x8e, 0xfd, 0x9d, 0x40, 0x5d, 0xcd, 0xc1, 0x30, 0xfa, 0x55, 0xe9, 0xac, - 0xbc, 0xc5, 0xd7, 0xd5, 0x0a, 0x7d, 0xa6, 0x31, 0x4a, 0xf7, 0x39, 0x2c, 0x95, 0xe0, 0x39, 0x47, - 0x7a, 0x7b, 0xfa, 0x48, 0x77, 0x4a, 0xf9, 0x94, 0x63, 0xf9, 0x40, 0xff, 0x0e, 0x35, 0x85, 0xbd, - 0x71, 0xad, 0x0c, 0xcf, 0xd5, 0x12, 0xcf, 0x0f, 0xcd, 0xaa, 0x2d, 0xa8, 0x24, 0x2b, 0x05, 0xc9, - 0x98, 0x43, 0xff, 0xb0, 0xff, 0x59, 0x01, 0x5b, 0xed, 0xcd, 0x4f, 0x81, 0x20, 0x69, 0x14, 0xd0, - 0xe8, 0x35, 0x39, 0x25, 0x42, 0x44, 0xf1, 0x90, 0x5b, 0x1f, 0xcb, 0x87, 0x95, 0x0e, 0x89, 0xd0, - 0x97, 0x0d, 0xf3, 0x2e, 0x69, 0x4c, 0x79, 0x59, 0x9f, 0xc2, 0x2a, 0x67, 0xe3, 0x34, 0x24, 0x3e, - 0xb9, 0x49, 0x52, 0xc2, 0x79, 0xc4, 0x62, 0xac, 0xa3, 0xa3, 0x15, 0x87, 0x39, 0x6e, 0x7d, 0x00, - 0x10, 0xa6, 0x24, 0x10, 0xc4, 0x1f, 0x0c, 0xa8, 0x2a, 0xac, 0xe9, 0x35, 0x35, 0x72, 0x30, 0xa0, - 0xce, 0x5f, 0x55, 0x58, 0x9b, 0x57, 0x46, 0x17, 0x1a, 0xd7, 0x2c, 0xbd, 0xba, 0xa4, 0xec, 0xda, - 0xb4, 0x6e, 0x64, 0xeb, 0x11, 0xac, 0x60, 0xfe, 0xa9, 0xad, 0x6a, 0x7a, 0x6d, 0x0d, 0xe7, 0xbb, - 0xf8, 0x08, 0x56, 0xb0, 0x97, 0xdc, 0x50, 0x17, 0xd0, 0xd6, 0x70, 0x6e, 0xb8, 0x0d, 0x2b, 0x5c, - 0xb0, 0xc4, 0x0f, 0x2e, 0x05, 0x49, 0xfd, 0x90, 0x25, 0x13, 0x3c, 0xd5, 0x2d, 0x09, 0xef, 0x4a, - 0x74, 0x9f, 0x25, 0x13, 0xeb, 0x07, 0x68, 0xe3, 0x05, 0xc6, 0x3a, 0xed, 0x9a, 0x5a, 0x9f, 0xad, - 0xd2, 0x38, 0xef, 0x62, 0xd6, 0x6b, 0xe9, 0x23, 0x6d, 0x3a, 0x34, 0x97, 0xb3, 0x5e, 0x5c, 0x4e, - 0x4d, 0xbe, 0xba, 0x6a, 0x62, 0x92, 0x10, 0x6e, 0x2f, 0x1a, 0xf2, 0x25, 0x76, 0x26, 0xa1, 0xbd, - 0xde, 0xaf, 0xdb, 0x59, 0x24, 0x08, 0xe7, 0x6e, 0xc4, 0xfa, 0xfa, 0xab, 0x3f, 0x64, 0xfd, 0x4c, - 0xf4, 0xd5, 0x5f, 0xd3, 0x7e, 0x5e, 0xc8, 0x45, 0x5d, 0x01, 0x5f, 0xfc, 0x1b, 0x00, 0x00, 0xff, - 0xff, 0x66, 0x2a, 0x0a, 0x0a, 0x20, 0x0b, 0x00, 0x00, + // 1708 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4b, 0x6f, 0xdb, 0x56, + 0x16, 0x06, 0x25, 0x4b, 0x96, 0x8e, 0x1e, 0xb6, 0x69, 0xd9, 0x56, 0x34, 0x49, 0xc6, 0xa1, 0x27, + 0x8e, 0xe0, 0x99, 0x91, 0xf2, 0xc0, 0x0c, 0x82, 0x4c, 0x06, 0x88, 0x63, 0x3b, 0x81, 0xe3, 0x8c, + 0xc7, 0xa5, 0x0d, 0x17, 0x68, 0x81, 0x12, 0x34, 0x75, 0x25, 0x13, 0xa6, 0x48, 0x86, 0xf7, 0x8a, + 0x36, 0xb3, 0xe9, 0xa6, 0x5d, 0x14, 0xe8, 0x3f, 0xc8, 0xa6, 0xab, 0x2e, 0xbb, 0xcc, 0xb2, 0xbf, + 0xad, 0xb8, 0x2f, 0x92, 0xa2, 0x24, 0xe7, 0xd5, 0x95, 0x79, 0xcf, 0xe3, 0x9e, 0xef, 0xdc, 0xf3, + 0x94, 0x61, 0x21, 0x24, 0x16, 0x71, 0x7a, 0x26, 0x31, 0x3b, 0x7e, 0xe0, 0x11, 0x4f, 0x2d, 0xc7, + 0x84, 0x56, 0xcd, 0xf1, 0x06, 0x23, 0x62, 0x3b, 0x9c, 0xd3, 0xaa, 0x0f, 0x23, 0xfc, 0xc6, 0xb1, + 0x88, 0x3c, 0xaf, 0x11, 0xf3, 0xcc, 0x41, 0x64, 0x68, 0xba, 0xe6, 0x00, 0x05, 0xc9, 0x15, 0xad, + 0x3a, 0xf1, 0x7c, 0x2f, 0x75, 0xae, 0x85, 0xd8, 0x3a, 0x47, 0x43, 0x79, 0xac, 0x86, 0x84, 0xd8, + 0x43, 0xc4, 0x4f, 0xda, 0xd7, 0xd0, 0xda, 0xbb, 0x42, 0xd6, 0x88, 0xa0, 0x53, 0x6a, 0x78, 0xc7, + 0x1b, 0x0e, 0x4d, 0xb7, 0xa7, 0xa3, 0x37, 0x23, 0x84, 0x89, 0xaa, 0xc2, 0x9c, 0x19, 0x0c, 0x70, + 0x53, 0x59, 0xcf, 0xb7, 0xcb, 0x3a, 0xfb, 0x56, 0xef, 0x42, 0xdd, 0xb4, 0x88, 0xed, 0xb9, 0x06, + 0xbd, 0xc6, 0x1b, 0x91, 0x66, 0x6e, 0x5d, 0x69, 0xe7, 0xf5, 0x1a, 0xa7, 0x9e, 0x70, 0xa2, 0xb6, + 0x03, 0x7f, 0x99, 0x7a, 0x31, 0xf6, 0x3d, 0x17, 0x23, 0xf5, 0x6f, 0x50, 0x40, 0x21, 0x72, 0x49, + 0x53, 0x59, 0x57, 0xda, 0x95, 0x87, 0xf5, 0x8e, 0x74, 0x76, 0x8f, 0x52, 0x75, 0xce, 0xd4, 0xde, + 0x29, 0xb0, 0xb6, 0x73, 0x6e, 0xba, 0x03, 0x74, 0xc2, 0x9c, 0x3d, 0x89, 0x7c, 0x24, 0xb1, 0x3d, + 0x86, 0x2a, 0x7f, 0x01, 0xc3, 0x74, 0x6c, 0x13, 0x8b, 0x8b, 0x56, 0x3a, 0xb1, 0xf7, 0x5c, 0x65, + 0x9b, 0x32, 0xf5, 0x0a, 0x49, 0x0e, 0xea, 0x3f, 0x61, 0xbe, 0x77, 0x66, 0x90, 0xc8, 0x47, 0x0c, + 0x7a, 0xfd, 0x61, 0x23, 0xab, 0xc4, 0xec, 0x14, 0x7b, 0x67, 0xf4, 0xaf, 0xba, 0x06, 0xf3, 0xbd, + 0x20, 0x32, 0x82, 0x91, 0xdb, 0xcc, 0xaf, 0x2b, 0xed, 0x92, 0x5e, 0xec, 0x05, 0x91, 0x3e, 0x72, + 0xb5, 0x5f, 0x15, 0x68, 0x4e, 0xa2, 0x13, 0x0e, 0xfe, 0x0b, 0x6a, 0x67, 0xa8, 0xef, 0x05, 0xc8, + 0xe0, 0xa6, 0x05, 0xbe, 0xc5, 0xac, 0x29, 0xbd, 0xca, 0xc5, 0xf8, 0x49, 0x7d, 0x04, 0x55, 0xb3, + 0x4f, 0x50, 0x20, 0xb5, 0x72, 0x33, 0xb4, 0x2a, 0x4c, 0x4a, 0x28, 0xdd, 0x86, 0xca, 0xa5, 0x89, + 0x8d, 0x71, 0x94, 0xe5, 0x4b, 0x13, 0xef, 0x72, 0xa0, 0xef, 0xf3, 0xb0, 0xb2, 0x13, 0x20, 0x93, + 0xa0, 0x03, 0x14, 0x61, 0xdf, 0xb4, 0x50, 0x2a, 0xc0, 0xae, 0x39, 0x44, 0x0c, 0x5c, 0x59, 0x67, + 0xdf, 0x6a, 0x03, 0x0a, 0x7d, 0x2f, 0xb0, 0xf8, 0xe3, 0x94, 0x74, 0x7e, 0x50, 0xbb, 0xd0, 0x30, + 0x1d, 0xc7, 0xbb, 0x34, 0xd0, 0xd0, 0x27, 0x91, 0x11, 0x1a, 0x3c, 0xa9, 0x84, 0xb1, 0x25, 0xc6, + 0xdb, 0xa3, 0xac, 0xd3, 0x63, 0xc6, 0x50, 0xef, 0x43, 0x03, 0x9f, 0x9b, 0x41, 0xcf, 0x76, 0x07, + 0x86, 0xe5, 0x39, 0xa3, 0xa1, 0x6b, 0x30, 0x53, 0x73, 0xcc, 0x94, 0x2a, 0x79, 0x3b, 0x8c, 0x75, + 0x48, 0x0d, 0xbf, 0x9a, 0xd4, 0x60, 0x41, 0x2a, 0xb0, 0x20, 0x35, 0x93, 0x37, 0x90, 0x5e, 0xec, + 0xf7, 0xd8, 0x93, 0x67, 0xee, 0x62, 0x41, 0x7b, 0x06, 0x55, 0x8c, 0x82, 0x10, 0xf5, 0x8c, 0x7e, + 0xe0, 0x0d, 0x71, 0xb3, 0xb8, 0x9e, 0x6f, 0x57, 0x1e, 0xde, 0x9a, 0xbc, 0xa3, 0x73, 0xcc, 0xc4, + 0x5e, 0x04, 0xde, 0x50, 0xaf, 0xe0, 0xf8, 0x1b, 0xab, 0x5b, 0x30, 0xc7, 0xac, 0xcf, 0x33, 0xeb, + 0xab, 0x93, 0x9a, 0xcc, 0x36, 0x93, 0x51, 0x37, 0xa0, 0x76, 0x66, 0x62, 0x64, 0x5c, 0x08, 0x56, + 0xb3, 0xc4, 0x9c, 0xac, 0x52, 0xa2, 0x14, 0x57, 0x1f, 0x40, 0x0d, 0xbb, 0xa6, 0x8f, 0xcf, 0x3d, + 0xc2, 0x4a, 0xa7, 0x59, 0x66, 0xb1, 0xad, 0x76, 0x44, 0x41, 0xd2, 0xca, 0xd1, 0xab, 0x52, 0x84, + 0x9e, 0xb4, 0x7d, 0x58, 0xcd, 0xc6, 0x4d, 0xa4, 0x57, 0x17, 0x4a, 0xb1, 0x31, 0x9e, 0x59, 0xcb, + 0x9d, 0xa4, 0x97, 0xc4, 0xe2, 0xb1, 0x90, 0xf6, 0xb3, 0x02, 0x2a, 0xbf, 0xeb, 0x98, 0xbe, 0x96, + 0x4c, 0x80, 0x56, 0xe6, 0x9e, 0x72, 0xa2, 0xa2, 0xde, 0x02, 0x60, 0x2f, 0xcb, 0xe3, 0x96, 0x63, + 0xdc, 0x32, 0xa3, 0x1c, 0x8e, 0xe5, 0x49, 0x3e, 0x9d, 0x27, 0x77, 0xa1, 0x6e, 0xbb, 0x96, 0x33, + 0xea, 0x21, 0xc3, 0x37, 0x03, 0x5a, 0xe1, 0x73, 0x8c, 0x5d, 0x13, 0xd4, 0x23, 0x46, 0xd4, 0x7e, + 0x51, 0x60, 0x79, 0x0c, 0xce, 0x67, 0xfa, 0xa5, 0x6e, 0x42, 0x81, 0x41, 0x8a, 0x2b, 0x25, 0x91, + 0xe6, 0x37, 0x73, 0x76, 0x9c, 0x8e, 0x86, 0xe9, 0x04, 0xc8, 0xec, 0x45, 0x06, 0xba, 0xb2, 0x31, + 0xc1, 0x02, 0x3c, 0x4f, 0xa1, 0x6d, 0xce, 0xda, 0x63, 0x1c, 0xed, 0x2b, 0x58, 0xd9, 0x45, 0x0e, + 0x9a, 0x2c, 0x9a, 0xeb, 0xde, 0xec, 0x26, 0x94, 0x03, 0x64, 0x8d, 0x02, 0x6c, 0x87, 0xb2, 0x80, + 0x12, 0x82, 0xd6, 0x84, 0xd5, 0xec, 0x95, 0xdc, 0x6f, 0xed, 0x47, 0x05, 0x96, 0x39, 0x8b, 0xa1, + 0xc6, 0xd2, 0x56, 0x1b, 0x8a, 0x0c, 0x1a, 0xef, 0xc1, 0xd3, 0xfc, 0x13, 0xfc, 0xeb, 0x2d, 0xab, + 0x9b, 0xb0, 0x40, 0x5b, 0xaa, 0x61, 0xf7, 0x0d, 0x9a, 0xe4, 0xb6, 0x3b, 0x90, 0x71, 0xa1, 0xe4, + 0xfd, 0xfe, 0x31, 0x27, 0x6a, 0xab, 0xd0, 0x18, 0x87, 0x21, 0xf0, 0x45, 0x92, 0xce, 0x5b, 0x4e, + 0x8c, 0xef, 0x29, 0xd4, 0xd3, 0x5d, 0x18, 0x49, 0x9c, 0x33, 0xfa, 0x70, 0x2d, 0xd5, 0x87, 0x11, + 0xa6, 0x75, 0xc3, 0x9b, 0x8a, 0x1f, 0xd8, 0x43, 0x33, 0x88, 0x04, 0xee, 0x2a, 0x23, 0x1e, 0x71, + 0x9a, 0xb6, 0x26, 0xe3, 0x10, 0x9b, 0x16, 0x98, 0xf6, 0x60, 0xe9, 0x25, 0x22, 0xcf, 0x4d, 0xeb, + 0x62, 0xe4, 0xe3, 0x8f, 0x09, 0x4e, 0x23, 0x9d, 0x2b, 0x65, 0x91, 0x19, 0xda, 0x2e, 0xa8, 0xe9, + 0x6b, 0x44, 0x22, 0x76, 0x60, 0xfe, 0x8c, 0x93, 0x84, 0x47, 0x8d, 0x4e, 0x3c, 0x80, 0xb9, 0xec, + 0xbe, 0xdb, 0xf7, 0x74, 0x29, 0xa4, 0xdd, 0x80, 0xb5, 0x97, 0x88, 0xec, 0x20, 0xc7, 0xa1, 0x74, + 0x5a, 0x20, 0x12, 0x92, 0x76, 0x1f, 0x9a, 0x93, 0x2c, 0x61, 0xa6, 0x01, 0x05, 0x5a, 0x5d, 0x72, + 0xc4, 0xf2, 0x83, 0xd6, 0x66, 0x90, 0xa4, 0x46, 0xaa, 0x59, 0x5b, 0xc8, 0x71, 0x64, 0xb3, 0xa6, + 0xdf, 0xda, 0x0b, 0x58, 0x1e, 0x93, 0x8c, 0xcb, 0xa8, 0x4c, 0xd9, 0x86, 0xed, 0xf6, 0x3d, 0x51, + 0x47, 0x6a, 0x12, 0x91, 0x58, 0xbc, 0x64, 0x89, 0x2f, 0x9a, 0x99, 0xe2, 0x1e, 0x2c, 0x82, 0x23, + 0xd1, 0xbf, 0x57, 0x62, 0xcf, 0x12, 0x96, 0x30, 0xb3, 0x0f, 0xf3, 0xe3, 0x61, 0xef, 0xa6, 0xd2, + 0x73, 0x86, 0x52, 0x47, 0x9c, 0xf7, 0x5c, 0x12, 0x44, 0xba, 0xd4, 0x6f, 0x1d, 0x41, 0x35, 0xcd, + 0x50, 0x17, 0x21, 0x7f, 0x81, 0x22, 0xe1, 0x2b, 0xfd, 0x54, 0xb7, 0xa0, 0x10, 0x9a, 0xce, 0x08, + 0x89, 0x4a, 0x6f, 0x8c, 0xfb, 0xc3, 0xcd, 0xe8, 0x5c, 0xe4, 0x49, 0xee, 0xb1, 0xa2, 0xad, 0xb0, + 0xa7, 0x91, 0x95, 0x16, 0xfb, 0xb3, 0x0f, 0x8d, 0x71, 0xb2, 0xf0, 0xe5, 0x01, 0x94, 0x65, 0xa2, + 0x48, 0x6f, 0xa6, 0xb6, 0x9e, 0x44, 0x4a, 0xbb, 0xcf, 0xc2, 0xf4, 0x09, 0xed, 0x41, 0x84, 0xeb, + 0xcb, 0xbb, 0xf9, 0x0f, 0x39, 0x58, 0x7c, 0x89, 0x08, 0x1f, 0xb5, 0x5f, 0xbe, 0x11, 0xad, 0x42, + 0x91, 0x1d, 0x71, 0x33, 0xc7, 0xd2, 0x50, 0x9c, 0x68, 0x33, 0x47, 0x57, 0xbc, 0x99, 0x0b, 0x7e, + 0x9e, 0xf1, 0x6b, 0x82, 0x7a, 0xc2, 0xc5, 0x36, 0x40, 0x76, 0x77, 0x23, 0xb4, 0xd1, 0x25, 0x16, + 0xad, 0xa5, 0x2a, 0x88, 0xa7, 0x94, 0xa6, 0xb6, 0x61, 0x91, 0xdd, 0xc1, 0xa6, 0x09, 0x36, 0x3c, + 0xd7, 0x89, 0xd8, 0x64, 0x2f, 0xe9, 0xbc, 0x83, 0xb0, 0xba, 0xf8, 0xbf, 0xeb, 0x44, 0x89, 0x24, + 0xb6, 0xdf, 0x4a, 0xc9, 0x62, 0x4a, 0xf2, 0x98, 0x92, 0xa9, 0xa4, 0x76, 0xc4, 0x3a, 0x80, 0x7c, + 0x05, 0xf1, 0x98, 0xff, 0x81, 0xa2, 0xd8, 0x4d, 0xf8, 0x03, 0x6c, 0x74, 0x26, 0x37, 0x65, 0xae, + 0xb2, 0x8b, 0xfa, 0xb6, 0x6b, 0xd3, 0xad, 0x55, 0x17, 0x2a, 0xda, 0x6b, 0x58, 0xa0, 0x37, 0xfe, + 0x39, 0x23, 0x52, 0x7b, 0xc2, 0xa3, 0x34, 0x36, 0xe1, 0xe2, 0x81, 0xa5, 0x5c, 0x3b, 0xb0, 0xb4, + 0x2d, 0x96, 0xa7, 0xc7, 0x41, 0x78, 0x3a, 0x1e, 0xe5, 0x69, 0x5d, 0xe0, 0x10, 0x56, 0x32, 0xb2, + 0xf1, 0x16, 0x5a, 0xc5, 0x41, 0x98, 0x6c, 0x6b, 0x71, 0x72, 0x89, 0x9f, 0x04, 0x29, 0x15, 0xc0, + 0xf1, 0xb7, 0xf6, 0x9a, 0xe1, 0x16, 0xab, 0xe6, 0x97, 0x66, 0x97, 0xf6, 0x5f, 0x16, 0x25, 0x79, + 0x9b, 0x40, 0xd6, 0x16, 0x29, 0x37, 0x7b, 0x31, 0x16, 0x7c, 0xed, 0xdb, 0x94, 0xfa, 0xe7, 0xb7, + 0x79, 0x4a, 0xa5, 0x6f, 0x25, 0x53, 0x98, 0x1f, 0xb4, 0x67, 0xac, 0x84, 0x33, 0x93, 0x45, 0xdd, + 0x82, 0x79, 0x6e, 0x3c, 0x19, 0xbb, 0x59, 0x74, 0x52, 0x40, 0xeb, 0x32, 0x78, 0x99, 0x20, 0x5d, + 0xd7, 0x03, 0x9e, 0x33, 0x93, 0xd9, 0x48, 0xfd, 0x03, 0x4a, 0x99, 0x28, 0x2d, 0xc5, 0x51, 0x8a, + 0x1b, 0xc0, 0x7c, 0x28, 0x02, 0xf4, 0x3d, 0xdc, 0xd0, 0xd1, 0xd0, 0x0b, 0xe3, 0x45, 0x82, 0xb6, + 0xc0, 0x8f, 0x79, 0x1b, 0x99, 0x3d, 0xb9, 0x24, 0x7b, 0x66, 0x2c, 0x72, 0x63, 0xfb, 0xc4, 0x5c, + 0x76, 0x93, 0xb9, 0x09, 0xad, 0x69, 0x00, 0xc4, 0x64, 0x7e, 0xa7, 0xc0, 0x2a, 0x67, 0xb3, 0x94, + 0xfe, 0x58, 0x70, 0x1f, 0x58, 0x38, 0x25, 0xf6, 0xfc, 0x34, 0xec, 0x73, 0x33, 0xb1, 0x17, 0xb2, + 0xd8, 0x6f, 0xc0, 0xda, 0x04, 0x38, 0x01, 0xfc, 0x10, 0x4a, 0x07, 0xa9, 0xa7, 0x9a, 0xf8, 0x6d, + 0xd4, 0x49, 0xa1, 0xcf, 0x65, 0xc7, 0xea, 0x94, 0x3e, 0xfd, 0x14, 0x6e, 0xbf, 0xb0, 0xdd, 0xde, + 0xb6, 0xe3, 0xf0, 0x7d, 0x6a, 0xdf, 0xfd, 0x94, 0x69, 0xf1, 0xbb, 0x02, 0x7f, 0x9d, 0xa9, 0x2e, + 0xf2, 0xe6, 0x30, 0xb3, 0x20, 0xfe, 0x3b, 0xd5, 0x4f, 0x3e, 0xa0, 0xcb, 0xfb, 0x8d, 0x18, 0xc4, + 0xe2, 0x96, 0xd6, 0x01, 0x54, 0x52, 0xe4, 0x29, 0x63, 0x78, 0x73, 0x7c, 0x0c, 0x4f, 0xe9, 0x5f, + 0xc9, 0x08, 0xfe, 0x0e, 0x0a, 0x8c, 0xf6, 0xa1, 0x94, 0x4c, 0xc5, 0x9b, 0xbf, 0xf3, 0x5d, 0x59, + 0xc2, 0x79, 0x66, 0x64, 0x21, 0x79, 0xe4, 0xb1, 0x1e, 0xf9, 0x93, 0x02, 0x4d, 0x56, 0x8f, 0xff, + 0x33, 0x09, 0x0a, 0x6c, 0xd3, 0xb1, 0xdf, 0xa2, 0x63, 0x44, 0x88, 0xed, 0x0e, 0xb0, 0x7a, 0x87, + 0x36, 0xac, 0x60, 0x80, 0x08, 0x9f, 0x5d, 0xc2, 0x6e, 0x85, 0xd3, 0x98, 0x96, 0xfa, 0x77, 0x58, + 0xc2, 0xde, 0x28, 0xb0, 0x90, 0x81, 0xae, 0xfc, 0x00, 0x61, 0x6c, 0x7b, 0xae, 0xc0, 0xb1, 0xc8, + 0x19, 0x7b, 0x31, 0x9d, 0x66, 0xa7, 0xc5, 0x7e, 0xb1, 0x18, 0xbd, 0x9e, 0x4c, 0xc2, 0x32, 0xa7, + 0xec, 0xf6, 0x1c, 0xed, 0xb7, 0x1c, 0x2c, 0x4f, 0x83, 0xd1, 0x82, 0xd2, 0xa5, 0x17, 0x5c, 0xf4, + 0x1d, 0xef, 0x52, 0xba, 0x2e, 0xcf, 0xea, 0x3d, 0x58, 0x10, 0xf6, 0xc7, 0xb2, 0xaa, 0xac, 0xd7, + 0x39, 0x39, 0xce, 0xc5, 0x7b, 0xb0, 0x20, 0x7c, 0x89, 0x05, 0x39, 0x80, 0x3a, 0x27, 0x1f, 0x24, + 0x3f, 0x87, 0x16, 0x30, 0xf1, 0x7c, 0x83, 0xff, 0x13, 0xc1, 0xf2, 0xfc, 0x48, 0xee, 0xf9, 0x94, + 0xbc, 0x4d, 0xa9, 0x3b, 0x9e, 0x1f, 0xa9, 0xaf, 0xc4, 0xde, 0x6e, 0x60, 0x81, 0xb3, 0x59, 0x60, + 0xe9, 0xb3, 0x91, 0x0a, 0xe7, 0xac, 0x97, 0x15, 0x5b, 0x7c, 0xec, 0xa1, 0xac, 0xcb, 0x62, 0xaa, + 0x2e, 0xef, 0xc4, 0xd3, 0x82, 0xfe, 0x40, 0xc6, 0xec, 0x57, 0x74, 0x59, 0x8e, 0x05, 0xfa, 0xcb, + 0x19, 0x3f, 0x6f, 0x7f, 0xb3, 0x19, 0xda, 0x04, 0x61, 0xdc, 0xb1, 0xbd, 0x2e, 0xff, 0xea, 0x0e, + 0xbc, 0x6e, 0x48, 0xba, 0xec, 0x5f, 0x53, 0xdd, 0x18, 0xc8, 0x59, 0x91, 0x11, 0x1e, 0xfd, 0x11, + 0x00, 0x00, 0xff, 0xff, 0xc0, 0xb3, 0xd6, 0x9d, 0x2e, 0x13, 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 6dd54ce6e4f..7adb985b3df 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,32 +29,42 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 395 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0x51, 0x4f, 0xea, 0x30, - 0x14, 0xc7, 0xef, 0x7d, 0xb8, 0xdc, 0x58, 0x31, 0x98, 0xfa, 0x60, 0x82, 0x80, 0x8a, 0xd1, 0x04, - 0x4d, 0x98, 0xc1, 0x4f, 0x00, 0x44, 0x91, 0x90, 0x90, 0x28, 0x84, 0x07, 0x12, 0x1f, 0xca, 0x76, - 0x94, 0xc5, 0x6d, 0x1d, 0x3b, 0x65, 0xd1, 0xcf, 0xee, 0x8b, 0x61, 0xa3, 0x65, 0x14, 0x8a, 0xbe, - 0x6d, 0xff, 0xdf, 0x39, 0xbf, 0x9e, 0xa6, 0x4d, 0x09, 0x8d, 0x85, 0x2d, 0x3c, 0x84, 0x28, 0x76, - 0x6d, 0xa8, 0x87, 0x11, 0x17, 0x9c, 0xe6, 0xb3, 0x59, 0xb1, 0x90, 0xfc, 0x39, 0x4c, 0xb0, 0x14, - 0x37, 0x66, 0xe4, 0xdf, 0x68, 0x11, 0xd1, 0x29, 0x39, 0xba, 0xff, 0x00, 0x7b, 0x2e, 0x20, 0xf9, - 0x6f, 0x73, 0xdf, 0x67, 0x81, 0x43, 0x2f, 0xeb, 0xab, 0x8e, 0x2d, 0xfc, 0x19, 0x66, 0x73, 0x40, - 0x51, 0xbc, 0xfa, 0xa9, 0x0c, 0x43, 0x1e, 0x20, 0x54, 0xff, 0xdc, 0xfe, 0x6d, 0x7c, 0xfd, 0x27, - 0xb9, 0x04, 0x3a, 0x34, 0x22, 0xc7, 0x0f, 0x6e, 0xe0, 0x34, 0x3d, 0x6f, 0x30, 0x65, 0x91, 0x83, - 0xdd, 0xa0, 0x07, 0x9f, 0x18, 0x32, 0x1b, 0x68, 0x2d, 0x63, 0x34, 0xd4, 0xc8, 0xc5, 0xaf, 0x7f, - 0x53, 0x2a, 0x07, 0xa0, 0x3d, 0x42, 0x3a, 0x20, 0x5a, 0xcc, 0x7e, 0x9f, 0x87, 0x48, 0x4b, 0x99, - 0xde, 0x55, 0x2c, 0xcd, 0x65, 0x03, 0x55, 0xb2, 0x17, 0x72, 0xd8, 0x01, 0xd1, 0x06, 0xcf, 0xeb, - 0x06, 0xaf, 0xbc, 0xcf, 0x7c, 0x40, 0x5a, 0x5d, 0x6f, 0x5a, 0x83, 0x52, 0x7c, 0xb1, 0xb3, 0x46, - 0xe9, 0xfb, 0x64, 0x3f, 0x43, 0x69, 0x79, 0x7b, 0x97, 0x94, 0x56, 0x4c, 0x58, 0xf9, 0xc6, 0xa4, - 0xb0, 0x04, 0xd8, 0xf4, 0x5c, 0x86, 0x80, 0xf4, 0x7c, 0xb3, 0x49, 0x32, 0xe9, 0xad, 0xee, 0x2a, - 0xd1, 0x66, 0x55, 0xe7, 0xa7, 0xcd, 0xaa, 0x9f, 0x59, 0xc5, 0x84, 0x95, 0xef, 0x89, 0xe4, 0x33, - 0x00, 0xa9, 0xa1, 0x43, 0x4d, 0x79, 0x6a, 0xe4, 0x4a, 0xf9, 0x48, 0xf6, 0x3a, 0x20, 0x06, 0xf6, - 0x14, 0x7c, 0x46, 0x4f, 0xd6, 0xeb, 0xd3, 0x54, 0xca, 0x4a, 0xdb, 0xa1, 0x32, 0x0d, 0xc9, 0xc1, - 0x22, 0x8e, 0xe2, 0xd1, 0xd2, 0xa6, 0xad, 0xbe, 0x22, 0xd2, 0x78, 0x66, 0x2e, 0xd0, 0xe6, 0x1b, - 0xb2, 0x89, 0x07, 0x42, 0x9f, 0x2f, 0x4d, 0x0d, 0xf3, 0x49, 0xa8, 0x5d, 0xf2, 0x34, 0xde, 0xb8, - 0xe4, 0xcb, 0xd8, 0x70, 0xc9, 0x15, 0xd5, 0x64, 0x72, 0xa7, 0x9a, 0x4c, 0xdb, 0x66, 0xd9, 0x40, - 0xa5, 0xac, 0x75, 0x33, 0xae, 0xc5, 0xae, 0x00, 0xc4, 0xba, 0xcb, 0xad, 0xf4, 0xcb, 0x7a, 0xe3, - 0x56, 0x2c, 0xac, 0xe4, 0x41, 0xb2, 0xb2, 0xcf, 0xd5, 0x24, 0x97, 0x64, 0x77, 0xdf, 0x01, 0x00, - 0x00, 0xff, 0xff, 0xd1, 0x33, 0xf9, 0x95, 0xd9, 0x04, 0x00, 0x00, + // 553 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x95, 0x6d, 0x4f, 0x13, 0x41, + 0x10, 0xc7, 0xf5, 0x85, 0x44, 0x57, 0x04, 0x32, 0xbe, 0x30, 0x29, 0xb4, 0xd2, 0x2a, 0x26, 0x68, + 0xd2, 0x33, 0xf8, 0x09, 0xa0, 0x62, 0x25, 0x24, 0x24, 0x42, 0x83, 0x09, 0x09, 0x2f, 0x96, 0xbb, + 0x91, 0x5e, 0xbc, 0x27, 0x6e, 0xb7, 0x17, 0xf9, 0x10, 0x7e, 0x67, 0xd3, 0xdd, 0xee, 0x76, 0x6f, + 0x1f, 0x5a, 0xdf, 0xb5, 0xf3, 0xfb, 0xcf, 0x7f, 0x76, 0xee, 0x66, 0xf6, 0x08, 0x34, 0x3c, 0xe6, + 0x19, 0xc3, 0xba, 0x49, 0x63, 0x1c, 0x56, 0x75, 0xc9, 0x4b, 0xd8, 0x34, 0x63, 0x9d, 0x6d, 0xf1, + 0x2f, 0xa1, 0x9c, 0x4a, 0x7c, 0xf4, 0x40, 0x9e, 0x5d, 0xcf, 0x43, 0x30, 0x25, 0xaf, 0x4f, 0xff, + 0x60, 0x3c, 0xe3, 0x28, 0xfe, 0x8f, 0xca, 0x3c, 0xa7, 0x45, 0x02, 0x07, 0xc3, 0x65, 0x86, 0x87, + 0x5f, 0xe2, 0xc3, 0x0c, 0x19, 0xef, 0x7c, 0x58, 0x27, 0x63, 0x55, 0x59, 0x30, 0x1c, 0x3c, 0xf9, + 0xfc, 0xf4, 0xe8, 0xef, 0x16, 0xd9, 0x10, 0x30, 0x81, 0x5b, 0xb2, 0x33, 0x9a, 0xd2, 0xe2, 0x1e, + 0x27, 0xf4, 0x2e, 0x43, 0x3e, 0x79, 0xac, 0x10, 0x06, 0x86, 0x95, 0x0d, 0x55, 0xb9, 0x77, 0x2b, + 0x35, 0xaa, 0x16, 0xfc, 0x24, 0x5b, 0xa3, 0x1a, 0x29, 0xc7, 0x73, 0x7c, 0x64, 0x15, 0x8d, 0x11, + 0xf6, 0xcd, 0xc4, 0x16, 0x52, 0xd6, 0xfd, 0x15, 0x0a, 0x6d, 0x7c, 0x41, 0x5e, 0x4a, 0x76, 0x35, + 0xa5, 0x75, 0x02, 0x5d, 0x27, 0x47, 0xc4, 0x95, 0x65, 0x2f, 0x84, 0xcd, 0x83, 0x7e, 0xc5, 0x0c, + 0x03, 0x07, 0x6d, 0x23, 0xdf, 0x41, 0x6d, 0x85, 0x36, 0xfe, 0x41, 0x36, 0x25, 0x13, 0x15, 0x19, + 0xf4, 0x9c, 0x24, 0x09, 0x94, 0xe9, 0xdb, 0x20, 0xd7, 0x96, 0x13, 0xf2, 0x4a, 0x12, 0xf9, 0xc8, + 0x19, 0xb8, 0x39, 0x0b, 0xa2, 0x4c, 0xf7, 0xc3, 0x02, 0xed, 0x5a, 0x93, 0x37, 0xdf, 0xd2, 0x22, + 0x39, 0xce, 0x32, 0x59, 0xf0, 0xac, 0xd0, 0x8f, 0xe2, 0xd0, 0x48, 0x0f, 0x68, 0x54, 0xa5, 0x8f, + 0xff, 0x23, 0xd5, 0x35, 0xcf, 0x09, 0x19, 0x23, 0x3f, 0xa1, 0xf1, 0xef, 0x59, 0xc5, 0x60, 0xcf, + 0xc8, 0x5d, 0x86, 0x95, 0x73, 0x37, 0x40, 0xb5, 0xd9, 0x2d, 0xd9, 0x19, 0x23, 0x1f, 0x61, 0x96, + 0x9d, 0x15, 0xbf, 0xca, 0x0b, 0x9a, 0x23, 0x6b, 0x8d, 0xb2, 0x0d, 0x7d, 0xa3, 0xec, 0x6a, 0xcc, + 0x89, 0x33, 0x28, 0x74, 0xfd, 0x59, 0xbe, 0x89, 0x6b, 0x61, 0xed, 0x77, 0x43, 0xb6, 0x17, 0x80, + 0x1d, 0x67, 0x29, 0x65, 0xc8, 0xa0, 0xef, 0x26, 0x29, 0xa6, 0x7c, 0x07, 0xab, 0x24, 0xd6, 0x59, + 0xf5, 0xfb, 0xb3, 0xce, 0x6a, 0xbf, 0xb3, 0x5e, 0x08, 0x9b, 0x43, 0x6c, 0x80, 0xf6, 0x10, 0x9b, + 0xc0, 0x37, 0xc4, 0x6d, 0xae, 0x2d, 0xbf, 0x93, 0x17, 0x63, 0xe4, 0x57, 0xf1, 0x14, 0x73, 0x0a, + 0xbb, 0x6d, 0xbd, 0x8c, 0x2a, 0xb3, 0x3d, 0x3f, 0xd4, 0x4e, 0xa7, 0xe4, 0xf9, 0x3c, 0x2c, 0xee, + 0x81, 0x8e, 0xa5, 0x35, 0x2f, 0x81, 0x5d, 0x2f, 0x33, 0xb7, 0x6a, 0x1e, 0xad, 0x9b, 0xeb, 0xc5, + 0xa1, 0xac, 0x26, 0x96, 0xc4, 0xb7, 0x55, 0x96, 0xc0, 0x6a, 0x53, 0x6e, 0x9b, 0xdd, 0xa6, 0x8c, + 0x06, 0xda, 0x54, 0xd0, 0xda, 0x15, 0xb5, 0xf2, 0x5e, 0x75, 0x68, 0x57, 0xdc, 0x65, 0x97, 0x66, + 0xaa, 0x53, 0xcb, 0xcc, 0x6a, 0xb3, 0x1b, 0xa0, 0xda, 0x2c, 0x26, 0x70, 0x89, 0x79, 0xd9, 0xe8, + 0xeb, 0x6f, 0x3e, 0x95, 0xf0, 0xde, 0x48, 0x73, 0xb1, 0x32, 0x3f, 0x58, 0xa3, 0x32, 0xd7, 0x45, + 0x72, 0xf1, 0xde, 0x44, 0x85, 0xbe, 0x93, 0xab, 0x99, 0x6f, 0x5d, 0x1c, 0x89, 0xf2, 0x3e, 0xf9, + 0x74, 0x73, 0xd8, 0xa4, 0x1c, 0x19, 0x1b, 0xa6, 0x65, 0x24, 0x7f, 0x45, 0xf7, 0x65, 0xd4, 0xf0, + 0x48, 0x7c, 0xa2, 0x23, 0xf3, 0x03, 0x7e, 0xb7, 0x21, 0x62, 0x5f, 0xfe, 0x05, 0x00, 0x00, 0xff, + 0xff, 0x73, 0x69, 0xff, 0x16, 0xeb, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -168,6 +178,30 @@ var _Vtctl_serviceDesc = grpc.ServiceDesc{ // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type VtctldClient interface { + // ChangeTabletType changes the db type for the specified tablet, if possible. + // This is used primarily to arrange replicas, and it will not convert a + // primary. For that, use InitShardPrimary. + // + // NOTE: This command automatically updates the serving graph. + ChangeTabletType(ctx context.Context, in *vtctldata.ChangeTabletTypeRequest, opts ...grpc.CallOption) (*vtctldata.ChangeTabletTypeResponse, error) + // CreateKeyspace creates the specified keyspace in the topology. For a + // SNAPSHOT keyspace, the request must specify the name of a base keyspace, + // as well as a snapshot time. + CreateKeyspace(ctx context.Context, in *vtctldata.CreateKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.CreateKeyspaceResponse, error) + // CreateShard creates the specified shard in the topology. + CreateShard(ctx context.Context, in *vtctldata.CreateShardRequest, opts ...grpc.CallOption) (*vtctldata.CreateShardResponse, error) + // DeleteKeyspace deletes the specified keyspace from the topology. In + // recursive mode, it also recursively deletes all shards in the keyspace. + // Otherwise, the keyspace must be empty (have no shards), or DeleteKeyspace + // returns an error. + DeleteKeyspace(ctx context.Context, in *vtctldata.DeleteKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.DeleteKeyspaceResponse, error) + // DeleteShards deletes the specified shards from the topology. In recursive + // mode, it also deletes all tablets belonging to the shard. Otherwise, the + // shard must be empty (have no tablets) or DeleteShards returns an error for + // that shard. + DeleteShards(ctx context.Context, in *vtctldata.DeleteShardsRequest, opts ...grpc.CallOption) (*vtctldata.DeleteShardsResponse, error) + // DeleteTablets deletes one or more tablets from the topology. + DeleteTablets(ctx context.Context, in *vtctldata.DeleteTabletsRequest, opts ...grpc.CallOption) (*vtctldata.DeleteTabletsResponse, error) // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. FindAllShardsInKeyspace(ctx context.Context, in *vtctldata.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.FindAllShardsInKeyspaceResponse, error) @@ -188,6 +222,8 @@ type VtctldClient interface { // GetSchema returns the schema for a tablet, or just the schema for the // specified tables in that tablet. GetSchema(ctx context.Context, in *vtctldata.GetSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSchemaResponse, error) + // GetShard returns information about a shard in the topology. + GetShard(ctx context.Context, in *vtctldata.GetShardRequest, opts ...grpc.CallOption) (*vtctldata.GetShardResponse, error) // GetSrvVSchema returns a the SrvVSchema for a cell. GetSrvVSchema(ctx context.Context, in *vtctldata.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSrvVSchemaResponse, error) // GetTablet returns information about a tablet. @@ -196,6 +232,13 @@ type VtctldClient interface { GetTablets(ctx context.Context, in *vtctldata.GetTabletsRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletsResponse, error) // GetVSchema returns the vschema for a keyspace. GetVSchema(ctx context.Context, in *vtctldata.GetVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetVSchemaResponse, error) + // RemoveKeyspaceCell removes the specified cell from the Cells list for all + // shards in the specified keyspace, as well as from the SrvKeyspace for that + // keyspace in that cell. + RemoveKeyspaceCell(ctx context.Context, in *vtctldata.RemoveKeyspaceCellRequest, opts ...grpc.CallOption) (*vtctldata.RemoveKeyspaceCellResponse, error) + // RemoveShardCell removes the specified cell from the specified shard's Cells + // list. + RemoveShardCell(ctx context.Context, in *vtctldata.RemoveShardCellRequest, opts ...grpc.CallOption) (*vtctldata.RemoveShardCellResponse, error) } type vtctldClient struct { @@ -206,6 +249,60 @@ func NewVtctldClient(cc *grpc.ClientConn) VtctldClient { return &vtctldClient{cc} } +func (c *vtctldClient) ChangeTabletType(ctx context.Context, in *vtctldata.ChangeTabletTypeRequest, opts ...grpc.CallOption) (*vtctldata.ChangeTabletTypeResponse, error) { + out := new(vtctldata.ChangeTabletTypeResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/ChangeTabletType", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) CreateKeyspace(ctx context.Context, in *vtctldata.CreateKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.CreateKeyspaceResponse, error) { + out := new(vtctldata.CreateKeyspaceResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/CreateKeyspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) CreateShard(ctx context.Context, in *vtctldata.CreateShardRequest, opts ...grpc.CallOption) (*vtctldata.CreateShardResponse, error) { + out := new(vtctldata.CreateShardResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/CreateShard", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) DeleteKeyspace(ctx context.Context, in *vtctldata.DeleteKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.DeleteKeyspaceResponse, error) { + out := new(vtctldata.DeleteKeyspaceResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/DeleteKeyspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) DeleteShards(ctx context.Context, in *vtctldata.DeleteShardsRequest, opts ...grpc.CallOption) (*vtctldata.DeleteShardsResponse, error) { + out := new(vtctldata.DeleteShardsResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/DeleteShards", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) DeleteTablets(ctx context.Context, in *vtctldata.DeleteTabletsRequest, opts ...grpc.CallOption) (*vtctldata.DeleteTabletsResponse, error) { + out := new(vtctldata.DeleteTabletsResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/DeleteTablets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldata.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldata.FindAllShardsInKeyspaceResponse, error) { out := new(vtctldata.FindAllShardsInKeyspaceResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/FindAllShardsInKeyspace", in, out, opts...) @@ -278,6 +375,15 @@ func (c *vtctldClient) GetSchema(ctx context.Context, in *vtctldata.GetSchemaReq return out, nil } +func (c *vtctldClient) GetShard(ctx context.Context, in *vtctldata.GetShardRequest, opts ...grpc.CallOption) (*vtctldata.GetShardResponse, error) { + out := new(vtctldata.GetShardResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetShard", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) GetSrvVSchema(ctx context.Context, in *vtctldata.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetSrvVSchemaResponse, error) { out := new(vtctldata.GetSrvVSchemaResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetSrvVSchema", in, out, opts...) @@ -314,8 +420,50 @@ func (c *vtctldClient) GetVSchema(ctx context.Context, in *vtctldata.GetVSchemaR return out, nil } +func (c *vtctldClient) RemoveKeyspaceCell(ctx context.Context, in *vtctldata.RemoveKeyspaceCellRequest, opts ...grpc.CallOption) (*vtctldata.RemoveKeyspaceCellResponse, error) { + out := new(vtctldata.RemoveKeyspaceCellResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/RemoveKeyspaceCell", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) RemoveShardCell(ctx context.Context, in *vtctldata.RemoveShardCellRequest, opts ...grpc.CallOption) (*vtctldata.RemoveShardCellResponse, error) { + out := new(vtctldata.RemoveShardCellResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/RemoveShardCell", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // VtctldServer is the server API for Vtctld service. type VtctldServer interface { + // ChangeTabletType changes the db type for the specified tablet, if possible. + // This is used primarily to arrange replicas, and it will not convert a + // primary. For that, use InitShardPrimary. + // + // NOTE: This command automatically updates the serving graph. + ChangeTabletType(context.Context, *vtctldata.ChangeTabletTypeRequest) (*vtctldata.ChangeTabletTypeResponse, error) + // CreateKeyspace creates the specified keyspace in the topology. For a + // SNAPSHOT keyspace, the request must specify the name of a base keyspace, + // as well as a snapshot time. + CreateKeyspace(context.Context, *vtctldata.CreateKeyspaceRequest) (*vtctldata.CreateKeyspaceResponse, error) + // CreateShard creates the specified shard in the topology. + CreateShard(context.Context, *vtctldata.CreateShardRequest) (*vtctldata.CreateShardResponse, error) + // DeleteKeyspace deletes the specified keyspace from the topology. In + // recursive mode, it also recursively deletes all shards in the keyspace. + // Otherwise, the keyspace must be empty (have no shards), or DeleteKeyspace + // returns an error. + DeleteKeyspace(context.Context, *vtctldata.DeleteKeyspaceRequest) (*vtctldata.DeleteKeyspaceResponse, error) + // DeleteShards deletes the specified shards from the topology. In recursive + // mode, it also deletes all tablets belonging to the shard. Otherwise, the + // shard must be empty (have no tablets) or DeleteShards returns an error for + // that shard. + DeleteShards(context.Context, *vtctldata.DeleteShardsRequest) (*vtctldata.DeleteShardsResponse, error) + // DeleteTablets deletes one or more tablets from the topology. + DeleteTablets(context.Context, *vtctldata.DeleteTabletsRequest) (*vtctldata.DeleteTabletsResponse, error) // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. FindAllShardsInKeyspace(context.Context, *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) @@ -336,6 +484,8 @@ type VtctldServer interface { // GetSchema returns the schema for a tablet, or just the schema for the // specified tables in that tablet. GetSchema(context.Context, *vtctldata.GetSchemaRequest) (*vtctldata.GetSchemaResponse, error) + // GetShard returns information about a shard in the topology. + GetShard(context.Context, *vtctldata.GetShardRequest) (*vtctldata.GetShardResponse, error) // GetSrvVSchema returns a the SrvVSchema for a cell. GetSrvVSchema(context.Context, *vtctldata.GetSrvVSchemaRequest) (*vtctldata.GetSrvVSchemaResponse, error) // GetTablet returns information about a tablet. @@ -344,12 +494,37 @@ type VtctldServer interface { GetTablets(context.Context, *vtctldata.GetTabletsRequest) (*vtctldata.GetTabletsResponse, error) // GetVSchema returns the vschema for a keyspace. GetVSchema(context.Context, *vtctldata.GetVSchemaRequest) (*vtctldata.GetVSchemaResponse, error) + // RemoveKeyspaceCell removes the specified cell from the Cells list for all + // shards in the specified keyspace, as well as from the SrvKeyspace for that + // keyspace in that cell. + RemoveKeyspaceCell(context.Context, *vtctldata.RemoveKeyspaceCellRequest) (*vtctldata.RemoveKeyspaceCellResponse, error) + // RemoveShardCell removes the specified cell from the specified shard's Cells + // list. + RemoveShardCell(context.Context, *vtctldata.RemoveShardCellRequest) (*vtctldata.RemoveShardCellResponse, error) } // UnimplementedVtctldServer can be embedded to have forward compatible implementations. type UnimplementedVtctldServer struct { } +func (*UnimplementedVtctldServer) ChangeTabletType(ctx context.Context, req *vtctldata.ChangeTabletTypeRequest) (*vtctldata.ChangeTabletTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangeTabletType not implemented") +} +func (*UnimplementedVtctldServer) CreateKeyspace(ctx context.Context, req *vtctldata.CreateKeyspaceRequest) (*vtctldata.CreateKeyspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateKeyspace not implemented") +} +func (*UnimplementedVtctldServer) CreateShard(ctx context.Context, req *vtctldata.CreateShardRequest) (*vtctldata.CreateShardResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateShard not implemented") +} +func (*UnimplementedVtctldServer) DeleteKeyspace(ctx context.Context, req *vtctldata.DeleteKeyspaceRequest) (*vtctldata.DeleteKeyspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteKeyspace not implemented") +} +func (*UnimplementedVtctldServer) DeleteShards(ctx context.Context, req *vtctldata.DeleteShardsRequest) (*vtctldata.DeleteShardsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteShards not implemented") +} +func (*UnimplementedVtctldServer) DeleteTablets(ctx context.Context, req *vtctldata.DeleteTabletsRequest) (*vtctldata.DeleteTabletsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteTablets not implemented") +} func (*UnimplementedVtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctldata.FindAllShardsInKeyspaceRequest) (*vtctldata.FindAllShardsInKeyspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method FindAllShardsInKeyspace not implemented") } @@ -374,6 +549,9 @@ func (*UnimplementedVtctldServer) GetKeyspaces(ctx context.Context, req *vtctlda func (*UnimplementedVtctldServer) GetSchema(ctx context.Context, req *vtctldata.GetSchemaRequest) (*vtctldata.GetSchemaResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSchema not implemented") } +func (*UnimplementedVtctldServer) GetShard(ctx context.Context, req *vtctldata.GetShardRequest) (*vtctldata.GetShardResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetShard not implemented") +} func (*UnimplementedVtctldServer) GetSrvVSchema(ctx context.Context, req *vtctldata.GetSrvVSchemaRequest) (*vtctldata.GetSrvVSchemaResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSrvVSchema not implemented") } @@ -386,11 +564,125 @@ func (*UnimplementedVtctldServer) GetTablets(ctx context.Context, req *vtctldata func (*UnimplementedVtctldServer) GetVSchema(ctx context.Context, req *vtctldata.GetVSchemaRequest) (*vtctldata.GetVSchemaResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetVSchema not implemented") } +func (*UnimplementedVtctldServer) RemoveKeyspaceCell(ctx context.Context, req *vtctldata.RemoveKeyspaceCellRequest) (*vtctldata.RemoveKeyspaceCellResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveKeyspaceCell not implemented") +} +func (*UnimplementedVtctldServer) RemoveShardCell(ctx context.Context, req *vtctldata.RemoveShardCellRequest) (*vtctldata.RemoveShardCellResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveShardCell not implemented") +} func RegisterVtctldServer(s *grpc.Server, srv VtctldServer) { s.RegisterService(&_Vtctld_serviceDesc, srv) } +func _Vtctld_ChangeTabletType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.ChangeTabletTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).ChangeTabletType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/ChangeTabletType", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).ChangeTabletType(ctx, req.(*vtctldata.ChangeTabletTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_CreateKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.CreateKeyspaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).CreateKeyspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/CreateKeyspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).CreateKeyspace(ctx, req.(*vtctldata.CreateKeyspaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_CreateShard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.CreateShardRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).CreateShard(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/CreateShard", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).CreateShard(ctx, req.(*vtctldata.CreateShardRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_DeleteKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.DeleteKeyspaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).DeleteKeyspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/DeleteKeyspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).DeleteKeyspace(ctx, req.(*vtctldata.DeleteKeyspaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_DeleteShards_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.DeleteShardsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).DeleteShards(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/DeleteShards", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).DeleteShards(ctx, req.(*vtctldata.DeleteShardsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_DeleteTablets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.DeleteTabletsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).DeleteTablets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/DeleteTablets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).DeleteTablets(ctx, req.(*vtctldata.DeleteTabletsRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_FindAllShardsInKeyspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.FindAllShardsInKeyspaceRequest) if err := dec(in); err != nil { @@ -535,6 +827,24 @@ func _Vtctld_GetSchema_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Vtctld_GetShard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetShardRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetShard(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetShard", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetShard(ctx, req.(*vtctldata.GetShardRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_GetSrvVSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.GetSrvVSchemaRequest) if err := dec(in); err != nil { @@ -607,10 +917,70 @@ func _Vtctld_GetVSchema_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Vtctld_RemoveKeyspaceCell_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.RemoveKeyspaceCellRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).RemoveKeyspaceCell(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/RemoveKeyspaceCell", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).RemoveKeyspaceCell(ctx, req.(*vtctldata.RemoveKeyspaceCellRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_RemoveShardCell_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.RemoveShardCellRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).RemoveShardCell(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/RemoveShardCell", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).RemoveShardCell(ctx, req.(*vtctldata.RemoveShardCellRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Vtctld_serviceDesc = grpc.ServiceDesc{ ServiceName: "vtctlservice.Vtctld", HandlerType: (*VtctldServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "ChangeTabletType", + Handler: _Vtctld_ChangeTabletType_Handler, + }, + { + MethodName: "CreateKeyspace", + Handler: _Vtctld_CreateKeyspace_Handler, + }, + { + MethodName: "CreateShard", + Handler: _Vtctld_CreateShard_Handler, + }, + { + MethodName: "DeleteKeyspace", + Handler: _Vtctld_DeleteKeyspace_Handler, + }, + { + MethodName: "DeleteShards", + Handler: _Vtctld_DeleteShards_Handler, + }, + { + MethodName: "DeleteTablets", + Handler: _Vtctld_DeleteTablets_Handler, + }, { MethodName: "FindAllShardsInKeyspace", Handler: _Vtctld_FindAllShardsInKeyspace_Handler, @@ -643,6 +1013,10 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "GetSchema", Handler: _Vtctld_GetSchema_Handler, }, + { + MethodName: "GetShard", + Handler: _Vtctld_GetShard_Handler, + }, { MethodName: "GetSrvVSchema", Handler: _Vtctld_GetSrvVSchema_Handler, @@ -659,6 +1033,14 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "GetVSchema", Handler: _Vtctld_GetVSchema_Handler, }, + { + MethodName: "RemoveKeyspaceCell", + Handler: _Vtctld_RemoveKeyspaceCell_Handler, + }, + { + MethodName: "RemoveShardCell", + Handler: _Vtctld_RemoveShardCell_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "vtctlservice.proto", diff --git a/go/vt/topo/tablet.go b/go/vt/topo/tablet.go index 06d44cab813..314cb8fcc8b 100644 --- a/go/vt/topo/tablet.go +++ b/go/vt/topo/tablet.go @@ -470,3 +470,21 @@ func (ts *Server) GetTabletsByCell(ctx context.Context, cell string) ([]*topodat } return result, nil } + +// ParseServingTabletType parses the tablet type into the enum, and makes sure +// that the enum is of serving type (MASTER, REPLICA, RDONLY/BATCH). +// +// Note: This function more closely belongs in topoproto, but that would create +// a circular import between packages topo and topoproto. +func ParseServingTabletType(param string) (topodatapb.TabletType, error) { + servedType, err := topoproto.ParseTabletType(param) + if err != nil { + return topodatapb.TabletType_UNKNOWN, err + } + + if !IsInServingGraph(servedType) { + return topodatapb.TabletType_UNKNOWN, fmt.Errorf("served_type has to be in the serving graph, not %v", param) + } + + return servedType, nil +} diff --git a/go/vt/topo/topoproto/keyspace.go b/go/vt/topo/topoproto/keyspace.go index e409f763fd7..625ec0b7293 100644 --- a/go/vt/topo/topoproto/keyspace.go +++ b/go/vt/topo/topoproto/keyspace.go @@ -23,7 +23,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) -// ParseKeyspaceType parses a string into a KeyspaceType +// ParseKeyspaceType parses a string into a KeyspaceType. func ParseKeyspaceType(param string) (topodatapb.KeyspaceType, error) { value, ok := topodatapb.KeyspaceType_value[strings.ToUpper(param)] if !ok { @@ -32,3 +32,13 @@ func ParseKeyspaceType(param string) (topodatapb.KeyspaceType, error) { } return topodatapb.KeyspaceType(value), nil } + +// KeyspaceTypeString returns the string representation of a KeyspaceType. +func KeyspaceTypeString(kt topodatapb.KeyspaceType) string { + str, ok := topodatapb.KeyspaceType_name[int32(kt)] + if !ok { + return "UNKNOWN" + } + + return str +} diff --git a/go/vt/topotools/tablet.go b/go/vt/topotools/tablet.go index b8fc57b1130..9022c322a1d 100644 --- a/go/vt/topotools/tablet.go +++ b/go/vt/topotools/tablet.go @@ -102,6 +102,44 @@ func CheckOwnership(oldTablet, newTablet *topodatapb.Tablet) error { return nil } +// IsPrimaryTablet is a helper function to determine whether the current tablet +// is a primary before we allow its tablet record to be deleted. The canonical +// way to determine the only true primary in a shard is to list all the tablets +// and find the one with the highest MasterTermStartTime among the ones that +// claim to be master. +// +// We err on the side of caution here, i.e. we should never return false for +// a true primary tablet, but it is okay to return true for a tablet that isn't +// the true primary. This can occur if someone issues a DeleteTablet while +// the system is in transition (a reparenting event is in progress and parts of +// the topo have not yet been updated). +func IsPrimaryTablet(ctx context.Context, ts *topo.Server, ti *topo.TabletInfo) (bool, error) { + // Tablet record claims to be non-master, we believe it + if ti.Type != topodatapb.TabletType_MASTER { + return false, nil + } + + si, err := ts.GetShard(ctx, ti.Keyspace, ti.Shard) + if err != nil { + // strictly speaking it isn't correct to return false here, the tablet + // status is unknown + return false, err + } + + // Tablet record claims to be master, and shard record matches + if topoproto.TabletAliasEqual(si.MasterAlias, ti.Tablet.Alias) { + return true, nil + } + + // Shard record has another tablet as master, so check MasterTermStartTime + // If tablet record's MasterTermStartTime is later than the one in the shard + // record, then the tablet is master + tabletMTST := ti.GetMasterTermStartTime() + shardMTST := si.GetMasterTermStartTime() + + return tabletMTST.After(shardMTST), nil +} + // DeleteTablet removes a tablet record from the topology: // - the replication data record if any // - the tablet record diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index ed32a09c69f..db3a1390f32 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -28,6 +28,60 @@ import ( vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) +// ChangeTabletType is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) ChangeTabletType(ctx context.Context, in *vtctldatapb.ChangeTabletTypeRequest, opts ...grpc.CallOption) (*vtctldatapb.ChangeTabletTypeResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.ChangeTabletType(ctx, in, opts...) +} + +// CreateKeyspace is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) CreateKeyspace(ctx context.Context, in *vtctldatapb.CreateKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.CreateKeyspaceResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.CreateKeyspace(ctx, in, opts...) +} + +// CreateShard is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) CreateShard(ctx context.Context, in *vtctldatapb.CreateShardRequest, opts ...grpc.CallOption) (*vtctldatapb.CreateShardResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.CreateShard(ctx, in, opts...) +} + +// DeleteKeyspace is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) DeleteKeyspace(ctx context.Context, in *vtctldatapb.DeleteKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.DeleteKeyspaceResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.DeleteKeyspace(ctx, in, opts...) +} + +// DeleteShards is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) DeleteShards(ctx context.Context, in *vtctldatapb.DeleteShardsRequest, opts ...grpc.CallOption) (*vtctldatapb.DeleteShardsResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.DeleteShards(ctx, in, opts...) +} + +// DeleteTablets is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) DeleteTablets(ctx context.Context, in *vtctldatapb.DeleteTabletsRequest, opts ...grpc.CallOption) (*vtctldatapb.DeleteTabletsResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.DeleteTablets(ctx, in, opts...) +} + // FindAllShardsInKeyspace is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) FindAllShardsInKeyspace(ctx context.Context, in *vtctldatapb.FindAllShardsInKeyspaceRequest, opts ...grpc.CallOption) (*vtctldatapb.FindAllShardsInKeyspaceResponse, error) { if client.c == nil { @@ -100,6 +154,15 @@ func (client *gRPCVtctldClient) GetSchema(ctx context.Context, in *vtctldatapb.G return client.c.GetSchema(ctx, in, opts...) } +// GetShard is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetShard(ctx context.Context, in *vtctldatapb.GetShardRequest, opts ...grpc.CallOption) (*vtctldatapb.GetShardResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetShard(ctx, in, opts...) +} + // GetSrvVSchema is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) GetSrvVSchema(ctx context.Context, in *vtctldatapb.GetSrvVSchemaRequest, opts ...grpc.CallOption) (*vtctldatapb.GetSrvVSchemaResponse, error) { if client.c == nil { @@ -135,3 +198,21 @@ func (client *gRPCVtctldClient) GetVSchema(ctx context.Context, in *vtctldatapb. return client.c.GetVSchema(ctx, in, opts...) } + +// RemoveKeyspaceCell is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) RemoveKeyspaceCell(ctx context.Context, in *vtctldatapb.RemoveKeyspaceCellRequest, opts ...grpc.CallOption) (*vtctldatapb.RemoveKeyspaceCellResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.RemoveKeyspaceCell(ctx, in, opts...) +} + +// RemoveShardCell is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) RemoveShardCell(ctx context.Context, in *vtctldatapb.RemoveShardCellRequest, opts ...grpc.CallOption) (*vtctldatapb.RemoveShardCellResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.RemoveShardCell(ctx, in, opts...) +} diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 96245825f3b..39f09fd66c5 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -18,11 +18,14 @@ package grpcvtctldserver import ( "context" + "errors" "fmt" "path/filepath" "time" "google.golang.org/grpc" + + "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/mysqlctl/mysqlctlproto" "vitess.io/vitess/go/vt/topo" @@ -33,6 +36,7 @@ import ( mysqlctlpb "vitess.io/vitess/go/vt/proto/mysqlctl" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" "vitess.io/vitess/go/vt/proto/vtrpc" @@ -49,6 +53,256 @@ func NewVtctldServer(ts *topo.Server) *VtctldServer { return &VtctldServer{ts: ts, tmc: tmclient.NewTabletManagerClient()} } +// ChangeTabletType is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) ChangeTabletType(ctx context.Context, req *vtctldatapb.ChangeTabletTypeRequest) (*vtctldatapb.ChangeTabletTypeResponse, error) { + tablet, err := s.ts.GetTablet(ctx, req.TabletAlias) + if err != nil { + return nil, err + } + + if !topo.IsTrivialTypeChange(tablet.Type, req.DbType) { + return nil, fmt.Errorf("tablet %v type change %v -> %v is not an allowed transition for ChangeTabletType", req.TabletAlias, tablet.Type, req.DbType) + } + + if req.DryRun { + afterTablet := *tablet.Tablet + afterTablet.Type = req.DbType + + return &vtctldatapb.ChangeTabletTypeResponse{ + BeforeTablet: tablet.Tablet, + AfterTablet: &afterTablet, + WasDryRun: true, + }, nil + } + + err = s.tmc.ChangeType(ctx, tablet.Tablet, req.DbType) + if err != nil { + return nil, err + } + + var changedTablet *topodatapb.Tablet + + changedTabletInfo, err := s.ts.GetTablet(ctx, req.TabletAlias) + if err != nil { + log.Warningf("error while reading the tablet we just changed back out of the topo: %v", err) + } else { + changedTablet = changedTabletInfo.Tablet + } + + return &vtctldatapb.ChangeTabletTypeResponse{ + BeforeTablet: tablet.Tablet, + AfterTablet: changedTablet, + WasDryRun: false, + }, nil +} + +// CreateKeyspace is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) CreateKeyspace(ctx context.Context, req *vtctldatapb.CreateKeyspaceRequest) (*vtctldatapb.CreateKeyspaceResponse, error) { + switch req.Type { + case topodatapb.KeyspaceType_NORMAL: + case topodatapb.KeyspaceType_SNAPSHOT: + if req.BaseKeyspace == "" { + return nil, errors.New("BaseKeyspace is required for SNAPSHOT keyspaces") + } + + if req.SnapshotTime == nil { + return nil, errors.New("SnapshotTime is required for SNAPSHOT keyspaces") + } + default: + return nil, fmt.Errorf("unknown keyspace type %v", req.Type) + } + + ki := &topodatapb.Keyspace{ + KeyspaceType: req.Type, + ShardingColumnName: req.ShardingColumnName, + ShardingColumnType: req.ShardingColumnType, + + ServedFroms: req.ServedFroms, + + BaseKeyspace: req.BaseKeyspace, + SnapshotTime: req.SnapshotTime, + } + + err := s.ts.CreateKeyspace(ctx, req.Name, ki) + if req.Force && topo.IsErrType(err, topo.NodeExists) { + log.Infof("keyspace %v already exists (ignoring error with Force=true)", req.Name) + err = nil + + // Get the actual keyspace out of the topo; it may differ in structure, + // and we want to return the authoritative version as the "created" one + // to the client. + var ks *topo.KeyspaceInfo + ks, _ = s.ts.GetKeyspace(ctx, req.Name) + ki = ks.Keyspace + } + + if err != nil { + return nil, err + } + + if !req.AllowEmptyVSchema { + if err := s.ts.EnsureVSchema(ctx, req.Name); err != nil { + return nil, err + } + } + + if req.Type == topodatapb.KeyspaceType_SNAPSHOT { + vs, err := s.ts.GetVSchema(ctx, req.BaseKeyspace) + if err != nil { + log.Infof("error from GetVSchema(%v) = %v", req.BaseKeyspace, err) + if topo.IsErrType(err, topo.NoNode) { + log.Infof("base keyspace %v does not exist; continuing with bare, unsharded vschema", req.BaseKeyspace) + vs = &vschemapb.Keyspace{ + Sharded: false, + Tables: map[string]*vschemapb.Table{}, + Vindexes: map[string]*vschemapb.Vindex{}, + } + } else { + return nil, err + } + } + + // SNAPSHOT keyspaces are excluded from global routing. + vs.RequireExplicitRouting = true + + if err := s.ts.SaveVSchema(ctx, req.Name, vs); err != nil { + return nil, fmt.Errorf("SaveVSchema(%v) = %w", vs, err) + } + } + + cells := []string{} + err = s.ts.RebuildSrvVSchema(ctx, cells) + if err != nil { + return nil, fmt.Errorf("RebuildSrvVSchema(%v) = %w", cells, err) + } + + return &vtctldatapb.CreateKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: req.Name, + Keyspace: ki, + }, + }, nil +} + +// CreateShard is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) CreateShard(ctx context.Context, req *vtctldatapb.CreateShardRequest) (*vtctldatapb.CreateShardResponse, error) { + if req.IncludeParent { + log.Infof("Creating empty keyspace for %s", req.Keyspace) + if err := s.ts.CreateKeyspace(ctx, req.Keyspace, &topodatapb.Keyspace{}); err != nil { + if req.Force && topo.IsErrType(err, topo.NodeExists) { + log.Infof("keyspace %v already exists; ignoring error because Force = true", req.Keyspace) + } else { + return nil, err + } + } + } + + shardExists := false + + if err := s.ts.CreateShard(ctx, req.Keyspace, req.ShardName); err != nil { + if req.Force && topo.IsErrType(err, topo.NodeExists) { + log.Infof("shard %v/%v already exists; ignoring error because Force = true", req.Keyspace, req.ShardName) + shardExists = true + } else { + return nil, err + } + } + + // Fetch what we just created out of the topo. Errors should never happen + // here, but we'll check them anyway. + + ks, err := s.ts.GetKeyspace(ctx, req.Keyspace) + if err != nil { + return nil, err + } + + shard, err := s.ts.GetShard(ctx, req.Keyspace, req.ShardName) + if err != nil { + return nil, err + } + + return &vtctldatapb.CreateShardResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: req.Keyspace, + Keyspace: ks.Keyspace, + }, + Shard: &vtctldatapb.Shard{ + Keyspace: req.Keyspace, + Name: req.ShardName, + Shard: shard.Shard, + }, + ShardAlreadyExists: shardExists, + }, nil +} + +// DeleteKeyspace is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) DeleteKeyspace(ctx context.Context, req *vtctldatapb.DeleteKeyspaceRequest) (*vtctldatapb.DeleteKeyspaceResponse, error) { + shards, err := s.ts.GetShardNames(ctx, req.Keyspace) + if err != nil { + return nil, err + } + + if len(shards) > 0 { + if !req.Recursive { + return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "keyspace %v still has %d shards; use Recursive=true or remove them manually", req.Keyspace, len(shards)) + } + + log.Infof("Deleting all %d shards (and their tablets) in keyspace %v", len(shards), req.Keyspace) + recursive := true + evenIfServing := true + + for _, shard := range shards { + log.Infof("Recursively deleting shard %v/%v", req.Keyspace, shard) + if err := deleteShard(ctx, s.ts, req.Keyspace, shard, recursive, evenIfServing); err != nil { + return nil, fmt.Errorf("cannot delete shard %v/%v: %w", req.Keyspace, shard, err) + } + } + } + + cells, err := s.ts.GetKnownCells(ctx) + if err != nil { + return nil, err + } + + for _, cell := range cells { + if err := s.ts.DeleteKeyspaceReplication(ctx, cell, req.Keyspace); err != nil && !topo.IsErrType(err, topo.NoNode) { + log.Warningf("Cannot delete KeyspaceReplication in cell %v for %v: %v", cell, req.Keyspace, err) + } + + if err := s.ts.DeleteSrvKeyspace(ctx, cell, req.Keyspace); err != nil && !topo.IsErrType(err, topo.NoNode) { + log.Warningf("Cannot delete SrvKeyspace in cell %v for %v: %v", cell, req.Keyspace, err) + } + } + + if err := s.ts.DeleteKeyspace(ctx, req.Keyspace); err != nil { + return nil, err + } + + return &vtctldatapb.DeleteKeyspaceResponse{}, nil +} + +// DeleteShards is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) DeleteShards(ctx context.Context, req *vtctldatapb.DeleteShardsRequest) (*vtctldatapb.DeleteShardsResponse, error) { + for _, shard := range req.Shards { + if err := deleteShard(ctx, s.ts, shard.Keyspace, shard.Name, req.Recursive, req.EvenIfServing); err != nil { + return nil, err + } + } + + return &vtctldatapb.DeleteShardsResponse{}, nil +} + +// DeleteTablets is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) DeleteTablets(ctx context.Context, req *vtctldatapb.DeleteTabletsRequest) (*vtctldatapb.DeleteTabletsResponse, error) { + for _, alias := range req.TabletAliases { + if err := deleteTablet(ctx, s.ts, alias, req.AllowPrimary); err != nil { + return nil, err + } + } + + return &vtctldatapb.DeleteTabletsResponse{}, nil +} + // FindAllShardsInKeyspace is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) FindAllShardsInKeyspace(ctx context.Context, req *vtctldatapb.FindAllShardsInKeyspaceRequest) (*vtctldatapb.FindAllShardsInKeyspaceResponse, error) { result, err := s.ts.FindAllShardsInKeyspace(ctx, req.Keyspace) @@ -212,6 +466,22 @@ func (s *VtctldServer) GetSchema(ctx context.Context, req *vtctldatapb.GetSchema }, nil } +// GetShard is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetShard(ctx context.Context, req *vtctldatapb.GetShardRequest) (*vtctldatapb.GetShardResponse, error) { + shard, err := s.ts.GetShard(ctx, req.Keyspace, req.ShardName) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetShardResponse{ + Shard: &vtctldatapb.Shard{ + Keyspace: req.Keyspace, + Name: req.ShardName, + Shard: shard.Shard, + }, + }, nil +} + // GetSrvVSchema is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) GetSrvVSchema(ctx context.Context, req *vtctldatapb.GetSrvVSchemaRequest) (*vtctldatapb.GetSrvVSchemaResponse, error) { vschema, err := s.ts.GetSrvVSchema(ctx, req.Cell) @@ -340,6 +610,39 @@ func (s *VtctldServer) GetVSchema(ctx context.Context, req *vtctldatapb.GetVSche }, nil } +// RemoveKeyspaceCell is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) RemoveKeyspaceCell(ctx context.Context, req *vtctldatapb.RemoveKeyspaceCellRequest) (*vtctldatapb.RemoveKeyspaceCellResponse, error) { + shards, err := s.ts.GetShardNames(ctx, req.Keyspace) + if err != nil { + return nil, err + } + + // Remove all the shards, serially. Stop immediately if any fail. + for _, shard := range shards { + log.Infof("Removing cell %v from shard %v/%v", req.Cell, req.Keyspace, shard) + if err := removeShardCell(ctx, s.ts, req.Cell, req.Keyspace, shard, req.Recursive, req.Force); err != nil { + return nil, fmt.Errorf("cannot remove cell %v from shard %v/%v: %w", req.Cell, req.Keyspace, shard, err) + } + } + + // Last, remove the SrvKeyspace object. + log.Infof("Removing cell %v keyspace %v SrvKeyspace object", req.Cell, req.Keyspace) + if err := s.ts.DeleteSrvKeyspace(ctx, req.Cell, req.Keyspace); err != nil { + return nil, fmt.Errorf("cannot delete SrvKeyspace from cell %v for keyspace %v: %w", req.Cell, req.Keyspace, err) + } + + return &vtctldatapb.RemoveKeyspaceCellResponse{}, nil +} + +// RemoveShardCell is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) RemoveShardCell(ctx context.Context, req *vtctldatapb.RemoveShardCellRequest) (*vtctldatapb.RemoveShardCellResponse, error) { + if err := removeShardCell(ctx, s.ts, req.Cell, req.Keyspace, req.ShardName, req.Recursive, req.Force); err != nil { + return nil, err + } + + return &vtctldatapb.RemoveShardCellResponse{}, nil +} + // StartServer registers a VtctldServer for RPCs on the given gRPC server. func StartServer(s *grpc.Server, ts *topo.Server) { vtctlservicepb.RegisterVtctldServer(s, NewVtctldServer(ts)) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 4bcb2e12b99..e0ec817bf8f 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -39,6 +39,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + "vitess.io/vitess/go/vt/proto/vttime" ) func init() { @@ -46,6 +47,1869 @@ func init() { *backupstorage.BackupStorageImplementation = testutil.BackupStorageImplementation } +func TestChangeTabletType(t *testing.T) { + tests := []struct { + name string + cells []string + tablets []*topodatapb.Tablet + req *vtctldatapb.ChangeTabletTypeRequest + expected *vtctldatapb.ChangeTabletTypeResponse + shouldErr bool + }{ + { + name: "success", + cells: []string{"zone1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + req: &vtctldatapb.ChangeTabletTypeRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + DbType: topodatapb.TabletType_RDONLY, + }, + expected: &vtctldatapb.ChangeTabletTypeResponse{ + BeforeTablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + }, + AfterTablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_RDONLY, + }, + WasDryRun: false, + }, + shouldErr: false, + }, + { + name: "dry run", + cells: []string{"zone1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + req: &vtctldatapb.ChangeTabletTypeRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + DbType: topodatapb.TabletType_RDONLY, + DryRun: true, + }, + expected: &vtctldatapb.ChangeTabletTypeResponse{ + BeforeTablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + }, + AfterTablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_RDONLY, + }, + WasDryRun: true, + }, + shouldErr: false, + }, + { + name: "tablet not found", + cells: []string{"zone1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 200, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + req: &vtctldatapb.ChangeTabletTypeRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + DbType: topodatapb.TabletType_RDONLY, + }, + expected: nil, + shouldErr: true, + }, + { + name: "master promotions not allowed", + cells: []string{"zone1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + }, + }, + req: &vtctldatapb.ChangeTabletTypeRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + DbType: topodatapb.TabletType_MASTER, + }, + expected: nil, + shouldErr: true, + }, + { + name: "master demotions not allowed", + cells: []string{"zone1"}, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_MASTER, + }, + }, + req: &vtctldatapb.ChangeTabletTypeRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + DbType: topodatapb.TabletType_REPLICA, + }, + expected: nil, + shouldErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer(tt.cells...) + vtctld := NewVtctldServer(ts) + testutil.TabletManagerClient.Topo = ts + + for _, tablet := range tt.tablets { + testutil.AddTablet(ctx, t, ts, tablet) + } + + resp, err := vtctld.ChangeTabletType(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, resp) + + // If we are testing a dry-run, then the tablet in the actual + // topo should match the BeforeTablet in the response. Otherwise, + // the tablet in the actual topo should match the AfterTablet in + // the response. + expectedRealType := resp.AfterTablet.Type + msg := "ChangeTabletType did not cause topo update" + if tt.req.DryRun { + expectedRealType = resp.BeforeTablet.Type + msg = "dryrun type change resulted in real type change" + } + + tablet, err := ts.GetTablet(ctx, tt.req.TabletAlias) + assert.NoError(t, err, + "could not load tablet %s from topo after type change %v -> %v [dryrun=%t]", + topoproto.TabletAliasString(tt.req.TabletAlias), + resp.BeforeTablet.Type, + resp.AfterTablet.Type, + resp.WasDryRun, + ) + assert.Equal(t, expectedRealType, tablet.Type, msg) + }) + } + + t.Run("tabletmanager failure", func(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("zone1") + vtctld := NewVtctldServer(ts) + testutil.TabletManagerClient.Topo = nil + + testutil.AddTablet(ctx, t, ts, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + }) + + _, err := vtctld.ChangeTabletType(ctx, &vtctldatapb.ChangeTabletTypeRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + DbType: topodatapb.TabletType_RDONLY, + }) + assert.Error(t, err) + }) +} + +func TestCreateKeyspace(t *testing.T) { + cells := []string{"zone1", "zone2", "zone3"} + tests := []struct { + name string + topo map[string]*topodatapb.Keyspace + vschemas map[string]*vschemapb.Keyspace + req *vtctldatapb.CreateKeyspaceRequest + expected *vtctldatapb.CreateKeyspaceResponse + shouldErr bool + vschemaShouldExist bool + expectedVSchema *vschemapb.Keyspace + }{ + { + name: "normal keyspace", + topo: nil, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "testkeyspace", + Type: topodatapb.KeyspaceType_NORMAL, + }, + expected: &vtctldatapb.CreateKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{ + KeyspaceType: topodatapb.KeyspaceType_NORMAL, + }, + }, + }, + vschemaShouldExist: true, + expectedVSchema: &vschemapb.Keyspace{ + Sharded: false, + }, + shouldErr: false, + }, + { + name: "snapshot keyspace", + topo: map[string]*topodatapb.Keyspace{ + "testkeyspace": { + KeyspaceType: topodatapb.KeyspaceType_NORMAL, + }, + }, + vschemas: map[string]*vschemapb.Keyspace{ + "testkeyspace": { + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "h1": { + Type: "hash", + }, + }, + }, + }, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "testsnapshot", + Type: topodatapb.KeyspaceType_SNAPSHOT, + BaseKeyspace: "testkeyspace", + SnapshotTime: &vttime.Time{ + Seconds: 1, + }, + }, + expected: &vtctldatapb.CreateKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testsnapshot", + Keyspace: &topodatapb.Keyspace{ + KeyspaceType: topodatapb.KeyspaceType_SNAPSHOT, + BaseKeyspace: "testkeyspace", + SnapshotTime: &vttime.Time{ + Seconds: 1, + }, + }, + }, + }, + vschemaShouldExist: true, + expectedVSchema: &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "h1": { + Type: "hash", + }, + }, + RequireExplicitRouting: true, + }, + shouldErr: false, + }, + { + name: "snapshot keyspace with no base keyspace specified", + topo: nil, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "testsnapshot", + Type: topodatapb.KeyspaceType_SNAPSHOT, + SnapshotTime: &vttime.Time{}, + }, + expected: nil, + shouldErr: true, + }, + { + name: "snapshot keyspace with no snapshot time", + topo: nil, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "testsnapshot", + Type: topodatapb.KeyspaceType_SNAPSHOT, + BaseKeyspace: "testkeyspace", + }, + expected: nil, + shouldErr: true, + }, + { + name: "snapshot keyspace with nonexistent base keyspace", + topo: nil, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "testsnapshot", + Type: topodatapb.KeyspaceType_SNAPSHOT, + BaseKeyspace: "testkeyspace", + SnapshotTime: &vttime.Time{Seconds: 100}, + }, + expected: &vtctldatapb.CreateKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testsnapshot", + Keyspace: &topodatapb.Keyspace{ + KeyspaceType: topodatapb.KeyspaceType_SNAPSHOT, + BaseKeyspace: "testkeyspace", + SnapshotTime: &vttime.Time{Seconds: 100}, + }, + }, + }, + vschemaShouldExist: true, + expectedVSchema: &vschemapb.Keyspace{ + Sharded: false, + RequireExplicitRouting: true, + }, + shouldErr: false, + }, + { + name: "invalid keyspace type", + topo: nil, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "badkeyspacetype", + Type: 10000000, + }, + expected: nil, + shouldErr: true, + }, + { + name: "keyspace exists/no force", + topo: map[string]*topodatapb.Keyspace{ + "testkeyspace": { + KeyspaceType: topodatapb.KeyspaceType_NORMAL, + ShardingColumnName: "col1", + ShardingColumnType: topodatapb.KeyspaceIdType_UINT64, + }, + }, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "testkeyspace", + Type: topodatapb.KeyspaceType_NORMAL, + Force: false, + }, + expected: nil, + shouldErr: true, + }, + { + name: "keyspace exists/force", + topo: map[string]*topodatapb.Keyspace{ + "testkeyspace": { + KeyspaceType: topodatapb.KeyspaceType_NORMAL, + ShardingColumnName: "col1", + ShardingColumnType: topodatapb.KeyspaceIdType_UINT64, + }, + }, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "testkeyspace", + Type: topodatapb.KeyspaceType_NORMAL, + Force: true, + }, + expected: &vtctldatapb.CreateKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{ + KeyspaceType: topodatapb.KeyspaceType_NORMAL, + ShardingColumnName: "col1", + ShardingColumnType: topodatapb.KeyspaceIdType_UINT64, + }, + }, + }, + vschemaShouldExist: true, + expectedVSchema: &vschemapb.Keyspace{ + Sharded: false, + }, + shouldErr: false, + }, + { + name: "allow empty vschema", + topo: nil, + req: &vtctldatapb.CreateKeyspaceRequest{ + Name: "testkeyspace", + Type: topodatapb.KeyspaceType_NORMAL, + AllowEmptyVSchema: true, + }, + expected: &vtctldatapb.CreateKeyspaceResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{ + KeyspaceType: topodatapb.KeyspaceType_NORMAL, + }, + }, + }, + vschemaShouldExist: false, + expectedVSchema: nil, + shouldErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.req == nil { + t.Skip("test not yet implemented") + } + + ctx := context.Background() + ts := memorytopo.NewServer(cells...) + vtctld := NewVtctldServer(ts) + + for name, ks := range tt.topo { + testutil.AddKeyspace(ctx, t, ts, &vtctldatapb.Keyspace{ + Name: name, + Keyspace: ks, + }) + } + + for name, vs := range tt.vschemas { + require.NoError(t, ts.SaveVSchema(ctx, name, vs), "error in SaveVSchema(%v, %+v)", name, vs) + } + + // Create the keyspace and make some assertions + resp, err := vtctld.CreateKeyspace(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + testutil.AssertKeyspacesEqual(t, tt.expected.Keyspace, resp.Keyspace, "%+v\n%+v\n", tt.expected.Keyspace, resp.Keyspace) + + // Fetch the newly-created keyspace out of the topo and assert on it + ks, err := ts.GetKeyspace(ctx, tt.req.Name) + assert.NoError(t, err, "cannot get keyspace %v after creating", tt.req.Name) + require.NotNil(t, ks.Keyspace) + + actualKs := &vtctldatapb.Keyspace{ + Name: tt.req.Name, + Keyspace: ks.Keyspace, + } + testutil.AssertKeyspacesEqual( + t, + tt.expected.Keyspace, + actualKs, + "created keyspace %v does not match requested keyspace (name = %v) %v", + actualKs, + tt.expected.Keyspace, + ) + + // Finally, check the VSchema + vs, err := ts.GetVSchema(ctx, tt.req.Name) + if !tt.vschemaShouldExist { + assert.True(t, topo.IsErrType(err, topo.NoNode), "vschema should not exist, but got other error = %v", err) + return + } + assert.NoError(t, err) + assert.Equal(t, tt.expectedVSchema, vs) + }) + } +} + +func TestCreateShard(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + keyspaces []*vtctldatapb.Keyspace + shards []*vtctldatapb.Shard + topoErr error + req *vtctldatapb.CreateShardRequest + expected *vtctldatapb.CreateShardResponse + shouldErr bool + }{ + { + name: "success", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: nil, + topoErr: nil, + req: &vtctldatapb.CreateShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + }, + expected: &vtctldatapb.CreateShardResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + Shard: &vtctldatapb.Shard{ + Keyspace: "testkeyspace", + Name: "-", + Shard: &topodatapb.Shard{ + KeyRange: &topodatapb.KeyRange{}, + IsMasterServing: true, + }, + }, + ShardAlreadyExists: false, + }, + shouldErr: false, + }, + { + name: "include parent", + keyspaces: nil, + shards: nil, + topoErr: nil, + req: &vtctldatapb.CreateShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + IncludeParent: true, + }, + expected: &vtctldatapb.CreateShardResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + Shard: &vtctldatapb.Shard{ + Keyspace: "testkeyspace", + Name: "-", + Shard: &topodatapb.Shard{ + KeyRange: &topodatapb.KeyRange{}, + IsMasterServing: true, + }, + }, + ShardAlreadyExists: false, + }, + shouldErr: false, + }, + { + name: "keyspace does not exist", + keyspaces: nil, + shards: nil, + topoErr: nil, + req: &vtctldatapb.CreateShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + }, + expected: nil, + shouldErr: true, + }, + { + name: "include parent/keyspace exists/no force", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: nil, + topoErr: nil, + req: &vtctldatapb.CreateShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + IncludeParent: true, + }, + expected: nil, + shouldErr: true, + }, + { + name: "include parent/keyspace exists/force", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: nil, + topoErr: nil, + req: &vtctldatapb.CreateShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + IncludeParent: true, + Force: true, + }, + expected: &vtctldatapb.CreateShardResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + Shard: &vtctldatapb.Shard{ + Keyspace: "testkeyspace", + Name: "-", + Shard: &topodatapb.Shard{ + KeyRange: &topodatapb.KeyRange{}, + IsMasterServing: true, + }, + }, + ShardAlreadyExists: false, + }, + shouldErr: false, + }, + { + name: "shard exists/no force", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoErr: nil, + req: &vtctldatapb.CreateShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + }, + expected: nil, + shouldErr: true, + }, + { + name: "shard exists/force", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoErr: nil, + req: &vtctldatapb.CreateShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Force: true, + }, + expected: &vtctldatapb.CreateShardResponse{ + Keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + Shard: &vtctldatapb.Shard{ + Keyspace: "testkeyspace", + Name: "-", + Shard: &topodatapb.Shard{ + KeyRange: &topodatapb.KeyRange{}, + IsMasterServing: true, + }, + }, + ShardAlreadyExists: true, + }, + shouldErr: false, + }, + { + name: "topo is down", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: nil, + topoErr: assert.AnError, + req: &vtctldatapb.CreateShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + }, + expected: nil, + shouldErr: true, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + if tt.req == nil { + t.Skip("focusing on other tests") + } + + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory("zone1") + vtctld := NewVtctldServer(ts) + + for _, ks := range tt.keyspaces { + testutil.AddKeyspace(ctx, t, ts, ks) + } + + testutil.AddShards(ctx, t, ts, tt.shards...) + + if tt.topoErr != nil { + topofactory.SetError(tt.topoErr) + } + + resp, err := vtctld.CreateShard(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, resp) + }) + } +} + +func TestDeleteKeyspace(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + keyspaces []*vtctldatapb.Keyspace + shards []*vtctldatapb.Shard + srvKeyspaces map[string]map[string]*topodatapb.SrvKeyspace + topoErr error + req *vtctldatapb.DeleteKeyspaceRequest + expected *vtctldatapb.DeleteKeyspaceResponse + expectedRemainingKeyspaces []string + expectedRemainingShards map[string][]string + shouldErr bool + }{ + { + name: "success", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: nil, + srvKeyspaces: nil, + topoErr: nil, + req: &vtctldatapb.DeleteKeyspaceRequest{ + Keyspace: "testkeyspace", + }, + expected: &vtctldatapb.DeleteKeyspaceResponse{}, + expectedRemainingKeyspaces: []string{}, + expectedRemainingShards: map[string][]string{}, + shouldErr: false, + }, + { + name: "keyspace does not exist", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "otherkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: nil, + srvKeyspaces: nil, + topoErr: nil, + req: &vtctldatapb.DeleteKeyspaceRequest{ + Keyspace: "testkeyspace", + }, + expected: nil, + expectedRemainingKeyspaces: []string{"otherkeyspace"}, + expectedRemainingShards: map[string][]string{ + "otherkeyspace": nil, + }, + shouldErr: true, + }, + { + name: "keyspace has shards/Recursive=false", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-80", + }, + { + Keyspace: "testkeyspace", + Name: "80-", + }, + }, + srvKeyspaces: nil, + topoErr: nil, + req: &vtctldatapb.DeleteKeyspaceRequest{ + Keyspace: "testkeyspace", + }, + expected: nil, + expectedRemainingKeyspaces: []string{"testkeyspace"}, + expectedRemainingShards: map[string][]string{ + "testkeyspace": {"-80", "80-"}, + }, + shouldErr: true, + }, + { + name: "keyspace has shards/Recursive=true", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-80", + }, + { + Keyspace: "testkeyspace", + Name: "80-", + }, + }, + srvKeyspaces: nil, + topoErr: nil, + req: &vtctldatapb.DeleteKeyspaceRequest{ + Keyspace: "testkeyspace", + Recursive: true, + }, + expected: &vtctldatapb.DeleteKeyspaceResponse{}, + expectedRemainingKeyspaces: []string{}, + expectedRemainingShards: map[string][]string{}, + shouldErr: false, + }, + // Not sure how to force this case because we always pass + // (Recursive=true, EvenIfServing=true) so anything short of "topo + // server is down" won't fail, and "topo server is down" will cause us + // to error before we even reach this point in the code, so, ¯\_(ツ)_/¯. + // { + // name: "recursive/cannot delete shard", + // }, + { + name: "topo error", + keyspaces: []*vtctldatapb.Keyspace{ + { + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + }, + shards: nil, + srvKeyspaces: nil, + topoErr: assert.AnError, + req: &vtctldatapb.DeleteKeyspaceRequest{ + Keyspace: "testkeyspace", + }, + expected: nil, + expectedRemainingKeyspaces: []string{"testkeyspace"}, + expectedRemainingShards: map[string][]string{ + "testkeyspace": nil, + }, + shouldErr: true, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + cells := []string{"zone1", "zone2", "zone3"} + + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory(cells...) + vtctld := NewVtctldServer(ts) + + testutil.AddKeyspaces(ctx, t, ts, tt.keyspaces...) + testutil.AddShards(ctx, t, ts, tt.shards...) + testutil.UpdateSrvKeyspaces(ctx, t, ts, tt.srvKeyspaces) + + if tt.topoErr != nil { + topofactory.SetError(tt.topoErr) + } + + defer func() { + if tt.expectedRemainingKeyspaces == nil { + return + } + + topofactory.SetError(nil) + + keyspaces, err := ts.GetKeyspaces(ctx) + require.NoError(t, err, "cannot get keyspaces names after DeleteKeyspace call") + assert.ElementsMatch(t, tt.expectedRemainingKeyspaces, keyspaces) + + if tt.expectedRemainingShards == nil { + return + } + + remainingShards := make(map[string][]string, len(keyspaces)) + + for _, ks := range keyspaces { + shards, err := ts.GetShardNames(ctx, ks) + require.NoError(t, err, "cannot get shard names for keyspace %s", ks) + + remainingShards[ks] = shards + } + + assert.Equal(t, tt.expectedRemainingShards, remainingShards) + }() + + resp, err := vtctld.DeleteKeyspace(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, resp) + }) + } +} + +func TestDeleteShards(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + shards []*vtctldatapb.Shard + tablets []*topodatapb.Tablet + replicationGraphs []*topo.ShardReplicationInfo + srvKeyspaces map[string]map[string]*topodatapb.SrvKeyspace + topoErr error + req *vtctldatapb.DeleteShardsRequest + expected *vtctldatapb.DeleteShardsResponse + expectedRemainingShards []*vtctldatapb.Shard + shouldErr bool + }{ + { + name: "success", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + tablets: nil, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + }, + expected: &vtctldatapb.DeleteShardsResponse{}, + expectedRemainingShards: []*vtctldatapb.Shard{}, + shouldErr: false, + }, + { + name: "shard not found", + shards: nil, + tablets: nil, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + }, + expected: nil, + shouldErr: true, + }, + { + name: "multiple shards", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + { + Keyspace: "otherkeyspace", + Name: "-80", + }, + { + Keyspace: "otherkeyspace", + Name: "80-", + }, + }, + tablets: nil, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + { + Keyspace: "otherkeyspace", + Name: "-80", + }, + }, + }, + expected: &vtctldatapb.DeleteShardsResponse{}, + expectedRemainingShards: []*vtctldatapb.Shard{ + { + Keyspace: "otherkeyspace", + Name: "80-", + }, + }, + shouldErr: false, + }, + { + name: "topo is down", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + tablets: nil, + topoErr: assert.AnError, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + }, + expected: nil, + expectedRemainingShards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + shouldErr: true, + }, + { + name: "shard is serving/EvenIfServing=false", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + tablets: nil, + srvKeyspaces: map[string]map[string]*topodatapb.SrvKeyspace{ + "zone1": { + "testkeyspace": &topodatapb.SrvKeyspace{ + Partitions: []*topodatapb.SrvKeyspace_KeyspacePartition{ + { + ServedType: topodatapb.TabletType_MASTER, + ShardReferences: []*topodatapb.ShardReference{ + { + Name: "-", + KeyRange: &topodatapb.KeyRange{}, + }, + }, + }, + }, + }, + }, + }, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + }, + expected: nil, + expectedRemainingShards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + shouldErr: true, + }, + { + name: "shard is serving/EvenIfServing=true", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + tablets: nil, + srvKeyspaces: map[string]map[string]*topodatapb.SrvKeyspace{ + "zone1": { + "testkeyspace": &topodatapb.SrvKeyspace{ + Partitions: []*topodatapb.SrvKeyspace_KeyspacePartition{ + { + ServedType: topodatapb.TabletType_MASTER, + ShardReferences: []*topodatapb.ShardReference{ + { + Name: "-", + KeyRange: &topodatapb.KeyRange{}, + }, + }, + }, + }, + }, + }, + }, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + EvenIfServing: true, + }, + expected: &vtctldatapb.DeleteShardsResponse{}, + expectedRemainingShards: []*vtctldatapb.Shard{}, + shouldErr: false, + }, + { + name: "ShardReplication in topo", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + tablets: nil, + replicationGraphs: []*topo.ShardReplicationInfo{ + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + }, "zone1", "testkeyspace", "-"), + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone2", + Uid: 200, + }, + }, + }, + }, "zone2", "testkeyspace", "-"), + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone3", + Uid: 300, + }, + }, + }, + }, "zone3", "testkeyspace", "-"), + }, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + }, + expected: &vtctldatapb.DeleteShardsResponse{}, + expectedRemainingShards: []*vtctldatapb.Shard{}, + shouldErr: false, + }, + { + name: "shard has tablets/Recursive=false", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + }, + expected: nil, + expectedRemainingShards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + shouldErr: true, + }, + { + name: "shard has tablets/Recursive=true", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + Recursive: true, + }, + expected: &vtctldatapb.DeleteShardsResponse{}, + expectedRemainingShards: []*vtctldatapb.Shard{}, + shouldErr: false, + }, + { + name: "tablets in topo belonging to other shard", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-80", + }, + { + Keyspace: "testkeyspace", + Name: "80-", + }, + }, + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Keyspace: "testkeyspace", + Shard: "80-", + }, + }, + topoErr: nil, + req: &vtctldatapb.DeleteShardsRequest{ + Shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-80", + }, + }, + }, + expected: &vtctldatapb.DeleteShardsResponse{}, + expectedRemainingShards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "80-", + }, + }, + shouldErr: false, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + cells := []string{"zone1", "zone2", "zone3"} + + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory(cells...) + vtctld := NewVtctldServer(ts) + + testutil.AddShards(ctx, t, ts, tt.shards...) + testutil.AddTablets(ctx, t, ts, tt.tablets...) + testutil.SetupReplicationGraphs(ctx, t, ts, tt.replicationGraphs...) + testutil.UpdateSrvKeyspaces(ctx, t, ts, tt.srvKeyspaces) + + if tt.topoErr != nil { + topofactory.SetError(tt.topoErr) + } + + if tt.expectedRemainingShards != nil { + defer func() { + topofactory.SetError(nil) + + actualShards := []*vtctldatapb.Shard{} + + keyspaces, err := ts.GetKeyspaces(ctx) + require.NoError(t, err, "cannot get keyspace names to check remaining shards") + + for _, ks := range keyspaces { + shards, err := ts.GetShardNames(ctx, ks) + require.NoError(t, err, "cannot get shard names for keyspace %s", ks) + + for _, shard := range shards { + actualShards = append(actualShards, &vtctldatapb.Shard{ + Keyspace: ks, + Name: shard, + }) + } + } + + assert.ElementsMatch(t, tt.expectedRemainingShards, actualShards) + }() + } + + resp, err := vtctld.DeleteShards(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, resp) + }) + } +} + +func TestDeleteTablets(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + tablets []*topodatapb.Tablet + shardFieldUpdates map[string]func(*topo.ShardInfo) error + lockedShards []*vtctldatapb.Shard + topoError error + req *vtctldatapb.DeleteTabletsRequest + expected *vtctldatapb.DeleteTabletsResponse + expectedRemainingTablets []*topodatapb.Tablet + shouldErr bool + }{ + { + name: "single replica", + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + lockedShards: nil, + topoError: nil, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + Cell: "zone1", + Uid: 100, + }, + }, + }, + expected: &vtctldatapb.DeleteTabletsResponse{}, + expectedRemainingTablets: []*topodatapb.Tablet{}, + shouldErr: false, + }, + { + name: "single primary/no AllowPrimary", + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "-", + MasterTermStartTime: &vttime.Time{ + Seconds: 100, + Nanoseconds: 10, + }, + }, + }, + lockedShards: nil, + topoError: nil, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + Cell: "zone1", + Uid: 100, + }, + }, + }, + expected: nil, + shouldErr: true, + }, + { + name: "single primary/with AllowPrimary", + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "-", + MasterTermStartTime: &vttime.Time{ + Seconds: 100, + Nanoseconds: 10, + }, + }, + }, + lockedShards: nil, + topoError: nil, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + Cell: "zone1", + Uid: 100, + }, + }, + AllowPrimary: true, + }, + expected: &vtctldatapb.DeleteTabletsResponse{}, + expectedRemainingTablets: []*topodatapb.Tablet{}, + shouldErr: false, + }, + { + name: "multiple tablets", + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 102, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + lockedShards: nil, + topoError: nil, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + Cell: "zone1", + Uid: 100, + }, + { + Cell: "zone1", + Uid: 102, + }, + }, + }, + expected: &vtctldatapb.DeleteTabletsResponse{}, + expectedRemainingTablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + shouldErr: false, + }, + { + name: "stale primary record", + tablets: []*topodatapb.Tablet{ + { + // The stale primary we're going to delete. + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "-", + MasterTermStartTime: &vttime.Time{ + Seconds: 100, + Nanoseconds: 10, + }, + }, + { + // The real shard primary, which we'll update in the shard + // record below. + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "-", + MasterTermStartTime: &vttime.Time{ + Seconds: 1001, + Nanoseconds: 101, + }, + }, + }, + shardFieldUpdates: map[string]func(*topo.ShardInfo) error{ + "testkeyspace/-": func(si *topo.ShardInfo) error { + si.MasterAlias = &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + } + si.MasterTermStartTime = &vttime.Time{ + Seconds: 1001, + Nanoseconds: 101, + } + + return nil + }, + }, + lockedShards: nil, + topoError: nil, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + Cell: "zone1", + Uid: 100, + }, + }, + }, + expected: &vtctldatapb.DeleteTabletsResponse{}, + expectedRemainingTablets: []*topodatapb.Tablet{ + { + // The true shard primary still exists (phew!) + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "-", + MasterTermStartTime: &vttime.Time{ + Seconds: 1001, + Nanoseconds: 101, + }, + }, + }, + shouldErr: false, + }, + { + name: "tablet not found", + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + lockedShards: nil, + topoError: nil, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + Cell: "zone1", + Uid: 200, + }, + }, + }, + expected: nil, + expectedRemainingTablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + shouldErr: true, + }, + { + name: "shard is locked", + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "-", + MasterTermStartTime: &vttime.Time{ + Seconds: 100, + Nanoseconds: 10, + }, + }, + }, + lockedShards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoError: nil, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + Cell: "zone1", + Uid: 100, + }, + }, + AllowPrimary: true, + }, + expected: nil, + expectedRemainingTablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "-", + MasterTermStartTime: &vttime.Time{ + Seconds: 100, + Nanoseconds: 10, + }, + }, + }, + shouldErr: true, + }, + { + name: "another shard is locked", + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "-80", + MasterTermStartTime: &vttime.Time{ + Seconds: 100, + Nanoseconds: 10, + }, + }, + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 200, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "80-", + MasterTermStartTime: &vttime.Time{ + Seconds: 200, + Nanoseconds: 20, + }, + }, + }, + lockedShards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "80-", + }, + }, + topoError: nil, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + // testkeyspace/-80 + Cell: "zone1", + Uid: 100, + }, + }, + AllowPrimary: true, + }, + expected: &vtctldatapb.DeleteTabletsResponse{}, + expectedRemainingTablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 200, + }, + Type: topodatapb.TabletType_MASTER, + Keyspace: "testkeyspace", + Shard: "80-", + MasterTermStartTime: &vttime.Time{ + Seconds: 200, + Nanoseconds: 20, + }, + }, + }, + shouldErr: false, + }, + { + name: "topo server is down", + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + lockedShards: nil, + topoError: assert.AnError, + req: &vtctldatapb.DeleteTabletsRequest{ + TabletAliases: []*topodatapb.TabletAlias{ + { + Cell: "zone1", + Uid: 200, + }, + }, + }, + expected: nil, + expectedRemainingTablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + Keyspace: "testkeyspace", + Shard: "-", + }, + }, + shouldErr: true, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + if tt.req == nil { + t.Skip("focusing on other tests") + } + + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory("zone1") + vtctld := NewVtctldServer(ts) + + // Setup tablets and shards + for _, tablet := range tt.tablets { + testutil.AddTablet(ctx, t, ts, tablet) + } + + for key, updateFn := range tt.shardFieldUpdates { + ks, shard, err := topoproto.ParseKeyspaceShard(key) + require.NoError(t, err, "bad keyspace/shard provided in shardFieldUpdates: %s", key) + + _, err = ts.UpdateShardFields(ctx, ks, shard, updateFn) + require.NoError(t, err, "failed to update shard fields for %s", key) + } + + // Set locks + for _, shard := range tt.lockedShards { + lctx, unlock, lerr := ts.LockShard(ctx, shard.Keyspace, shard.Name, "testing locked shard") + require.NoError(t, lerr, "cannot lock shard %s/%s", shard.Keyspace, shard.Name) + // unlock at the end of the test, we don't care about this error + // value anymore + defer unlock(&lerr) + + // we do, however, care that the lock context gets propogated + // both to additional calls to lock, and to the actual RPC call. + ctx = lctx + } + + // Set errors + if tt.topoError != nil { + topofactory.SetError(tt.topoError) + } + + checkRemainingTablets := func() { + topofactory.SetError(nil) + + resp, err := vtctld.GetTablets(ctx, &vtctldatapb.GetTabletsRequest{}) + assert.NoError(t, err, "cannot look up tablets from topo after issuing DeleteTablets request") + + assert.ElementsMatch(t, tt.expectedRemainingTablets, resp.Tablets) + } + + // Run the test + resp, err := vtctld.DeleteTablets(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + + if tt.expectedRemainingTablets != nil { + checkRemainingTablets() + } + + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, resp) + checkRemainingTablets() + }) + } +} + func TestFindAllShardsInKeyspace(t *testing.T) { ctx := context.Background() ts := memorytopo.NewServer("cell1") @@ -426,6 +2290,91 @@ func TestGetSchema(t *testing.T) { } } +func TestGetShard(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + topo []*vtctldatapb.Shard + topoError error + req *vtctldatapb.GetShardRequest + expected *vtctldatapb.GetShardResponse + shouldErr bool + }{ + { + name: "success", + topo: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoError: nil, + req: &vtctldatapb.GetShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + }, + expected: &vtctldatapb.GetShardResponse{ + Shard: &vtctldatapb.Shard{ + Keyspace: "testkeyspace", + Name: "-", + Shard: &topodatapb.Shard{ + KeyRange: &topodatapb.KeyRange{}, + IsMasterServing: true, + }, + }, + }, + shouldErr: false, + }, + { + name: "shard not found", + topo: nil, + topoError: nil, + req: &vtctldatapb.GetShardRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + }, + shouldErr: true, + }, + { + name: "unavailable topo server", + topo: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoError: assert.AnError, + req: nil, + shouldErr: true, + }, + } + + for _, tt := range tests { + tt := tt + + cells := []string{"zone1", "zone2", "zone3"} + + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory(cells...) + vtctld := NewVtctldServer(ts) + + testutil.AddShards(ctx, t, ts, tt.topo...) + + if tt.topoError != nil { + topofactory.SetError(tt.topoError) + } + + resp, err := vtctld.GetShard(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.Equal(t, tt.expected, resp) + } +} + func TestGetSrvVSchema(t *testing.T) { ctx := context.Background() ts, topofactory := memorytopo.NewServerAndFactory("zone1", "zone2") @@ -899,3 +2848,487 @@ func TestGetVSchema(t *testing.T) { assert.Error(t, err) }) } + +func TestRemoveKeyspaceCell(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + keyspace *vtctldatapb.Keyspace + shards []*vtctldatapb.Shard + topoError error + topoIsLocked bool + srvKeyspaceDoesNotExist bool + req *vtctldatapb.RemoveKeyspaceCellRequest + expected *vtctldatapb.RemoveKeyspaceCellResponse + shouldErr bool + }{ + { + name: "success", + keyspace: nil, + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoError: nil, + topoIsLocked: false, + srvKeyspaceDoesNotExist: false, + req: &vtctldatapb.RemoveKeyspaceCellRequest{ + Keyspace: "testkeyspace", + Cell: "zone1", + }, + expected: &vtctldatapb.RemoveKeyspaceCellResponse{}, + shouldErr: false, + }, + { + name: "success/empty keyspace", + keyspace: &vtctldatapb.Keyspace{ + Name: "testkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + shards: nil, + topoError: nil, + topoIsLocked: false, + srvKeyspaceDoesNotExist: false, + req: &vtctldatapb.RemoveKeyspaceCellRequest{ + Keyspace: "testkeyspace", + Cell: "zone1", + }, + expected: &vtctldatapb.RemoveKeyspaceCellResponse{}, + shouldErr: false, + }, + { + name: "keyspace not found", + keyspace: &vtctldatapb.Keyspace{ + Name: "otherkeyspace", + Keyspace: &topodatapb.Keyspace{}, + }, + shards: nil, + topoError: nil, + topoIsLocked: false, + srvKeyspaceDoesNotExist: false, + req: &vtctldatapb.RemoveKeyspaceCellRequest{ + Keyspace: "testkeyspace", + Cell: "zone1", + }, + expected: nil, + shouldErr: true, + }, + { + name: "topo is down", + keyspace: nil, + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoError: assert.AnError, + topoIsLocked: false, + srvKeyspaceDoesNotExist: false, + req: &vtctldatapb.RemoveKeyspaceCellRequest{ + Keyspace: "testkeyspace", + Cell: "zone1", + }, + expected: nil, + shouldErr: true, + }, + { + name: "topo is locked", + keyspace: nil, + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoError: nil, + topoIsLocked: true, + srvKeyspaceDoesNotExist: false, + req: &vtctldatapb.RemoveKeyspaceCellRequest{ + Keyspace: "testkeyspace", + Cell: "zone1", + }, + expected: nil, + shouldErr: true, + }, + { + name: "srvkeyspace already deleted", + keyspace: nil, + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + topoError: nil, + topoIsLocked: false, + srvKeyspaceDoesNotExist: true, + req: &vtctldatapb.RemoveKeyspaceCellRequest{ + Keyspace: "testkeyspace", + Cell: "zone1", + }, + expected: nil, + shouldErr: true, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + cells := []string{"zone1", "zone2", "zone3"} + + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory(cells...) + vtctld := NewVtctldServer(ts) + + // Setup topo + if tt.keyspace != nil { + testutil.AddKeyspace(ctx, t, ts, tt.keyspace) + } + + testutil.AddShards(ctx, t, ts, tt.shards...) + + // For certain tests, we don't actually create the SrvKeyspace + // object. + if !tt.srvKeyspaceDoesNotExist { + updateSrvKeyspace := func(keyspace string) { + for _, cell := range cells { + err := ts.UpdateSrvKeyspace(ctx, cell, keyspace, &topodatapb.SrvKeyspace{}) + require.NoError(t, err, "could not create empty SrvKeyspace for keyspace %s in cell %s", tt.req.Keyspace, cell) + } + } + + updateSrvKeyspace(tt.req.Keyspace) + if tt.keyspace != nil { + updateSrvKeyspace(tt.keyspace.Name) + } + } + + // Set errors and locks + if tt.topoError != nil { + topofactory.SetError(tt.topoError) + } + + if tt.topoIsLocked { + lctx, unlock, err := ts.LockKeyspace(ctx, tt.req.Keyspace, "testing locked keyspace") + require.NoError(t, err, "cannot lock keyspace %s", tt.req.Keyspace) + defer unlock(&err) + + ctx = lctx + } + + resp, err := vtctld.RemoveKeyspaceCell(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, resp) + }) + } +} + +func TestRemoveShardCell(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + servingCells []string + shards []*vtctldatapb.Shard + replicationGraphs []*topo.ShardReplicationInfo + topoError error + topoIsLocked bool + req *vtctldatapb.RemoveShardCellRequest + expected *vtctldatapb.RemoveShardCellResponse + shouldErr bool + }{ + { + name: "success", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + replicationGraphs: []*topo.ShardReplicationInfo{ + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + }, "zone1", "testkeyspace", "-"), + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone2", + Uid: 200, + }, + }, + }, + }, "zone2", "testkeyspace", "-"), + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone3", + Uid: 300, + }, + }, + }, + }, "zone3", "testkeyspace", "-"), + }, + req: &vtctldatapb.RemoveShardCellRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Cell: "zone2", + Recursive: true, + }, + expected: &vtctldatapb.RemoveShardCellResponse{}, + shouldErr: false, + }, + { + name: "success/no tablets", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + req: &vtctldatapb.RemoveShardCellRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Cell: "zone2", + }, + expected: &vtctldatapb.RemoveShardCellResponse{}, + shouldErr: false, + }, + { + name: "nonexistent shard", + shards: nil, + replicationGraphs: nil, + req: &vtctldatapb.RemoveShardCellRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Cell: "zone2", + }, + expected: nil, + shouldErr: true, + }, + { + name: "cell does not exist", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + req: &vtctldatapb.RemoveShardCellRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Cell: "fourthzone", + }, + expected: nil, + shouldErr: true, + }, + { + name: "cell not in serving list", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + servingCells: []string{"zone1"}, + replicationGraphs: nil, + req: &vtctldatapb.RemoveShardCellRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Cell: "zone2", + }, + expected: nil, + shouldErr: true, + }, + { + name: "tablets/non-recursive", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + replicationGraphs: []*topo.ShardReplicationInfo{ + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + }, "zone1", "testkeyspace", "-"), + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone2", + Uid: 200, + }, + }, + }, + }, "zone2", "testkeyspace", "-"), + topo.NewShardReplicationInfo(&topodatapb.ShardReplication{ + Nodes: []*topodatapb.ShardReplication_Node{ + { + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone3", + Uid: 300, + }, + }, + }, + }, "zone3", "testkeyspace", "-"), + }, + req: &vtctldatapb.RemoveShardCellRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Cell: "zone2", + Recursive: false, // non-recursive + replication graph = failure + }, + expected: nil, + shouldErr: true, + }, + { + name: "topo server down", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + replicationGraphs: nil, + req: &vtctldatapb.RemoveShardCellRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Cell: "zone2", + }, + topoError: assert.AnError, + topoIsLocked: false, + expected: nil, + shouldErr: true, + }, + // Not sure how to set up this test case. + // { + // name: "topo server down for replication check/no force", + // }, + // Not sure how to set up this test case. + // { + // name: "topo server down for replication check/force", + // }, + { + name: "cannot lock keyspace", + shards: []*vtctldatapb.Shard{ + { + Keyspace: "testkeyspace", + Name: "-", + }, + }, + replicationGraphs: nil, + req: &vtctldatapb.RemoveShardCellRequest{ + Keyspace: "testkeyspace", + ShardName: "-", + Cell: "zone2", + }, + topoError: nil, + topoIsLocked: true, + expected: nil, + shouldErr: true, + }, + // Not sure how to set up this test case. + // { + // name: "cannot delete srvkeyspace partition", + // }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + cells := []string{"zone1", "zone2", "zone3"} + + ctx := context.Background() + ts, topofactory := memorytopo.NewServerAndFactory(cells...) + vtctld := NewVtctldServer(ts) + + // Setup shard topos and replication graphs. + testutil.AddShards(ctx, t, ts, tt.shards...) + testutil.SetupReplicationGraphs(ctx, t, ts, tt.replicationGraphs...) + + // Set up srvkeyspace partitions; a little gross. + servingCells := tt.servingCells + if servingCells == nil { // we expect an explicit empty list to have a shard with no serving cells + servingCells = cells + } + + for _, shard := range tt.shards { + lctx, unlock, lerr := ts.LockKeyspace(ctx, shard.Keyspace, "initializing serving graph for test") + require.NoError(t, lerr, "cannot lock keyspace %s to initialize serving graph", shard.Keyspace) + + for _, cell := range servingCells { + + err := ts.UpdateSrvKeyspace(lctx, cell, shard.Keyspace, &topodatapb.SrvKeyspace{ + Partitions: []*topodatapb.SrvKeyspace_KeyspacePartition{ + { + ServedType: topodatapb.TabletType_REPLICA, + ShardReferences: []*topodatapb.ShardReference{ + { + Name: shard.Name, + }, + }, + }, + }, + }) + require.NoError(t, err, "cannot update srvkeyspace for %s/%s in cell %v", shard.Keyspace, shard.Name, cell) + } + + unlock(&lerr) + } + + // Set errors and locks. + if tt.topoError != nil { + topofactory.SetError(tt.topoError) + } + + if tt.topoIsLocked { + lctx, unlock, err := ts.LockKeyspace(ctx, tt.req.Keyspace, "testing locked keyspace") + require.NoError(t, err, "cannot lock keyspace %s", tt.req.Keyspace) + defer unlock(&err) + + // Need to use the lock ctx in the RPC call so we fail when + // attempting to lock the keyspace rather than waiting forever + // for the lock. Explicitly setting a deadline would be another + // way to achieve this. + ctx = lctx + } + + // Make the RPC and assert things about it. + resp, err := vtctld.RemoveShardCell(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, resp) + }) + } +} diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/proto_compare.go b/go/vt/vtctl/grpcvtctldserver/testutil/proto_compare.go new file mode 100644 index 00000000000..dd06ec80d84 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldserver/testutil/proto_compare.go @@ -0,0 +1,46 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +// AssertKeyspacesEqual is a convenience function to assert that two +// vtctldatapb.Keyspace objects are equal, after clearing out any reserved +// proto XXX_ fields. +func AssertKeyspacesEqual(t *testing.T, expected *vtctldatapb.Keyspace, actual *vtctldatapb.Keyspace, msgAndArgs ...interface{}) { + t.Helper() + + for _, ks := range []*vtctldatapb.Keyspace{expected, actual} { + if ks.Keyspace != nil { + ks.Keyspace.XXX_sizecache = 0 + ks.Keyspace.XXX_unrecognized = nil + } + + if ks.Keyspace.SnapshotTime != nil { + ks.Keyspace.SnapshotTime.XXX_sizecache = 0 + ks.Keyspace.SnapshotTime.XXX_unrecognized = nil + } + } + + assert.Equal(t, expected, actual, msgAndArgs...) +} diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go index 938e71e9595..414f794d694 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go @@ -20,20 +20,36 @@ import ( "context" "fmt" + "github.com/stretchr/testify/assert" + + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vttablet/tmclient" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vttime" ) // tabletManagerClient implements the tmclient.TabletManagerClient for // testing. It allows users to mock various tmclient methods. type tabletManagerClient struct { tmclient.TabletManagerClient + Topo *topo.Server Schemas map[string]*tabletmanagerdatapb.SchemaDefinition } +// ChangeType is part of the tmclient.TabletManagerClient interface. +func (c *tabletManagerClient) ChangeType(ctx context.Context, tablet *topodatapb.Tablet, newType topodatapb.TabletType) error { + if c.Topo == nil { + return assert.AnError + } + + _, err := topotools.ChangeType(ctx, c.Topo, tablet.Alias, newType, &vttime.Time{}) + return err +} + // GetSchema is part of the tmclient.TabletManagerClient interface. func (c *tabletManagerClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tablets []string, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { key := topoproto.TabletAliasString(tablet.Alias) diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/util.go b/go/vt/vtctl/grpcvtctldserver/testutil/util.go index 99928b54936..c6298c86556 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/util.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/util.go @@ -69,6 +69,14 @@ func AddKeyspace(ctx context.Context, t *testing.T, ts *topo.Server, ks *vtctlda require.NoError(t, err) } +// AddKeyspaces adds a list of keyspaces to the topology, failing a test if any +// of those keyspaces cannot be added. See AddKeyspace for details. +func AddKeyspaces(ctx context.Context, t *testing.T, ts *topo.Server, keyspaces ...*vtctldatapb.Keyspace) { + for _, keyspace := range keyspaces { + AddKeyspace(ctx, t, ts, keyspace) + } +} + // AddTablet adds a tablet to the topology, failing a test if that tablet record // could not be created. It shallow copies to prevent XXX_ fields from changing, // including nested proto message fields. @@ -98,3 +106,52 @@ func AddTablet(ctx context.Context, t *testing.T, ts *topo.Server, tablet *topod } } } + +// AddTablets adds a list of tablets to the topology. See AddTablet for more +// details. +func AddTablets(ctx context.Context, t *testing.T, ts *topo.Server, tablets ...*topodatapb.Tablet) { + for _, tablet := range tablets { + AddTablet(ctx, t, ts, tablet) + } +} + +// AddShards adds a list of shards to the topology, failing a test if any of the +// shard records could not be created. It also ensures that every shard's +// keyspace exists, or creates an empty keyspace if that shard's keyspace does +// not exist. +func AddShards(ctx context.Context, t *testing.T, ts *topo.Server, shards ...*vtctldatapb.Shard) { + for _, shard := range shards { + if shard.Keyspace != "" { + if _, err := ts.GetKeyspace(ctx, shard.Keyspace); err != nil { + err := ts.CreateKeyspace(ctx, shard.Keyspace, &topodatapb.Keyspace{}) + require.NoError(t, err, "CreateKeyspace(%s)", shard.Keyspace) + } + } + + err := ts.CreateShard(ctx, shard.Keyspace, shard.Name) + require.NoError(t, err, "CreateShard(%s/%s)", shard.Keyspace, shard.Name) + } +} + +// SetupReplicationGraphs creates a set of ShardReplication objects in the topo, +// failing the test if any of the records could not be created. +func SetupReplicationGraphs(ctx context.Context, t *testing.T, ts *topo.Server, replicationGraphs ...*topo.ShardReplicationInfo) { + for _, graph := range replicationGraphs { + err := ts.UpdateShardReplicationFields(ctx, graph.Cell(), graph.Keyspace(), graph.Shard(), func(sr *topodatapb.ShardReplication) error { + sr.Nodes = graph.Nodes + return nil + }) + require.NoError(t, err, "could not save replication graph for %s/%s in cell %v", graph.Keyspace(), graph.Shard(), graph.Cell()) + } +} + +// UpdateSrvKeyspaces updates a set of SrvKeyspace records, grouped by cell and +// then by keyspace. It fails the test if any records cannot be updated. +func UpdateSrvKeyspaces(ctx context.Context, t *testing.T, ts *topo.Server, srvkeyspacesByCellByKeyspace map[string]map[string]*topodatapb.SrvKeyspace) { + for cell, srvKeyspacesByKeyspace := range srvkeyspacesByCellByKeyspace { + for keyspace, srvKeyspace := range srvKeyspacesByKeyspace { + err := ts.UpdateSrvKeyspace(ctx, cell, keyspace, srvKeyspace) + require.NoError(t, err, "UpdateSrvKeyspace(%v, %v, %v)", cell, keyspace, srvKeyspace) + } + } +} diff --git a/go/vt/vtctl/grpcvtctldserver/topo.go b/go/vt/vtctl/grpcvtctldserver/topo.go new file mode 100644 index 00000000000..7de161bcd22 --- /dev/null +++ b/go/vt/vtctl/grpcvtctldserver/topo.go @@ -0,0 +1,292 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package grpcvtctldserver + +import ( + "context" + "fmt" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vterrors" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vtrpc" +) + +func deleteShard(ctx context.Context, ts *topo.Server, keyspace string, shard string, recursive bool, evenIfServing bool) error { + // Read the Shard object. If it's not in the topo, try to clean up the topo + // anyway. + shardInfo, err := ts.GetShard(ctx, keyspace, shard) + if err != nil { + if topo.IsErrType(err, topo.NoNode) { + log.Infof("Shard %v/%v doesn't seem to exist; cleaning up any potential leftover topo data", keyspace, shard) + + return ts.DeleteShard(ctx, keyspace, shard) + } + + return err + } + + servingCells, err := ts.GetShardServingCells(ctx, shardInfo) + if err != nil { + return err + } + + // We never want to remove a potentially serving shard unless someone + // explicitly requested it. + if len(servingCells) > 0 && !evenIfServing { + return vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "shard %v/%v is still serving; cannot delete it; use EvenIfServing = true to delete anyway", keyspace, shard) + } + + cells, err := ts.GetCellInfoNames(ctx) + if err != nil { + return err + } + + for _, cell := range cells { + if err := deleteShardCell(ctx, ts, keyspace, shard, cell, recursive); err != nil { + return err + } + } + + // Try to remove the replication and serving graphs from each cell, + // regardless of whether they exist. + for _, cell := range cells { + if err := ts.DeleteShardReplication(ctx, cell, keyspace, shard); err != nil && !topo.IsErrType(err, topo.NoNode) { + log.Warningf("Cannot delete ShardReplication in cell %v for %v/%v: %w", cell, keyspace, shard, err) + } + } + + return ts.DeleteShard(ctx, keyspace, shard) +} + +// deleteShardCell is the per-cell helper function for deleteShard, and is +// distinct from the RemoveShardCell rpc. Despite having similar names, they are +// **not** the same! +func deleteShardCell(ctx context.Context, ts *topo.Server, keyspace string, shard string, cell string, recursive bool) error { + var aliases []*topodatapb.TabletAlias + + // Get the ShardReplication object for the cell. Collect all the tablets + // that belong to the shard. + sri, err := ts.GetShardReplication(ctx, cell, keyspace, shard) + switch { + case topo.IsErrType(err, topo.NoNode): + // No ShardReplication object means that the topo is inconsistent. + // Therefore we read all the tablets for that cell, and if we find any + // in our shard, we'll either abort or try to delete them, depending on + // whether recursive=true. + aliases, err = ts.GetTabletsByCell(ctx, cell) + if err != nil { + return fmt.Errorf("GetTabletsByCell(%v) failed: %w", cell, err) + } + case err == nil: + // If a ShardReplication object exists, we trust it to have all the + // tablet records for the shard in that cell. + aliases = make([]*topodatapb.TabletAlias, len(sri.Nodes)) + + for i, node := range sri.Nodes { + aliases[i] = node.TabletAlias + } + default: + return fmt.Errorf("GetShardReplication(%v, %v, %v) failed: %w", cell, keyspace, shard, err) + } + + // Get all the tablet records for the aliases we've collected. Note that + // GetTabletMap ignores ErrNoNode, which is convenient for our purpose; it + // means a tablet was deleted but is still referenced. + tabletMap, err := ts.GetTabletMap(ctx, aliases) + if err != nil { + return fmt.Errorf("GetTabletMap() failed: %w", err) + } + + // In the case where no ShardReplication object exists, we collect the + // aliases of every tablet in the cell, so we'll need to filter + // out anything not in our shard. + for alias, ti := range tabletMap { + if !(ti.Keyspace == keyspace && ti.Shard == shard) { + delete(tabletMap, alias) + } + } + + // If there are any tablets in the shard in the cell, delete them. + if len(tabletMap) > 0 { + if !recursive { + return vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "Shard %v/%v still hase %v tablets in cell %v; use Recursive = true or remove them manually", keyspace, shard, len(tabletMap), cell) + } + + log.Infof("Deleting all %d tablets in shard %v/%v cell %v", len(tabletMap), keyspace, shard, cell) + for alias, tablet := range tabletMap { + // We don't care about updating the ShardReplication object, because + // later we're going to delete the entire object. + log.Infof("Deleting tablet %v", alias) + if err := ts.DeleteTablet(ctx, tablet.Alias); err != nil && !topo.IsErrType(err, topo.NoNode) { + // We don't want to continue if a DeleteTablet fails for any + // reason other than a missing tablet (in which case it's just + // topo server inconsistency, which we can ignore). If we were + // to continue and delete the replication graph, the tablet + // record would become orphaned, since we'd no longer know that + // it belongs to this shard. + // + // If the problem is temporary, or resolved externally, + // re-running DeleteShard will skip over tablets that were + // already deleted. + return fmt.Errorf("cannot delete tablet %v: %w", alias, err) + } + } + } + + return nil +} + +func deleteTablet(ctx context.Context, ts *topo.Server, alias *topodatapb.TabletAlias, allowPrimary bool) (err error) { + tablet, err := ts.GetTablet(ctx, alias) + if err != nil { + return err + } + + isPrimary, err := topotools.IsPrimaryTablet(ctx, ts, tablet) + if err != nil { + return err + } + + if isPrimary && !allowPrimary { + return vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "cannot delete tablet %v as it is a master, pass AllowPrimary = true", topoproto.TabletAliasString(alias)) + } + + // Update the Shard object if the master was scrapped. We do this before + // calling DeleteTablet so that the operation can be retried in case of + // failure. + if isPrimary { + lockCtx, unlock, lockErr := ts.LockShard(ctx, tablet.Keyspace, tablet.Shard, fmt.Sprintf("DeleteTablet(%v)", topoproto.TabletAliasString(alias))) + if lockErr != nil { + return lockErr + } + + defer unlock(&err) + + if _, err := ts.UpdateShardFields(lockCtx, tablet.Keyspace, tablet.Shard, func(si *topo.ShardInfo) error { + if !topoproto.TabletAliasEqual(si.MasterAlias, alias) { + log.Warningf( + "Deleting master %v from shard %v/%v but master in Shard object was %v", + topoproto.TabletAliasString(alias), tablet.Keyspace, tablet.Shard, topoproto.TabletAliasString(si.MasterAlias), + ) + + return topo.NewError(topo.NoUpdateNeeded, si.Keyspace()+"/"+si.ShardName()) + } + + si.MasterAlias = nil + + return nil + }); err != nil { + return err + } + } + + // Remove the tablet record and its replication graph entry. + if err := topotools.DeleteTablet(ctx, ts, tablet.Tablet); err != nil { + return err + } + + // Return any error from unlocking the keyspace. + return err +} + +func removeShardCell(ctx context.Context, ts *topo.Server, cell string, keyspace string, shardName string, recursive bool, force bool) error { + shard, err := ts.GetShard(ctx, keyspace, shardName) + if err != nil { + return err + } + + servingCells, err := ts.GetShardServingCells(ctx, shard) + if err != nil { + return err + } + + if !topo.InCellList(cell, servingCells) { + return vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "shard %v/%v does not have serving cell %v", keyspace, shardName, cell) + } + + if shard.MasterAlias != nil && shard.MasterAlias.Cell == cell { + return vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "cannot remove cell %v; shard master %v is in cell", cell, topoproto.TabletAliasString(shard.MasterAlias)) + } + + replication, err := ts.GetShardReplication(ctx, cell, keyspace, shardName) + switch { + case err == nil: + // We have tablets in the shard in this cell. + if recursive { + log.Infof("Deleting all tablets in cell %v in shard %v/%v", cell, keyspace, shardName) + for _, node := range replication.Nodes { + // We don't care about scraping our updating the replication + // graph, because we're about to delete the entire replication + // graph. + log.Infof("Deleting tablet %v", topoproto.TabletAliasString(node.TabletAlias)) + if err := ts.DeleteTablet(ctx, node.TabletAlias); err != nil && !topo.IsErrType(err, topo.NoNode) { + return fmt.Errorf("cannot delete tablet %v: %w", topoproto.TabletAliasString(node.TabletAlias), err) + } + } + } else if len(replication.Nodes) > 0 { + return vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "cell %v has %v possible tablets in replication graph", cell, len(replication.Nodes)) + } + + // Remove the empty replication graph. + if err := ts.DeleteShardReplication(ctx, cell, keyspace, shardName); err != nil && !topo.IsErrType(err, topo.NoNode) { + return fmt.Errorf("error deleting ShardReplication object in cell %v: %w", cell, err) + } + case topo.IsErrType(err, topo.NoNode): + // No ShardReplication object. This is the expected path when there are + // no tablets in the shard in that cell. + err = nil + default: + // If we can't get the replication object out of the local topo, we + // assume the topo server is down in that cell, so we'll only continue + // if Force was specified. + if !force { + return err + } + + log.Warningf("Cannot get ShardReplication from cell %v; assuming cell topo server is down and forcing removal", cell) + } + + // Finally, update the shard. + + log.Infof("Removing cell %v from SrvKeyspace %v/%v", cell, keyspace, shardName) + + ctx, unlock, lockErr := ts.LockKeyspace(ctx, keyspace, "Locking keyspace to remove shard from SrvKeyspace") + if lockErr != nil { + return lockErr + } + + defer unlock(&err) + + if err := ts.DeleteSrvKeyspacePartitions(ctx, keyspace, []*topo.ShardInfo{shard}, topodatapb.TabletType_RDONLY, []string{cell}); err != nil { + return err + } + + if err := ts.DeleteSrvKeyspacePartitions(ctx, keyspace, []*topo.ShardInfo{shard}, topodatapb.TabletType_REPLICA, []string{cell}); err != nil { + return err + } + + if err := ts.DeleteSrvKeyspacePartitions(ctx, keyspace, []*topo.ShardInfo{shard}, topodatapb.TabletType_MASTER, []string{cell}); err != nil { + return err + } + + return err +} diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 1671e33f063..34e56862112 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -730,19 +730,6 @@ func parseTabletType(param string, types []topodatapb.TabletType) (topodatapb.Ta return tabletType, nil } -// parseServingTabletType3 parses the tablet type into the enum, -// and makes sure the enum is of serving type (MASTER, REPLICA, RDONLY/BATCH) -func parseServingTabletType3(param string) (topodatapb.TabletType, error) { - servedType, err := topoproto.ParseTabletType(param) - if err != nil { - return topodatapb.TabletType_UNKNOWN, err - } - if !topo.IsInServingGraph(servedType) { - return topodatapb.TabletType_UNKNOWN, fmt.Errorf("served_type has to be in the serving graph, not %v", param) - } - return servedType, nil -} - func commandInitTablet(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { dbNameOverride := subFlags.String("db_name_override", "", "Overrides the name of the database that the vttablet uses") allowUpdate := subFlags.Bool("allow_update", false, "Use this flag to force initialization if a tablet with the same name already exists. Use with caution.") @@ -1116,7 +1103,7 @@ func commandWaitForDrain(ctx context.Context, wr *wrangler.Wrangler, subFlags *f if err != nil { return err } - servedType, err := parseServingTabletType3(subFlags.Arg(1)) + servedType, err := topo.ParseServingTabletType(subFlags.Arg(1)) if err != nil { return err } @@ -1397,7 +1384,7 @@ func commandUpdateSrvKeyspacePartition(ctx context.Context, wr *wrangler.Wrangle if err != nil { return err } - tabletType, err := parseServingTabletType3(subFlags.Arg(1)) + tabletType, err := topo.ParseServingTabletType(subFlags.Arg(1)) if err != nil { return err } @@ -1429,7 +1416,7 @@ func commandSetShardTabletControl(ctx context.Context, wr *wrangler.Wrangler, su if err != nil { return err } - tabletType, err := parseServingTabletType3(subFlags.Arg(1)) + tabletType, err := topo.ParseServingTabletType(subFlags.Arg(1)) if err != nil { return err } @@ -1686,7 +1673,7 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags } if len(servedFrom) > 0 { for name, value := range servedFrom { - tt, err := parseServingTabletType3(name) + tt, err := topo.ParseServingTabletType(name) if err != nil { return err } @@ -2049,7 +2036,7 @@ func commandMigrateServedTypes(ctx context.Context, wr *wrangler.Wrangler, subFl if err != nil { return err } - servedType, err := parseServingTabletType3(subFlags.Arg(1)) + servedType, err := topo.ParseServingTabletType(subFlags.Arg(1)) if err != nil { return err } diff --git a/go/vt/wrangler/tablet.go b/go/vt/wrangler/tablet.go index 77d112a450e..3bd61f59fbf 100644 --- a/go/vt/wrangler/tablet.go +++ b/go/vt/wrangler/tablet.go @@ -229,22 +229,5 @@ func (wr *Wrangler) GenericVExec(ctx context.Context, tabletAlias *topodatapb.Ta // the system is in transition (a reparenting event is in progress and parts of // the topo have not yet been updated). func (wr *Wrangler) isMasterTablet(ctx context.Context, ti *topo.TabletInfo) (bool, error) { - // Tablet record claims to be non-master, we believe it - if ti.Type != topodatapb.TabletType_MASTER { - return false, nil - } - si, err := wr.ts.GetShard(ctx, ti.Keyspace, ti.Shard) - if err != nil { - // strictly speaking it isn't correct to return false here, the tablet status is unknown - return false, err - } - // Tablet record claims to be master, and shard record matches - if topoproto.TabletAliasEqual(si.MasterAlias, ti.Tablet.Alias) { - return true, nil - } - // Shard record has another tablet as master, so check MasterTermStartTime - // If tablet record's MasterTermStartTime is later than the one in the shard record, then tablet is master - tabletMTST := ti.GetMasterTermStartTime() - shardMTST := si.GetMasterTermStartTime() - return tabletMTST.After(shardMTST), nil + return topotools.IsPrimaryTablet(ctx, wr.TopoServer(), ti) } diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 69c6f561488..361bd4a2083 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -27,6 +27,7 @@ import "mysqlctl.proto"; import "tabletmanagerdata.proto"; import "topodata.proto"; import "vschema.proto"; +import "vttime.proto"; // ExecuteVtctlCommandRequest is the payload for ExecuteVtctlCommand. // timeouts are in nanoseconds. @@ -40,6 +41,114 @@ message ExecuteVtctlCommandResponse { logutil.Event event = 1; } +message ChangeTabletTypeRequest { + topodata.TabletAlias tablet_alias = 1; + topodata.TabletType db_type = 2; + bool dry_run = 3; +} + +message ChangeTabletTypeResponse { + topodata.Tablet before_tablet = 1; + topodata.Tablet after_tablet = 2; + bool was_dry_run = 3; +} + +message CreateKeyspaceRequest { + // Name is the name of the keyspace. + string name = 1; + // Force proceeds with the request even if the keyspace already exists. + bool force = 2; + // AllowEmptyVSchema allows a keyspace to be created with no vschema. + bool allow_empty_v_schema = 3; + + // ShardingColumnName specifies the column to use for sharding operations. + string sharding_column_name = 4; + // ShardingColumnType specifies the type of the column to use for sharding + // operations. + topodata.KeyspaceIdType sharding_column_type = 5; + + // ServedFroms specifies a set of db_type:keyspace pairs used to serve + // traffic for the keyspace. + repeated topodata.Keyspace.ServedFrom served_froms = 6; + + // Type is the type of the keyspace to create. + topodata.KeyspaceType type = 7; + // BaseKeyspace specifies the base keyspace for SNAPSHOT keyspaces. It is + // required to create a SNAPSHOT keyspace. + string base_keyspace = 8; + // SnapshotTime specifies the snapshot time for this keyspace. It is required + // to create a SNAPSHOT keyspace. + vttime.Time snapshot_time = 9; +} + +message CreateKeyspaceResponse { + // Keyspace is the newly-created keyspace. + Keyspace keyspace = 1; +} + +message CreateShardRequest { + // Keyspace is the name of the keyspace to create the shard in. + string keyspace = 1; + // ShardName is the name of the shard to create. E.g. "-" or "-80". + string shard_name = 2; + // Force treats an attempt to create a shard that already exists as a + // non-error. + bool force = 3; + // IncludeParent creates the parent keyspace as an empty BASE keyspace, if it + // doesn't already exist. + bool include_parent = 4; +} + +message CreateShardResponse { + // Keyspace is the created keyspace. It is set only if IncludeParent was + // specified in the request and the parent keyspace needed to be created. + Keyspace keyspace = 1; + // Shard is the newly-created shard object. + Shard shard = 2; + // ShardAlreadyExists is set if Force was specified in the request and the + // shard already existed. + bool shard_already_exists = 3; +} + +message DeleteKeyspaceRequest { + // Keyspace is the name of the keyspace to delete. + string keyspace = 1; + // Recursive causes all shards in the keyspace to be recursively deleted + // before deleting the keyspace. It is an error to call DeleteKeyspace on a + // non-empty keyspace without also specifying Recursive. + bool recursive = 2; +} + +message DeleteKeyspaceResponse { +} + +message DeleteShardsRequest { + // Shards is the list of shards to delete. The nested topodatapb.Shard field + // is not required for DeleteShard, but the Keyspace and Shard fields are. + repeated Shard shards = 1; + // Recursive also deletes all tablets belonging to the shard(s). It is an + // error to call DeleteShard on a non-empty shard without also specificying + // Recursive. + bool recursive = 2; + // EvenIfServing allows a shard to be deleted even if it is serving, which is + // normally an error. Use with caution. + bool even_if_serving = 4; +} + +message DeleteShardsResponse { +} + +message DeleteTabletsRequest { + // TabletAliases is the list of tablets to delete. + repeated topodata.TabletAlias tablet_aliases = 1; + // AllowPrimary allows for the master/primary tablet of a shard to be deleted. + // Use with caution. + bool allow_primary = 2; +} + +message DeleteTabletsResponse { +} + message GetBackupsRequest { string keyspace = 1; string shard = 2; @@ -109,6 +218,15 @@ message GetSchemaResponse { tabletmanagerdata.SchemaDefinition schema = 1; } +message GetShardRequest { + string keyspace = 1; + string shard_name = 2; +} + +message GetShardResponse { + Shard shard = 1; +} + message GetSrvVSchemaRequest { string cell = 1; } @@ -148,6 +266,41 @@ message GetVSchemaResponse { vschema.Keyspace v_schema = 1; } +message RemoveKeyspaceCellRequest { + string keyspace = 1; + string cell = 2; + // Force proceeds even if the cell's topology server cannot be reached. This + // should only be set if a cell has been shut down entirely, and the global + // topology data just needs to be updated. + bool force = 3; + // Recursive also deletes all tablets in that cell belonging to the specified + // keyspace. + bool recursive = 4; +} + +message RemoveKeyspaceCellResponse { + // (TODO:@amason) Consider including the deleted SrvKeyspace object and any + // deleted Tablet objects here. +} + +message RemoveShardCellRequest { + string keyspace = 1; + string shard_name = 2; + string cell = 3; + // Force proceeds even if the cell's topology server cannot be reached. This + // should only be set if a cell has been shut down entirely, and the global + // topology data just needs to be updated. + bool force = 4; + // Recursive also deletes all tablets in that cell belonging to the specified + // keyspace and shard. + bool recursive = 5; +} + +message RemoveShardCellResponse { + // (TODO:@amason) Consider including the deleted SrvKeyspacePartitions objects + // and any deleted Tablet objects here. +} + message Keyspace { string name = 1; topodata.Keyspace keyspace = 2; diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index bcf94e9aa98..15b0d6729c9 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -31,6 +31,30 @@ service Vtctl { // Service Vtctld exposes gRPC endpoints for each vt command. service Vtctld { + // ChangeTabletType changes the db type for the specified tablet, if possible. + // This is used primarily to arrange replicas, and it will not convert a + // primary. For that, use InitShardPrimary. + // + // NOTE: This command automatically updates the serving graph. + rpc ChangeTabletType(vtctldata.ChangeTabletTypeRequest) returns (vtctldata.ChangeTabletTypeResponse) {}; + // CreateKeyspace creates the specified keyspace in the topology. For a + // SNAPSHOT keyspace, the request must specify the name of a base keyspace, + // as well as a snapshot time. + rpc CreateKeyspace(vtctldata.CreateKeyspaceRequest) returns (vtctldata.CreateKeyspaceResponse) {}; + // CreateShard creates the specified shard in the topology. + rpc CreateShard(vtctldata.CreateShardRequest) returns (vtctldata.CreateShardResponse) {}; + // DeleteKeyspace deletes the specified keyspace from the topology. In + // recursive mode, it also recursively deletes all shards in the keyspace. + // Otherwise, the keyspace must be empty (have no shards), or DeleteKeyspace + // returns an error. + rpc DeleteKeyspace(vtctldata.DeleteKeyspaceRequest) returns (vtctldata.DeleteKeyspaceResponse) {}; + // DeleteShards deletes the specified shards from the topology. In recursive + // mode, it also deletes all tablets belonging to the shard. Otherwise, the + // shard must be empty (have no tablets) or DeleteShards returns an error for + // that shard. + rpc DeleteShards(vtctldata.DeleteShardsRequest) returns (vtctldata.DeleteShardsResponse) {}; + // DeleteTablets deletes one or more tablets from the topology. + rpc DeleteTablets(vtctldata.DeleteTabletsRequest) returns (vtctldata.DeleteTabletsResponse) {}; // FindAllShardsInKeyspace returns a map of shard names to shard references // for a given keyspace. rpc FindAllShardsInKeyspace(vtctldata.FindAllShardsInKeyspaceRequest) returns (vtctldata.FindAllShardsInKeyspaceResponse) {}; @@ -51,6 +75,8 @@ service Vtctld { // GetSchema returns the schema for a tablet, or just the schema for the // specified tables in that tablet. rpc GetSchema(vtctldata.GetSchemaRequest) returns (vtctldata.GetSchemaResponse) {}; + // GetShard returns information about a shard in the topology. + rpc GetShard(vtctldata.GetShardRequest) returns (vtctldata.GetShardResponse) {}; // GetSrvVSchema returns a the SrvVSchema for a cell. rpc GetSrvVSchema(vtctldata.GetSrvVSchemaRequest) returns (vtctldata.GetSrvVSchemaResponse) {}; // GetTablet returns information about a tablet. @@ -59,4 +85,11 @@ service Vtctld { rpc GetTablets(vtctldata.GetTabletsRequest) returns (vtctldata.GetTabletsResponse) {}; // GetVSchema returns the vschema for a keyspace. rpc GetVSchema(vtctldata.GetVSchemaRequest) returns (vtctldata.GetVSchemaResponse) {}; + // RemoveKeyspaceCell removes the specified cell from the Cells list for all + // shards in the specified keyspace, as well as from the SrvKeyspace for that + // keyspace in that cell. + rpc RemoveKeyspaceCell(vtctldata.RemoveKeyspaceCellRequest) returns (vtctldata.RemoveKeyspaceCellResponse) {}; + // RemoveShardCell removes the specified cell from the specified shard's Cells + // list. + rpc RemoveShardCell(vtctldata.RemoveShardCellRequest) returns (vtctldata.RemoveShardCellResponse) {}; } From 1032ee6f8b88ac758a4bcc27603ceee034f4c017 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Tue, 2 Feb 2021 14:47:45 -0800 Subject: [PATCH 14/21] Merge pull request #7404 from tinyspeck/am_vtctldclient_silence_errors [vtctldclient] Set `SilenceErrors` on the root command, so we don't double-log --- go/cmd/vtctldclient/internal/command/root.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/go/cmd/vtctldclient/internal/command/root.go b/go/cmd/vtctldclient/internal/command/root.go index 63ef37fe346..7243c8836e5 100644 --- a/go/cmd/vtctldclient/internal/command/root.go +++ b/go/cmd/vtctldclient/internal/command/root.go @@ -64,6 +64,14 @@ var ( return err }, TraverseChildren: true, + // By default, cobra will print any error returned by a child command to + // stderr, and then return that error back up the call chain. Since we + // use vitess's log package to log any error we get back from + // Root.Execute() (in ../../main.go) this actually results in duplicate + // stderr lines. So, somewhat counterintuitively, we actually "silence" + // all errors in cobra (just from being output, they still get + // propagated). + SilenceErrors: true, } ) From 87a7a3d10cb0aa5a17b957203b7c3ab0601c6225 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Fri, 5 Feb 2021 12:21:42 +0100 Subject: [PATCH 15/21] Merge pull request #7451 from tinyspeck/am_vtctldclient_errors Provide named function for squashing usage errors; start using it --- go.mod | 1 + go/cmd/vtctldclient/cli/cobra.go | 32 ++++++++++++++++++ .../vtctldclient/internal/command/backups.go | 3 ++ go/cmd/vtctldclient/internal/command/cells.go | 8 ++++- go/cmd/vtctldclient/internal/command/doc.go | 33 +++++++++++++++++++ .../internal/command/keyspaces.go | 14 +++++++- .../vtctldclient/internal/command/schema.go | 2 ++ .../vtctldclient/internal/command/shards.go | 8 +++++ .../vtctldclient/internal/command/tablets.go | 8 +++++ .../vtctldclient/internal/command/vschemas.go | 4 +++ 10 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 go/cmd/vtctldclient/cli/cobra.go diff --git a/go.mod b/go.mod index 4136bb84f46..c4292f248d5 100644 --- a/go.mod +++ b/go.mod @@ -80,6 +80,7 @@ require ( github.com/sjmudd/stopwatch v0.0.0-20170613150411-f380bf8a9be1 github.com/smartystreets/goconvey v1.6.4 // indirect github.com/spf13/cobra v0.0.5 + github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.4.0 github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b github.com/tebeka/selenium v0.9.9 diff --git a/go/cmd/vtctldclient/cli/cobra.go b/go/cmd/vtctldclient/cli/cobra.go new file mode 100644 index 00000000000..d3f43bddbfb --- /dev/null +++ b/go/cmd/vtctldclient/cli/cobra.go @@ -0,0 +1,32 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cli + +import "github.com/spf13/cobra" + +// FinishedParsing transitions a cobra.Command from treating RunE errors as +// usage errors to treating them just as normal runtime errors that should be +// propagated up to the root command's Execute method without also printing the +// subcommand's usage text on stderr. A subcommand should call this function +// from its RunE function when it has finished processing its flags and is +// moving into the pure "business logic" of its entrypoint. +// +// Package vitess.io/vitess/go/cmd/vtctldclient/internal/command has more +// details on why this exists. +func FinishedParsing(cmd *cobra.Command) { + cmd.SilenceUsage = true +} diff --git a/go/cmd/vtctldclient/internal/command/backups.go b/go/cmd/vtctldclient/internal/command/backups.go index 3b1fea947d2..21d5673ef34 100644 --- a/go/cmd/vtctldclient/internal/command/backups.go +++ b/go/cmd/vtctldclient/internal/command/backups.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/cobra" + "vitess.io/vitess/go/cmd/vtctldclient/cli" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -33,6 +34,8 @@ var GetBackups = &cobra.Command{ } func commandGetBackups(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + keyspace := cmd.Flags().Arg(0) shard := cmd.Flags().Arg(1) diff --git a/go/cmd/vtctldclient/internal/command/cells.go b/go/cmd/vtctldclient/internal/command/cells.go index e37709abc44..e04984f761b 100644 --- a/go/cmd/vtctldclient/internal/command/cells.go +++ b/go/cmd/vtctldclient/internal/command/cells.go @@ -49,6 +49,8 @@ var ( ) func commandGetCellInfoNames(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + resp, err := client.GetCellInfoNames(commandCtx, &vtctldatapb.GetCellInfoNamesRequest{}) if err != nil { return err @@ -60,9 +62,11 @@ func commandGetCellInfoNames(cmd *cobra.Command, args []string) error { } func commandGetCellInfo(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + cell := cmd.Flags().Arg(0) - resp, err := client.GetCellInfo(commandCtx, &vtctldatapb.GetCellInfoRequest{Cell: cell}) + resp, err := client.GetCellInfo(commandCtx, &vtctldatapb.GetCellInfoRequest{Cell: cell}) if err != nil { return err } @@ -78,6 +82,8 @@ func commandGetCellInfo(cmd *cobra.Command, args []string) error { } func commandGetCellsAliases(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + resp, err := client.GetCellsAliases(commandCtx, &vtctldatapb.GetCellsAliasesRequest{}) if err != nil { return err diff --git a/go/cmd/vtctldclient/internal/command/doc.go b/go/cmd/vtctldclient/internal/command/doc.go index 57500b0fccd..b83db0ef0a4 100644 --- a/go/cmd/vtctldclient/internal/command/doc.go +++ b/go/cmd/vtctldclient/internal/command/doc.go @@ -107,5 +107,38 @@ A good pattern we have found is to do the following: Root.AddCommand(GetTablet) } + +A note on RunE and SilenceUsage: + +We prefer using RunE over Run for the entrypoint to our subcommands, because it +allows us return errors back up to the vtctldclient main function and do error +handling, logging, and exit-code management once, in one place, rather than on a +per-command basis. However, cobra treats errors returned from a command's RunE +as usage errors, and therefore will print the command's full usage text to +stderr when RunE returns non-nil, in addition to propagating that error back up +to the result of the root command's Execute() method. This is decidedly not what +we want. There is no plan to address this in cobra v1. [1] + +The suggested workaround for this issue is to set SilenceUsage: true, either on +the root command or on every subcommand individually. This also does not work +for vtctldclient, because not every flag can be parsed during pflag.Parse time, +and for certain flags (mutually exclusive options, optional flags that require +other flags to be set with them, etc) we do additional parsing and validation of +flags in an individual subcommand. We want errors during this phase to be +treated as usage errors, so setting SilenceUsage=true before this point would +not cause usage text to be printed for us. + +So, for us, we want to individually set cmd.SilenceUsage = true at *particular +points* in each command, dependending on whether that command needs to do +an additional parse & validation pass. In most cases, the command does not need +to post-validate its options, and can set cmd.SilencUsage = true as their first +line. We feel, though, that a line that reads "SilenceUsage = true" to be +potentially confusing in how it reads. A maintainer without sufficient context +may read this and say "Silence usage? We don't want that" and remove the lines, +so we provide a wrapper function that communicates intent, cli.FinishedParsing, +that each subcommand should call when they have transitioned from the parsing & +validation phase of their entrypoint to the actual logic. + +[1]: https://github.com/spf13/cobra/issues/340 */ package command diff --git a/go/cmd/vtctldclient/internal/command/keyspaces.go b/go/cmd/vtctldclient/internal/command/keyspaces.go index 0f3ec9fcc1d..c9e779358a1 100644 --- a/go/cmd/vtctldclient/internal/command/keyspaces.go +++ b/go/cmd/vtctldclient/internal/command/keyspaces.go @@ -121,6 +121,8 @@ func commandCreateKeyspace(cmd *cobra.Command, args []string) error { snapshotTime = logutil.TimeToProto(t) } + cli.FinishedParsing(cmd) + req := &vtctldatapb.CreateKeyspaceRequest{ Name: name, Force: createKeyspaceOptions.Force, @@ -164,12 +166,14 @@ var deleteKeyspaceOptions = struct { }{} func commandDeleteKeyspace(cmd *cobra.Command, args []string) error { - ks := cmd.Flags().Arg(0) + cli.FinishedParsing(cmd) + ks := cmd.Flags().Arg(0) _, err := client.DeleteKeyspace(commandCtx, &vtctldatapb.DeleteKeyspaceRequest{ Keyspace: ks, Recursive: deleteKeyspaceOptions.Recursive, }) + if err != nil { return fmt.Errorf("DeleteKeyspace(%v) error: %w; please check the topo", ks, err) } @@ -180,6 +184,8 @@ func commandDeleteKeyspace(cmd *cobra.Command, args []string) error { } func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + ks := cmd.Flags().Arg(0) resp, err := client.FindAllShardsInKeyspace(commandCtx, &vtctldatapb.FindAllShardsInKeyspaceRequest{ Keyspace: ks, @@ -199,6 +205,8 @@ func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { } func commandGetKeyspace(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + ks := cmd.Flags().Arg(0) resp, err := client.GetKeyspace(commandCtx, &vtctldatapb.GetKeyspaceRequest{ Keyspace: ks, @@ -214,6 +222,8 @@ func commandGetKeyspace(cmd *cobra.Command, args []string) error { } func commandGetKeyspaces(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + resp, err := client.GetKeyspaces(commandCtx, &vtctldatapb.GetKeyspacesRequest{}) if err != nil { return err @@ -235,6 +245,8 @@ var removeKeyspaceCellOptions = struct { }{} func commandRemoveKeyspaceCell(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + keyspace := cmd.Flags().Arg(0) cell := cmd.Flags().Arg(1) diff --git a/go/cmd/vtctldclient/internal/command/schema.go b/go/cmd/vtctldclient/internal/command/schema.go index da6493d156e..f1e438df308 100644 --- a/go/cmd/vtctldclient/internal/command/schema.go +++ b/go/cmd/vtctldclient/internal/command/schema.go @@ -54,6 +54,8 @@ func commandGetSchema(cmd *cobra.Command, args []string) error { return err } + cli.FinishedParsing(cmd) + resp, err := client.GetSchema(commandCtx, &vtctldatapb.GetSchemaRequest{ TabletAlias: alias, Tables: getSchemaOptions.Tables, diff --git a/go/cmd/vtctldclient/internal/command/shards.go b/go/cmd/vtctldclient/internal/command/shards.go index 029e9be97fd..62d8205fb23 100644 --- a/go/cmd/vtctldclient/internal/command/shards.go +++ b/go/cmd/vtctldclient/internal/command/shards.go @@ -65,6 +65,8 @@ func commandCreateShard(cmd *cobra.Command, args []string) error { return err } + cli.FinishedParsing(cmd) + resp, err := client.CreateShard(commandCtx, &vtctldatapb.CreateShardRequest{ Keyspace: keyspace, ShardName: shard, @@ -96,6 +98,8 @@ func commandDeleteShards(cmd *cobra.Command, args []string) error { return err } + cli.FinishedParsing(cmd) + _, err = client.DeleteShards(commandCtx, &vtctldatapb.DeleteShardsRequest{ Shards: shards, EvenIfServing: deleteShardsOptions.EvenIfServing, @@ -117,6 +121,8 @@ func commandGetShard(cmd *cobra.Command, args []string) error { return err } + cli.FinishedParsing(cmd) + resp, err := client.GetShard(commandCtx, &vtctldatapb.GetShardRequest{ Keyspace: keyspace, ShardName: shard, @@ -146,6 +152,8 @@ func commandRemoveShardCell(cmd *cobra.Command, args []string) error { return err } + cli.FinishedParsing(cmd) + cell := cmd.Flags().Arg(1) _, err = client.RemoveShardCell(commandCtx, &vtctldatapb.RemoveShardCellRequest{ diff --git a/go/cmd/vtctldclient/internal/command/tablets.go b/go/cmd/vtctldclient/internal/command/tablets.go index 5b56ff38d32..dcf7e832d54 100644 --- a/go/cmd/vtctldclient/internal/command/tablets.go +++ b/go/cmd/vtctldclient/internal/command/tablets.go @@ -73,6 +73,8 @@ func commandChangeTabletType(cmd *cobra.Command, args []string) error { return err } + cli.FinishedParsing(cmd) + resp, err := client.ChangeTabletType(commandCtx, &vtctldatapb.ChangeTabletTypeRequest{ TabletAlias: alias, DbType: newType, @@ -102,6 +104,8 @@ func commandDeleteTablets(cmd *cobra.Command, args []string) error { return err } + cli.FinishedParsing(cmd) + _, err = client.DeleteTablets(commandCtx, &vtctldatapb.DeleteTabletsRequest{ TabletAliases: aliases, AllowPrimary: deleteTabletsOptions.AllowPrimary, @@ -123,6 +127,8 @@ func commandGetTablet(cmd *cobra.Command, args []string) error { return err } + cli.FinishedParsing(cmd) + resp, err := client.GetTablet(commandCtx, &vtctldatapb.GetTabletRequest{TabletAlias: alias}) if err != nil { return err @@ -159,6 +165,8 @@ func commandGetTablets(cmd *cobra.Command, args []string) error { return fmt.Errorf("--shard (= %s) cannot be passed without also passing --keyspace", getTabletsOptions.Shard) } + cli.FinishedParsing(cmd) + resp, err := client.GetTablets(commandCtx, &vtctldatapb.GetTabletsRequest{ Cells: getTabletsOptions.Cells, Keyspace: getTabletsOptions.Keyspace, diff --git a/go/cmd/vtctldclient/internal/command/vschemas.go b/go/cmd/vtctldclient/internal/command/vschemas.go index 1c5e848e6d2..0184b9b50ac 100644 --- a/go/cmd/vtctldclient/internal/command/vschemas.go +++ b/go/cmd/vtctldclient/internal/command/vschemas.go @@ -42,6 +42,8 @@ var ( ) func commandGetSrvVSchema(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + cell := cmd.Flags().Arg(0) resp, err := client.GetSrvVSchema(commandCtx, &vtctldatapb.GetSrvVSchemaRequest{ @@ -62,6 +64,8 @@ func commandGetSrvVSchema(cmd *cobra.Command, args []string) error { } func commandGetVSchema(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + keyspace := cmd.Flags().Arg(0) resp, err := client.GetVSchema(commandCtx, &vtctldatapb.GetVSchemaRequest{ From 32c17595cedf2ce1c4ac00642120aa439b6134da Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Thu, 11 Feb 2021 11:43:09 -0500 Subject: [PATCH 16/21] Apply missing test initializer fix for grpcvtctldclient Signed-off-by: Andrew Mason --- go/vt/vtctl/grpcvtctldclient/client_test.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/go/vt/vtctl/grpcvtctldclient/client_test.go b/go/vt/vtctl/grpcvtctldclient/client_test.go index 84a8b3b8133..0597f7144f3 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_test.go +++ b/go/vt/vtctl/grpcvtctldclient/client_test.go @@ -27,14 +27,19 @@ import ( "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" "vitess.io/vitess/go/vt/vtctl/vtctldclient" + "vitess.io/vitess/go/vt/vttablet/tmclient" topodatapb "vitess.io/vitess/go/vt/proto/topodata" - "vitess.io/vitess/go/vt/proto/vtctldata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" ) +func init() { + *tmclient.TabletManagerProtocol = testutil.TabletManagerClientProtocol +} + // annoyingly, this is duplicated with theu tests in package grpcvtctldserver. // fine for now, I suppose. func addKeyspace(ctx context.Context, t *testing.T, ts *topo.Server, ks *vtctldatapb.Keyspace) { @@ -116,7 +121,7 @@ func TestGetKeyspace(t *testing.T) { withTestServer(t, vtctld, func(t *testing.T, client vtctldclient.VtctldClient) { expected := &vtctldatapb.GetKeyspaceResponse{ - Keyspace: &vtctldata.Keyspace{ + Keyspace: &vtctldatapb.Keyspace{ Name: "testkeyspace", Keyspace: &topodatapb.Keyspace{ ShardingColumnName: "col1", From 57ecb3380b9b8cd680a41db8d500de7d88731dc3 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Sun, 21 Feb 2021 20:10:26 -0800 Subject: [PATCH 17/21] Merge pull request #7518 from tinyspeck/am_testtmclient_refactor [vtctld | tests only] testtmclient refactor Conflicts: go/vt/vtadmin/api_test.go go/vt/vtctl/reparentutil/emergency_reparenter_test.go go/vt/vtctl/reparentutil/planned_reparenter_test.go Resolved by `git rm -f` those files. Note: Also includes a change to grpcvtctldclient/client_test.go, not in the cherry-picked commit, to use the testutil constructor for vtctldservers. Signed-off-by: Andrew Mason wip test fixes Signed-off-by: Andrew Mason Signed-off-by: Richard Bailey --- go/vt/vtctl/grpcvtctldclient/client_test.go | 17 +- go/vt/vtctl/grpcvtctldserver/server_test.go | 76 ++- .../testutil/test_tmclient.go | 501 +++++++++++++++++- 3 files changed, 541 insertions(+), 53 deletions(-) diff --git a/go/vt/vtctl/grpcvtctldclient/client_test.go b/go/vt/vtctl/grpcvtctldclient/client_test.go index 0597f7144f3..9cee9efdbde 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_test.go +++ b/go/vt/vtctl/grpcvtctldclient/client_test.go @@ -29,17 +29,12 @@ import ( "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver" "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" "vitess.io/vitess/go/vt/vtctl/vtctldclient" - "vitess.io/vitess/go/vt/vttablet/tmclient" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" ) -func init() { - *tmclient.TabletManagerProtocol = testutil.TabletManagerClientProtocol -} - // annoyingly, this is duplicated with theu tests in package grpcvtctldserver. // fine for now, I suppose. func addKeyspace(ctx context.Context, t *testing.T, ts *topo.Server, ks *vtctldatapb.Keyspace) { @@ -74,7 +69,9 @@ func withTestServer( func TestFindAllShardsInKeyspace(t *testing.T) { ctx := context.Background() ts := memorytopo.NewServer("cell1") - vtctld := grpcvtctldserver.NewVtctldServer(ts) + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, nil, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return grpcvtctldserver.NewVtctldServer(ts) + }) withTestServer(t, vtctld, func(t *testing.T, client vtctldclient.VtctldClient) { ks := &vtctldatapb.Keyspace{ @@ -117,7 +114,9 @@ func TestGetKeyspace(t *testing.T) { ctx := context.Background() ts := memorytopo.NewServer("cell1") - vtctld := grpcvtctldserver.NewVtctldServer(ts) + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, nil, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return grpcvtctldserver.NewVtctldServer(ts) + }) withTestServer(t, vtctld, func(t *testing.T, client vtctldclient.VtctldClient) { expected := &vtctldatapb.GetKeyspaceResponse{ @@ -144,7 +143,9 @@ func TestGetKeyspaces(t *testing.T) { ctx := context.Background() ts := memorytopo.NewServer("cell1") - vtctld := grpcvtctldserver.NewVtctldServer(ts) + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, nil, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return grpcvtctldserver.NewVtctldServer(ts) + }) withTestServer(t, vtctld, func(t *testing.T, client vtctldclient.VtctldClient) { resp, err := client.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{}) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index e0ec817bf8f..261561563fe 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -39,15 +39,29 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" "vitess.io/vitess/go/vt/proto/vttime" ) func init() { - *tmclient.TabletManagerProtocol = testutil.TabletManagerClientProtocol *backupstorage.BackupStorageImplementation = testutil.BackupStorageImplementation + + // For tests that don't actually care about mocking the tmclient (i.e. they + // call NewVtctldServer to initialize the unit under test), this needs to be + // set. + // + // Tests that do care about the tmclient should use + // testutil.NewVtctldServerWithTabletManagerClient to initialize their + // VtctldServer. + *tmclient.TabletManagerProtocol = "grpcvtctldserver.test" + tmclient.RegisterTabletManagerClientFactory("grpcvtctldserver.test", func() tmclient.TabletManagerClient { + return nil + }) } func TestChangeTabletType(t *testing.T) { + t.Parallel() + tests := []struct { name string cells []string @@ -202,11 +216,16 @@ func TestChangeTabletType(t *testing.T) { } for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ctx := context.Background() ts := memorytopo.NewServer(tt.cells...) - vtctld := NewVtctldServer(ts) - testutil.TabletManagerClient.Topo = ts + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, &testutil.TabletManagerClient{ + TopoServer: ts, + }, func(ts *topo.Server) vtctlservicepb.VtctldServer { return NewVtctldServer(ts) }) for _, tablet := range tt.tablets { testutil.AddTablet(ctx, t, ts, tablet) @@ -245,10 +264,13 @@ func TestChangeTabletType(t *testing.T) { } t.Run("tabletmanager failure", func(t *testing.T) { + t.Parallel() + ctx := context.Background() ts := memorytopo.NewServer("zone1") - vtctld := NewVtctldServer(ts) - testutil.TabletManagerClient.Topo = nil + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, &testutil.TabletManagerClient{ + TopoServer: nil, + }, func(ts *topo.Server) vtctlservicepb.VtctldServer { return NewVtctldServer(ts) }) testutil.AddTablet(ctx, t, ts, &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{ @@ -2114,7 +2136,15 @@ func TestGetTablet(t *testing.T) { func TestGetSchema(t *testing.T) { ctx := context.Background() ts := memorytopo.NewServer("zone1") - vtctld := NewVtctldServer(ts) + tmc := testutil.TabletManagerClient{ + GetSchemaResults: map[string]struct { + Schema *tabletmanagerdatapb.SchemaDefinition + Error error + }{}, + } + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, &tmc, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return NewVtctldServer(ts) + }) validAlias := &topodatapb.TabletAlias{ Cell: "zone1", @@ -2133,27 +2163,33 @@ func TestGetSchema(t *testing.T) { // we need to run this on each test case or they will pollute each other setupSchema := func() { - testutil.TabletManagerClient.Schemas[topoproto.TabletAliasString(validAlias)] = &tabletmanagerdatapb.SchemaDefinition{ - DatabaseSchema: "CREATE DATABASE vt_testkeyspace", - TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ - { - Name: "t1", - Schema: `CREATE TABLE t1 ( + tmc.GetSchemaResults[topoproto.TabletAliasString(validAlias)] = struct { + Schema *tabletmanagerdatapb.SchemaDefinition + Error error + }{ + Schema: &tabletmanagerdatapb.SchemaDefinition{ + DatabaseSchema: "CREATE DATABASE vt_testkeyspace", + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Schema: `CREATE TABLE t1 ( id int(11) not null, PRIMARY KEY (id) );`, - Type: "BASE", - Columns: []string{"id"}, - DataLength: 100, - RowCount: 50, - Fields: []*querypb.Field{ - { - Name: "id", - Type: querypb.Type_INT32, + Type: "BASE", + Columns: []string{"id"}, + DataLength: 100, + RowCount: 50, + Fields: []*querypb.Field{ + { + Name: "id", + Type: querypb.Type_INT32, + }, }, }, }, }, + Error: nil, } } diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go index 414f794d694..0fd14bd75ae 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go @@ -19,6 +19,9 @@ package testutil import ( "context" "fmt" + "sync" + "testing" + "time" "github.com/stretchr/testify/assert" @@ -27,54 +30,502 @@ import ( "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vttablet/tmclient" + replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" "vitess.io/vitess/go/vt/proto/vttime" ) -// tabletManagerClient implements the tmclient.TabletManagerClient for -// testing. It allows users to mock various tmclient methods. -type tabletManagerClient struct { +var ( + tmclientLock sync.Mutex + tmclientFactoryLock sync.Mutex + tmclients = map[string]tmclient.TabletManagerClient{} + tmclientFactories = map[string]func() tmclient.TabletManagerClient{} +) + +// NewVtctldServerWithTabletManagerClient returns a new +// grpcvtctldserver.VtctldServer configured with the given topo server and +// tmclient.TabletManagerClient implementation for testing. +// +// It synchronizes on private locks to prevent multiple goroutines from stepping +// on each other during VtctldServer initialization, but still run the rest of +// the test in parallel. +// +// NOTE, THE FIRST: It is only safe to use in parallel with other tests using +// this method of creating a VtctldServer, or with tests that do not depend on a +// VtctldServer's tmclient.TabletManagerClient implementation. +// +// NOTE, THE SECOND: It needs to register a unique name to the tmclient factory +// registry, so we keep a shadow map of factories registered for "protocols" by +// this function. That way, if we happen to have multiple tests with the same +// name, we can swap out the return value for the factory and allow both tests +// to run, rather than the second test failing when it attempts to register a +// second factory for the same "protocol" name. +// +// NOTE, THE THIRD: we take a "new" func to produce a valid +// vtctlservicepb.VtctldServer implementation, rather than constructing directly +// ourselves with grpcvtctldserver.NewVtctldServer. This is to prevent an import +// cycle between this package and package grpcvtctldserver. Further, because the +// return type of NewVtctldServer is the struct type +// (*grpcvtctldserver.VtctldServer) and not the interface type +// vtctlservicepb.VtctldServer, tests will need to indirect that call through an +// extra layer rather than passing the function identifier directly, e.g.: +// +// vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, &testutil.TabletManagerClient{ +// ... +// }, func(ts *topo.Server) vtctlservicepb.VtctldServer { return NewVtctldServer(ts) }) +// +func NewVtctldServerWithTabletManagerClient(t *testing.T, ts *topo.Server, tmc tmclient.TabletManagerClient, newVtctldServerFn func(ts *topo.Server) vtctlservicepb.VtctldServer) vtctlservicepb.VtctldServer { + tmclientFactoryLock.Lock() + defer tmclientFactoryLock.Unlock() + + protocol := t.Name() + + if _, alreadyRegisteredFactory := tmclientFactories[protocol]; !alreadyRegisteredFactory { + factory := func() tmclient.TabletManagerClient { + tmclientLock.Lock() + defer tmclientLock.Unlock() + + client, ok := tmclients[protocol] + if !ok { + t.Fatal("Test managed to register a factory for a client value that never got set; this should be impossible") + } + + return client + } + + tmclient.RegisterTabletManagerClientFactory(protocol, factory) + tmclientFactories[protocol] = factory + } + + // Always swap in the new client return value for the given protocol name. + // We cannot defer the unlock here, because grpcvtctldserver.NewVtctldServer + // eventually will call into the factory we registered above, and we will + // deadlock ourselves. + tmclientLock.Lock() + tmclients[protocol] = tmc + tmclientLock.Unlock() + + // Be (mostly, we can't help concurrent goroutines not using this function) + // atomic with our mutation of the global TabletManagerProtocol pointer. + oldProto := *tmclient.TabletManagerProtocol + defer func() { *tmclient.TabletManagerProtocol = oldProto }() + + *tmclient.TabletManagerProtocol = protocol + + return newVtctldServerFn(ts) +} + +// TabletManagerClient implements the tmclient.TabletManagerClient interface +// with mock delays and response values, for use in unit tests. +type TabletManagerClient struct { tmclient.TabletManagerClient - Topo *topo.Server - Schemas map[string]*tabletmanagerdatapb.SchemaDefinition + // TopoServer is used for certain TabletManagerClient rpcs that update topo + // information, e.g. ChangeType. To force an error result for those rpcs in + // a test, set tmc.TopoServer = nil. + TopoServer *topo.Server + // keyed by tablet alias. + DemoteMasterDelays map[string]time.Duration + // keyed by tablet alias. + DemoteMasterResults map[string]struct { + Status *replicationdatapb.MasterStatus + Error error + } + // keyed by tablet alias. + GetSchemaDelays map[string]time.Duration + // keyed by tablet alias. + GetSchemaResults map[string]struct { + Schema *tabletmanagerdatapb.SchemaDefinition + Error error + } + // keyed by tablet alias. + MasterPositionDelays map[string]time.Duration + // keyed by tablet alias. + MasterPositionResults map[string]struct { + Position string + Error error + } + // keyed by tablet alias. + PopulateReparentJournalDelays map[string]time.Duration + // keyed by tablet alias + PopulateReparentJournalResults map[string]error + // keyed by tablet alias. + PromoteReplicaDelays map[string]time.Duration + // keyed by tablet alias. injects a sleep to the end of the function + // regardless of parent context timeout or error result. + PromoteReplicaPostDelays map[string]time.Duration + // keyed by tablet alias. + PromoteReplicaResults map[string]struct { + Result string + Error error + } + ReplicationStatusResults map[string]struct { + Position *replicationdatapb.Status + Error error + } + // keyed by tablet alias. + SetMasterDelays map[string]time.Duration + // keyed by tablet alias. + SetMasterResults map[string]error + // keyed by tablet alias. + SetReadWriteDelays map[string]time.Duration + // keyed by tablet alias. + SetReadWriteResults map[string]error + // keyed by tablet alias. + StopReplicationAndGetStatusDelays map[string]time.Duration + // keyed by tablet alias. + StopReplicationAndGetStatusResults map[string]struct { + Status *replicationdatapb.Status + StopStatus *replicationdatapb.StopReplicationStatus + Error error + } + // keyed by tablet alias. + WaitForPositionDelays map[string]time.Duration + // keyed by tablet alias. injects a sleep to the end of the function + // regardless of parent context timeout or error result. + WaitForPositionPostDelays map[string]time.Duration + // WaitForPosition(tablet *topodatapb.Tablet, position string) error, so we + // key by tablet alias and then by position. + WaitForPositionResults map[string]map[string]error + // keyed by tablet alias. + UndoDemoteMasterDelays map[string]time.Duration + // keyed by tablet alias + UndoDemoteMasterResults map[string]error } // ChangeType is part of the tmclient.TabletManagerClient interface. -func (c *tabletManagerClient) ChangeType(ctx context.Context, tablet *topodatapb.Tablet, newType topodatapb.TabletType) error { - if c.Topo == nil { +func (fake *TabletManagerClient) ChangeType(ctx context.Context, tablet *topodatapb.Tablet, newType topodatapb.TabletType) error { + if fake.TopoServer == nil { return assert.AnError } - _, err := topotools.ChangeType(ctx, c.Topo, tablet.Alias, newType, &vttime.Time{}) + _, err := topotools.ChangeType(ctx, fake.TopoServer, tablet.Alias, newType, &vttime.Time{}) return err } +// DemoteMaster is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) DemoteMaster(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.MasterStatus, error) { + if fake.DemoteMasterResults == nil { + return nil, assert.AnError + } + + if tablet.Alias == nil { + return nil, assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if fake.DemoteMasterDelays != nil { + if delay, ok := fake.DemoteMasterDelays[key]; ok { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if result, ok := fake.DemoteMasterResults[key]; ok { + return result.Status, result.Error + } + + return nil, assert.AnError +} + // GetSchema is part of the tmclient.TabletManagerClient interface. -func (c *tabletManagerClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tablets []string, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { +func (fake *TabletManagerClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tablets []string, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { + if fake.GetSchemaResults == nil { + return nil, assert.AnError + } + + if tablet.Alias == nil { + return nil, assert.AnError + } + key := topoproto.TabletAliasString(tablet.Alias) - schema, ok := c.Schemas[key] - if !ok { - return nil, fmt.Errorf("no schemas for %s", key) + if fake.GetSchemaDelays != nil { + if delay, ok := fake.GetSchemaDelays[key]; ok { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(delay): + // proceed to results + } + } } - return schema, nil + if result, ok := fake.GetSchemaResults[key]; ok { + return result.Schema, result.Error + } + + return nil, fmt.Errorf("%w: no schemas for %s", assert.AnError, key) +} + +// MasterPosition is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) MasterPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error) { + if fake.MasterPositionResults == nil { + return "", assert.AnError + } + + if tablet.Alias == nil { + return "", assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if fake.MasterPositionDelays != nil { + if delay, ok := fake.MasterPositionDelays[key]; ok { + select { + case <-ctx.Done(): + return "", ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if result, ok := fake.MasterPositionResults[key]; ok { + return result.Position, result.Error + } + + return "", assert.AnError +} + +// PopulateReparentJournal is part of the tmclient.TabletManagerClient +// interface. +func (fake *TabletManagerClient) PopulateReparentJournal(ctx context.Context, tablet *topodatapb.Tablet, timeCreatedNS int64, actionName string, primaryAlias *topodatapb.TabletAlias, pos string) error { + if fake.PopulateReparentJournalResults == nil { + return assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if fake.PopulateReparentJournalDelays != nil { + if delay, ok := fake.PopulateReparentJournalDelays[key]; ok { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + if result, ok := fake.PopulateReparentJournalResults[key]; ok { + return result + } + + return assert.AnError } -// TabletManagerClientProtocol is the protocol this package registers its client -// test implementation under. Users should set *tmclient.TabletManagerProtocol -// to this value before use. -const TabletManagerClientProtocol = "grpcvtctldserver.testutil" +// PromoteReplica is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) PromoteReplica(ctx context.Context, tablet *topodatapb.Tablet) (string, error) { + if fake.PromoteReplicaResults == nil { + return "", assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + defer func() { + if fake.PromoteReplicaPostDelays == nil { + return + } + + if delay, ok := fake.PromoteReplicaPostDelays[key]; ok { + time.Sleep(delay) + } + }() -// TabletManagerClient is the singleton test client instance. It is public and -// singleton to allow tests to mutate and verify its state. -var TabletManagerClient = &tabletManagerClient{ - Schemas: map[string]*tabletmanagerdatapb.SchemaDefinition{}, + if fake.PromoteReplicaDelays != nil { + if delay, ok := fake.PromoteReplicaDelays[key]; ok { + select { + case <-ctx.Done(): + return "", ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if result, ok := fake.PromoteReplicaResults[key]; ok { + return result.Result, result.Error + } + + return "", assert.AnError } -func init() { - tmclient.RegisterTabletManagerClientFactory(TabletManagerClientProtocol, func() tmclient.TabletManagerClient { - return TabletManagerClient - }) +// ReplicationStatus is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) ReplicationStatus(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.Status, error) { + if fake.ReplicationStatusResults == nil { + return nil, assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if result, ok := fake.ReplicationStatusResults[key]; ok { + return result.Position, result.Error + } + + return nil, assert.AnError +} + +// SetMaster is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartReplication bool) error { + if fake.SetMasterResults == nil { + return assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if fake.SetMasterDelays != nil { + if delay, ok := fake.SetMasterDelays[key]; ok { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if result, ok := fake.SetMasterResults[key]; ok { + return result + } + + return assert.AnError +} + +// SetReadWrite is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) SetReadWrite(ctx context.Context, tablet *topodatapb.Tablet) error { + if fake.SetReadWriteResults == nil { + return assert.AnError + } + + if tablet.Alias == nil { + return assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if fake.SetReadWriteDelays != nil { + if delay, ok := fake.SetReadWriteDelays[key]; ok { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if err, ok := fake.SetReadWriteResults[key]; ok { + return err + } + + return assert.AnError +} + +// StopReplicationAndGetStatus is part of the tmclient.TabletManagerClient +// interface. +func (fake *TabletManagerClient) StopReplicationAndGetStatus(ctx context.Context, tablet *topodatapb.Tablet, mode replicationdatapb.StopReplicationMode) (*replicationdatapb.Status, *replicationdatapb.StopReplicationStatus, error) { + if fake.StopReplicationAndGetStatusResults == nil { + return nil, nil, assert.AnError + } + + if tablet.Alias == nil { + return nil, nil, assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if fake.StopReplicationAndGetStatusDelays != nil { + if delay, ok := fake.StopReplicationAndGetStatusDelays[key]; ok { + select { + case <-ctx.Done(): + return nil, nil, ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if result, ok := fake.StopReplicationAndGetStatusResults[key]; ok { + return result.Status, result.StopStatus, result.Error + } + + return nil, nil, assert.AnError +} + +// WaitForPosition is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, position string) error { + tabletKey := topoproto.TabletAliasString(tablet.Alias) + + defer func() { + if fake.WaitForPositionPostDelays == nil { + return + } + + if delay, ok := fake.WaitForPositionPostDelays[tabletKey]; ok { + time.Sleep(delay) + } + }() + + if fake.WaitForPositionDelays != nil { + if delay, ok := fake.WaitForPositionDelays[tabletKey]; ok { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if fake.WaitForPositionResults == nil { + return assert.AnError + } + + tabletResultsByPosition, ok := fake.WaitForPositionResults[tabletKey] + if !ok { + return assert.AnError + } + + result, ok := tabletResultsByPosition[position] + if !ok { + return assert.AnError + } + + return result +} + +// UndoDemoteMaster is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) UndoDemoteMaster(ctx context.Context, tablet *topodatapb.Tablet) error { + if fake.UndoDemoteMasterResults == nil { + return assert.AnError + } + + if tablet.Alias == nil { + return assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if fake.UndoDemoteMasterDelays != nil { + if delay, ok := fake.UndoDemoteMasterDelays[key]; ok { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if result, ok := fake.UndoDemoteMasterResults[key]; ok { + return result + } + + return assert.AnError } From ade01360413dee1c0a26ea97cb6e10de38b5e3e8 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Thu, 4 Mar 2021 17:24:25 +0100 Subject: [PATCH 18/21] Merge pull request #7575 from tinyspeck/am_vtctld_workflows [vtctld] Add v0 GetWorkflows rpc and workflow/vexec packages Signed-off-by: Andrew Mason Conflicts: go/vt/proto/vtctldata/vtctldata.pb.go go/vt/proto/vtctlservice/vtctlservice.pb.go go/vt/vtctl/grpcvtctldclient/client_gen.go go/vt/vtctl/grpcvtctldserver/server.go go/vt/wrangler/vexec.go proto/vtctldata.proto proto/vtctlservice.proto --- .../internal/command/workflows.go | 69 + go/vt/proto/vtctldata/vtctldata.pb.go | 1623 ++++++++++++----- go/vt/proto/vtctlservice/vtctlservice.pb.go | 111 +- go/vt/vtctl/grpcvtctldclient/client_gen.go | 9 + go/vt/vtctl/grpcvtctldserver/server.go | 15 +- .../testutil/test_tmclient.go | 62 +- go/vt/vtctl/workflow/doc.go | 45 + go/vt/vtctl/workflow/server.go | 341 ++++ go/vt/vtctl/workflow/vexec/query_plan.go | 116 ++ go/vt/vtctl/workflow/vexec/query_plan_test.go | 332 ++++ go/vt/vtctl/workflow/vexec/query_planner.go | 326 ++++ .../workflow/vexec/query_planner_test.go | 244 +++ go/vt/vtctl/workflow/vexec/testutil/query.go | 48 + go/vt/vtctl/workflow/vexec/vexec.go | 235 +++ proto/vtctldata.proto | 154 +- proto/vtctlservice.proto | 2 + 16 files changed, 3194 insertions(+), 538 deletions(-) create mode 100644 go/cmd/vtctldclient/internal/command/workflows.go create mode 100644 go/vt/vtctl/workflow/doc.go create mode 100644 go/vt/vtctl/workflow/server.go create mode 100644 go/vt/vtctl/workflow/vexec/query_plan.go create mode 100644 go/vt/vtctl/workflow/vexec/query_plan_test.go create mode 100644 go/vt/vtctl/workflow/vexec/query_planner.go create mode 100644 go/vt/vtctl/workflow/vexec/query_planner_test.go create mode 100644 go/vt/vtctl/workflow/vexec/testutil/query.go create mode 100644 go/vt/vtctl/workflow/vexec/vexec.go diff --git a/go/cmd/vtctldclient/internal/command/workflows.go b/go/cmd/vtctldclient/internal/command/workflows.go new file mode 100644 index 00000000000..760139a9be9 --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/workflows.go @@ -0,0 +1,69 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "fmt" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // GetWorkflows makes a GetWorkflows gRPC call to a vtctld. + GetWorkflows = &cobra.Command{ + Use: "GetWorkflows ", + Args: cobra.ExactArgs(1), + RunE: commandGetWorkflows, + } +) + +var getWorkflowsOptions = struct { + ShowAll bool +}{} + +func commandGetWorkflows(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + + ks := cmd.Flags().Arg(0) + + resp, err := client.GetWorkflows(commandCtx, &vtctldatapb.GetWorkflowsRequest{ + Keyspace: ks, + ActiveOnly: !getWorkflowsOptions.ShowAll, + }) + + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +func init() { + GetWorkflows.Flags().BoolVarP(&getWorkflowsOptions.ShowAll, "show-all", "a", false, "Show all workflows instead of just active workflows") + Root.AddCommand(GetWorkflows) +} diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 0180e99e138..54deb2c00e7 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -8,6 +8,7 @@ import ( math "math" proto "github.com/golang/protobuf/proto" + binlogdata "vitess.io/vitess/go/vt/proto/binlogdata" logutil "vitess.io/vitess/go/vt/proto/logutil" mysqlctl "vitess.io/vitess/go/vt/proto/mysqlctl" tabletmanagerdata "vitess.io/vitess/go/vt/proto/tabletmanagerdata" @@ -116,6 +117,617 @@ func (m *ExecuteVtctlCommandResponse) GetEvent() *logutil.Event { return nil } +// TableMaterializeSttings contains the settings for one table. +type TableMaterializeSettings struct { + TargetTable string `protobuf:"bytes,1,opt,name=target_table,json=targetTable,proto3" json:"target_table,omitempty"` + // source_expression is a select statement. + SourceExpression string `protobuf:"bytes,2,opt,name=source_expression,json=sourceExpression,proto3" json:"source_expression,omitempty"` + // create_ddl contains the DDL to create the target table. + // If empty, the target table must already exist. + // if "copy", the target table DDL is the same as the source table. + CreateDdl string `protobuf:"bytes,3,opt,name=create_ddl,json=createDdl,proto3" json:"create_ddl,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettings{} } +func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } +func (*TableMaterializeSettings) ProtoMessage() {} +func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{2} +} + +func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TableMaterializeSettings.Unmarshal(m, b) +} +func (m *TableMaterializeSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TableMaterializeSettings.Marshal(b, m, deterministic) +} +func (m *TableMaterializeSettings) XXX_Merge(src proto.Message) { + xxx_messageInfo_TableMaterializeSettings.Merge(m, src) +} +func (m *TableMaterializeSettings) XXX_Size() int { + return xxx_messageInfo_TableMaterializeSettings.Size(m) +} +func (m *TableMaterializeSettings) XXX_DiscardUnknown() { + xxx_messageInfo_TableMaterializeSettings.DiscardUnknown(m) +} + +var xxx_messageInfo_TableMaterializeSettings proto.InternalMessageInfo + +func (m *TableMaterializeSettings) GetTargetTable() string { + if m != nil { + return m.TargetTable + } + return "" +} + +func (m *TableMaterializeSettings) GetSourceExpression() string { + if m != nil { + return m.SourceExpression + } + return "" +} + +func (m *TableMaterializeSettings) GetCreateDdl() string { + if m != nil { + return m.CreateDdl + } + return "" +} + +// MaterializeSettings contains the settings for the Materialize command. +type MaterializeSettings struct { + // workflow is the name of the workflow. + Workflow string `protobuf:"bytes,1,opt,name=workflow,proto3" json:"workflow,omitempty"` + SourceKeyspace string `protobuf:"bytes,2,opt,name=source_keyspace,json=sourceKeyspace,proto3" json:"source_keyspace,omitempty"` + TargetKeyspace string `protobuf:"bytes,3,opt,name=target_keyspace,json=targetKeyspace,proto3" json:"target_keyspace,omitempty"` + // stop_after_copy specifies if vreplication should be stopped after copying. + StopAfterCopy bool `protobuf:"varint,4,opt,name=stop_after_copy,json=stopAfterCopy,proto3" json:"stop_after_copy,omitempty"` + TableSettings []*TableMaterializeSettings `protobuf:"bytes,5,rep,name=table_settings,json=tableSettings,proto3" json:"table_settings,omitempty"` + // optional parameters. + Cell string `protobuf:"bytes,6,opt,name=cell,proto3" json:"cell,omitempty"` + TabletTypes string `protobuf:"bytes,7,opt,name=tablet_types,json=tabletTypes,proto3" json:"tablet_types,omitempty"` + // ExternalCluster is the name of the mounted cluster which has the source keyspace/db for this workflow + // it is of the type + ExternalCluster string `protobuf:"bytes,8,opt,name=external_cluster,json=externalCluster,proto3" json:"external_cluster,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } +func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } +func (*MaterializeSettings) ProtoMessage() {} +func (*MaterializeSettings) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{3} +} + +func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MaterializeSettings.Unmarshal(m, b) +} +func (m *MaterializeSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MaterializeSettings.Marshal(b, m, deterministic) +} +func (m *MaterializeSettings) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaterializeSettings.Merge(m, src) +} +func (m *MaterializeSettings) XXX_Size() int { + return xxx_messageInfo_MaterializeSettings.Size(m) +} +func (m *MaterializeSettings) XXX_DiscardUnknown() { + xxx_messageInfo_MaterializeSettings.DiscardUnknown(m) +} + +var xxx_messageInfo_MaterializeSettings proto.InternalMessageInfo + +func (m *MaterializeSettings) GetWorkflow() string { + if m != nil { + return m.Workflow + } + return "" +} + +func (m *MaterializeSettings) GetSourceKeyspace() string { + if m != nil { + return m.SourceKeyspace + } + return "" +} + +func (m *MaterializeSettings) GetTargetKeyspace() string { + if m != nil { + return m.TargetKeyspace + } + return "" +} + +func (m *MaterializeSettings) GetStopAfterCopy() bool { + if m != nil { + return m.StopAfterCopy + } + return false +} + +func (m *MaterializeSettings) GetTableSettings() []*TableMaterializeSettings { + if m != nil { + return m.TableSettings + } + return nil +} + +func (m *MaterializeSettings) GetCell() string { + if m != nil { + return m.Cell + } + return "" +} + +func (m *MaterializeSettings) GetTabletTypes() string { + if m != nil { + return m.TabletTypes + } + return "" +} + +func (m *MaterializeSettings) GetExternalCluster() string { + if m != nil { + return m.ExternalCluster + } + return "" +} + +type Keyspace struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Keyspace *topodata.Keyspace `protobuf:"bytes,2,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Keyspace) Reset() { *m = Keyspace{} } +func (m *Keyspace) String() string { return proto.CompactTextString(m) } +func (*Keyspace) ProtoMessage() {} +func (*Keyspace) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{4} +} + +func (m *Keyspace) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Keyspace.Unmarshal(m, b) +} +func (m *Keyspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Keyspace.Marshal(b, m, deterministic) +} +func (m *Keyspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_Keyspace.Merge(m, src) +} +func (m *Keyspace) XXX_Size() int { + return xxx_messageInfo_Keyspace.Size(m) +} +func (m *Keyspace) XXX_DiscardUnknown() { + xxx_messageInfo_Keyspace.DiscardUnknown(m) +} + +var xxx_messageInfo_Keyspace proto.InternalMessageInfo + +func (m *Keyspace) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Keyspace) GetKeyspace() *topodata.Keyspace { + if m != nil { + return m.Keyspace + } + return nil +} + +type Shard struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Shard *topodata.Shard `protobuf:"bytes,3,opt,name=shard,proto3" json:"shard,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Shard) Reset() { *m = Shard{} } +func (m *Shard) String() string { return proto.CompactTextString(m) } +func (*Shard) ProtoMessage() {} +func (*Shard) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{5} +} + +func (m *Shard) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Shard.Unmarshal(m, b) +} +func (m *Shard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Shard.Marshal(b, m, deterministic) +} +func (m *Shard) XXX_Merge(src proto.Message) { + xxx_messageInfo_Shard.Merge(m, src) +} +func (m *Shard) XXX_Size() int { + return xxx_messageInfo_Shard.Size(m) +} +func (m *Shard) XXX_DiscardUnknown() { + xxx_messageInfo_Shard.DiscardUnknown(m) +} + +var xxx_messageInfo_Shard proto.InternalMessageInfo + +func (m *Shard) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *Shard) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Shard) GetShard() *topodata.Shard { + if m != nil { + return m.Shard + } + return nil +} + +// TODO: comment the hell out of this. +type Workflow struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Source *Workflow_ReplicationLocation `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + Target *Workflow_ReplicationLocation `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"` + MaxVReplicationLag int64 `protobuf:"varint,4,opt,name=max_v_replication_lag,json=maxVReplicationLag,proto3" json:"max_v_replication_lag,omitempty"` + ShardStreams map[string]*Workflow_ShardStream `protobuf:"bytes,5,rep,name=shard_streams,json=shardStreams,proto3" json:"shard_streams,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Workflow) Reset() { *m = Workflow{} } +func (m *Workflow) String() string { return proto.CompactTextString(m) } +func (*Workflow) ProtoMessage() {} +func (*Workflow) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{6} +} + +func (m *Workflow) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Workflow.Unmarshal(m, b) +} +func (m *Workflow) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Workflow.Marshal(b, m, deterministic) +} +func (m *Workflow) XXX_Merge(src proto.Message) { + xxx_messageInfo_Workflow.Merge(m, src) +} +func (m *Workflow) XXX_Size() int { + return xxx_messageInfo_Workflow.Size(m) +} +func (m *Workflow) XXX_DiscardUnknown() { + xxx_messageInfo_Workflow.DiscardUnknown(m) +} + +var xxx_messageInfo_Workflow proto.InternalMessageInfo + +func (m *Workflow) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Workflow) GetSource() *Workflow_ReplicationLocation { + if m != nil { + return m.Source + } + return nil +} + +func (m *Workflow) GetTarget() *Workflow_ReplicationLocation { + if m != nil { + return m.Target + } + return nil +} + +func (m *Workflow) GetMaxVReplicationLag() int64 { + if m != nil { + return m.MaxVReplicationLag + } + return 0 +} + +func (m *Workflow) GetShardStreams() map[string]*Workflow_ShardStream { + if m != nil { + return m.ShardStreams + } + return nil +} + +type Workflow_ReplicationLocation struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Shards []string `protobuf:"bytes,2,rep,name=shards,proto3" json:"shards,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Workflow_ReplicationLocation) Reset() { *m = Workflow_ReplicationLocation{} } +func (m *Workflow_ReplicationLocation) String() string { return proto.CompactTextString(m) } +func (*Workflow_ReplicationLocation) ProtoMessage() {} +func (*Workflow_ReplicationLocation) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{6, 1} +} + +func (m *Workflow_ReplicationLocation) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Workflow_ReplicationLocation.Unmarshal(m, b) +} +func (m *Workflow_ReplicationLocation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Workflow_ReplicationLocation.Marshal(b, m, deterministic) +} +func (m *Workflow_ReplicationLocation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Workflow_ReplicationLocation.Merge(m, src) +} +func (m *Workflow_ReplicationLocation) XXX_Size() int { + return xxx_messageInfo_Workflow_ReplicationLocation.Size(m) +} +func (m *Workflow_ReplicationLocation) XXX_DiscardUnknown() { + xxx_messageInfo_Workflow_ReplicationLocation.DiscardUnknown(m) +} + +var xxx_messageInfo_Workflow_ReplicationLocation proto.InternalMessageInfo + +func (m *Workflow_ReplicationLocation) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *Workflow_ReplicationLocation) GetShards() []string { + if m != nil { + return m.Shards + } + return nil +} + +type Workflow_ShardStream struct { + Streams []*Workflow_Stream `protobuf:"bytes,1,rep,name=streams,proto3" json:"streams,omitempty"` + TabletControls []*topodata.Shard_TabletControl `protobuf:"bytes,2,rep,name=tablet_controls,json=tabletControls,proto3" json:"tablet_controls,omitempty"` + IsPrimaryServing bool `protobuf:"varint,3,opt,name=is_primary_serving,json=isPrimaryServing,proto3" json:"is_primary_serving,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Workflow_ShardStream) Reset() { *m = Workflow_ShardStream{} } +func (m *Workflow_ShardStream) String() string { return proto.CompactTextString(m) } +func (*Workflow_ShardStream) ProtoMessage() {} +func (*Workflow_ShardStream) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{6, 2} +} + +func (m *Workflow_ShardStream) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Workflow_ShardStream.Unmarshal(m, b) +} +func (m *Workflow_ShardStream) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Workflow_ShardStream.Marshal(b, m, deterministic) +} +func (m *Workflow_ShardStream) XXX_Merge(src proto.Message) { + xxx_messageInfo_Workflow_ShardStream.Merge(m, src) +} +func (m *Workflow_ShardStream) XXX_Size() int { + return xxx_messageInfo_Workflow_ShardStream.Size(m) +} +func (m *Workflow_ShardStream) XXX_DiscardUnknown() { + xxx_messageInfo_Workflow_ShardStream.DiscardUnknown(m) +} + +var xxx_messageInfo_Workflow_ShardStream proto.InternalMessageInfo + +func (m *Workflow_ShardStream) GetStreams() []*Workflow_Stream { + if m != nil { + return m.Streams + } + return nil +} + +func (m *Workflow_ShardStream) GetTabletControls() []*topodata.Shard_TabletControl { + if m != nil { + return m.TabletControls + } + return nil +} + +func (m *Workflow_ShardStream) GetIsPrimaryServing() bool { + if m != nil { + return m.IsPrimaryServing + } + return false +} + +type Workflow_Stream struct { + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` + Tablet *topodata.TabletAlias `protobuf:"bytes,3,opt,name=tablet,proto3" json:"tablet,omitempty"` + BinlogSource *binlogdata.BinlogSource `protobuf:"bytes,4,opt,name=binlog_source,json=binlogSource,proto3" json:"binlog_source,omitempty"` + Position string `protobuf:"bytes,5,opt,name=position,proto3" json:"position,omitempty"` + StopPosition string `protobuf:"bytes,6,opt,name=stop_position,json=stopPosition,proto3" json:"stop_position,omitempty"` + State string `protobuf:"bytes,7,opt,name=state,proto3" json:"state,omitempty"` + DbName string `protobuf:"bytes,8,opt,name=db_name,json=dbName,proto3" json:"db_name,omitempty"` + TransactionTimestamp *vttime.Time `protobuf:"bytes,9,opt,name=transaction_timestamp,json=transactionTimestamp,proto3" json:"transaction_timestamp,omitempty"` + TimeUpdated *vttime.Time `protobuf:"bytes,10,opt,name=time_updated,json=timeUpdated,proto3" json:"time_updated,omitempty"` + Message string `protobuf:"bytes,11,opt,name=message,proto3" json:"message,omitempty"` + CopyStates []*Workflow_Stream_CopyState `protobuf:"bytes,12,rep,name=copy_states,json=copyStates,proto3" json:"copy_states,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Workflow_Stream) Reset() { *m = Workflow_Stream{} } +func (m *Workflow_Stream) String() string { return proto.CompactTextString(m) } +func (*Workflow_Stream) ProtoMessage() {} +func (*Workflow_Stream) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{6, 3} +} + +func (m *Workflow_Stream) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Workflow_Stream.Unmarshal(m, b) +} +func (m *Workflow_Stream) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Workflow_Stream.Marshal(b, m, deterministic) +} +func (m *Workflow_Stream) XXX_Merge(src proto.Message) { + xxx_messageInfo_Workflow_Stream.Merge(m, src) +} +func (m *Workflow_Stream) XXX_Size() int { + return xxx_messageInfo_Workflow_Stream.Size(m) +} +func (m *Workflow_Stream) XXX_DiscardUnknown() { + xxx_messageInfo_Workflow_Stream.DiscardUnknown(m) +} + +var xxx_messageInfo_Workflow_Stream proto.InternalMessageInfo + +func (m *Workflow_Stream) GetId() int64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Workflow_Stream) GetShard() string { + if m != nil { + return m.Shard + } + return "" +} + +func (m *Workflow_Stream) GetTablet() *topodata.TabletAlias { + if m != nil { + return m.Tablet + } + return nil +} + +func (m *Workflow_Stream) GetBinlogSource() *binlogdata.BinlogSource { + if m != nil { + return m.BinlogSource + } + return nil +} + +func (m *Workflow_Stream) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} + +func (m *Workflow_Stream) GetStopPosition() string { + if m != nil { + return m.StopPosition + } + return "" +} + +func (m *Workflow_Stream) GetState() string { + if m != nil { + return m.State + } + return "" +} + +func (m *Workflow_Stream) GetDbName() string { + if m != nil { + return m.DbName + } + return "" +} + +func (m *Workflow_Stream) GetTransactionTimestamp() *vttime.Time { + if m != nil { + return m.TransactionTimestamp + } + return nil +} + +func (m *Workflow_Stream) GetTimeUpdated() *vttime.Time { + if m != nil { + return m.TimeUpdated + } + return nil +} + +func (m *Workflow_Stream) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func (m *Workflow_Stream) GetCopyStates() []*Workflow_Stream_CopyState { + if m != nil { + return m.CopyStates + } + return nil +} + +type Workflow_Stream_CopyState struct { + Table string `protobuf:"bytes,1,opt,name=table,proto3" json:"table,omitempty"` + LastPk string `protobuf:"bytes,2,opt,name=last_pk,json=lastPk,proto3" json:"last_pk,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Workflow_Stream_CopyState) Reset() { *m = Workflow_Stream_CopyState{} } +func (m *Workflow_Stream_CopyState) String() string { return proto.CompactTextString(m) } +func (*Workflow_Stream_CopyState) ProtoMessage() {} +func (*Workflow_Stream_CopyState) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{6, 3, 0} +} + +func (m *Workflow_Stream_CopyState) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Workflow_Stream_CopyState.Unmarshal(m, b) +} +func (m *Workflow_Stream_CopyState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Workflow_Stream_CopyState.Marshal(b, m, deterministic) +} +func (m *Workflow_Stream_CopyState) XXX_Merge(src proto.Message) { + xxx_messageInfo_Workflow_Stream_CopyState.Merge(m, src) +} +func (m *Workflow_Stream_CopyState) XXX_Size() int { + return xxx_messageInfo_Workflow_Stream_CopyState.Size(m) +} +func (m *Workflow_Stream_CopyState) XXX_DiscardUnknown() { + xxx_messageInfo_Workflow_Stream_CopyState.DiscardUnknown(m) +} + +var xxx_messageInfo_Workflow_Stream_CopyState proto.InternalMessageInfo + +func (m *Workflow_Stream_CopyState) GetTable() string { + if m != nil { + return m.Table + } + return "" +} + +func (m *Workflow_Stream_CopyState) GetLastPk() string { + if m != nil { + return m.LastPk + } + return "" +} + type ChangeTabletTypeRequest struct { TabletAlias *topodata.TabletAlias `protobuf:"bytes,1,opt,name=tablet_alias,json=tabletAlias,proto3" json:"tablet_alias,omitempty"` DbType topodata.TabletType `protobuf:"varint,2,opt,name=db_type,json=dbType,proto3,enum=topodata.TabletType" json:"db_type,omitempty"` @@ -129,7 +741,7 @@ func (m *ChangeTabletTypeRequest) Reset() { *m = ChangeTabletTypeRequest func (m *ChangeTabletTypeRequest) String() string { return proto.CompactTextString(m) } func (*ChangeTabletTypeRequest) ProtoMessage() {} func (*ChangeTabletTypeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{2} + return fileDescriptor_f41247b323a1ab2e, []int{7} } func (m *ChangeTabletTypeRequest) XXX_Unmarshal(b []byte) error { @@ -184,7 +796,7 @@ func (m *ChangeTabletTypeResponse) Reset() { *m = ChangeTabletTypeRespon func (m *ChangeTabletTypeResponse) String() string { return proto.CompactTextString(m) } func (*ChangeTabletTypeResponse) ProtoMessage() {} func (*ChangeTabletTypeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{3} + return fileDescriptor_f41247b323a1ab2e, []int{8} } func (m *ChangeTabletTypeResponse) XXX_Unmarshal(b []byte) error { @@ -258,7 +870,7 @@ func (m *CreateKeyspaceRequest) Reset() { *m = CreateKeyspaceRequest{} } func (m *CreateKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*CreateKeyspaceRequest) ProtoMessage() {} func (*CreateKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{4} + return fileDescriptor_f41247b323a1ab2e, []int{9} } func (m *CreateKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -354,7 +966,7 @@ func (m *CreateKeyspaceResponse) Reset() { *m = CreateKeyspaceResponse{} func (m *CreateKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*CreateKeyspaceResponse) ProtoMessage() {} func (*CreateKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{5} + return fileDescriptor_f41247b323a1ab2e, []int{10} } func (m *CreateKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -402,7 +1014,7 @@ func (m *CreateShardRequest) Reset() { *m = CreateShardRequest{} } func (m *CreateShardRequest) String() string { return proto.CompactTextString(m) } func (*CreateShardRequest) ProtoMessage() {} func (*CreateShardRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{6} + return fileDescriptor_f41247b323a1ab2e, []int{11} } func (m *CreateShardRequest) XXX_Unmarshal(b []byte) error { @@ -469,7 +1081,7 @@ func (m *CreateShardResponse) Reset() { *m = CreateShardResponse{} } func (m *CreateShardResponse) String() string { return proto.CompactTextString(m) } func (*CreateShardResponse) ProtoMessage() {} func (*CreateShardResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{7} + return fileDescriptor_f41247b323a1ab2e, []int{12} } func (m *CreateShardResponse) XXX_Unmarshal(b []byte) error { @@ -527,7 +1139,7 @@ func (m *DeleteKeyspaceRequest) Reset() { *m = DeleteKeyspaceRequest{} } func (m *DeleteKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*DeleteKeyspaceRequest) ProtoMessage() {} func (*DeleteKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{8} + return fileDescriptor_f41247b323a1ab2e, []int{13} } func (m *DeleteKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -572,7 +1184,7 @@ func (m *DeleteKeyspaceResponse) Reset() { *m = DeleteKeyspaceResponse{} func (m *DeleteKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*DeleteKeyspaceResponse) ProtoMessage() {} func (*DeleteKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{9} + return fileDescriptor_f41247b323a1ab2e, []int{14} } func (m *DeleteKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -613,7 +1225,7 @@ func (m *DeleteShardsRequest) Reset() { *m = DeleteShardsRequest{} } func (m *DeleteShardsRequest) String() string { return proto.CompactTextString(m) } func (*DeleteShardsRequest) ProtoMessage() {} func (*DeleteShardsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{10} + return fileDescriptor_f41247b323a1ab2e, []int{15} } func (m *DeleteShardsRequest) XXX_Unmarshal(b []byte) error { @@ -665,7 +1277,7 @@ func (m *DeleteShardsResponse) Reset() { *m = DeleteShardsResponse{} } func (m *DeleteShardsResponse) String() string { return proto.CompactTextString(m) } func (*DeleteShardsResponse) ProtoMessage() {} func (*DeleteShardsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{11} + return fileDescriptor_f41247b323a1ab2e, []int{16} } func (m *DeleteShardsResponse) XXX_Unmarshal(b []byte) error { @@ -701,7 +1313,7 @@ func (m *DeleteTabletsRequest) Reset() { *m = DeleteTabletsRequest{} } func (m *DeleteTabletsRequest) String() string { return proto.CompactTextString(m) } func (*DeleteTabletsRequest) ProtoMessage() {} func (*DeleteTabletsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{12} + return fileDescriptor_f41247b323a1ab2e, []int{17} } func (m *DeleteTabletsRequest) XXX_Unmarshal(b []byte) error { @@ -719,53 +1331,131 @@ func (m *DeleteTabletsRequest) XXX_Size() int { func (m *DeleteTabletsRequest) XXX_DiscardUnknown() { xxx_messageInfo_DeleteTabletsRequest.DiscardUnknown(m) } - -var xxx_messageInfo_DeleteTabletsRequest proto.InternalMessageInfo - -func (m *DeleteTabletsRequest) GetTabletAliases() []*topodata.TabletAlias { - if m != nil { - return m.TabletAliases - } - return nil + +var xxx_messageInfo_DeleteTabletsRequest proto.InternalMessageInfo + +func (m *DeleteTabletsRequest) GetTabletAliases() []*topodata.TabletAlias { + if m != nil { + return m.TabletAliases + } + return nil +} + +func (m *DeleteTabletsRequest) GetAllowPrimary() bool { + if m != nil { + return m.AllowPrimary + } + return false +} + +type DeleteTabletsResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteTabletsResponse) Reset() { *m = DeleteTabletsResponse{} } +func (m *DeleteTabletsResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteTabletsResponse) ProtoMessage() {} +func (*DeleteTabletsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{18} +} + +func (m *DeleteTabletsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteTabletsResponse.Unmarshal(m, b) +} +func (m *DeleteTabletsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteTabletsResponse.Marshal(b, m, deterministic) +} +func (m *DeleteTabletsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteTabletsResponse.Merge(m, src) +} +func (m *DeleteTabletsResponse) XXX_Size() int { + return xxx_messageInfo_DeleteTabletsResponse.Size(m) +} +func (m *DeleteTabletsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteTabletsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteTabletsResponse proto.InternalMessageInfo + +type FindAllShardsInKeyspaceRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInKeyspaceRequest{} } +func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } +func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} +func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{19} +} + +func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Unmarshal(m, b) +} +func (m *FindAllShardsInKeyspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Marshal(b, m, deterministic) +} +func (m *FindAllShardsInKeyspaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_FindAllShardsInKeyspaceRequest.Merge(m, src) +} +func (m *FindAllShardsInKeyspaceRequest) XXX_Size() int { + return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Size(m) +} +func (m *FindAllShardsInKeyspaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_FindAllShardsInKeyspaceRequest.DiscardUnknown(m) } -func (m *DeleteTabletsRequest) GetAllowPrimary() bool { +var xxx_messageInfo_FindAllShardsInKeyspaceRequest proto.InternalMessageInfo + +func (m *FindAllShardsInKeyspaceRequest) GetKeyspace() string { if m != nil { - return m.AllowPrimary + return m.Keyspace } - return false + return "" } -type DeleteTabletsResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +type FindAllShardsInKeyspaceResponse struct { + Shards map[string]*Shard `protobuf:"bytes,1,rep,name=shards,proto3" json:"shards,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *DeleteTabletsResponse) Reset() { *m = DeleteTabletsResponse{} } -func (m *DeleteTabletsResponse) String() string { return proto.CompactTextString(m) } -func (*DeleteTabletsResponse) ProtoMessage() {} -func (*DeleteTabletsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{13} +func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsInKeyspaceResponse{} } +func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } +func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} +func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{20} } -func (m *DeleteTabletsResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeleteTabletsResponse.Unmarshal(m, b) +func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Unmarshal(m, b) } -func (m *DeleteTabletsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeleteTabletsResponse.Marshal(b, m, deterministic) +func (m *FindAllShardsInKeyspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Marshal(b, m, deterministic) } -func (m *DeleteTabletsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeleteTabletsResponse.Merge(m, src) +func (m *FindAllShardsInKeyspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_FindAllShardsInKeyspaceResponse.Merge(m, src) } -func (m *DeleteTabletsResponse) XXX_Size() int { - return xxx_messageInfo_DeleteTabletsResponse.Size(m) +func (m *FindAllShardsInKeyspaceResponse) XXX_Size() int { + return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Size(m) } -func (m *DeleteTabletsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_DeleteTabletsResponse.DiscardUnknown(m) +func (m *FindAllShardsInKeyspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_FindAllShardsInKeyspaceResponse.DiscardUnknown(m) } -var xxx_messageInfo_DeleteTabletsResponse proto.InternalMessageInfo +var xxx_messageInfo_FindAllShardsInKeyspaceResponse proto.InternalMessageInfo + +func (m *FindAllShardsInKeyspaceResponse) GetShards() map[string]*Shard { + if m != nil { + return m.Shards + } + return nil +} type GetBackupsRequest struct { Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` @@ -779,7 +1469,7 @@ func (m *GetBackupsRequest) Reset() { *m = GetBackupsRequest{} } func (m *GetBackupsRequest) String() string { return proto.CompactTextString(m) } func (*GetBackupsRequest) ProtoMessage() {} func (*GetBackupsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{14} + return fileDescriptor_f41247b323a1ab2e, []int{21} } func (m *GetBackupsRequest) XXX_Unmarshal(b []byte) error { @@ -825,7 +1515,7 @@ func (m *GetBackupsResponse) Reset() { *m = GetBackupsResponse{} } func (m *GetBackupsResponse) String() string { return proto.CompactTextString(m) } func (*GetBackupsResponse) ProtoMessage() {} func (*GetBackupsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{15} + return fileDescriptor_f41247b323a1ab2e, []int{22} } func (m *GetBackupsResponse) XXX_Unmarshal(b []byte) error { @@ -863,7 +1553,7 @@ func (m *GetCellInfoNamesRequest) Reset() { *m = GetCellInfoNamesRequest func (m *GetCellInfoNamesRequest) String() string { return proto.CompactTextString(m) } func (*GetCellInfoNamesRequest) ProtoMessage() {} func (*GetCellInfoNamesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{16} + return fileDescriptor_f41247b323a1ab2e, []int{23} } func (m *GetCellInfoNamesRequest) XXX_Unmarshal(b []byte) error { @@ -895,7 +1585,7 @@ func (m *GetCellInfoNamesResponse) Reset() { *m = GetCellInfoNamesRespon func (m *GetCellInfoNamesResponse) String() string { return proto.CompactTextString(m) } func (*GetCellInfoNamesResponse) ProtoMessage() {} func (*GetCellInfoNamesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{17} + return fileDescriptor_f41247b323a1ab2e, []int{24} } func (m *GetCellInfoNamesResponse) XXX_Unmarshal(b []byte) error { @@ -934,7 +1624,7 @@ func (m *GetCellInfoRequest) Reset() { *m = GetCellInfoRequest{} } func (m *GetCellInfoRequest) String() string { return proto.CompactTextString(m) } func (*GetCellInfoRequest) ProtoMessage() {} func (*GetCellInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{18} + return fileDescriptor_f41247b323a1ab2e, []int{25} } func (m *GetCellInfoRequest) XXX_Unmarshal(b []byte) error { @@ -973,7 +1663,7 @@ func (m *GetCellInfoResponse) Reset() { *m = GetCellInfoResponse{} } func (m *GetCellInfoResponse) String() string { return proto.CompactTextString(m) } func (*GetCellInfoResponse) ProtoMessage() {} func (*GetCellInfoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{19} + return fileDescriptor_f41247b323a1ab2e, []int{26} } func (m *GetCellInfoResponse) XXX_Unmarshal(b []byte) error { @@ -1011,7 +1701,7 @@ func (m *GetCellsAliasesRequest) Reset() { *m = GetCellsAliasesRequest{} func (m *GetCellsAliasesRequest) String() string { return proto.CompactTextString(m) } func (*GetCellsAliasesRequest) ProtoMessage() {} func (*GetCellsAliasesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{20} + return fileDescriptor_f41247b323a1ab2e, []int{27} } func (m *GetCellsAliasesRequest) XXX_Unmarshal(b []byte) error { @@ -1043,7 +1733,7 @@ func (m *GetCellsAliasesResponse) Reset() { *m = GetCellsAliasesResponse func (m *GetCellsAliasesResponse) String() string { return proto.CompactTextString(m) } func (*GetCellsAliasesResponse) ProtoMessage() {} func (*GetCellsAliasesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{21} + return fileDescriptor_f41247b323a1ab2e, []int{28} } func (m *GetCellsAliasesResponse) XXX_Unmarshal(b []byte) error { @@ -1081,7 +1771,7 @@ func (m *GetKeyspacesRequest) Reset() { *m = GetKeyspacesRequest{} } func (m *GetKeyspacesRequest) String() string { return proto.CompactTextString(m) } func (*GetKeyspacesRequest) ProtoMessage() {} func (*GetKeyspacesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{22} + return fileDescriptor_f41247b323a1ab2e, []int{29} } func (m *GetKeyspacesRequest) XXX_Unmarshal(b []byte) error { @@ -1113,7 +1803,7 @@ func (m *GetKeyspacesResponse) Reset() { *m = GetKeyspacesResponse{} } func (m *GetKeyspacesResponse) String() string { return proto.CompactTextString(m) } func (*GetKeyspacesResponse) ProtoMessage() {} func (*GetKeyspacesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{23} + return fileDescriptor_f41247b323a1ab2e, []int{30} } func (m *GetKeyspacesResponse) XXX_Unmarshal(b []byte) error { @@ -1152,7 +1842,7 @@ func (m *GetKeyspaceRequest) Reset() { *m = GetKeyspaceRequest{} } func (m *GetKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*GetKeyspaceRequest) ProtoMessage() {} func (*GetKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{24} + return fileDescriptor_f41247b323a1ab2e, []int{31} } func (m *GetKeyspaceRequest) XXX_Unmarshal(b []byte) error { @@ -1191,7 +1881,7 @@ func (m *GetKeyspaceResponse) Reset() { *m = GetKeyspaceResponse{} } func (m *GetKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*GetKeyspaceResponse) ProtoMessage() {} func (*GetKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{25} + return fileDescriptor_f41247b323a1ab2e, []int{32} } func (m *GetKeyspaceResponse) XXX_Unmarshal(b []byte) error { @@ -1245,7 +1935,7 @@ func (m *GetSchemaRequest) Reset() { *m = GetSchemaRequest{} } func (m *GetSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetSchemaRequest) ProtoMessage() {} func (*GetSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{26} + return fileDescriptor_f41247b323a1ab2e, []int{33} } func (m *GetSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -1319,7 +2009,7 @@ func (m *GetSchemaResponse) Reset() { *m = GetSchemaResponse{} } func (m *GetSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetSchemaResponse) ProtoMessage() {} func (*GetSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{27} + return fileDescriptor_f41247b323a1ab2e, []int{34} } func (m *GetSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -1359,7 +2049,7 @@ func (m *GetShardRequest) Reset() { *m = GetShardRequest{} } func (m *GetShardRequest) String() string { return proto.CompactTextString(m) } func (*GetShardRequest) ProtoMessage() {} func (*GetShardRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{28} + return fileDescriptor_f41247b323a1ab2e, []int{35} } func (m *GetShardRequest) XXX_Unmarshal(b []byte) error { @@ -1405,7 +2095,7 @@ func (m *GetShardResponse) Reset() { *m = GetShardResponse{} } func (m *GetShardResponse) String() string { return proto.CompactTextString(m) } func (*GetShardResponse) ProtoMessage() {} func (*GetShardResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{29} + return fileDescriptor_f41247b323a1ab2e, []int{36} } func (m *GetShardResponse) XXX_Unmarshal(b []byte) error { @@ -1444,7 +2134,7 @@ func (m *GetSrvVSchemaRequest) Reset() { *m = GetSrvVSchemaRequest{} } func (m *GetSrvVSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetSrvVSchemaRequest) ProtoMessage() {} func (*GetSrvVSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{30} + return fileDescriptor_f41247b323a1ab2e, []int{37} } func (m *GetSrvVSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -1483,7 +2173,7 @@ func (m *GetSrvVSchemaResponse) Reset() { *m = GetSrvVSchemaResponse{} } func (m *GetSrvVSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetSrvVSchemaResponse) ProtoMessage() {} func (*GetSrvVSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{31} + return fileDescriptor_f41247b323a1ab2e, []int{38} } func (m *GetSrvVSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -1522,7 +2212,7 @@ func (m *GetTabletRequest) Reset() { *m = GetTabletRequest{} } func (m *GetTabletRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletRequest) ProtoMessage() {} func (*GetTabletRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{32} + return fileDescriptor_f41247b323a1ab2e, []int{39} } func (m *GetTabletRequest) XXX_Unmarshal(b []byte) error { @@ -1561,7 +2251,7 @@ func (m *GetTabletResponse) Reset() { *m = GetTabletResponse{} } func (m *GetTabletResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletResponse) ProtoMessage() {} func (*GetTabletResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{33} + return fileDescriptor_f41247b323a1ab2e, []int{40} } func (m *GetTabletResponse) XXX_Unmarshal(b []byte) error { @@ -1607,7 +2297,7 @@ func (m *GetTabletsRequest) Reset() { *m = GetTabletsRequest{} } func (m *GetTabletsRequest) String() string { return proto.CompactTextString(m) } func (*GetTabletsRequest) ProtoMessage() {} func (*GetTabletsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{34} + return fileDescriptor_f41247b323a1ab2e, []int{41} } func (m *GetTabletsRequest) XXX_Unmarshal(b []byte) error { @@ -1660,7 +2350,7 @@ func (m *GetTabletsResponse) Reset() { *m = GetTabletsResponse{} } func (m *GetTabletsResponse) String() string { return proto.CompactTextString(m) } func (*GetTabletsResponse) ProtoMessage() {} func (*GetTabletsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{35} + return fileDescriptor_f41247b323a1ab2e, []int{42} } func (m *GetTabletsResponse) XXX_Unmarshal(b []byte) error { @@ -1699,7 +2389,7 @@ func (m *GetVSchemaRequest) Reset() { *m = GetVSchemaRequest{} } func (m *GetVSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetVSchemaRequest) ProtoMessage() {} func (*GetVSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{36} + return fileDescriptor_f41247b323a1ab2e, []int{43} } func (m *GetVSchemaRequest) XXX_Unmarshal(b []byte) error { @@ -1738,7 +2428,7 @@ func (m *GetVSchemaResponse) Reset() { *m = GetVSchemaResponse{} } func (m *GetVSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetVSchemaResponse) ProtoMessage() {} func (*GetVSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{37} + return fileDescriptor_f41247b323a1ab2e, []int{44} } func (m *GetVSchemaResponse) XXX_Unmarshal(b []byte) error { @@ -1766,6 +2456,92 @@ func (m *GetVSchemaResponse) GetVSchema() *vschema.Keyspace { return nil } +type GetWorkflowsRequest struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + ActiveOnly bool `protobuf:"varint,2,opt,name=active_only,json=activeOnly,proto3" json:"active_only,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetWorkflowsRequest) Reset() { *m = GetWorkflowsRequest{} } +func (m *GetWorkflowsRequest) String() string { return proto.CompactTextString(m) } +func (*GetWorkflowsRequest) ProtoMessage() {} +func (*GetWorkflowsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{45} +} + +func (m *GetWorkflowsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetWorkflowsRequest.Unmarshal(m, b) +} +func (m *GetWorkflowsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetWorkflowsRequest.Marshal(b, m, deterministic) +} +func (m *GetWorkflowsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetWorkflowsRequest.Merge(m, src) +} +func (m *GetWorkflowsRequest) XXX_Size() int { + return xxx_messageInfo_GetWorkflowsRequest.Size(m) +} +func (m *GetWorkflowsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetWorkflowsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetWorkflowsRequest proto.InternalMessageInfo + +func (m *GetWorkflowsRequest) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *GetWorkflowsRequest) GetActiveOnly() bool { + if m != nil { + return m.ActiveOnly + } + return false +} + +type GetWorkflowsResponse struct { + Workflows []*Workflow `protobuf:"bytes,1,rep,name=workflows,proto3" json:"workflows,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetWorkflowsResponse) Reset() { *m = GetWorkflowsResponse{} } +func (m *GetWorkflowsResponse) String() string { return proto.CompactTextString(m) } +func (*GetWorkflowsResponse) ProtoMessage() {} +func (*GetWorkflowsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{46} +} + +func (m *GetWorkflowsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetWorkflowsResponse.Unmarshal(m, b) +} +func (m *GetWorkflowsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetWorkflowsResponse.Marshal(b, m, deterministic) +} +func (m *GetWorkflowsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetWorkflowsResponse.Merge(m, src) +} +func (m *GetWorkflowsResponse) XXX_Size() int { + return xxx_messageInfo_GetWorkflowsResponse.Size(m) +} +func (m *GetWorkflowsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetWorkflowsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetWorkflowsResponse proto.InternalMessageInfo + +func (m *GetWorkflowsResponse) GetWorkflows() []*Workflow { + if m != nil { + return m.Workflows + } + return nil +} + type RemoveKeyspaceCellRequest struct { Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` Cell string `protobuf:"bytes,2,opt,name=cell,proto3" json:"cell,omitempty"` @@ -1785,7 +2561,7 @@ func (m *RemoveKeyspaceCellRequest) Reset() { *m = RemoveKeyspaceCellReq func (m *RemoveKeyspaceCellRequest) String() string { return proto.CompactTextString(m) } func (*RemoveKeyspaceCellRequest) ProtoMessage() {} func (*RemoveKeyspaceCellRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{38} + return fileDescriptor_f41247b323a1ab2e, []int{47} } func (m *RemoveKeyspaceCellRequest) XXX_Unmarshal(b []byte) error { @@ -1844,7 +2620,7 @@ func (m *RemoveKeyspaceCellResponse) Reset() { *m = RemoveKeyspaceCellRe func (m *RemoveKeyspaceCellResponse) String() string { return proto.CompactTextString(m) } func (*RemoveKeyspaceCellResponse) ProtoMessage() {} func (*RemoveKeyspaceCellResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{39} + return fileDescriptor_f41247b323a1ab2e, []int{48} } func (m *RemoveKeyspaceCellResponse) XXX_Unmarshal(b []byte) error { @@ -1885,7 +2661,7 @@ func (m *RemoveShardCellRequest) Reset() { *m = RemoveShardCellRequest{} func (m *RemoveShardCellRequest) String() string { return proto.CompactTextString(m) } func (*RemoveShardCellRequest) ProtoMessage() {} func (*RemoveShardCellRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{40} + return fileDescriptor_f41247b323a1ab2e, []int{49} } func (m *RemoveShardCellRequest) XXX_Unmarshal(b []byte) error { @@ -1910,402 +2686,284 @@ func (m *RemoveShardCellRequest) GetKeyspace() string { if m != nil { return m.Keyspace } - return "" -} - -func (m *RemoveShardCellRequest) GetShardName() string { - if m != nil { - return m.ShardName - } - return "" -} - -func (m *RemoveShardCellRequest) GetCell() string { - if m != nil { - return m.Cell - } - return "" -} - -func (m *RemoveShardCellRequest) GetForce() bool { - if m != nil { - return m.Force - } - return false -} - -func (m *RemoveShardCellRequest) GetRecursive() bool { - if m != nil { - return m.Recursive - } - return false -} - -type RemoveShardCellResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *RemoveShardCellResponse) Reset() { *m = RemoveShardCellResponse{} } -func (m *RemoveShardCellResponse) String() string { return proto.CompactTextString(m) } -func (*RemoveShardCellResponse) ProtoMessage() {} -func (*RemoveShardCellResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{41} -} - -func (m *RemoveShardCellResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RemoveShardCellResponse.Unmarshal(m, b) -} -func (m *RemoveShardCellResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RemoveShardCellResponse.Marshal(b, m, deterministic) -} -func (m *RemoveShardCellResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RemoveShardCellResponse.Merge(m, src) -} -func (m *RemoveShardCellResponse) XXX_Size() int { - return xxx_messageInfo_RemoveShardCellResponse.Size(m) -} -func (m *RemoveShardCellResponse) XXX_DiscardUnknown() { - xxx_messageInfo_RemoveShardCellResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_RemoveShardCellResponse proto.InternalMessageInfo - -type Keyspace struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Keyspace *topodata.Keyspace `protobuf:"bytes,2,opt,name=keyspace,proto3" json:"keyspace,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Keyspace) Reset() { *m = Keyspace{} } -func (m *Keyspace) String() string { return proto.CompactTextString(m) } -func (*Keyspace) ProtoMessage() {} -func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{42} -} - -func (m *Keyspace) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Keyspace.Unmarshal(m, b) -} -func (m *Keyspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Keyspace.Marshal(b, m, deterministic) -} -func (m *Keyspace) XXX_Merge(src proto.Message) { - xxx_messageInfo_Keyspace.Merge(m, src) -} -func (m *Keyspace) XXX_Size() int { - return xxx_messageInfo_Keyspace.Size(m) -} -func (m *Keyspace) XXX_DiscardUnknown() { - xxx_messageInfo_Keyspace.DiscardUnknown(m) + return "" } -var xxx_messageInfo_Keyspace proto.InternalMessageInfo +func (m *RemoveShardCellRequest) GetShardName() string { + if m != nil { + return m.ShardName + } + return "" +} -func (m *Keyspace) GetName() string { +func (m *RemoveShardCellRequest) GetCell() string { if m != nil { - return m.Name + return m.Cell } return "" } -func (m *Keyspace) GetKeyspace() *topodata.Keyspace { +func (m *RemoveShardCellRequest) GetForce() bool { if m != nil { - return m.Keyspace + return m.Force } - return nil + return false } -type FindAllShardsInKeyspaceRequest struct { - Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` +func (m *RemoveShardCellRequest) GetRecursive() bool { + if m != nil { + return m.Recursive + } + return false +} + +type RemoveShardCellResponse struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } -func (m *FindAllShardsInKeyspaceRequest) Reset() { *m = FindAllShardsInKeyspaceRequest{} } -func (m *FindAllShardsInKeyspaceRequest) String() string { return proto.CompactTextString(m) } -func (*FindAllShardsInKeyspaceRequest) ProtoMessage() {} -func (*FindAllShardsInKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{43} +func (m *RemoveShardCellResponse) Reset() { *m = RemoveShardCellResponse{} } +func (m *RemoveShardCellResponse) String() string { return proto.CompactTextString(m) } +func (*RemoveShardCellResponse) ProtoMessage() {} +func (*RemoveShardCellResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{50} } -func (m *FindAllShardsInKeyspaceRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Unmarshal(m, b) +func (m *RemoveShardCellResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RemoveShardCellResponse.Unmarshal(m, b) } -func (m *FindAllShardsInKeyspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Marshal(b, m, deterministic) +func (m *RemoveShardCellResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RemoveShardCellResponse.Marshal(b, m, deterministic) } -func (m *FindAllShardsInKeyspaceRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_FindAllShardsInKeyspaceRequest.Merge(m, src) +func (m *RemoveShardCellResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RemoveShardCellResponse.Merge(m, src) } -func (m *FindAllShardsInKeyspaceRequest) XXX_Size() int { - return xxx_messageInfo_FindAllShardsInKeyspaceRequest.Size(m) +func (m *RemoveShardCellResponse) XXX_Size() int { + return xxx_messageInfo_RemoveShardCellResponse.Size(m) } -func (m *FindAllShardsInKeyspaceRequest) XXX_DiscardUnknown() { - xxx_messageInfo_FindAllShardsInKeyspaceRequest.DiscardUnknown(m) +func (m *RemoveShardCellResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RemoveShardCellResponse.DiscardUnknown(m) } -var xxx_messageInfo_FindAllShardsInKeyspaceRequest proto.InternalMessageInfo - -func (m *FindAllShardsInKeyspaceRequest) GetKeyspace() string { - if m != nil { - return m.Keyspace - } - return "" -} +var xxx_messageInfo_RemoveShardCellResponse proto.InternalMessageInfo -type FindAllShardsInKeyspaceResponse struct { - Shards map[string]*Shard `protobuf:"bytes,1,rep,name=shards,proto3" json:"shards,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +type ReparentTabletRequest struct { + // Tablet is the alias of the tablet that should be reparented under the + // current shard primary. + Tablet *topodata.TabletAlias `protobuf:"bytes,1,opt,name=tablet,proto3" json:"tablet,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *FindAllShardsInKeyspaceResponse) Reset() { *m = FindAllShardsInKeyspaceResponse{} } -func (m *FindAllShardsInKeyspaceResponse) String() string { return proto.CompactTextString(m) } -func (*FindAllShardsInKeyspaceResponse) ProtoMessage() {} -func (*FindAllShardsInKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{44} +func (m *ReparentTabletRequest) Reset() { *m = ReparentTabletRequest{} } +func (m *ReparentTabletRequest) String() string { return proto.CompactTextString(m) } +func (*ReparentTabletRequest) ProtoMessage() {} +func (*ReparentTabletRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{51} } -func (m *FindAllShardsInKeyspaceResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Unmarshal(m, b) +func (m *ReparentTabletRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ReparentTabletRequest.Unmarshal(m, b) } -func (m *FindAllShardsInKeyspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Marshal(b, m, deterministic) +func (m *ReparentTabletRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ReparentTabletRequest.Marshal(b, m, deterministic) } -func (m *FindAllShardsInKeyspaceResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_FindAllShardsInKeyspaceResponse.Merge(m, src) +func (m *ReparentTabletRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReparentTabletRequest.Merge(m, src) } -func (m *FindAllShardsInKeyspaceResponse) XXX_Size() int { - return xxx_messageInfo_FindAllShardsInKeyspaceResponse.Size(m) +func (m *ReparentTabletRequest) XXX_Size() int { + return xxx_messageInfo_ReparentTabletRequest.Size(m) } -func (m *FindAllShardsInKeyspaceResponse) XXX_DiscardUnknown() { - xxx_messageInfo_FindAllShardsInKeyspaceResponse.DiscardUnknown(m) +func (m *ReparentTabletRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ReparentTabletRequest.DiscardUnknown(m) } -var xxx_messageInfo_FindAllShardsInKeyspaceResponse proto.InternalMessageInfo +var xxx_messageInfo_ReparentTabletRequest proto.InternalMessageInfo -func (m *FindAllShardsInKeyspaceResponse) GetShards() map[string]*Shard { +func (m *ReparentTabletRequest) GetTablet() *topodata.TabletAlias { if m != nil { - return m.Shards + return m.Tablet } return nil } -type Shard struct { - Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Shard *topodata.Shard `protobuf:"bytes,3,opt,name=shard,proto3" json:"shard,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +type ReparentTabletResponse struct { + // Keyspace is the name of the keyspace the tablet was reparented in. + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + // Shard is the name of the shard the tablet was reparented in. + Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` + // Primary is the alias of the tablet that the tablet was reparented under. + Primary *topodata.TabletAlias `protobuf:"bytes,3,opt,name=primary,proto3" json:"primary,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *Shard) Reset() { *m = Shard{} } -func (m *Shard) String() string { return proto.CompactTextString(m) } -func (*Shard) ProtoMessage() {} -func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{45} +func (m *ReparentTabletResponse) Reset() { *m = ReparentTabletResponse{} } +func (m *ReparentTabletResponse) String() string { return proto.CompactTextString(m) } +func (*ReparentTabletResponse) ProtoMessage() {} +func (*ReparentTabletResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{52} } -func (m *Shard) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Shard.Unmarshal(m, b) +func (m *ReparentTabletResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ReparentTabletResponse.Unmarshal(m, b) } -func (m *Shard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Shard.Marshal(b, m, deterministic) +func (m *ReparentTabletResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ReparentTabletResponse.Marshal(b, m, deterministic) } -func (m *Shard) XXX_Merge(src proto.Message) { - xxx_messageInfo_Shard.Merge(m, src) +func (m *ReparentTabletResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReparentTabletResponse.Merge(m, src) } -func (m *Shard) XXX_Size() int { - return xxx_messageInfo_Shard.Size(m) +func (m *ReparentTabletResponse) XXX_Size() int { + return xxx_messageInfo_ReparentTabletResponse.Size(m) } -func (m *Shard) XXX_DiscardUnknown() { - xxx_messageInfo_Shard.DiscardUnknown(m) +func (m *ReparentTabletResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ReparentTabletResponse.DiscardUnknown(m) } -var xxx_messageInfo_Shard proto.InternalMessageInfo +var xxx_messageInfo_ReparentTabletResponse proto.InternalMessageInfo -func (m *Shard) GetKeyspace() string { +func (m *ReparentTabletResponse) GetKeyspace() string { if m != nil { return m.Keyspace } return "" } -func (m *Shard) GetName() string { +func (m *ReparentTabletResponse) GetShard() string { if m != nil { - return m.Name + return m.Shard } return "" } -func (m *Shard) GetShard() *topodata.Shard { +func (m *ReparentTabletResponse) GetPrimary() *topodata.TabletAlias { if m != nil { - return m.Shard + return m.Primary } return nil } -// TableMaterializeSttings contains the settings for one table. -type TableMaterializeSettings struct { - TargetTable string `protobuf:"bytes,1,opt,name=target_table,json=targetTable,proto3" json:"target_table,omitempty"` - // source_expression is a select statement. - SourceExpression string `protobuf:"bytes,2,opt,name=source_expression,json=sourceExpression,proto3" json:"source_expression,omitempty"` - // create_ddl contains the DDL to create the target table. - // If empty, the target table must already exist. - // if "copy", the target table DDL is the same as the source table. - CreateDdl string `protobuf:"bytes,3,opt,name=create_ddl,json=createDdl,proto3" json:"create_ddl,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +type TabletExternallyReparentedRequest struct { + // Tablet is the alias of the tablet that was promoted externally and should + // be updated to the shard primary in the topo. + Tablet *topodata.TabletAlias `protobuf:"bytes,1,opt,name=tablet,proto3" json:"tablet,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *TableMaterializeSettings) Reset() { *m = TableMaterializeSettings{} } -func (m *TableMaterializeSettings) String() string { return proto.CompactTextString(m) } -func (*TableMaterializeSettings) ProtoMessage() {} -func (*TableMaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{46} +func (m *TabletExternallyReparentedRequest) Reset() { *m = TabletExternallyReparentedRequest{} } +func (m *TabletExternallyReparentedRequest) String() string { return proto.CompactTextString(m) } +func (*TabletExternallyReparentedRequest) ProtoMessage() {} +func (*TabletExternallyReparentedRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{53} } -func (m *TableMaterializeSettings) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TableMaterializeSettings.Unmarshal(m, b) -} -func (m *TableMaterializeSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TableMaterializeSettings.Marshal(b, m, deterministic) +func (m *TabletExternallyReparentedRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TabletExternallyReparentedRequest.Unmarshal(m, b) } -func (m *TableMaterializeSettings) XXX_Merge(src proto.Message) { - xxx_messageInfo_TableMaterializeSettings.Merge(m, src) +func (m *TabletExternallyReparentedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TabletExternallyReparentedRequest.Marshal(b, m, deterministic) } -func (m *TableMaterializeSettings) XXX_Size() int { - return xxx_messageInfo_TableMaterializeSettings.Size(m) +func (m *TabletExternallyReparentedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TabletExternallyReparentedRequest.Merge(m, src) } -func (m *TableMaterializeSettings) XXX_DiscardUnknown() { - xxx_messageInfo_TableMaterializeSettings.DiscardUnknown(m) +func (m *TabletExternallyReparentedRequest) XXX_Size() int { + return xxx_messageInfo_TabletExternallyReparentedRequest.Size(m) } - -var xxx_messageInfo_TableMaterializeSettings proto.InternalMessageInfo - -func (m *TableMaterializeSettings) GetTargetTable() string { - if m != nil { - return m.TargetTable - } - return "" +func (m *TabletExternallyReparentedRequest) XXX_DiscardUnknown() { + xxx_messageInfo_TabletExternallyReparentedRequest.DiscardUnknown(m) } -func (m *TableMaterializeSettings) GetSourceExpression() string { - if m != nil { - return m.SourceExpression - } - return "" -} +var xxx_messageInfo_TabletExternallyReparentedRequest proto.InternalMessageInfo -func (m *TableMaterializeSettings) GetCreateDdl() string { +func (m *TabletExternallyReparentedRequest) GetTablet() *topodata.TabletAlias { if m != nil { - return m.CreateDdl + return m.Tablet } - return "" + return nil } -// MaterializeSettings contains the settings for the Materialize command. -type MaterializeSettings struct { - // workflow is the name of the workflow. - Workflow string `protobuf:"bytes,1,opt,name=workflow,proto3" json:"workflow,omitempty"` - SourceKeyspace string `protobuf:"bytes,2,opt,name=source_keyspace,json=sourceKeyspace,proto3" json:"source_keyspace,omitempty"` - TargetKeyspace string `protobuf:"bytes,3,opt,name=target_keyspace,json=targetKeyspace,proto3" json:"target_keyspace,omitempty"` - // stop_after_copy specifies if vreplication should be stopped after copying. - StopAfterCopy bool `protobuf:"varint,4,opt,name=stop_after_copy,json=stopAfterCopy,proto3" json:"stop_after_copy,omitempty"` - TableSettings []*TableMaterializeSettings `protobuf:"bytes,5,rep,name=table_settings,json=tableSettings,proto3" json:"table_settings,omitempty"` - // optional parameters. - Cell string `protobuf:"bytes,6,opt,name=cell,proto3" json:"cell,omitempty"` - TabletTypes string `protobuf:"bytes,7,opt,name=tablet_types,json=tabletTypes,proto3" json:"tablet_types,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +type TabletExternallyReparentedResponse struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` + NewPrimary *topodata.TabletAlias `protobuf:"bytes,3,opt,name=new_primary,json=newPrimary,proto3" json:"new_primary,omitempty"` + OldPrimary *topodata.TabletAlias `protobuf:"bytes,4,opt,name=old_primary,json=oldPrimary,proto3" json:"old_primary,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *MaterializeSettings) Reset() { *m = MaterializeSettings{} } -func (m *MaterializeSettings) String() string { return proto.CompactTextString(m) } -func (*MaterializeSettings) ProtoMessage() {} -func (*MaterializeSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_f41247b323a1ab2e, []int{47} +func (m *TabletExternallyReparentedResponse) Reset() { *m = TabletExternallyReparentedResponse{} } +func (m *TabletExternallyReparentedResponse) String() string { return proto.CompactTextString(m) } +func (*TabletExternallyReparentedResponse) ProtoMessage() {} +func (*TabletExternallyReparentedResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f41247b323a1ab2e, []int{54} } -func (m *MaterializeSettings) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_MaterializeSettings.Unmarshal(m, b) +func (m *TabletExternallyReparentedResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TabletExternallyReparentedResponse.Unmarshal(m, b) } -func (m *MaterializeSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_MaterializeSettings.Marshal(b, m, deterministic) +func (m *TabletExternallyReparentedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TabletExternallyReparentedResponse.Marshal(b, m, deterministic) } -func (m *MaterializeSettings) XXX_Merge(src proto.Message) { - xxx_messageInfo_MaterializeSettings.Merge(m, src) +func (m *TabletExternallyReparentedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TabletExternallyReparentedResponse.Merge(m, src) } -func (m *MaterializeSettings) XXX_Size() int { - return xxx_messageInfo_MaterializeSettings.Size(m) +func (m *TabletExternallyReparentedResponse) XXX_Size() int { + return xxx_messageInfo_TabletExternallyReparentedResponse.Size(m) } -func (m *MaterializeSettings) XXX_DiscardUnknown() { - xxx_messageInfo_MaterializeSettings.DiscardUnknown(m) +func (m *TabletExternallyReparentedResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TabletExternallyReparentedResponse.DiscardUnknown(m) } -var xxx_messageInfo_MaterializeSettings proto.InternalMessageInfo - -func (m *MaterializeSettings) GetWorkflow() string { - if m != nil { - return m.Workflow - } - return "" -} +var xxx_messageInfo_TabletExternallyReparentedResponse proto.InternalMessageInfo -func (m *MaterializeSettings) GetSourceKeyspace() string { +func (m *TabletExternallyReparentedResponse) GetKeyspace() string { if m != nil { - return m.SourceKeyspace + return m.Keyspace } return "" } -func (m *MaterializeSettings) GetTargetKeyspace() string { +func (m *TabletExternallyReparentedResponse) GetShard() string { if m != nil { - return m.TargetKeyspace + return m.Shard } return "" } -func (m *MaterializeSettings) GetStopAfterCopy() bool { - if m != nil { - return m.StopAfterCopy - } - return false -} - -func (m *MaterializeSettings) GetTableSettings() []*TableMaterializeSettings { +func (m *TabletExternallyReparentedResponse) GetNewPrimary() *topodata.TabletAlias { if m != nil { - return m.TableSettings + return m.NewPrimary } return nil } -func (m *MaterializeSettings) GetCell() string { - if m != nil { - return m.Cell - } - return "" -} - -func (m *MaterializeSettings) GetTabletTypes() string { +func (m *TabletExternallyReparentedResponse) GetOldPrimary() *topodata.TabletAlias { if m != nil { - return m.TabletTypes + return m.OldPrimary } - return "" + return nil } func init() { proto.RegisterType((*ExecuteVtctlCommandRequest)(nil), "vtctldata.ExecuteVtctlCommandRequest") proto.RegisterType((*ExecuteVtctlCommandResponse)(nil), "vtctldata.ExecuteVtctlCommandResponse") + proto.RegisterType((*TableMaterializeSettings)(nil), "vtctldata.TableMaterializeSettings") + proto.RegisterType((*MaterializeSettings)(nil), "vtctldata.MaterializeSettings") + proto.RegisterType((*Keyspace)(nil), "vtctldata.Keyspace") + proto.RegisterType((*Shard)(nil), "vtctldata.Shard") + proto.RegisterType((*Workflow)(nil), "vtctldata.Workflow") + proto.RegisterMapType((map[string]*Workflow_ShardStream)(nil), "vtctldata.Workflow.ShardStreamsEntry") + proto.RegisterType((*Workflow_ReplicationLocation)(nil), "vtctldata.Workflow.ReplicationLocation") + proto.RegisterType((*Workflow_ShardStream)(nil), "vtctldata.Workflow.ShardStream") + proto.RegisterType((*Workflow_Stream)(nil), "vtctldata.Workflow.Stream") + proto.RegisterType((*Workflow_Stream_CopyState)(nil), "vtctldata.Workflow.Stream.CopyState") proto.RegisterType((*ChangeTabletTypeRequest)(nil), "vtctldata.ChangeTabletTypeRequest") proto.RegisterType((*ChangeTabletTypeResponse)(nil), "vtctldata.ChangeTabletTypeResponse") proto.RegisterType((*CreateKeyspaceRequest)(nil), "vtctldata.CreateKeyspaceRequest") @@ -2318,6 +2976,9 @@ func init() { proto.RegisterType((*DeleteShardsResponse)(nil), "vtctldata.DeleteShardsResponse") proto.RegisterType((*DeleteTabletsRequest)(nil), "vtctldata.DeleteTabletsRequest") proto.RegisterType((*DeleteTabletsResponse)(nil), "vtctldata.DeleteTabletsResponse") + proto.RegisterType((*FindAllShardsInKeyspaceRequest)(nil), "vtctldata.FindAllShardsInKeyspaceRequest") + proto.RegisterType((*FindAllShardsInKeyspaceResponse)(nil), "vtctldata.FindAllShardsInKeyspaceResponse") + proto.RegisterMapType((map[string]*Shard)(nil), "vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry") proto.RegisterType((*GetBackupsRequest)(nil), "vtctldata.GetBackupsRequest") proto.RegisterType((*GetBackupsResponse)(nil), "vtctldata.GetBackupsResponse") proto.RegisterType((*GetCellInfoNamesRequest)(nil), "vtctldata.GetCellInfoNamesRequest") @@ -2343,128 +3004,164 @@ func init() { proto.RegisterType((*GetTabletsResponse)(nil), "vtctldata.GetTabletsResponse") proto.RegisterType((*GetVSchemaRequest)(nil), "vtctldata.GetVSchemaRequest") proto.RegisterType((*GetVSchemaResponse)(nil), "vtctldata.GetVSchemaResponse") + proto.RegisterType((*GetWorkflowsRequest)(nil), "vtctldata.GetWorkflowsRequest") + proto.RegisterType((*GetWorkflowsResponse)(nil), "vtctldata.GetWorkflowsResponse") proto.RegisterType((*RemoveKeyspaceCellRequest)(nil), "vtctldata.RemoveKeyspaceCellRequest") proto.RegisterType((*RemoveKeyspaceCellResponse)(nil), "vtctldata.RemoveKeyspaceCellResponse") proto.RegisterType((*RemoveShardCellRequest)(nil), "vtctldata.RemoveShardCellRequest") proto.RegisterType((*RemoveShardCellResponse)(nil), "vtctldata.RemoveShardCellResponse") - proto.RegisterType((*Keyspace)(nil), "vtctldata.Keyspace") - proto.RegisterType((*FindAllShardsInKeyspaceRequest)(nil), "vtctldata.FindAllShardsInKeyspaceRequest") - proto.RegisterType((*FindAllShardsInKeyspaceResponse)(nil), "vtctldata.FindAllShardsInKeyspaceResponse") - proto.RegisterMapType((map[string]*Shard)(nil), "vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry") - proto.RegisterType((*Shard)(nil), "vtctldata.Shard") - proto.RegisterType((*TableMaterializeSettings)(nil), "vtctldata.TableMaterializeSettings") - proto.RegisterType((*MaterializeSettings)(nil), "vtctldata.MaterializeSettings") + proto.RegisterType((*ReparentTabletRequest)(nil), "vtctldata.ReparentTabletRequest") + proto.RegisterType((*ReparentTabletResponse)(nil), "vtctldata.ReparentTabletResponse") + proto.RegisterType((*TabletExternallyReparentedRequest)(nil), "vtctldata.TabletExternallyReparentedRequest") + proto.RegisterType((*TabletExternallyReparentedResponse)(nil), "vtctldata.TabletExternallyReparentedResponse") } func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } var fileDescriptor_f41247b323a1ab2e = []byte{ - // 1708 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4b, 0x6f, 0xdb, 0x56, - 0x16, 0x06, 0x25, 0x4b, 0x96, 0x8e, 0x1e, 0xb6, 0x69, 0xd9, 0x56, 0x34, 0x49, 0xc6, 0xa1, 0x27, - 0x8e, 0xe0, 0x99, 0x91, 0xf2, 0xc0, 0x0c, 0x82, 0x4c, 0x06, 0x88, 0x63, 0x3b, 0x81, 0xe3, 0x8c, - 0xc7, 0xa5, 0x0d, 0x17, 0x68, 0x81, 0x12, 0x34, 0x75, 0x25, 0x13, 0xa6, 0x48, 0x86, 0xf7, 0x8a, - 0x36, 0xb3, 0xe9, 0xa6, 0x5d, 0x14, 0xe8, 0x3f, 0xc8, 0xa6, 0xab, 0x2e, 0xbb, 0xcc, 0xb2, 0xbf, - 0xad, 0xb8, 0x2f, 0x92, 0xa2, 0x24, 0xe7, 0xd5, 0x95, 0x79, 0xcf, 0xe3, 0x9e, 0xef, 0xdc, 0xf3, - 0x94, 0x61, 0x21, 0x24, 0x16, 0x71, 0x7a, 0x26, 0x31, 0x3b, 0x7e, 0xe0, 0x11, 0x4f, 0x2d, 0xc7, - 0x84, 0x56, 0xcd, 0xf1, 0x06, 0x23, 0x62, 0x3b, 0x9c, 0xd3, 0xaa, 0x0f, 0x23, 0xfc, 0xc6, 0xb1, - 0x88, 0x3c, 0xaf, 0x11, 0xf3, 0xcc, 0x41, 0x64, 0x68, 0xba, 0xe6, 0x00, 0x05, 0xc9, 0x15, 0xad, - 0x3a, 0xf1, 0x7c, 0x2f, 0x75, 0xae, 0x85, 0xd8, 0x3a, 0x47, 0x43, 0x79, 0xac, 0x86, 0x84, 0xd8, - 0x43, 0xc4, 0x4f, 0xda, 0xd7, 0xd0, 0xda, 0xbb, 0x42, 0xd6, 0x88, 0xa0, 0x53, 0x6a, 0x78, 0xc7, - 0x1b, 0x0e, 0x4d, 0xb7, 0xa7, 0xa3, 0x37, 0x23, 0x84, 0x89, 0xaa, 0xc2, 0x9c, 0x19, 0x0c, 0x70, - 0x53, 0x59, 0xcf, 0xb7, 0xcb, 0x3a, 0xfb, 0x56, 0xef, 0x42, 0xdd, 0xb4, 0x88, 0xed, 0xb9, 0x06, - 0xbd, 0xc6, 0x1b, 0x91, 0x66, 0x6e, 0x5d, 0x69, 0xe7, 0xf5, 0x1a, 0xa7, 0x9e, 0x70, 0xa2, 0xb6, - 0x03, 0x7f, 0x99, 0x7a, 0x31, 0xf6, 0x3d, 0x17, 0x23, 0xf5, 0x6f, 0x50, 0x40, 0x21, 0x72, 0x49, - 0x53, 0x59, 0x57, 0xda, 0x95, 0x87, 0xf5, 0x8e, 0x74, 0x76, 0x8f, 0x52, 0x75, 0xce, 0xd4, 0xde, - 0x29, 0xb0, 0xb6, 0x73, 0x6e, 0xba, 0x03, 0x74, 0xc2, 0x9c, 0x3d, 0x89, 0x7c, 0x24, 0xb1, 0x3d, - 0x86, 0x2a, 0x7f, 0x01, 0xc3, 0x74, 0x6c, 0x13, 0x8b, 0x8b, 0x56, 0x3a, 0xb1, 0xf7, 0x5c, 0x65, - 0x9b, 0x32, 0xf5, 0x0a, 0x49, 0x0e, 0xea, 0x3f, 0x61, 0xbe, 0x77, 0x66, 0x90, 0xc8, 0x47, 0x0c, - 0x7a, 0xfd, 0x61, 0x23, 0xab, 0xc4, 0xec, 0x14, 0x7b, 0x67, 0xf4, 0xaf, 0xba, 0x06, 0xf3, 0xbd, - 0x20, 0x32, 0x82, 0x91, 0xdb, 0xcc, 0xaf, 0x2b, 0xed, 0x92, 0x5e, 0xec, 0x05, 0x91, 0x3e, 0x72, - 0xb5, 0x5f, 0x15, 0x68, 0x4e, 0xa2, 0x13, 0x0e, 0xfe, 0x0b, 0x6a, 0x67, 0xa8, 0xef, 0x05, 0xc8, - 0xe0, 0xa6, 0x05, 0xbe, 0xc5, 0xac, 0x29, 0xbd, 0xca, 0xc5, 0xf8, 0x49, 0x7d, 0x04, 0x55, 0xb3, - 0x4f, 0x50, 0x20, 0xb5, 0x72, 0x33, 0xb4, 0x2a, 0x4c, 0x4a, 0x28, 0xdd, 0x86, 0xca, 0xa5, 0x89, - 0x8d, 0x71, 0x94, 0xe5, 0x4b, 0x13, 0xef, 0x72, 0xa0, 0xef, 0xf3, 0xb0, 0xb2, 0x13, 0x20, 0x93, - 0xa0, 0x03, 0x14, 0x61, 0xdf, 0xb4, 0x50, 0x2a, 0xc0, 0xae, 0x39, 0x44, 0x0c, 0x5c, 0x59, 0x67, - 0xdf, 0x6a, 0x03, 0x0a, 0x7d, 0x2f, 0xb0, 0xf8, 0xe3, 0x94, 0x74, 0x7e, 0x50, 0xbb, 0xd0, 0x30, - 0x1d, 0xc7, 0xbb, 0x34, 0xd0, 0xd0, 0x27, 0x91, 0x11, 0x1a, 0x3c, 0xa9, 0x84, 0xb1, 0x25, 0xc6, - 0xdb, 0xa3, 0xac, 0xd3, 0x63, 0xc6, 0x50, 0xef, 0x43, 0x03, 0x9f, 0x9b, 0x41, 0xcf, 0x76, 0x07, - 0x86, 0xe5, 0x39, 0xa3, 0xa1, 0x6b, 0x30, 0x53, 0x73, 0xcc, 0x94, 0x2a, 0x79, 0x3b, 0x8c, 0x75, - 0x48, 0x0d, 0xbf, 0x9a, 0xd4, 0x60, 0x41, 0x2a, 0xb0, 0x20, 0x35, 0x93, 0x37, 0x90, 0x5e, 0xec, - 0xf7, 0xd8, 0x93, 0x67, 0xee, 0x62, 0x41, 0x7b, 0x06, 0x55, 0x8c, 0x82, 0x10, 0xf5, 0x8c, 0x7e, - 0xe0, 0x0d, 0x71, 0xb3, 0xb8, 0x9e, 0x6f, 0x57, 0x1e, 0xde, 0x9a, 0xbc, 0xa3, 0x73, 0xcc, 0xc4, - 0x5e, 0x04, 0xde, 0x50, 0xaf, 0xe0, 0xf8, 0x1b, 0xab, 0x5b, 0x30, 0xc7, 0xac, 0xcf, 0x33, 0xeb, - 0xab, 0x93, 0x9a, 0xcc, 0x36, 0x93, 0x51, 0x37, 0xa0, 0x76, 0x66, 0x62, 0x64, 0x5c, 0x08, 0x56, - 0xb3, 0xc4, 0x9c, 0xac, 0x52, 0xa2, 0x14, 0x57, 0x1f, 0x40, 0x0d, 0xbb, 0xa6, 0x8f, 0xcf, 0x3d, - 0xc2, 0x4a, 0xa7, 0x59, 0x66, 0xb1, 0xad, 0x76, 0x44, 0x41, 0xd2, 0xca, 0xd1, 0xab, 0x52, 0x84, - 0x9e, 0xb4, 0x7d, 0x58, 0xcd, 0xc6, 0x4d, 0xa4, 0x57, 0x17, 0x4a, 0xb1, 0x31, 0x9e, 0x59, 0xcb, - 0x9d, 0xa4, 0x97, 0xc4, 0xe2, 0xb1, 0x90, 0xf6, 0xb3, 0x02, 0x2a, 0xbf, 0xeb, 0x98, 0xbe, 0x96, - 0x4c, 0x80, 0x56, 0xe6, 0x9e, 0x72, 0xa2, 0xa2, 0xde, 0x02, 0x60, 0x2f, 0xcb, 0xe3, 0x96, 0x63, - 0xdc, 0x32, 0xa3, 0x1c, 0x8e, 0xe5, 0x49, 0x3e, 0x9d, 0x27, 0x77, 0xa1, 0x6e, 0xbb, 0x96, 0x33, - 0xea, 0x21, 0xc3, 0x37, 0x03, 0x5a, 0xe1, 0x73, 0x8c, 0x5d, 0x13, 0xd4, 0x23, 0x46, 0xd4, 0x7e, - 0x51, 0x60, 0x79, 0x0c, 0xce, 0x67, 0xfa, 0xa5, 0x6e, 0x42, 0x81, 0x41, 0x8a, 0x2b, 0x25, 0x91, - 0xe6, 0x37, 0x73, 0x76, 0x9c, 0x8e, 0x86, 0xe9, 0x04, 0xc8, 0xec, 0x45, 0x06, 0xba, 0xb2, 0x31, - 0xc1, 0x02, 0x3c, 0x4f, 0xa1, 0x6d, 0xce, 0xda, 0x63, 0x1c, 0xed, 0x2b, 0x58, 0xd9, 0x45, 0x0e, - 0x9a, 0x2c, 0x9a, 0xeb, 0xde, 0xec, 0x26, 0x94, 0x03, 0x64, 0x8d, 0x02, 0x6c, 0x87, 0xb2, 0x80, - 0x12, 0x82, 0xd6, 0x84, 0xd5, 0xec, 0x95, 0xdc, 0x6f, 0xed, 0x47, 0x05, 0x96, 0x39, 0x8b, 0xa1, - 0xc6, 0xd2, 0x56, 0x1b, 0x8a, 0x0c, 0x1a, 0xef, 0xc1, 0xd3, 0xfc, 0x13, 0xfc, 0xeb, 0x2d, 0xab, - 0x9b, 0xb0, 0x40, 0x5b, 0xaa, 0x61, 0xf7, 0x0d, 0x9a, 0xe4, 0xb6, 0x3b, 0x90, 0x71, 0xa1, 0xe4, - 0xfd, 0xfe, 0x31, 0x27, 0x6a, 0xab, 0xd0, 0x18, 0x87, 0x21, 0xf0, 0x45, 0x92, 0xce, 0x5b, 0x4e, - 0x8c, 0xef, 0x29, 0xd4, 0xd3, 0x5d, 0x18, 0x49, 0x9c, 0x33, 0xfa, 0x70, 0x2d, 0xd5, 0x87, 0x11, - 0xa6, 0x75, 0xc3, 0x9b, 0x8a, 0x1f, 0xd8, 0x43, 0x33, 0x88, 0x04, 0xee, 0x2a, 0x23, 0x1e, 0x71, - 0x9a, 0xb6, 0x26, 0xe3, 0x10, 0x9b, 0x16, 0x98, 0xf6, 0x60, 0xe9, 0x25, 0x22, 0xcf, 0x4d, 0xeb, - 0x62, 0xe4, 0xe3, 0x8f, 0x09, 0x4e, 0x23, 0x9d, 0x2b, 0x65, 0x91, 0x19, 0xda, 0x2e, 0xa8, 0xe9, - 0x6b, 0x44, 0x22, 0x76, 0x60, 0xfe, 0x8c, 0x93, 0x84, 0x47, 0x8d, 0x4e, 0x3c, 0x80, 0xb9, 0xec, - 0xbe, 0xdb, 0xf7, 0x74, 0x29, 0xa4, 0xdd, 0x80, 0xb5, 0x97, 0x88, 0xec, 0x20, 0xc7, 0xa1, 0x74, - 0x5a, 0x20, 0x12, 0x92, 0x76, 0x1f, 0x9a, 0x93, 0x2c, 0x61, 0xa6, 0x01, 0x05, 0x5a, 0x5d, 0x72, - 0xc4, 0xf2, 0x83, 0xd6, 0x66, 0x90, 0xa4, 0x46, 0xaa, 0x59, 0x5b, 0xc8, 0x71, 0x64, 0xb3, 0xa6, - 0xdf, 0xda, 0x0b, 0x58, 0x1e, 0x93, 0x8c, 0xcb, 0xa8, 0x4c, 0xd9, 0x86, 0xed, 0xf6, 0x3d, 0x51, - 0x47, 0x6a, 0x12, 0x91, 0x58, 0xbc, 0x64, 0x89, 0x2f, 0x9a, 0x99, 0xe2, 0x1e, 0x2c, 0x82, 0x23, - 0xd1, 0xbf, 0x57, 0x62, 0xcf, 0x12, 0x96, 0x30, 0xb3, 0x0f, 0xf3, 0xe3, 0x61, 0xef, 0xa6, 0xd2, - 0x73, 0x86, 0x52, 0x47, 0x9c, 0xf7, 0x5c, 0x12, 0x44, 0xba, 0xd4, 0x6f, 0x1d, 0x41, 0x35, 0xcd, - 0x50, 0x17, 0x21, 0x7f, 0x81, 0x22, 0xe1, 0x2b, 0xfd, 0x54, 0xb7, 0xa0, 0x10, 0x9a, 0xce, 0x08, - 0x89, 0x4a, 0x6f, 0x8c, 0xfb, 0xc3, 0xcd, 0xe8, 0x5c, 0xe4, 0x49, 0xee, 0xb1, 0xa2, 0xad, 0xb0, - 0xa7, 0x91, 0x95, 0x16, 0xfb, 0xb3, 0x0f, 0x8d, 0x71, 0xb2, 0xf0, 0xe5, 0x01, 0x94, 0x65, 0xa2, - 0x48, 0x6f, 0xa6, 0xb6, 0x9e, 0x44, 0x4a, 0xbb, 0xcf, 0xc2, 0xf4, 0x09, 0xed, 0x41, 0x84, 0xeb, - 0xcb, 0xbb, 0xf9, 0x0f, 0x39, 0x58, 0x7c, 0x89, 0x08, 0x1f, 0xb5, 0x5f, 0xbe, 0x11, 0xad, 0x42, - 0x91, 0x1d, 0x71, 0x33, 0xc7, 0xd2, 0x50, 0x9c, 0x68, 0x33, 0x47, 0x57, 0xbc, 0x99, 0x0b, 0x7e, - 0x9e, 0xf1, 0x6b, 0x82, 0x7a, 0xc2, 0xc5, 0x36, 0x40, 0x76, 0x77, 0x23, 0xb4, 0xd1, 0x25, 0x16, - 0xad, 0xa5, 0x2a, 0x88, 0xa7, 0x94, 0xa6, 0xb6, 0x61, 0x91, 0xdd, 0xc1, 0xa6, 0x09, 0x36, 0x3c, - 0xd7, 0x89, 0xd8, 0x64, 0x2f, 0xe9, 0xbc, 0x83, 0xb0, 0xba, 0xf8, 0xbf, 0xeb, 0x44, 0x89, 0x24, - 0xb6, 0xdf, 0x4a, 0xc9, 0x62, 0x4a, 0xf2, 0x98, 0x92, 0xa9, 0xa4, 0x76, 0xc4, 0x3a, 0x80, 0x7c, - 0x05, 0xf1, 0x98, 0xff, 0x81, 0xa2, 0xd8, 0x4d, 0xf8, 0x03, 0x6c, 0x74, 0x26, 0x37, 0x65, 0xae, - 0xb2, 0x8b, 0xfa, 0xb6, 0x6b, 0xd3, 0xad, 0x55, 0x17, 0x2a, 0xda, 0x6b, 0x58, 0xa0, 0x37, 0xfe, - 0x39, 0x23, 0x52, 0x7b, 0xc2, 0xa3, 0x34, 0x36, 0xe1, 0xe2, 0x81, 0xa5, 0x5c, 0x3b, 0xb0, 0xb4, - 0x2d, 0x96, 0xa7, 0xc7, 0x41, 0x78, 0x3a, 0x1e, 0xe5, 0x69, 0x5d, 0xe0, 0x10, 0x56, 0x32, 0xb2, - 0xf1, 0x16, 0x5a, 0xc5, 0x41, 0x98, 0x6c, 0x6b, 0x71, 0x72, 0x89, 0x9f, 0x04, 0x29, 0x15, 0xc0, - 0xf1, 0xb7, 0xf6, 0x9a, 0xe1, 0x16, 0xab, 0xe6, 0x97, 0x66, 0x97, 0xf6, 0x5f, 0x16, 0x25, 0x79, - 0x9b, 0x40, 0xd6, 0x16, 0x29, 0x37, 0x7b, 0x31, 0x16, 0x7c, 0xed, 0xdb, 0x94, 0xfa, 0xe7, 0xb7, - 0x79, 0x4a, 0xa5, 0x6f, 0x25, 0x53, 0x98, 0x1f, 0xb4, 0x67, 0xac, 0x84, 0x33, 0x93, 0x45, 0xdd, - 0x82, 0x79, 0x6e, 0x3c, 0x19, 0xbb, 0x59, 0x74, 0x52, 0x40, 0xeb, 0x32, 0x78, 0x99, 0x20, 0x5d, - 0xd7, 0x03, 0x9e, 0x33, 0x93, 0xd9, 0x48, 0xfd, 0x03, 0x4a, 0x99, 0x28, 0x2d, 0xc5, 0x51, 0x8a, - 0x1b, 0xc0, 0x7c, 0x28, 0x02, 0xf4, 0x3d, 0xdc, 0xd0, 0xd1, 0xd0, 0x0b, 0xe3, 0x45, 0x82, 0xb6, - 0xc0, 0x8f, 0x79, 0x1b, 0x99, 0x3d, 0xb9, 0x24, 0x7b, 0x66, 0x2c, 0x72, 0x63, 0xfb, 0xc4, 0x5c, - 0x76, 0x93, 0xb9, 0x09, 0xad, 0x69, 0x00, 0xc4, 0x64, 0x7e, 0xa7, 0xc0, 0x2a, 0x67, 0xb3, 0x94, - 0xfe, 0x58, 0x70, 0x1f, 0x58, 0x38, 0x25, 0xf6, 0xfc, 0x34, 0xec, 0x73, 0x33, 0xb1, 0x17, 0xb2, - 0xd8, 0x6f, 0xc0, 0xda, 0x04, 0x38, 0x01, 0xfc, 0x10, 0x4a, 0x07, 0xa9, 0xa7, 0x9a, 0xf8, 0x6d, - 0xd4, 0x49, 0xa1, 0xcf, 0x65, 0xc7, 0xea, 0x94, 0x3e, 0xfd, 0x14, 0x6e, 0xbf, 0xb0, 0xdd, 0xde, - 0xb6, 0xe3, 0xf0, 0x7d, 0x6a, 0xdf, 0xfd, 0x94, 0x69, 0xf1, 0xbb, 0x02, 0x7f, 0x9d, 0xa9, 0x2e, - 0xf2, 0xe6, 0x30, 0xb3, 0x20, 0xfe, 0x3b, 0xd5, 0x4f, 0x3e, 0xa0, 0xcb, 0xfb, 0x8d, 0x18, 0xc4, - 0xe2, 0x96, 0xd6, 0x01, 0x54, 0x52, 0xe4, 0x29, 0x63, 0x78, 0x73, 0x7c, 0x0c, 0x4f, 0xe9, 0x5f, - 0xc9, 0x08, 0xfe, 0x0e, 0x0a, 0x8c, 0xf6, 0xa1, 0x94, 0x4c, 0xc5, 0x9b, 0xbf, 0xf3, 0x5d, 0x59, - 0xc2, 0x79, 0x66, 0x64, 0x21, 0x79, 0xe4, 0xb1, 0x1e, 0xf9, 0x93, 0x02, 0x4d, 0x56, 0x8f, 0xff, - 0x33, 0x09, 0x0a, 0x6c, 0xd3, 0xb1, 0xdf, 0xa2, 0x63, 0x44, 0x88, 0xed, 0x0e, 0xb0, 0x7a, 0x87, - 0x36, 0xac, 0x60, 0x80, 0x08, 0x9f, 0x5d, 0xc2, 0x6e, 0x85, 0xd3, 0x98, 0x96, 0xfa, 0x77, 0x58, - 0xc2, 0xde, 0x28, 0xb0, 0x90, 0x81, 0xae, 0xfc, 0x00, 0x61, 0x6c, 0x7b, 0xae, 0xc0, 0xb1, 0xc8, - 0x19, 0x7b, 0x31, 0x9d, 0x66, 0xa7, 0xc5, 0x7e, 0xb1, 0x18, 0xbd, 0x9e, 0x4c, 0xc2, 0x32, 0xa7, - 0xec, 0xf6, 0x1c, 0xed, 0xb7, 0x1c, 0x2c, 0x4f, 0x83, 0xd1, 0x82, 0xd2, 0xa5, 0x17, 0x5c, 0xf4, - 0x1d, 0xef, 0x52, 0xba, 0x2e, 0xcf, 0xea, 0x3d, 0x58, 0x10, 0xf6, 0xc7, 0xb2, 0xaa, 0xac, 0xd7, - 0x39, 0x39, 0xce, 0xc5, 0x7b, 0xb0, 0x20, 0x7c, 0x89, 0x05, 0x39, 0x80, 0x3a, 0x27, 0x1f, 0x24, - 0x3f, 0x87, 0x16, 0x30, 0xf1, 0x7c, 0x83, 0xff, 0x13, 0xc1, 0xf2, 0xfc, 0x48, 0xee, 0xf9, 0x94, - 0xbc, 0x4d, 0xa9, 0x3b, 0x9e, 0x1f, 0xa9, 0xaf, 0xc4, 0xde, 0x6e, 0x60, 0x81, 0xb3, 0x59, 0x60, - 0xe9, 0xb3, 0x91, 0x0a, 0xe7, 0xac, 0x97, 0x15, 0x5b, 0x7c, 0xec, 0xa1, 0xac, 0xcb, 0x62, 0xaa, - 0x2e, 0xef, 0xc4, 0xd3, 0x82, 0xfe, 0x40, 0xc6, 0xec, 0x57, 0x74, 0x59, 0x8e, 0x05, 0xfa, 0xcb, - 0x19, 0x3f, 0x6f, 0x7f, 0xb3, 0x19, 0xda, 0x04, 0x61, 0xdc, 0xb1, 0xbd, 0x2e, 0xff, 0xea, 0x0e, - 0xbc, 0x6e, 0x48, 0xba, 0xec, 0x5f, 0x53, 0xdd, 0x18, 0xc8, 0x59, 0x91, 0x11, 0x1e, 0xfd, 0x11, - 0x00, 0x00, 0xff, 0xff, 0xc0, 0xb3, 0xd6, 0x9d, 0x2e, 0x13, 0x00, 0x00, + // 2293 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xdd, 0x6e, 0x1b, 0xc7, + 0x15, 0xc6, 0x8a, 0x14, 0x45, 0x1e, 0x52, 0x3f, 0x1e, 0x51, 0xd2, 0x86, 0x8d, 0x63, 0x67, 0x1d, + 0x3b, 0xaa, 0x1b, 0x93, 0xb6, 0xd2, 0x04, 0x81, 0x9b, 0xa0, 0xb1, 0x65, 0xc9, 0x90, 0xe3, 0xba, + 0xea, 0x52, 0x75, 0x80, 0x16, 0xe8, 0x76, 0xc8, 0x1d, 0xd2, 0x0b, 0x2d, 0x77, 0x99, 0x9d, 0x21, + 0x25, 0xa6, 0x17, 0xbd, 0x69, 0x2f, 0x0a, 0xf4, 0x0d, 0x82, 0x02, 0xbd, 0x2a, 0xfa, 0x04, 0x01, + 0x7a, 0xd3, 0xcb, 0xbe, 0x43, 0xdf, 0xa6, 0x98, 0x33, 0x33, 0xcb, 0xe5, 0xaf, 0x6d, 0xa5, 0x57, + 0xda, 0x39, 0x73, 0xce, 0x9c, 0x6f, 0xce, 0xff, 0x50, 0xb0, 0x39, 0x14, 0x6d, 0x11, 0xfa, 0x54, + 0xd0, 0x7a, 0x3f, 0x89, 0x45, 0x4c, 0x4a, 0x29, 0xa1, 0xb6, 0xd5, 0x0a, 0xa2, 0x30, 0xee, 0x8e, + 0x37, 0x6b, 0xeb, 0x61, 0xdc, 0x1d, 0x88, 0x20, 0xd4, 0xcb, 0x8d, 0xde, 0x88, 0x7f, 0x13, 0xb6, + 0x85, 0x59, 0xef, 0x09, 0xda, 0x0a, 0x99, 0xe8, 0xd1, 0x88, 0x76, 0x59, 0x92, 0x91, 0xdb, 0x10, + 0x71, 0x3f, 0xce, 0x9e, 0x33, 0xe4, 0xed, 0x57, 0xac, 0x67, 0x96, 0x95, 0xa1, 0x10, 0x41, 0x8f, + 0xa9, 0x95, 0xf3, 0x35, 0xd4, 0x8e, 0x2e, 0x59, 0x7b, 0x20, 0xd8, 0x4b, 0x09, 0xe5, 0x30, 0xee, + 0xf5, 0x68, 0xe4, 0xbb, 0xec, 0x9b, 0x01, 0xe3, 0x82, 0x10, 0xc8, 0xd3, 0xa4, 0xcb, 0x6d, 0xeb, + 0x66, 0x6e, 0xbf, 0xe4, 0xe2, 0x37, 0xb9, 0x0d, 0x1b, 0xb4, 0x2d, 0x82, 0x38, 0xf2, 0xe4, 0x31, + 0xf1, 0x40, 0xd8, 0x2b, 0x37, 0xad, 0xfd, 0x9c, 0xbb, 0xae, 0xa8, 0x67, 0x8a, 0xe8, 0x1c, 0xc2, + 0x8f, 0xe6, 0x1e, 0xcc, 0xfb, 0x71, 0xc4, 0x19, 0xf9, 0x00, 0x56, 0xd9, 0x90, 0x45, 0xc2, 0xb6, + 0x6e, 0x5a, 0xfb, 0xe5, 0x83, 0x8d, 0xba, 0xb9, 0xec, 0x91, 0xa4, 0xba, 0x6a, 0xd3, 0xf9, 0x8b, + 0x05, 0xf6, 0x99, 0xbc, 0xe6, 0x2f, 0xa8, 0x60, 0x49, 0x40, 0xc3, 0xe0, 0x5b, 0xd6, 0x64, 0x42, + 0x04, 0x51, 0x97, 0x93, 0xf7, 0xa1, 0x22, 0x68, 0xd2, 0x65, 0xc2, 0x43, 0x4b, 0xe0, 0x49, 0x25, + 0xb7, 0xac, 0x68, 0x28, 0x45, 0x7e, 0x02, 0xd7, 0x78, 0x3c, 0x48, 0xda, 0xcc, 0x63, 0x97, 0xfd, + 0x84, 0x71, 0x1e, 0xc4, 0x11, 0xc2, 0x2d, 0xb9, 0x5b, 0x6a, 0xe3, 0x28, 0xa5, 0x93, 0xeb, 0x00, + 0xed, 0x84, 0x51, 0xc1, 0x3c, 0xdf, 0x0f, 0xed, 0x1c, 0x72, 0x95, 0x14, 0xe5, 0x89, 0x1f, 0x3a, + 0xff, 0x5d, 0x81, 0xed, 0x79, 0x30, 0x6a, 0x50, 0xbc, 0x88, 0x93, 0xf3, 0x4e, 0x18, 0x5f, 0x68, + 0x08, 0xe9, 0x9a, 0x7c, 0x08, 0x9b, 0x5a, 0xff, 0x39, 0x1b, 0xf1, 0x3e, 0x6d, 0x33, 0xad, 0x7d, + 0x43, 0x91, 0xbf, 0xd2, 0x54, 0xc9, 0xa8, 0xef, 0x92, 0x32, 0x2a, 0x00, 0x1b, 0x8a, 0x9c, 0x32, + 0xde, 0x81, 0x4d, 0x2e, 0xe2, 0xbe, 0x47, 0x3b, 0x82, 0x25, 0x5e, 0x3b, 0xee, 0x8f, 0xec, 0xfc, + 0x4d, 0x6b, 0xbf, 0xe8, 0xae, 0x4b, 0xf2, 0x23, 0x49, 0x3d, 0x8c, 0xfb, 0x23, 0xf2, 0x0c, 0x36, + 0xd0, 0x2a, 0x1e, 0xd7, 0x38, 0xed, 0xd5, 0x9b, 0xb9, 0xfd, 0xf2, 0xc1, 0xad, 0xfa, 0x38, 0x06, + 0x17, 0x59, 0xd6, 0x5d, 0x47, 0xd1, 0xf4, 0x86, 0x04, 0xf2, 0x6d, 0x16, 0x86, 0x76, 0x01, 0x11, + 0xe1, 0xb7, 0x32, 0xbe, 0x8c, 0x3f, 0x4f, 0x8c, 0xfa, 0x8c, 0xdb, 0x6b, 0xc6, 0xf8, 0x92, 0x76, + 0x26, 0x49, 0xe4, 0xc7, 0xb0, 0xc5, 0x2e, 0x05, 0x4b, 0x22, 0x1a, 0x7a, 0xed, 0x70, 0xc0, 0x05, + 0x4b, 0xec, 0x22, 0xb2, 0x6d, 0x1a, 0xfa, 0xa1, 0x22, 0x3b, 0x2f, 0xa0, 0x98, 0xde, 0x90, 0x40, + 0x3e, 0xa2, 0x3d, 0xe3, 0x4e, 0xfc, 0x26, 0x75, 0x28, 0x4e, 0x18, 0xb0, 0x7c, 0x40, 0xea, 0x69, + 0x94, 0x1b, 0x49, 0x37, 0xe5, 0x71, 0x7e, 0x07, 0xab, 0xcd, 0x57, 0x34, 0xf1, 0xa5, 0x73, 0x52, + 0x41, 0xed, 0x9c, 0xf3, 0x69, 0x45, 0x2b, 0x19, 0x45, 0xb7, 0x61, 0x95, 0x4b, 0x41, 0xb4, 0x7e, + 0xf9, 0x60, 0x73, 0xac, 0x05, 0xcf, 0x73, 0xd5, 0xae, 0xf3, 0xcf, 0x12, 0x14, 0xbf, 0x36, 0x4e, + 0x9e, 0x07, 0xf8, 0xe7, 0x50, 0x50, 0x1e, 0xd6, 0x70, 0x3f, 0xcc, 0x98, 0xdd, 0x08, 0xd6, 0x5d, + 0xd6, 0x0f, 0x83, 0x36, 0x95, 0x59, 0xf3, 0x3c, 0x56, 0x7f, 0x5d, 0x2d, 0x26, 0x0f, 0x50, 0x9e, + 0xd7, 0x48, 0xde, 0xfc, 0x00, 0x25, 0x46, 0x1e, 0xc0, 0x4e, 0x8f, 0x5e, 0x7a, 0x43, 0x2f, 0x19, + 0x33, 0x79, 0x21, 0xed, 0x62, 0xb8, 0xe4, 0x5c, 0xd2, 0xa3, 0x97, 0x2f, 0xb3, 0xf2, 0xb4, 0x4b, + 0x9e, 0xc1, 0x3a, 0x5e, 0xcf, 0xe3, 0x22, 0x61, 0xb4, 0x67, 0x42, 0xe6, 0xf6, 0x3c, 0xd5, 0x68, + 0x8e, 0xa6, 0xe2, 0x3b, 0x8a, 0x44, 0x32, 0x72, 0x2b, 0x3c, 0x43, 0xaa, 0xfd, 0x1e, 0xae, 0xcd, + 0xb0, 0x90, 0x2d, 0xc8, 0x9d, 0xb3, 0x91, 0x36, 0x94, 0xfc, 0x24, 0x9f, 0xc0, 0xea, 0x90, 0x86, + 0x03, 0x63, 0xa6, 0x1b, 0xaf, 0x51, 0xe5, 0x2a, 0xee, 0x87, 0x2b, 0x9f, 0x59, 0xb5, 0x13, 0xd8, + 0x9e, 0x73, 0xff, 0xa5, 0x1e, 0xdf, 0x85, 0x02, 0x82, 0xe4, 0xf6, 0x0a, 0x16, 0x34, 0xbd, 0xaa, + 0xfd, 0xcb, 0x82, 0x72, 0x46, 0x0b, 0xf9, 0x29, 0xac, 0x19, 0x13, 0x58, 0x68, 0x82, 0xda, 0x5c, + 0x5c, 0x0a, 0x92, 0x61, 0x25, 0xc7, 0x32, 0x87, 0x31, 0x25, 0xda, 0x71, 0x24, 0x92, 0x38, 0x54, + 0x6a, 0xca, 0x07, 0xd7, 0xa7, 0xa2, 0x48, 0x25, 0x9e, 0x38, 0x54, 0x5c, 0xae, 0x4a, 0x54, 0xb3, + 0xe4, 0xe4, 0x23, 0x20, 0x01, 0xf7, 0xfa, 0x49, 0xd0, 0xa3, 0xc9, 0xc8, 0xe3, 0x2c, 0x19, 0x06, + 0x51, 0x17, 0xc3, 0xa0, 0xe8, 0x6e, 0x05, 0xfc, 0x54, 0x6d, 0x34, 0x15, 0xbd, 0xf6, 0xb7, 0x3c, + 0x14, 0x34, 0xec, 0x0d, 0x58, 0x09, 0x7c, 0xbc, 0x74, 0xce, 0x5d, 0x09, 0x7c, 0x52, 0x35, 0xc1, + 0xac, 0x22, 0x5c, 0x2d, 0xc8, 0x3d, 0x19, 0x59, 0x52, 0xa1, 0x8e, 0xac, 0x9d, 0x31, 0x3a, 0x85, + 0xeb, 0x51, 0x18, 0x50, 0xee, 0x6a, 0x26, 0xf2, 0x05, 0xac, 0xab, 0xce, 0xe4, 0xe9, 0x80, 0xce, + 0xa3, 0x94, 0x5d, 0xcf, 0xf4, 0xab, 0xc7, 0xf8, 0xd9, 0xc4, 0x7d, 0xb7, 0xd2, 0xca, 0xac, 0xa4, + 0x3b, 0xfa, 0x31, 0x0f, 0xa4, 0x6b, 0xec, 0x55, 0xe5, 0x0e, 0xb3, 0x26, 0xb7, 0x00, 0x8b, 0x96, + 0x97, 0x32, 0xa8, 0x02, 0x53, 0x91, 0xc4, 0x53, 0xc3, 0x24, 0x2f, 0x21, 0xa8, 0x60, 0xba, 0xc2, + 0xa8, 0x05, 0xd9, 0x83, 0x35, 0xbf, 0xe5, 0x61, 0xda, 0xa9, 0x92, 0x52, 0xf0, 0x5b, 0x2f, 0x64, + 0xe2, 0x3d, 0x82, 0x1d, 0x91, 0xd0, 0x88, 0x67, 0x5a, 0x14, 0x17, 0xb4, 0xd7, 0xb7, 0x4b, 0x08, + 0xbb, 0x52, 0xd7, 0xdd, 0x4f, 0xb6, 0x29, 0xb7, 0x9a, 0x61, 0x3d, 0x33, 0x9c, 0xa4, 0x01, 0x15, + 0xc9, 0xe2, 0x0d, 0xfa, 0x3e, 0x15, 0xcc, 0xb7, 0x61, 0x8e, 0x64, 0x59, 0x7e, 0xfe, 0x5a, 0x31, + 0x10, 0x1b, 0xd6, 0x7a, 0x8c, 0x73, 0xda, 0x65, 0x76, 0x19, 0xc1, 0x98, 0x25, 0x39, 0x82, 0xb2, + 0x2c, 0xd1, 0x1e, 0x82, 0xe6, 0x76, 0x05, 0xc3, 0xe1, 0x83, 0xc5, 0xc1, 0x54, 0x97, 0xb5, 0xbb, + 0x29, 0x99, 0x5d, 0x68, 0x9b, 0x4f, 0x5e, 0x7b, 0x08, 0xa5, 0x74, 0x43, 0x1a, 0x24, 0xdb, 0xef, + 0xd4, 0x42, 0x1a, 0x24, 0xa4, 0x5c, 0x78, 0xfd, 0x73, 0xed, 0xed, 0x82, 0x5c, 0x9e, 0x9e, 0x3b, + 0xdf, 0x59, 0xb0, 0x77, 0xf8, 0x8a, 0x46, 0x5d, 0x76, 0x96, 0xd6, 0x66, 0xd3, 0xde, 0x3f, 0x4b, + 0x8b, 0x38, 0x95, 0x3e, 0xd7, 0xbd, 0x78, 0x41, 0x40, 0xe8, 0xda, 0x8e, 0x0b, 0x72, 0x0f, 0xed, + 0x2f, 0x4b, 0x3f, 0xaa, 0xdb, 0x38, 0xa8, 0x4e, 0x0b, 0xa1, 0x9e, 0x82, 0xdf, 0x92, 0x7f, 0xd1, + 0x5d, 0xc9, 0xc8, 0x4b, 0x06, 0x91, 0x8e, 0xe3, 0x82, 0x9f, 0x8c, 0xdc, 0x41, 0xe4, 0xfc, 0xc3, + 0x02, 0x7b, 0x16, 0x9d, 0x9e, 0x11, 0x3e, 0x81, 0xf5, 0x16, 0xeb, 0xc4, 0x09, 0xf3, 0x74, 0xc0, + 0x2a, 0x7c, 0x5b, 0xd3, 0xaa, 0xdc, 0x8a, 0x62, 0x53, 0x2b, 0xf2, 0x31, 0x54, 0x54, 0x77, 0xd4, + 0x52, 0x2b, 0x0b, 0xa4, 0xca, 0xc8, 0xa5, 0x85, 0xde, 0x83, 0xf2, 0x05, 0xe5, 0xde, 0x24, 0xca, + 0xd2, 0x05, 0xe5, 0x4f, 0x14, 0xd0, 0xef, 0x73, 0xb0, 0x73, 0x88, 0xb3, 0x40, 0xda, 0x6e, 0xc6, + 0x33, 0xd2, 0x4c, 0xf9, 0xaf, 0xc2, 0x6a, 0x27, 0x36, 0xd5, 0xbf, 0xe8, 0xaa, 0x05, 0x69, 0x40, + 0x95, 0x86, 0x61, 0x7c, 0xe1, 0xb1, 0x5e, 0x5f, 0x8c, 0xbc, 0xa1, 0xa7, 0xe6, 0x32, 0xad, 0xec, + 0x1a, 0xee, 0x1d, 0xc9, 0xad, 0x97, 0x4d, 0xdc, 0x20, 0xf7, 0xa1, 0x8a, 0x39, 0x1b, 0x44, 0x5d, + 0xaf, 0x1d, 0x87, 0x83, 0x5e, 0xa4, 0x42, 0x3e, 0x8f, 0xaa, 0x88, 0xd9, 0x3b, 0xc4, 0x2d, 0x0c, + 0xff, 0x67, 0xb3, 0x12, 0xe8, 0xa4, 0x55, 0x74, 0x92, 0x3d, 0xdb, 0x34, 0x4f, 0x7c, 0x34, 0xf9, + 0xd4, 0x59, 0xe8, 0xb4, 0x2f, 0xa1, 0x22, 0x8b, 0x0f, 0xf3, 0xbd, 0x4e, 0x12, 0xf7, 0xb8, 0x5d, + 0x98, 0x2e, 0x66, 0xe6, 0x8c, 0x7a, 0x13, 0xd9, 0x8e, 0x93, 0xb8, 0xe7, 0x96, 0x79, 0xfa, 0xcd, + 0xc9, 0x5d, 0xc8, 0xa3, 0xf6, 0x35, 0xd4, 0xbe, 0x3b, 0x2b, 0x89, 0xba, 0x91, 0x47, 0x16, 0x83, + 0x16, 0xe5, 0x99, 0x41, 0x49, 0xe5, 0x75, 0x45, 0x12, 0xd3, 0xd9, 0xe0, 0x01, 0xac, 0xf3, 0x88, + 0xf6, 0xf9, 0xab, 0x58, 0x60, 0x6a, 0xcf, 0xcd, 0xea, 0x8a, 0x61, 0x91, 0x2b, 0xe7, 0x04, 0x76, + 0xa7, 0xfd, 0xa6, 0xc3, 0xab, 0x31, 0xd5, 0x29, 0xca, 0x07, 0xdb, 0x99, 0xcc, 0x9c, 0x33, 0x55, + 0xfc, 0xd5, 0x02, 0xa2, 0xce, 0x52, 0xc3, 0x80, 0x0e, 0x80, 0x65, 0x1d, 0xe7, 0x3a, 0x80, 0x6a, + 0xa9, 0x99, 0x49, 0xa3, 0x84, 0x94, 0x17, 0x13, 0x71, 0x92, 0xcb, 0xc6, 0xc9, 0x6d, 0xd8, 0x08, + 0xa2, 0x76, 0x38, 0xf0, 0x99, 0xd7, 0xa7, 0x89, 0x1c, 0x92, 0xf5, 0x88, 0xa7, 0xa9, 0xa7, 0x48, + 0x74, 0xfe, 0x6e, 0xc1, 0xf6, 0x04, 0x9c, 0x2b, 0xde, 0x8b, 0xdc, 0xc9, 0xf6, 0x09, 0x99, 0x29, + 0x63, 0xee, 0xec, 0xd4, 0x93, 0x86, 0xa3, 0x47, 0xc3, 0x84, 0x51, 0x7f, 0xe4, 0xb1, 0xcb, 0x80, + 0x0b, 0xae, 0xc1, 0xab, 0x10, 0x7a, 0xa4, 0xb6, 0x8e, 0x70, 0xc7, 0xf9, 0x15, 0xec, 0x3c, 0x61, + 0x21, 0x9b, 0x4d, 0x9a, 0x65, 0x36, 0x7b, 0x17, 0x4a, 0x09, 0x6b, 0x0f, 0x12, 0x1e, 0x0c, 0x4d, + 0x02, 0x8d, 0x09, 0x8e, 0x0d, 0xbb, 0xd3, 0x47, 0xaa, 0x7b, 0x3b, 0x7f, 0xb6, 0x60, 0x5b, 0x6d, + 0x21, 0x6a, 0x6e, 0x74, 0xed, 0xa7, 0x5d, 0x5f, 0x35, 0xf3, 0xd9, 0xfb, 0xe9, 0xfd, 0xe5, 0x9a, + 0xe5, 0xe8, 0x2d, 0x5f, 0x25, 0x5e, 0xd0, 0x49, 0x9b, 0xb2, 0xf6, 0x8b, 0x24, 0x9f, 0x74, 0x74, + 0x47, 0x76, 0x76, 0xa1, 0x3a, 0x09, 0x43, 0xe3, 0x1b, 0x19, 0xba, 0x2a, 0x39, 0x29, 0xbe, 0xcf, + 0xf5, 0xa8, 0xae, 0xab, 0x30, 0x33, 0x38, 0x17, 0xd4, 0xe1, 0xf5, 0x4c, 0x1d, 0x66, 0x5c, 0xe6, + 0x8d, 0x2a, 0x2a, 0x7a, 0x60, 0xd0, 0xb8, 0x2b, 0x48, 0xd4, 0xb3, 0x82, 0xb3, 0x67, 0xfc, 0x90, + 0xaa, 0xd6, 0x98, 0x3e, 0x87, 0xf7, 0x8e, 0x83, 0xc8, 0x7f, 0x14, 0x86, 0x0a, 0xec, 0x49, 0xf4, + 0x16, 0x9e, 0x72, 0xfe, 0x6d, 0xc1, 0x8d, 0x85, 0xe2, 0x3a, 0x1a, 0x5f, 0x4c, 0x59, 0xff, 0xd3, + 0x8c, 0xf5, 0x5f, 0x23, 0xab, 0xbc, 0xa3, 0xc7, 0x4b, 0x33, 0xab, 0x7d, 0xa5, 0x47, 0xb5, 0x85, + 0x23, 0xe5, 0x9d, 0xc9, 0x91, 0x72, 0x4e, 0x34, 0xa7, 0x33, 0xa4, 0x73, 0x04, 0xd7, 0x9e, 0x32, + 0xf1, 0x98, 0xb6, 0xcf, 0x07, 0x7d, 0xfe, 0x26, 0xb1, 0x39, 0x77, 0xa4, 0x72, 0x9e, 0x00, 0xc9, + 0x1e, 0xa3, 0x6f, 0x5e, 0x87, 0xb5, 0x96, 0x22, 0xe9, 0xab, 0x57, 0xeb, 0xe9, 0x13, 0x5e, 0xf1, + 0x9e, 0x44, 0x9d, 0xd8, 0x35, 0x4c, 0xce, 0x3b, 0xb0, 0xf7, 0x94, 0x89, 0x43, 0x16, 0x86, 0x92, + 0x2e, 0xeb, 0x83, 0x81, 0xe4, 0xdc, 0x07, 0x7b, 0x76, 0x4b, 0xab, 0xa9, 0xc2, 0xaa, 0x2c, 0x2e, + 0xe6, 0x91, 0xae, 0x16, 0xce, 0x3e, 0x42, 0x32, 0x12, 0x99, 0x5e, 0x85, 0x2f, 0x39, 0x6b, 0xfc, + 0x92, 0x73, 0x8e, 0x61, 0x7b, 0x82, 0x33, 0xad, 0x22, 0x25, 0xb9, 0xed, 0x05, 0x51, 0x27, 0xd6, + 0x65, 0x24, 0xf3, 0xe6, 0x4a, 0xd9, 0x8b, 0x6d, 0xfd, 0x25, 0x13, 0x53, 0x9f, 0xc3, 0x75, 0x6c, + 0x1a, 0xf4, 0xdf, 0x5b, 0xe9, 0xcd, 0xc6, 0x5b, 0x5a, 0xcd, 0x09, 0xac, 0x4d, 0x46, 0x7d, 0x23, + 0xe3, 0xaf, 0x05, 0x42, 0x75, 0xbd, 0x56, 0x81, 0x61, 0xe4, 0x6b, 0xa7, 0x50, 0xc9, 0x6e, 0xcc, + 0x09, 0x8d, 0xbb, 0x93, 0xa1, 0x51, 0x9d, 0xbc, 0x8f, 0x52, 0x93, 0x0d, 0x8f, 0x1d, 0x34, 0x8d, + 0x09, 0xcb, 0xf4, 0x3e, 0x27, 0x50, 0x9d, 0x24, 0xeb, 0xbb, 0x3c, 0x80, 0x92, 0x09, 0x14, 0x73, + 0x9b, 0xb9, 0x95, 0x77, 0xcc, 0xe5, 0xdc, 0x47, 0x37, 0xbd, 0x4d, 0xce, 0x1d, 0x4f, 0x60, 0xba, + 0x7a, 0x33, 0xfb, 0xd3, 0x0a, 0x6c, 0x3d, 0x65, 0x42, 0x4d, 0x1a, 0x3f, 0x7c, 0x20, 0xdc, 0xd5, + 0xaf, 0x8a, 0xf4, 0x69, 0xa5, 0x56, 0xb2, 0x97, 0xb1, 0x4b, 0xd5, 0xcb, 0xf4, 0x7e, 0x0e, 0xf7, + 0xd7, 0x35, 0xf5, 0x4c, 0xb1, 0xdd, 0x02, 0xd3, 0xdc, 0xbc, 0x61, 0xc0, 0x2e, 0xb8, 0xae, 0xac, + 0x15, 0x4d, 0x7c, 0x29, 0x69, 0x64, 0x1f, 0xb6, 0xd4, 0x6f, 0x1a, 0x18, 0xe2, 0x5e, 0x1c, 0x85, + 0x23, 0x1c, 0x6c, 0x8a, 0xfa, 0x09, 0x85, 0x79, 0xf1, 0xcb, 0x28, 0x1c, 0x8d, 0x39, 0x79, 0xf0, + 0xad, 0xe1, 0x2c, 0x64, 0x38, 0x9b, 0x92, 0x2c, 0x39, 0x9d, 0x53, 0xac, 0x00, 0xc6, 0x0a, 0xda, + 0x98, 0x3f, 0x83, 0x82, 0x1e, 0xcd, 0x94, 0x01, 0x6e, 0xd5, 0x67, 0x7f, 0x6b, 0x53, 0x22, 0x4f, + 0x58, 0x27, 0x88, 0x02, 0xfd, 0x72, 0x47, 0x8a, 0xf3, 0x1c, 0x36, 0xe5, 0x89, 0xff, 0x9f, 0x09, + 0xc1, 0x79, 0xa8, 0xbc, 0x34, 0xd1, 0xe0, 0xd3, 0x7e, 0x6d, 0x2d, 0xed, 0xd7, 0xce, 0x5d, 0x8c, + 0xd3, 0x66, 0x32, 0x7c, 0x39, 0xe9, 0xe5, 0x79, 0x55, 0xe0, 0x05, 0xec, 0x4c, 0xf1, 0xa6, 0x43, + 0x78, 0x85, 0x27, 0xc3, 0xf1, 0xb0, 0x9a, 0x06, 0x97, 0xfe, 0x51, 0x31, 0x23, 0x02, 0x3c, 0xfd, + 0x76, 0x9e, 0x23, 0x6e, 0x3d, 0x69, 0xff, 0xd0, 0xe8, 0x72, 0xbe, 0x40, 0x2f, 0x99, 0xd3, 0x34, + 0xb2, 0xfd, 0xf4, 0x21, 0xbb, 0xe8, 0x5d, 0xa0, 0xf7, 0x9d, 0xdf, 0x66, 0xc4, 0xaf, 0x5e, 0xe6, + 0x25, 0x55, 0xda, 0xca, 0x84, 0xb0, 0x5a, 0x38, 0x5f, 0x62, 0x0a, 0x4f, 0x35, 0x56, 0x72, 0x17, + 0xd6, 0x94, 0xf2, 0xf1, 0xd4, 0x31, 0x8d, 0xce, 0x30, 0x38, 0x0d, 0x84, 0x37, 0xe5, 0xa4, 0x65, + 0x35, 0xe0, 0x31, 0xaa, 0x9c, 0xf6, 0xd4, 0x47, 0x50, 0x9c, 0xf2, 0xd2, 0xb5, 0xd4, 0x4b, 0x69, + 0x01, 0x58, 0x1b, 0x6a, 0x07, 0xb9, 0x58, 0x47, 0xcc, 0xfb, 0xf3, 0x8d, 0xac, 0x72, 0x03, 0xca, + 0xf2, 0xad, 0x3c, 0x64, 0x2a, 0xa1, 0xd4, 0xa0, 0x01, 0x8a, 0x84, 0xc9, 0xa4, 0x0a, 0x63, 0xe6, + 0xcc, 0x71, 0x61, 0x34, 0x3f, 0x89, 0xce, 0x2b, 0x8c, 0x46, 0xc0, 0x1d, 0x73, 0x39, 0x7f, 0x84, + 0x77, 0x5c, 0xd6, 0x8b, 0x87, 0xe9, 0x98, 0x27, 0x2b, 0xf4, 0x9b, 0x80, 0x34, 0xc1, 0xbd, 0x92, + 0xf9, 0xb1, 0x72, 0xfe, 0x98, 0x3d, 0x31, 0xed, 0xe5, 0xa7, 0xe7, 0xcc, 0x77, 0xa1, 0x36, 0x0f, + 0x80, 0x9e, 0x9b, 0xbe, 0xb3, 0x60, 0x57, 0x6d, 0x63, 0xc6, 0xbd, 0x29, 0xb8, 0xd7, 0x3c, 0x07, + 0x0c, 0xf6, 0xdc, 0x3c, 0xec, 0xf9, 0x85, 0xd8, 0x57, 0xa7, 0xb1, 0xbf, 0x03, 0x7b, 0x33, 0xe0, + 0x34, 0xf0, 0x63, 0xd8, 0x71, 0x99, 0x7a, 0x55, 0x4c, 0x26, 0xe7, 0xbd, 0xa9, 0x6c, 0x5a, 0xfe, + 0xb3, 0x90, 0xf3, 0x07, 0x79, 0xff, 0xc9, 0x73, 0xb4, 0xb3, 0xdf, 0x3e, 0xaf, 0x1a, 0xb0, 0x66, + 0x86, 0xd7, 0xa5, 0x3f, 0x49, 0x19, 0x2e, 0xc7, 0x85, 0xf7, 0x15, 0xfd, 0x48, 0xff, 0x8e, 0x1c, + 0x8e, 0x0c, 0x18, 0xe6, 0x5f, 0xf1, 0x42, 0xff, 0xb1, 0xc0, 0x59, 0x76, 0xe8, 0x95, 0x6f, 0xf7, + 0x29, 0x94, 0x23, 0x36, 0x1e, 0xcf, 0x97, 0xde, 0x10, 0x22, 0x66, 0x66, 0x76, 0x29, 0x17, 0x87, + 0x7e, 0x2a, 0x97, 0x5f, 0x2a, 0x17, 0x87, 0xbe, 0x96, 0x7b, 0xbc, 0xff, 0x9b, 0x3b, 0xc3, 0x40, + 0x30, 0xce, 0xeb, 0x41, 0xdc, 0x50, 0x5f, 0x8d, 0x6e, 0xdc, 0x18, 0x8a, 0x06, 0xfe, 0xc7, 0xa7, + 0x91, 0xe6, 0x5d, 0xab, 0x80, 0x84, 0x8f, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xfc, 0x24, + 0xcf, 0x97, 0x1a, 0x00, 0x00, } diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 7adb985b3df..13e2a965efa 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -29,42 +29,43 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } var fileDescriptor_27055cdbb1148d2b = []byte{ - // 553 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x95, 0x6d, 0x4f, 0x13, 0x41, - 0x10, 0xc7, 0xf5, 0x85, 0x44, 0x57, 0x04, 0x32, 0xbe, 0x30, 0x29, 0xb4, 0xd2, 0x2a, 0x26, 0x68, - 0xd2, 0x33, 0xf8, 0x09, 0xa0, 0x62, 0x25, 0x24, 0x24, 0x42, 0x83, 0x09, 0x09, 0x2f, 0x96, 0xbb, - 0x91, 0x5e, 0xbc, 0x27, 0x6e, 0xb7, 0x17, 0xf9, 0x10, 0x7e, 0x67, 0xd3, 0xdd, 0xee, 0x76, 0x6f, - 0x1f, 0x5a, 0xdf, 0xb5, 0xf3, 0xfb, 0xcf, 0x7f, 0x76, 0xee, 0x66, 0xf6, 0x08, 0x34, 0x3c, 0xe6, - 0x19, 0xc3, 0xba, 0x49, 0x63, 0x1c, 0x56, 0x75, 0xc9, 0x4b, 0xd8, 0x34, 0x63, 0x9d, 0x6d, 0xf1, - 0x2f, 0xa1, 0x9c, 0x4a, 0x7c, 0xf4, 0x40, 0x9e, 0x5d, 0xcf, 0x43, 0x30, 0x25, 0xaf, 0x4f, 0xff, - 0x60, 0x3c, 0xe3, 0x28, 0xfe, 0x8f, 0xca, 0x3c, 0xa7, 0x45, 0x02, 0x07, 0xc3, 0x65, 0x86, 0x87, - 0x5f, 0xe2, 0xc3, 0x0c, 0x19, 0xef, 0x7c, 0x58, 0x27, 0x63, 0x55, 0x59, 0x30, 0x1c, 0x3c, 0xf9, - 0xfc, 0xf4, 0xe8, 0xef, 0x16, 0xd9, 0x10, 0x30, 0x81, 0x5b, 0xb2, 0x33, 0x9a, 0xd2, 0xe2, 0x1e, - 0x27, 0xf4, 0x2e, 0x43, 0x3e, 0x79, 0xac, 0x10, 0x06, 0x86, 0x95, 0x0d, 0x55, 0xb9, 0x77, 0x2b, - 0x35, 0xaa, 0x16, 0xfc, 0x24, 0x5b, 0xa3, 0x1a, 0x29, 0xc7, 0x73, 0x7c, 0x64, 0x15, 0x8d, 0x11, - 0xf6, 0xcd, 0xc4, 0x16, 0x52, 0xd6, 0xfd, 0x15, 0x0a, 0x6d, 0x7c, 0x41, 0x5e, 0x4a, 0x76, 0x35, - 0xa5, 0x75, 0x02, 0x5d, 0x27, 0x47, 0xc4, 0x95, 0x65, 0x2f, 0x84, 0xcd, 0x83, 0x7e, 0xc5, 0x0c, - 0x03, 0x07, 0x6d, 0x23, 0xdf, 0x41, 0x6d, 0x85, 0x36, 0xfe, 0x41, 0x36, 0x25, 0x13, 0x15, 0x19, - 0xf4, 0x9c, 0x24, 0x09, 0x94, 0xe9, 0xdb, 0x20, 0xd7, 0x96, 0x13, 0xf2, 0x4a, 0x12, 0xf9, 0xc8, - 0x19, 0xb8, 0x39, 0x0b, 0xa2, 0x4c, 0xf7, 0xc3, 0x02, 0xed, 0x5a, 0x93, 0x37, 0xdf, 0xd2, 0x22, - 0x39, 0xce, 0x32, 0x59, 0xf0, 0xac, 0xd0, 0x8f, 0xe2, 0xd0, 0x48, 0x0f, 0x68, 0x54, 0xa5, 0x8f, - 0xff, 0x23, 0xd5, 0x35, 0xcf, 0x09, 0x19, 0x23, 0x3f, 0xa1, 0xf1, 0xef, 0x59, 0xc5, 0x60, 0xcf, - 0xc8, 0x5d, 0x86, 0x95, 0x73, 0x37, 0x40, 0xb5, 0xd9, 0x2d, 0xd9, 0x19, 0x23, 0x1f, 0x61, 0x96, - 0x9d, 0x15, 0xbf, 0xca, 0x0b, 0x9a, 0x23, 0x6b, 0x8d, 0xb2, 0x0d, 0x7d, 0xa3, 0xec, 0x6a, 0xcc, - 0x89, 0x33, 0x28, 0x74, 0xfd, 0x59, 0xbe, 0x89, 0x6b, 0x61, 0xed, 0x77, 0x43, 0xb6, 0x17, 0x80, - 0x1d, 0x67, 0x29, 0x65, 0xc8, 0xa0, 0xef, 0x26, 0x29, 0xa6, 0x7c, 0x07, 0xab, 0x24, 0xd6, 0x59, - 0xf5, 0xfb, 0xb3, 0xce, 0x6a, 0xbf, 0xb3, 0x5e, 0x08, 0x9b, 0x43, 0x6c, 0x80, 0xf6, 0x10, 0x9b, - 0xc0, 0x37, 0xc4, 0x6d, 0xae, 0x2d, 0xbf, 0x93, 0x17, 0x63, 0xe4, 0x57, 0xf1, 0x14, 0x73, 0x0a, - 0xbb, 0x6d, 0xbd, 0x8c, 0x2a, 0xb3, 0x3d, 0x3f, 0xd4, 0x4e, 0xa7, 0xe4, 0xf9, 0x3c, 0x2c, 0xee, - 0x81, 0x8e, 0xa5, 0x35, 0x2f, 0x81, 0x5d, 0x2f, 0x33, 0xb7, 0x6a, 0x1e, 0xad, 0x9b, 0xeb, 0xc5, - 0xa1, 0xac, 0x26, 0x96, 0xc4, 0xb7, 0x55, 0x96, 0xc0, 0x6a, 0x53, 0x6e, 0x9b, 0xdd, 0xa6, 0x8c, - 0x06, 0xda, 0x54, 0xd0, 0xda, 0x15, 0xb5, 0xf2, 0x5e, 0x75, 0x68, 0x57, 0xdc, 0x65, 0x97, 0x66, - 0xaa, 0x53, 0xcb, 0xcc, 0x6a, 0xb3, 0x1b, 0xa0, 0xda, 0x2c, 0x26, 0x70, 0x89, 0x79, 0xd9, 0xe8, - 0xeb, 0x6f, 0x3e, 0x95, 0xf0, 0xde, 0x48, 0x73, 0xb1, 0x32, 0x3f, 0x58, 0xa3, 0x32, 0xd7, 0x45, - 0x72, 0xf1, 0xde, 0x44, 0x85, 0xbe, 0x93, 0xab, 0x99, 0x6f, 0x5d, 0x1c, 0x89, 0xf2, 0x3e, 0xf9, - 0x74, 0x73, 0xd8, 0xa4, 0x1c, 0x19, 0x1b, 0xa6, 0x65, 0x24, 0x7f, 0x45, 0xf7, 0x65, 0xd4, 0xf0, - 0x48, 0x7c, 0xa2, 0x23, 0xf3, 0x03, 0x7e, 0xb7, 0x21, 0x62, 0x5f, 0xfe, 0x05, 0x00, 0x00, 0xff, - 0xff, 0x73, 0x69, 0xff, 0x16, 0xeb, 0x07, 0x00, 0x00, + // 570 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x96, 0x6f, 0x4f, 0xdb, 0x30, + 0x10, 0xc6, 0xb7, 0x17, 0x43, 0x9b, 0xc7, 0x00, 0x79, 0x2f, 0x26, 0x01, 0xed, 0x68, 0x37, 0x26, + 0xb1, 0x49, 0xcd, 0xc4, 0x3e, 0x01, 0x74, 0xac, 0x43, 0x48, 0x48, 0x83, 0x0a, 0x24, 0x24, 0x5e, + 0x98, 0xe4, 0xa0, 0x11, 0x4e, 0x1c, 0x62, 0x37, 0x1b, 0xdf, 0x76, 0x1f, 0x65, 0xaa, 0x5d, 0xbb, + 0x8e, 0xff, 0x94, 0xbd, 0x23, 0xf7, 0x7b, 0xee, 0x39, 0x5f, 0x72, 0x67, 0x8a, 0x70, 0x23, 0x52, + 0x41, 0x39, 0xd4, 0x4d, 0x9e, 0xc2, 0xa0, 0xaa, 0x99, 0x60, 0x78, 0xd5, 0x8e, 0x6d, 0xae, 0xcb, + 0xa7, 0x8c, 0x08, 0xa2, 0xf0, 0xfe, 0x03, 0x7a, 0x71, 0x31, 0x0b, 0xe1, 0x09, 0x7a, 0x7b, 0xf4, + 0x07, 0xd2, 0xa9, 0x00, 0xf9, 0x3c, 0x64, 0x45, 0x41, 0xca, 0x0c, 0xef, 0x0e, 0x16, 0x19, 0x01, + 0x7e, 0x06, 0x0f, 0x53, 0xe0, 0x62, 0xf3, 0xd3, 0x53, 0x32, 0x5e, 0xb1, 0x92, 0x43, 0xff, 0xd9, + 0xd7, 0xe7, 0xfb, 0x7f, 0xd7, 0xd0, 0x8a, 0x84, 0x19, 0xbe, 0x46, 0x1b, 0xc3, 0x09, 0x29, 0xef, + 0x60, 0x4c, 0x6e, 0x28, 0x88, 0xf1, 0x63, 0x05, 0xb8, 0x6f, 0x59, 0xb9, 0x50, 0x97, 0xfb, 0xb0, + 0x54, 0xa3, 0x6b, 0xe1, 0x4b, 0xb4, 0x36, 0xac, 0x81, 0x08, 0x38, 0x81, 0x47, 0x5e, 0x91, 0x14, + 0xf0, 0x8e, 0x9d, 0xd8, 0x42, 0xda, 0xba, 0xb7, 0x44, 0x61, 0x8c, 0x4f, 0xd1, 0x6b, 0xc5, 0xce, + 0x27, 0xa4, 0xce, 0x70, 0xc7, 0xcb, 0x91, 0x71, 0x6d, 0xd9, 0x8d, 0x61, 0xfb, 0xa0, 0xdf, 0x81, + 0x42, 0xe4, 0xa0, 0x6d, 0x14, 0x3a, 0xa8, 0xab, 0x30, 0xc6, 0xbf, 0xd0, 0xaa, 0x62, 0xb2, 0x22, + 0xc7, 0x5d, 0x2f, 0x49, 0x01, 0x6d, 0xfa, 0x3e, 0xca, 0x8d, 0xe5, 0x18, 0xbd, 0x51, 0x44, 0xbd, + 0x72, 0x8e, 0xfd, 0x9c, 0x39, 0xd1, 0xa6, 0x3b, 0x71, 0x81, 0x71, 0xad, 0xd1, 0xbb, 0x1f, 0x79, + 0x99, 0x1d, 0x50, 0xaa, 0x0a, 0x1e, 0x97, 0xe6, 0x55, 0xec, 0x59, 0xe9, 0x11, 0x8d, 0xae, 0xf4, + 0xf9, 0x7f, 0xa4, 0xa6, 0xe6, 0x09, 0x42, 0x23, 0x10, 0x87, 0x24, 0xbd, 0x9f, 0x56, 0x1c, 0x6f, + 0x5b, 0xb9, 0x8b, 0xb0, 0x76, 0xee, 0x44, 0xa8, 0x31, 0xbb, 0x46, 0x1b, 0x23, 0x10, 0x43, 0xa0, + 0xf4, 0xb8, 0xbc, 0x65, 0xa7, 0xa4, 0x00, 0xde, 0x1a, 0x65, 0x17, 0x86, 0x46, 0xd9, 0xd7, 0xd8, + 0x13, 0x67, 0x51, 0xdc, 0x09, 0x67, 0x85, 0x26, 0xae, 0x85, 0x8d, 0xdf, 0x15, 0x5a, 0x9f, 0x03, + 0x7e, 0x40, 0x73, 0xc2, 0x81, 0xe3, 0x9e, 0x9f, 0xa4, 0x99, 0xf6, 0xed, 0x2f, 0x93, 0x38, 0x67, + 0x35, 0xdf, 0xcf, 0x39, 0xab, 0xfb, 0xcd, 0xba, 0x31, 0x6c, 0x0f, 0xb1, 0x05, 0xda, 0x43, 0x6c, + 0x83, 0xd0, 0x10, 0xb7, 0xb9, 0xb1, 0xfc, 0x89, 0x5e, 0x8d, 0x40, 0x9c, 0xa7, 0x13, 0x28, 0x08, + 0xde, 0x6a, 0xeb, 0x55, 0x54, 0x9b, 0x6d, 0x87, 0xa1, 0x71, 0x3a, 0x42, 0x2f, 0x67, 0x61, 0x79, + 0x0f, 0x6c, 0x3a, 0x5a, 0xfb, 0x12, 0xd8, 0x0a, 0x32, 0x7b, 0xab, 0x66, 0xd1, 0xba, 0xb9, 0x98, + 0x1f, 0xca, 0x69, 0x62, 0x41, 0x42, 0x5b, 0xe5, 0x08, 0x9c, 0x36, 0xd5, 0xb6, 0xb9, 0x6d, 0xaa, + 0x68, 0xa4, 0x4d, 0x0d, 0x9d, 0x5d, 0xd1, 0x2b, 0x1f, 0x54, 0xc7, 0x76, 0xc5, 0x5f, 0x76, 0x65, + 0xa6, 0x3b, 0x75, 0xcc, 0x9c, 0x36, 0x3b, 0x11, 0xea, 0x4c, 0xc7, 0x25, 0xab, 0xef, 0x6f, 0x29, + 0xfb, 0xed, 0x4d, 0x87, 0x01, 0x91, 0xe9, 0xb0, 0xb8, 0xb1, 0x4c, 0x11, 0x3e, 0x83, 0x82, 0x35, + 0xe6, 0x46, 0x9d, 0x0d, 0x3a, 0xfe, 0x68, 0x25, 0xfa, 0x58, 0xdb, 0xef, 0x3e, 0xa1, 0xb2, 0x37, + 0x50, 0x71, 0x39, 0x0a, 0xb2, 0x42, 0xcf, 0xcb, 0x35, 0x2c, 0xb4, 0x81, 0x9e, 0x44, 0x7b, 0x1f, + 0x7e, 0xb9, 0xda, 0x6b, 0x72, 0x01, 0x9c, 0x0f, 0x72, 0x96, 0xa8, 0xbf, 0x92, 0x3b, 0x96, 0x34, + 0x22, 0x91, 0xff, 0xf5, 0x13, 0xfb, 0x37, 0xc1, 0xcd, 0x8a, 0x8c, 0x7d, 0xfb, 0x17, 0x00, 0x00, + 0xff, 0xff, 0xb0, 0xcb, 0xe1, 0x8e, 0x3e, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -232,6 +233,8 @@ type VtctldClient interface { GetTablets(ctx context.Context, in *vtctldata.GetTabletsRequest, opts ...grpc.CallOption) (*vtctldata.GetTabletsResponse, error) // GetVSchema returns the vschema for a keyspace. GetVSchema(ctx context.Context, in *vtctldata.GetVSchemaRequest, opts ...grpc.CallOption) (*vtctldata.GetVSchemaResponse, error) + // GetWorkflows returns a list of workflows for the given keyspace. + GetWorkflows(ctx context.Context, in *vtctldata.GetWorkflowsRequest, opts ...grpc.CallOption) (*vtctldata.GetWorkflowsResponse, error) // RemoveKeyspaceCell removes the specified cell from the Cells list for all // shards in the specified keyspace, as well as from the SrvKeyspace for that // keyspace in that cell. @@ -420,6 +423,15 @@ func (c *vtctldClient) GetVSchema(ctx context.Context, in *vtctldata.GetVSchemaR return out, nil } +func (c *vtctldClient) GetWorkflows(ctx context.Context, in *vtctldata.GetWorkflowsRequest, opts ...grpc.CallOption) (*vtctldata.GetWorkflowsResponse, error) { + out := new(vtctldata.GetWorkflowsResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetWorkflows", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) RemoveKeyspaceCell(ctx context.Context, in *vtctldata.RemoveKeyspaceCellRequest, opts ...grpc.CallOption) (*vtctldata.RemoveKeyspaceCellResponse, error) { out := new(vtctldata.RemoveKeyspaceCellResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/RemoveKeyspaceCell", in, out, opts...) @@ -494,6 +506,8 @@ type VtctldServer interface { GetTablets(context.Context, *vtctldata.GetTabletsRequest) (*vtctldata.GetTabletsResponse, error) // GetVSchema returns the vschema for a keyspace. GetVSchema(context.Context, *vtctldata.GetVSchemaRequest) (*vtctldata.GetVSchemaResponse, error) + // GetWorkflows returns a list of workflows for the given keyspace. + GetWorkflows(context.Context, *vtctldata.GetWorkflowsRequest) (*vtctldata.GetWorkflowsResponse, error) // RemoveKeyspaceCell removes the specified cell from the Cells list for all // shards in the specified keyspace, as well as from the SrvKeyspace for that // keyspace in that cell. @@ -564,6 +578,9 @@ func (*UnimplementedVtctldServer) GetTablets(ctx context.Context, req *vtctldata func (*UnimplementedVtctldServer) GetVSchema(ctx context.Context, req *vtctldata.GetVSchemaRequest) (*vtctldata.GetVSchemaResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetVSchema not implemented") } +func (*UnimplementedVtctldServer) GetWorkflows(ctx context.Context, req *vtctldata.GetWorkflowsRequest) (*vtctldata.GetWorkflowsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetWorkflows not implemented") +} func (*UnimplementedVtctldServer) RemoveKeyspaceCell(ctx context.Context, req *vtctldata.RemoveKeyspaceCellRequest) (*vtctldata.RemoveKeyspaceCellResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RemoveKeyspaceCell not implemented") } @@ -917,6 +934,24 @@ func _Vtctld_GetVSchema_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Vtctld_GetWorkflows_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetWorkflowsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetWorkflows(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetWorkflows", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetWorkflows(ctx, req.(*vtctldata.GetWorkflowsRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_RemoveKeyspaceCell_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.RemoveKeyspaceCellRequest) if err := dec(in); err != nil { @@ -1033,6 +1068,10 @@ var _Vtctld_serviceDesc = grpc.ServiceDesc{ MethodName: "GetVSchema", Handler: _Vtctld_GetVSchema_Handler, }, + { + MethodName: "GetWorkflows", + Handler: _Vtctld_GetWorkflows_Handler, + }, { MethodName: "RemoveKeyspaceCell", Handler: _Vtctld_RemoveKeyspaceCell_Handler, diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index db3a1390f32..a36b5c13797 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -199,6 +199,15 @@ func (client *gRPCVtctldClient) GetVSchema(ctx context.Context, in *vtctldatapb. return client.c.GetVSchema(ctx, in, opts...) } +// GetWorkflows is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetWorkflows(ctx context.Context, in *vtctldatapb.GetWorkflowsRequest, opts ...grpc.CallOption) (*vtctldatapb.GetWorkflowsResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetWorkflows(ctx, in, opts...) +} + // RemoveKeyspaceCell is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) RemoveKeyspaceCell(ctx context.Context, in *vtctldatapb.RemoveKeyspaceCellRequest, opts ...grpc.CallOption) (*vtctldatapb.RemoveKeyspaceCellResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 39f09fd66c5..8bfa475fade 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -30,6 +30,7 @@ import ( "vitess.io/vitess/go/vt/mysqlctl/mysqlctlproto" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vtctl/workflow" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tmclient" @@ -46,11 +47,18 @@ import ( type VtctldServer struct { ts *topo.Server tmc tmclient.TabletManagerClient + ws *workflow.Server } // NewVtctldServer returns a new VtctldServer for the given topo server. func NewVtctldServer(ts *topo.Server) *VtctldServer { - return &VtctldServer{ts: ts, tmc: tmclient.NewTabletManagerClient()} + tmc := tmclient.NewTabletManagerClient() + + return &VtctldServer{ + ts: ts, + tmc: tmc, + ws: workflow.NewServer(ts, tmc), + } } // ChangeTabletType is part of the vtctlservicepb.VtctldServer interface. @@ -610,6 +618,11 @@ func (s *VtctldServer) GetVSchema(ctx context.Context, req *vtctldatapb.GetVSche }, nil } +// GetWorkflows is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetWorkflows(ctx context.Context, req *vtctldatapb.GetWorkflowsRequest) (*vtctldatapb.GetWorkflowsResponse, error) { + return s.ws.GetWorkflows(ctx, req) +} + // RemoveKeyspaceCell is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) RemoveKeyspaceCell(ctx context.Context, req *vtctldatapb.RemoveKeyspaceCellRequest) (*vtctldatapb.RemoveKeyspaceCellResponse, error) { shards, err := s.ts.GetShardNames(ctx, req.Keyspace) diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go index 0fd14bd75ae..20aa3959e75 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go @@ -25,11 +25,13 @@ import ( "github.com/stretchr/testify/assert" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vttablet/tmclient" + querypb "vitess.io/vitess/go/vt/proto/query" replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -181,6 +183,17 @@ type TabletManagerClient struct { Error error } // keyed by tablet alias. + UndoDemoteMasterDelays map[string]time.Duration + // keyed by tablet alias + UndoDemoteMasterResults map[string]error + // tablet alias => duration + VReplicationExecDelays map[string]time.Duration + // tablet alias => query string => result + VReplicationExecResults map[string]map[string]struct { + Result *querypb.QueryResult + Error error + } + // keyed by tablet alias. WaitForPositionDelays map[string]time.Duration // keyed by tablet alias. injects a sleep to the end of the function // regardless of parent context timeout or error result. @@ -188,10 +201,6 @@ type TabletManagerClient struct { // WaitForPosition(tablet *topodatapb.Tablet, position string) error, so we // key by tablet alias and then by position. WaitForPositionResults map[string]map[string]error - // keyed by tablet alias. - UndoDemoteMasterDelays map[string]time.Duration - // keyed by tablet alias - UndoDemoteMasterResults map[string]error } // ChangeType is part of the tmclient.TabletManagerClient interface. @@ -529,3 +538,48 @@ func (fake *TabletManagerClient) UndoDemoteMaster(ctx context.Context, tablet *t return assert.AnError } + +// VReplicationExec is part of the tmclient.TabletManagerCLient interface. +func (fake *TabletManagerClient) VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error) { + if fake.VReplicationExecResults == nil { + return nil, assert.AnError + } + + if tablet.Alias == nil { + return nil, assert.AnError + } + + key := topoproto.TabletAliasString(tablet.Alias) + + if fake.VReplicationExecDelays != nil { + if delay, ok := fake.VReplicationExecDelays[key]; ok { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(delay): + // proceed to results + } + } + } + + if resultsForTablet, ok := fake.VReplicationExecResults[key]; ok { + // Round trip the expected query both to ensure it's valid and to + // standardize on capitalization and formatting. + stmt, err := sqlparser.Parse(query) + if err != nil { + return nil, err + } + + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("%v", stmt) + + parsedQuery := buf.ParsedQuery().Query + + // Now do the map lookup. + if result, ok := resultsForTablet[parsedQuery]; ok { + return result.Result, result.Error + } + } + + return nil, assert.AnError +} diff --git a/go/vt/vtctl/workflow/doc.go b/go/vt/vtctl/workflow/doc.go new file mode 100644 index 00000000000..c334470320f --- /dev/null +++ b/go/vt/vtctl/workflow/doc.go @@ -0,0 +1,45 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package workflow defines types and functions for working with Vitess workflows. + +This is still a very rough sketch, far from a final API, but I want to document +some things here as I go: + +(1) The lines between package workflow and package workflow/vexec are, uh, + blurry at best, and definitely need serious thinking and refinement. Maybe + there shouldn't even be two separate packages at all. The reason I have the + two packages right now is because I'm operating under the assumption that + there are workflows that are vexec, and then there are other workflows. If + it's true that all workflows are vexec workflows, then probably one single + package could make more sense. For now, two packages seems the way to go, + but like I said, the boundaries are blurry, and things that belong in one + package are in the other, because I haven't gone back and moved things + around. +(2) I'm aiming for this to be a drop-in replacement (more or less) for the + function calls in go/vt/wrangler. However, I'd rather define a better + abstraction if it means having to rewrite even significant portions of the + existing wrangler code to adapt to it, than make a subpar API in the name of + backwards compatibility. I'm not sure if that's a tradeoff I'll even need to + consider in the future, but I'm putting a stake in the ground on which side + of that tradeoff I intend to fall, should it come to it. +(3) Eventually we'll need to consider how the online schema migration workflows + fit into this. I'm trying to at least be somewhat abstract in the + vexec / queryplanner APIs to fit with the QueryParams thing that wrangler + uses, which _should_ work, but who knows?? Time will tell. +*/ +package workflow diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go new file mode 100644 index 00000000000..86c02718d4f --- /dev/null +++ b/go/vt/vtctl/workflow/server.go @@ -0,0 +1,341 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package workflow + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "k8s.io/apimachinery/pkg/util/sets" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vtctl/workflow/vexec" + "vitess.io/vitess/go/vt/vtgate/evalengine" + "vitess.io/vitess/go/vt/vttablet/tmclient" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + "vitess.io/vitess/go/vt/proto/vttime" +) + +var ( + // ErrInvalidWorkflow is a catchall error type for conditions that should be + // impossible when operating on a workflow. + ErrInvalidWorkflow = errors.New("invalid workflow") + // ErrMultipleSourceKeyspaces occurs when a workflow somehow has multiple + // source keyspaces across different shard primaries. This should be + // impossible. + ErrMultipleSourceKeyspaces = errors.New("multiple source keyspaces for a single workflow") + // ErrMultipleTargetKeyspaces occurs when a workflow somehow has multiple + // target keyspaces across different shard primaries. This should be + // impossible. + ErrMultipleTargetKeyspaces = errors.New("multiple target keyspaces for a single workflow") +) + +// Server provides an API to work with Vitess workflows, like vreplication +// workflows (MoveTables, Reshard, etc) and schema migration workflows. +// +// NB: This is in alpha, and you probably don't want to depend on it (yet!). +// Currently, it provides only a read-only API to vreplication workflows. Write +// actions on vreplication workflows, and schema migration workflows entirely, +// are not yet supported, but planned. +type Server struct { + ts *topo.Server + tmc tmclient.TabletManagerClient +} + +// NewServer returns a new server instance with the given topo.Server and +// TabletManagerClient. +func NewServer(ts *topo.Server, tmc tmclient.TabletManagerClient) *Server { + return &Server{ + ts: ts, + tmc: tmc, + } +} + +// GetWorkflows returns a list of all workflows that exist in a given keyspace, +// with some additional filtering depending on the request parameters (for +// example, ActiveOnly=true restricts the search to only workflows that are +// currently running). +// +// It has the same signature as the vtctlservicepb.VtctldServer's GetWorkflows +// rpc, and grpcvtctldserver delegates to this function. +func (s *Server) GetWorkflows(ctx context.Context, req *vtctldatapb.GetWorkflowsRequest) (*vtctldatapb.GetWorkflowsResponse, error) { + where := "" + if req.ActiveOnly { + where = "WHERE state <> 'Stopped'" + } + + query := fmt.Sprintf(` + SELECT + id, + workflow, + source, + pos, + stop_pos, + max_replication_lag, + state, + db_name, + time_updated, + transaction_timestamp, + message + FROM + _vt.vreplication + %s`, + where, + ) + + vx := vexec.NewVExec(req.Keyspace, "", s.ts, s.tmc) + results, err := vx.QueryContext(ctx, query) + if err != nil { + return nil, err + } + + workflowsMap := make(map[string]*vtctldatapb.Workflow, len(results)) + sourceKeyspaceByWorkflow := make(map[string]string, len(results)) + sourceShardsByWorkflow := make(map[string]sets.String, len(results)) + targetKeyspaceByWorkflow := make(map[string]string, len(results)) + targetShardsByWorkflow := make(map[string]sets.String, len(results)) + maxVReplicationLagByWorkflow := make(map[string]float64, len(results)) + + // We guarantee the following invariants when this function is called for a + // given workflow: + // - workflow.Name != "" (more precisely, ".Name is set 'properly'") + // - workflowsMap[workflow.Name] == workflow + // - sourceShardsByWorkflow[workflow.Name] != nil + // - targetShardsByWorkflow[workflow.Name] != nil + // - workflow.ShardStatuses != nil + scanWorkflow := func(ctx context.Context, workflow *vtctldatapb.Workflow, row []sqltypes.Value, tablet *topo.TabletInfo) error { + id, err := evalengine.ToInt64(row[0]) + if err != nil { + return err + } + + var bls binlogdatapb.BinlogSource + if err := proto.UnmarshalText(row[2].ToString(), &bls); err != nil { + return err + } + + pos := row[3].ToString() + stopPos := row[4].ToString() + state := row[6].ToString() + dbName := row[7].ToString() + + timeUpdatedSeconds, err := evalengine.ToInt64(row[8]) + if err != nil { + return err + } + + transactionTimeSeconds, err := evalengine.ToInt64(row[9]) + if err != nil { + return err + } + + message := row[10].ToString() + + stream := &vtctldatapb.Workflow_Stream{ + Id: id, + Shard: tablet.Shard, + Tablet: tablet.Alias, + BinlogSource: &bls, + Position: pos, + StopPosition: stopPos, + State: state, + DbName: dbName, + TransactionTimestamp: &vttime.Time{ + Seconds: transactionTimeSeconds, + }, + TimeUpdated: &vttime.Time{ + Seconds: timeUpdatedSeconds, + }, + Message: message, + } + + stream.CopyStates, err = s.getWorkflowCopyStates(ctx, tablet, id) + if err != nil { + return err + } + + switch { + case strings.Contains(strings.ToLower(stream.Message), "error"): + stream.State = "Error" + case stream.State == "Running" && len(stream.CopyStates) > 0: + stream.State = "Copying" + case stream.State == "Running" && int64(time.Now().Second())-timeUpdatedSeconds > 10: + stream.State = "Lagging" + } + + shardStreamKey := fmt.Sprintf("%s/%s", tablet.Shard, tablet.AliasString()) + shardStream, ok := workflow.ShardStreams[shardStreamKey] + if !ok { + ctx, cancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancel() + + si, err := s.ts.GetShard(ctx, req.Keyspace, tablet.Shard) + if err != nil { + return err + } + + shardStream = &vtctldatapb.Workflow_ShardStream{ + Streams: nil, + TabletControls: si.TabletControls, + IsPrimaryServing: si.IsMasterServing, + } + + workflow.ShardStreams[shardStreamKey] = shardStream + } + + shardStream.Streams = append(shardStream.Streams, stream) + sourceShardsByWorkflow[workflow.Name].Insert(stream.BinlogSource.Shard) + targetShardsByWorkflow[workflow.Name].Insert(tablet.Shard) + + if ks, ok := sourceKeyspaceByWorkflow[workflow.Name]; ok && ks != stream.BinlogSource.Keyspace { + return fmt.Errorf("%w: workflow = %v, ks1 = %v, ks2 = %v", ErrMultipleSourceKeyspaces, workflow.Name, ks, stream.BinlogSource.Keyspace) + } + + sourceKeyspaceByWorkflow[workflow.Name] = stream.BinlogSource.Keyspace + + if ks, ok := targetKeyspaceByWorkflow[workflow.Name]; ok && ks != tablet.Keyspace { + return fmt.Errorf("%w: workflow = %v, ks1 = %v, ks2 = %v", ErrMultipleTargetKeyspaces, workflow.Name, ks, tablet.Keyspace) + } + + targetKeyspaceByWorkflow[workflow.Name] = tablet.Keyspace + + timeUpdated := time.Unix(timeUpdatedSeconds, 0) + vreplicationLag := time.Since(timeUpdated) + + if currentMaxLag, ok := maxVReplicationLagByWorkflow[workflow.Name]; ok { + if vreplicationLag.Seconds() > currentMaxLag { + maxVReplicationLagByWorkflow[workflow.Name] = vreplicationLag.Seconds() + } + } else { + maxVReplicationLagByWorkflow[workflow.Name] = vreplicationLag.Seconds() + } + + return nil + } + + for tablet, result := range results { + qr := sqltypes.Proto3ToResult(result) + + // In the old implementation, we knew we had at most one (0 <= N <= 1) + // workflow for each shard primary we queried. There might be multiple + // rows (streams) comprising that workflow, so we would aggregate the + // rows for a given primary into a single value ("the workflow", + // ReplicationStatusResult in the old types). + // + // In this version, we have many (N >= 0) workflows for each shard + // primary we queried, so we need to determine if each row corresponds + // to a workflow we're already aggregating, or if it's a workflow we + // haven't seen yet for that shard primary. We use the workflow name to + // dedupe for this. + for _, row := range qr.Rows { + workflowName := row[1].ToString() + workflow, ok := workflowsMap[workflowName] + if !ok { + workflow = &vtctldatapb.Workflow{ + Name: workflowName, + ShardStreams: map[string]*vtctldatapb.Workflow_ShardStream{}, + } + + workflowsMap[workflowName] = workflow + sourceShardsByWorkflow[workflowName] = sets.NewString() + targetShardsByWorkflow[workflowName] = sets.NewString() + } + + if err := scanWorkflow(ctx, workflow, row, tablet); err != nil { + return nil, err + } + } + } + + workflows := make([]*vtctldatapb.Workflow, 0, len(workflowsMap)) + + for name, workflow := range workflowsMap { + sourceShards, ok := sourceShardsByWorkflow[name] + if !ok { + return nil, fmt.Errorf("%w: %s has no source shards", ErrInvalidWorkflow, name) + } + + sourceKeyspace, ok := sourceKeyspaceByWorkflow[name] + if !ok { + return nil, fmt.Errorf("%w: %s has no source keyspace", ErrInvalidWorkflow, name) + } + + targetShards, ok := targetShardsByWorkflow[name] + if !ok { + return nil, fmt.Errorf("%w: %s has no target shards", ErrInvalidWorkflow, name) + } + + targetKeyspace, ok := targetKeyspaceByWorkflow[name] + if !ok { + return nil, fmt.Errorf("%w: %s has no target keyspace", ErrInvalidWorkflow, name) + } + + maxVReplicationLag, ok := maxVReplicationLagByWorkflow[name] + if !ok { + return nil, fmt.Errorf("%w: %s has no tracked vreplication lag", ErrInvalidWorkflow, name) + } + + workflow.Source = &vtctldatapb.Workflow_ReplicationLocation{ + Keyspace: sourceKeyspace, + Shards: sourceShards.List(), + } + + workflow.Target = &vtctldatapb.Workflow_ReplicationLocation{ + Keyspace: targetKeyspace, + Shards: targetShards.List(), + } + + workflow.MaxVReplicationLag = int64(maxVReplicationLag) + + workflows = append(workflows, workflow) + } + + return &vtctldatapb.GetWorkflowsResponse{ + Workflows: workflows, + }, nil +} + +func (s *Server) getWorkflowCopyStates(ctx context.Context, tablet *topo.TabletInfo, id int64) ([]*vtctldatapb.Workflow_Stream_CopyState, error) { + query := fmt.Sprintf("select table_name, lastpk from _vt.copy_state where vrepl_id = %d", id) + qr, err := s.tmc.VReplicationExec(ctx, tablet.Tablet, query) + if err != nil { + return nil, err + } + + result := sqltypes.Proto3ToResult(qr) + if result == nil { + return nil, nil + } + + copyStates := make([]*vtctldatapb.Workflow_Stream_CopyState, len(result.Rows)) + for i, row := range result.Rows { + // These fields are technically varbinary, but this is close enough. + copyStates[i] = &vtctldatapb.Workflow_Stream_CopyState{ + Table: row[0].ToString(), + LastPk: row[1].ToString(), + } + } + + return copyStates, nil +} diff --git a/go/vt/vtctl/workflow/vexec/query_plan.go b/go/vt/vtctl/workflow/vexec/query_plan.go new file mode 100644 index 00000000000..f71e124b786 --- /dev/null +++ b/go/vt/vtctl/workflow/vexec/query_plan.go @@ -0,0 +1,116 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vexec + +import ( + "context" + "fmt" + "sync" + + "vitess.io/vitess/go/vt/concurrency" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/tmclient" + + querypb "vitess.io/vitess/go/vt/proto/query" +) + +// QueryPlan wraps a planned query produced by a QueryPlanner. It is safe to +// execute a QueryPlan repeatedly and in multiple goroutines. +type QueryPlan struct { + ParsedQuery *sqlparser.ParsedQuery + + workflow string + tmc tmclient.TabletManagerClient +} + +// Execute executes a QueryPlan on a single target. +func (qp *QueryPlan) Execute(ctx context.Context, target *topo.TabletInfo) (qr *querypb.QueryResult, err error) { + if qp.ParsedQuery == nil { + return nil, fmt.Errorf("%w: call PlanQuery on a query planner first", ErrUnpreparedQuery) + } + + targetAliasStr := target.AliasString() + + log.Infof("Running %v on %v", qp.ParsedQuery.Query, targetAliasStr) + defer func() { + if err != nil { + log.Warningf("Result on %v: %v", targetAliasStr, err) + + return + } + + log.Infof("Result on %v: %v", targetAliasStr, qr) + }() + + qr, err = qp.tmc.VReplicationExec(ctx, target.Tablet, qp.ParsedQuery.Query) + if err != nil { + return nil, err + } + + if qr.RowsAffected == 0 { + log.Infof("no matching streams found for workflows %s, tablet %s, query %s", qp.workflow, targetAliasStr, qp.ParsedQuery.Query) + } + + return qr, nil +} + +// ExecuteScatter executes a QueryPlan on multiple targets concurrently, +// returning a mapping of target tablet to querypb.QueryResult. Errors from +// individual targets are aggregated into a singular error. +func (qp *QueryPlan) ExecuteScatter(ctx context.Context, targets ...*topo.TabletInfo) (map[*topo.TabletInfo]*querypb.QueryResult, error) { + if qp.ParsedQuery == nil { + // This check is an "optimization" on error handling. We check here, + // even though we will check this during the individual Execute calls, + // so that we return one error, rather than the same error aggregated + // len(targets) times. + return nil, fmt.Errorf("%w: call PlanQuery on a query planner first", ErrUnpreparedQuery) + } + + var ( + m sync.Mutex + wg sync.WaitGroup + rec concurrency.AllErrorRecorder + results = make(map[*topo.TabletInfo]*querypb.QueryResult, len(targets)) + ) + + for _, target := range targets { + wg.Add(1) + + go func(ctx context.Context, target *topo.TabletInfo) { + defer wg.Done() + + qr, err := qp.Execute(ctx, target) + if err != nil { + rec.RecordError(err) + + return + } + + m.Lock() + defer m.Unlock() + + results[target] = qr + }(ctx, target) + } + + wg.Wait() + + return results, rec.AggrError(vterrors.Aggregate) +} diff --git a/go/vt/vtctl/workflow/vexec/query_plan_test.go b/go/vt/vtctl/workflow/vexec/query_plan_test.go new file mode 100644 index 00000000000..ec4f6fab95d --- /dev/null +++ b/go/vt/vtctl/workflow/vexec/query_plan_test.go @@ -0,0 +1,332 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vexec + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" + + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +func TestQueryPlanExecute(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + plan QueryPlan + target *topo.TabletInfo + expected *querypb.QueryResult + shouldErr bool + errKind error + }{ + { + name: "success", + plan: QueryPlan{ + ParsedQuery: &sqlparser.ParsedQuery{ + Query: "SELECT id FROM _vt.vreplication", + }, + tmc: &testutil.TabletManagerClient{ + VReplicationExecResults: map[string]map[string]struct { + Result *querypb.QueryResult + Error error + }{ + "zone1-0000000100": { + "select id from _vt.vreplication": { + Result: &querypb.QueryResult{ + RowsAffected: 1, + }, + }, + }, + }, + }, + }, + target: &topo.TabletInfo{ + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + expected: &querypb.QueryResult{ + RowsAffected: 1, + }, + shouldErr: false, + }, + { + name: "no rows affected", + plan: QueryPlan{ + ParsedQuery: &sqlparser.ParsedQuery{ + Query: "SELECT id FROM _vt.vreplication", + }, + tmc: &testutil.TabletManagerClient{ + VReplicationExecResults: map[string]map[string]struct { + Result *querypb.QueryResult + Error error + }{ + "zone1-0000000100": { + "select id from _vt.vreplication": { + Result: &querypb.QueryResult{ + RowsAffected: 0, + }, + }, + }, + }, + }, + }, + target: &topo.TabletInfo{ + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + expected: &querypb.QueryResult{ + RowsAffected: 0, + }, + shouldErr: false, + }, + { + name: "error", + plan: QueryPlan{ + ParsedQuery: &sqlparser.ParsedQuery{ + Query: "SELECT id FROM _vt.vreplication", + }, + tmc: &testutil.TabletManagerClient{ + VReplicationExecResults: map[string]map[string]struct { + Result *querypb.QueryResult + Error error + }{ + "zone1-0000000100": { + "select id from _vt.vreplication": { + Error: assert.AnError, + }, + }, + }, + }, + }, + target: &topo.TabletInfo{ + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + expected: nil, + shouldErr: true, + }, + { + name: "unprepared query", + plan: QueryPlan{ + ParsedQuery: nil, + }, + shouldErr: true, + errKind: ErrUnpreparedQuery, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + ctx := context.Background() + + qr, err := tt.plan.Execute(ctx, tt.target) + if tt.shouldErr { + assert.Error(t, err) + + if tt.errKind != nil { + assert.True(t, errors.Is(err, tt.errKind), "expected error kind (= %v), got = %v", tt.errKind, err) + } + + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expected, qr) + }) + } +} + +func TestQueryPlanExecuteScatter(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + plan QueryPlan + targets []*topo.TabletInfo + // This is different from our actual return type because guaranteeing + // exact pointers in this table-driven style is a bit tough. + expected map[string]*querypb.QueryResult + shouldErr bool + errKind error + }{ + { + name: "success", + plan: QueryPlan{ + ParsedQuery: &sqlparser.ParsedQuery{ + Query: "SELECT id FROM _vt.vreplication", + }, + tmc: &testutil.TabletManagerClient{ + VReplicationExecResults: map[string]map[string]struct { + Result *querypb.QueryResult + Error error + }{ + "zone1-0000000100": { + "select id from _vt.vreplication": { + Result: &querypb.QueryResult{ + RowsAffected: 10, + }, + }, + }, + "zone1-0000000101": { + "select id from _vt.vreplication": { + Result: &querypb.QueryResult{ + RowsAffected: 5, + }, + }, + }, + }, + }, + }, + targets: []*topo.TabletInfo{ + { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + }, + }, + }, + expected: map[string]*querypb.QueryResult{ + "zone1-0000000100": { + RowsAffected: 10, + }, + "zone1-0000000101": { + RowsAffected: 5, + }, + }, + shouldErr: false, + }, + { + name: "some targets fail", + plan: QueryPlan{ + ParsedQuery: &sqlparser.ParsedQuery{ + Query: "SELECT id FROM _vt.vreplication", + }, + tmc: &testutil.TabletManagerClient{ + VReplicationExecResults: map[string]map[string]struct { + Result *querypb.QueryResult + Error error + }{ + "zone1-0000000100": { + "select id from _vt.vreplication": { + Error: assert.AnError, + }, + }, + "zone1-0000000101": { + "select id from _vt.vreplication": { + Result: &querypb.QueryResult{ + RowsAffected: 5, + }, + }, + }, + }, + }, + }, + targets: []*topo.TabletInfo{ + { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + { + Tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + }, + }, + }, + shouldErr: true, + }, + { + name: "unprepared query", + plan: QueryPlan{ + ParsedQuery: nil, + }, + shouldErr: true, + errKind: ErrUnpreparedQuery, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + ctx := context.Background() + + results, err := tt.plan.ExecuteScatter(ctx, tt.targets...) + if tt.shouldErr { + assert.Error(t, err) + + if tt.errKind != nil { + assert.True(t, errors.Is(err, tt.errKind), "expected error kind (= %v), got = %v", tt.errKind, err) + } + + return + } + + assert.NoError(t, err) + + resultsByAlias := make(map[string]*querypb.QueryResult, len(results)) + for tablet, qr := range results { + resultsByAlias[tablet.AliasString()] = qr + } + + assert.Equal(t, tt.expected, resultsByAlias) + }) + } +} diff --git a/go/vt/vtctl/workflow/vexec/query_planner.go b/go/vt/vtctl/workflow/vexec/query_planner.go new file mode 100644 index 00000000000..a850cc9816a --- /dev/null +++ b/go/vt/vtctl/workflow/vexec/query_planner.go @@ -0,0 +1,326 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vexec + +import ( + "errors" + "fmt" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vttablet/tmclient" +) + +var ( // Query planning errors. + // ErrCannotUpdateImmutableColumn is returned when attempting to plan a + // query that updates a column that should be treated as immutable. + ErrCannotUpdateImmutableColumn = errors.New("cannot update immutable column") + // ErrUnsupportedQueryConstruct is returned when a particular query + // construct is unsupported by a QueryPlanner, despite the more general kind + // of query being supported. + // + // For example, VReplication supports DELETEs, but does not support DELETEs + // with LIMIT clauses, so planning a "DELETE ... LIMIT" will return + // ErrUnsupportedQueryConstruct rather than a "CREATE TABLE", which would + // return an ErrUnsupportedQuery. + ErrUnsupportedQueryConstruct = errors.New("unsupported query construct") +) + +var ( // Query execution errors. + // ErrUnpreparedQuery is returned when attempting to execute an unprepared + // QueryPlan. + ErrUnpreparedQuery = errors.New("attempted to execute unprepared query") +) + +// QueryPlanner defines the interface that VExec uses to build QueryPlans for +// various vexec workflows. A given vexec table, which is to say a table in the +// "_vt" database, will have at most one QueryPlanner implementation, which is +// responsible for defining both what queries are supported for that table, as +// well as how to build plans for those queries. +// +// VReplicationQueryPlanner is a good example implementation to refer to. +type QueryPlanner interface { + // (NOTE:@ajm188) I don't think this method fits on the query planner. To + // me, especially given that it's only implemented by the vrep query planner + // in the old implementation (the schema migration query planner no-ops this + // method), this fits better on our workflow.Manager struct, probably as a + // method called something like "VReplicationExec(ctx, query, Options{DryRun: true})" + // DryRun(ctx context.Context) error + + // PlanQuery constructs and returns a QueryPlan for a given statement. The + // resulting QueryPlan is suitable for repeated, concurrent use. + PlanQuery(stmt sqlparser.Statement) (*QueryPlan, error) + // QueryParams returns a struct of column parameters the QueryPlanner uses. + // It is used primarily to abstract the adding of default WHERE clauses to + // queries by a private function of this package, and may be removed from + // the interface later. + QueryParams() QueryParams +} + +// QueryParams is a struct that QueryPlanner implementations can provide to +// control the addition of default WHERE clauses to their queries. +type QueryParams struct { + // DBName is the value that the column referred to by DBNameColumn should + // equal in a WHERE clause, if set. + DBName string + // DBNameColumn is the name of the column that DBName should equal in a + // WHERE clause, if set. + DBNameColumn string + // Workflow is the value that the column referred to by WorkflowColumn + // should equal in a WHERE clause, if set. + Workflow string + // WorkflowColumn is the name of the column that Workflow should equal in a + // WHERE clause, if set. + WorkflowColumn string +} + +// VReplicationQueryPlanner implements the QueryPlanner interface for queries on +// the _vt.vreplication table. +type VReplicationQueryPlanner struct { + tmc tmclient.TabletManagerClient + + dbname string + workflow string +} + +// NewVReplicationQueryPlanner returns a new VReplicationQueryPlanner. It is +// valid to pass empty strings for both the dbname and workflow parameters. +func NewVReplicationQueryPlanner(tmc tmclient.TabletManagerClient, workflow string, dbname string) *VReplicationQueryPlanner { + return &VReplicationQueryPlanner{ + tmc: tmc, + dbname: dbname, + workflow: workflow, + } +} + +// PlanQuery is part of the QueryPlanner interface. +// +// For vreplication query planners, only SELECT, UPDATE, and DELETE queries are +// supported. +// +// For UPDATE queries, ORDER BY and LIMIT clauses are not supported. Attempting +// to update vreplication.id is an error. +// +// For DELETE queries, USING, PARTITION, ORDER BY, and LIMIT clauses are not +// supported. +func (planner *VReplicationQueryPlanner) PlanQuery(stmt sqlparser.Statement) (plan *QueryPlan, err error) { + switch stmt := stmt.(type) { + case *sqlparser.Select: + plan, err = planner.planSelect(stmt) + case *sqlparser.Insert: + err = ErrUnsupportedQuery + case *sqlparser.Update: + plan, err = planner.planUpdate(stmt) + case *sqlparser.Delete: + plan, err = planner.planDelete(stmt) + default: + err = ErrUnsupportedQuery + } + + if err != nil { + return nil, fmt.Errorf("%w: %s", err, sqlparser.String(stmt)) + } + + return plan, nil +} + +// QueryParams is part of the QueryPlanner interface. A VReplicationQueryPlanner +// will attach the following WHERE clauses iff (a) DBName, Workflow are set, +// respectively, and (b) db_name and workflow do not appear in the original +// query's WHERE clause: +// +// WHERE (db_name = {{ .DBName }} AND)? (workflow = {{ .Workflow }} AND)? {{ .OriginalWhere }} +func (planner *VReplicationQueryPlanner) QueryParams() QueryParams { + return QueryParams{ + DBName: planner.dbname, + DBNameColumn: "db_name", + Workflow: planner.workflow, + WorkflowColumn: "workflow", + } +} + +func (planner *VReplicationQueryPlanner) planDelete(del *sqlparser.Delete) (*QueryPlan, error) { + if del.Targets != nil { + return nil, fmt.Errorf( + "%w: DELETE must not have USING clause (have: %v): %v", + ErrUnsupportedQueryConstruct, + del.Targets, + sqlparser.String(del), + ) + } + + if del.Partitions != nil { + return nil, fmt.Errorf( + "%w: DELETE must not have explicit partitions (have: %v): %v", + ErrUnsupportedQueryConstruct, + del.Partitions, + sqlparser.String(del), + ) + } + + if del.OrderBy != nil || del.Limit != nil { + return nil, fmt.Errorf( + "%w: DELETE must not have explicit ordering (have: %v) or limit clauses (have: %v): %v", + ErrUnsupportedQueryConstruct, + del.OrderBy, + del.Limit, + sqlparser.String(del), + ) + } + + del.Where = addDefaultWheres(planner, del.Where) + + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("%v", del) + + return &QueryPlan{ + ParsedQuery: buf.ParsedQuery(), + workflow: planner.workflow, + tmc: planner.tmc, + }, nil +} + +func (planner *VReplicationQueryPlanner) planSelect(sel *sqlparser.Select) (*QueryPlan, error) { + sel.Where = addDefaultWheres(planner, sel.Where) + + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("%v", sel) + + return &QueryPlan{ + ParsedQuery: buf.ParsedQuery(), + workflow: planner.workflow, + tmc: planner.tmc, + }, nil +} + +func (planner *VReplicationQueryPlanner) planUpdate(upd *sqlparser.Update) (*QueryPlan, error) { + if upd.OrderBy != nil || upd.Limit != nil { + return nil, fmt.Errorf( + "%w: UPDATE must not have explicit ordering (have: %v) or limit clauses (have: %v): %v", + ErrUnsupportedQueryConstruct, + upd.OrderBy, + upd.Limit, + sqlparser.String(upd), + ) + } + + // For updates on the _vt.vreplication table, we ban updates to the `id` + // column, and allow updates to all other columns. + for _, expr := range upd.Exprs { + if expr.Name.Name.EqualString("id") { + return nil, fmt.Errorf( + "%w %+v: %v", + ErrCannotUpdateImmutableColumn, + expr.Name.Name, + sqlparser.String(expr), + ) + } + } + + upd.Where = addDefaultWheres(planner, upd.Where) + + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("%v", upd) + + return &QueryPlan{ + ParsedQuery: buf.ParsedQuery(), + workflow: planner.workflow, + tmc: planner.tmc, + }, nil +} + +func addDefaultWheres(planner QueryPlanner, where *sqlparser.Where) *sqlparser.Where { + cols := extractWhereComparisonColumns(where) + + params := planner.QueryParams() + hasDBNameCol := false + hasWorkflowCol := false + + for _, col := range cols { + switch col { + case params.DBNameColumn: + hasDBNameCol = true + case params.WorkflowColumn: + hasWorkflowCol = true + } + } + + newWhere := where + + if !hasDBNameCol { + expr := &sqlparser.ComparisonExpr{ + Left: &sqlparser.ColName{ + Name: sqlparser.NewColIdent(params.DBNameColumn), + }, + Operator: sqlparser.EqualOp, + Right: sqlparser.NewStrLiteral([]byte(params.DBName)), + } + + switch newWhere { + case nil: + newWhere = &sqlparser.Where{ + Type: sqlparser.WhereClause, + Expr: expr, + } + default: + newWhere.Expr = &sqlparser.AndExpr{ + Left: newWhere.Expr, + Right: expr, + } + } + } + + if !hasWorkflowCol && params.Workflow != "" { + expr := &sqlparser.ComparisonExpr{ + Left: &sqlparser.ColName{ + Name: sqlparser.NewColIdent(params.WorkflowColumn), + }, + Operator: sqlparser.EqualOp, + Right: sqlparser.NewStrLiteral([]byte(params.Workflow)), + } + + newWhere.Expr = &sqlparser.AndExpr{ + Left: newWhere.Expr, + Right: expr, + } + } + + return newWhere +} + +// extractWhereComparisonColumns extracts the column names used in AND-ed +// comparison expressions in a where clause, given the following assumptions: +// - (1) The column name is always the left-hand side of the comparison. +// - (2) There are no compound expressions within the where clause involving OR. +func extractWhereComparisonColumns(where *sqlparser.Where) []string { + if where == nil { + return nil + } + + exprs := sqlparser.SplitAndExpression(nil, where.Expr) + cols := make([]string, 0, len(exprs)) + + for _, expr := range exprs { + switch expr := expr.(type) { + case *sqlparser.ComparisonExpr: + if qualifiedName, ok := expr.Left.(*sqlparser.ColName); ok { + cols = append(cols, qualifiedName.Name.String()) + } + } + } + + return cols +} diff --git a/go/vt/vtctl/workflow/vexec/query_planner_test.go b/go/vt/vtctl/workflow/vexec/query_planner_test.go new file mode 100644 index 00000000000..a63fbb96a65 --- /dev/null +++ b/go/vt/vtctl/workflow/vexec/query_planner_test.go @@ -0,0 +1,244 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vexec + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + + "vitess.io/vitess/go/vt/vtctl/workflow/vexec/testutil" +) + +func TestVReplicationQueryPlanner_PlanQuery(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + query string + err error + }{ + { + name: "basic select", + query: "SELECT id FROM _vt.vreplication", + err: nil, + }, + { + name: "insert not supported", + query: "INSERT INTO _vt.vreplication (id) VALUES (1)", + err: ErrUnsupportedQuery, + }, + { + name: "basic update", + query: "UPDATE _vt.vreplication SET workflow = 'my workflow'", + err: nil, + }, + { + name: "basic delete", + query: "DELETE FROM _vt.vreplication", + err: nil, + }, + { + name: "other query", + query: "CREATE TABLE foo (id INT(11) PRIMARY KEY NOT NULL) ENGINE=InnoDB", + err: ErrUnsupportedQuery, + }, + } + + planner := NewVReplicationQueryPlanner(nil, "", "") + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + stmt := testutil.StatementFromString(t, tt.query) + + _, err := planner.PlanQuery(stmt) + if tt.err != nil { + assert.True(t, errors.Is(err, tt.err), "expected err of type %v, got %v", tt.err, err) + + return + } + + assert.NoError(t, err) + }) + } +} + +func TestVReplicationQueryPlanner_planSelect(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + query string + expectedPlannedQuery string + }{ + { + name: "simple select", + query: "SELECT id FROM _vt.vreplication WHERE id > 10", + expectedPlannedQuery: "SELECT id FROM _vt.vreplication WHERE id > 10 AND db_name = 'vt_testkeyspace' AND workflow = 'testworkflow'", + }, + { + name: "select with workflow and dbname columns already in WHERE", + query: "SELECT id FROM _vt.vreplication WHERE id > 10 AND db_name = 'vt_testkeyspace' AND workflow = 'testworkflow'", + expectedPlannedQuery: "SELECT id FROM _vt.vreplication WHERE id > 10 AND db_name = 'vt_testkeyspace' AND workflow = 'testworkflow'", + }, + { + // In this case, the QueryParams for the planner (which have + // workflow = "testworkflow"; db_name = "vt_testkeyspace") are + // ignored because the WHERE clause was explicit. + name: "select with workflow and dbname columns with different values", + query: "SELECT id FROM _vt.vreplication WHERE id > 10 AND db_name = 'different_keyspace' AND workflow = 'otherworkflow'", + expectedPlannedQuery: "SELECT id FROM _vt.vreplication WHERE id > 10 AND db_name = 'different_keyspace' AND workflow = 'otherworkflow'", + }, + } + + planner := NewVReplicationQueryPlanner(nil, "testworkflow", "vt_testkeyspace") + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + stmt := testutil.StatementFromString(t, tt.query) + qp, err := planner.PlanQuery(stmt) + + assert.NoError(t, err) + assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), qp.ParsedQuery) + }) + } +} + +func TestVReplicationQueryPlanner_planUpdate(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + planner *VReplicationQueryPlanner + query string + expectedPlannedQuery string + expectedErr error + }{ + { + name: "simple update", + planner: NewVReplicationQueryPlanner(nil, "testworkflow", "vt_testkeyspace"), + query: "UPDATE _vt.vreplication SET state = 'Running'", + expectedPlannedQuery: "UPDATE _vt.vreplication SET state = 'Running' WHERE db_name = 'vt_testkeyspace' AND workflow = 'testworkflow'", + expectedErr: nil, + }, + { + name: "including an ORDER BY is an error", + planner: NewVReplicationQueryPlanner(nil, "", ""), + query: "UPDATE _vt.vreplication SET state = 'Running' ORDER BY id DESC", + expectedErr: ErrUnsupportedQueryConstruct, + }, + { + name: "including a LIMIT is an error", + planner: NewVReplicationQueryPlanner(nil, "", ""), + query: "UPDATE _vt.vreplication SET state = 'Running' LIMIT 5", + expectedErr: ErrUnsupportedQueryConstruct, + }, + { + name: "cannot update id column", + planner: NewVReplicationQueryPlanner(nil, "", "vt_testkeyspace"), + query: "UPDATE _vt.vreplication SET id = 5", + expectedErr: ErrCannotUpdateImmutableColumn, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + stmt := testutil.StatementFromString(t, tt.query) + + qp, err := tt.planner.PlanQuery(stmt) + if tt.expectedErr != nil { + assert.True(t, errors.Is(err, tt.expectedErr), "expected err of type %q, got %q", tt.expectedErr, err) + + return + } + + assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), qp.ParsedQuery) + }) + } +} + +func TestVReplicationQueryPlanner_planDelete(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + query string + expectedPlannedQuery string + expectedErr error + }{ + { + name: "simple delete", + query: "DELETE FROM _vt.vreplication WHERE id = 1", + expectedPlannedQuery: "DELETE FROM _vt.vreplication WHERE id = 1 AND db_name = 'vt_testkeyspace'", + expectedErr: nil, + }, + { + name: "DELETE with USING clause is not supported", + query: "DELETE FROM _vt.vreplication, _vt.schema_migrations USING _vt.vreplication INNER JOIN _vt.schema_migrations", + expectedErr: ErrUnsupportedQueryConstruct, + }, + { + name: "DELETE with a PARTITION clause is not supported", + query: "DELETE FROM _vt.vreplication PARTITION (p1)", + expectedErr: ErrUnsupportedQueryConstruct, + }, + { + name: "DELETE with ORDER BY is not supported", + query: "DELETE FROM _vt.vreplication ORDER BY id DESC", + expectedErr: ErrUnsupportedQueryConstruct, + }, + { + name: "DELETE with LIMIT is not supported", + query: "DELETE FROM _vt.vreplication LIMIT 5", + expectedErr: ErrUnsupportedQueryConstruct, + }, + } + + planner := NewVReplicationQueryPlanner(nil, "", "vt_testkeyspace") + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + stmt := testutil.StatementFromString(t, tt.query) + + qp, err := planner.PlanQuery(stmt) + if tt.expectedErr != nil { + assert.True(t, errors.Is(err, tt.expectedErr), "expected err of type %q, got %q", tt.expectedErr, err) + + return + } + + assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), qp.ParsedQuery) + }) + } +} diff --git a/go/vt/vtctl/workflow/vexec/testutil/query.go b/go/vt/vtctl/workflow/vexec/testutil/query.go new file mode 100644 index 00000000000..3988f7a112f --- /dev/null +++ b/go/vt/vtctl/workflow/vexec/testutil/query.go @@ -0,0 +1,48 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/sqlparser" +) + +// ParsedQueryFromString is a test helper that returns a *sqlparser.ParsedQuery +// from a plain string. It marks the test as a failure if the query cannot be +// parsed. +func ParsedQueryFromString(t *testing.T, query string) *sqlparser.ParsedQuery { + t.Helper() + + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("%v", StatementFromString(t, query)) + + return buf.ParsedQuery() +} + +// StatementFromString is a test helper that returns a sqlparser.Statement from +// a plain string. It marks the test as a failure if the query cannot be parsed. +func StatementFromString(t *testing.T, query string) sqlparser.Statement { + t.Helper() + + stmt, err := sqlparser.Parse(query) + require.NoError(t, err, "could not parse query %v", query) + + return stmt +} diff --git a/go/vt/vtctl/workflow/vexec/vexec.go b/go/vt/vtctl/workflow/vexec/vexec.go new file mode 100644 index 00000000000..d61bd16ab31 --- /dev/null +++ b/go/vt/vtctl/workflow/vexec/vexec.go @@ -0,0 +1,235 @@ +/* +Copyright 2021 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vexec + +import ( + "context" + "errors" + "fmt" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vttablet/tmclient" + + querypb "vitess.io/vitess/go/vt/proto/query" +) + +const ( + // VExecTableQualifier is the qualifier that all tables supported by vexec + // are prefixed by. + VExecTableQualifier = "_vt" + + // SchemaMigrationsTableName is the unqualified name of the schema + // migrations table supported by vexec. + SchemaMigrationsTableName = "schema_migrations" + // VReplicationTableName is the unqualified name of the vreplication table + // supported by vexec. + VReplicationTableName = "vreplication" +) + +var ( // Topo lookup errors. + // ErrNoShardPrimary occurs when a shard is found with no serving + // primary. + ErrNoShardPrimary = errors.New("no primary found for shard") + // ErrNoShardsForKeyspace occurs when attempting to run a vexec on an empty + // keyspace. + ErrNoShardsForKeyspace = errors.New("no shards found in keyspace") +) + +var ( // Query parsing and planning errors. + // ErrUnsupportedQuery occurs when attempting to run an unsupported query + // through vexec. + ErrUnsupportedQuery = errors.New("query not supported by vexec") + // ErrUnsupportedTable occurs when attempting to run vexec on an unsupported + // table. At the time of writing, this occurs when attempting to query any + // table other than _vt.vreplication. + ErrUnsupportedTable = errors.New("table not supported by vexec") +) + +// VExec provides the main interface to planning and executing vexec queries +// (normally, queries on tables in the `_vt` database). It currently supports +// some limited vreplication queries; this set of supported behavior will expand +// over time. It may be extended to support schema_migrations queries as well. +type VExec struct { + ts *topo.Server + tmc tmclient.TabletManagerClient + + keyspace string + workflow string + + // (TODO:@ajm188) Consider renaming this field to "targets", and then + // support different Strategy functions for loading target tablets from a + // topo.Server. + // + // For this, I'm currently thinking: + // type TargetStrategy func(ts *topo.Server) ([]*topo.TabletInfo, error) + // + // We _may_ want this if we ever want a vexec query to target anything other + // than "all of the shard primaries in a given keyspace", and I'm not sure + // about potential future usages yet. + primaries []*topo.TabletInfo + // (TODO:@ajm188) Similar to supporting a TargetStrategy for controlling how + // a VExec picks which tablets to query, we may also want an + // ExecutionStrategy (I'm far less sure about whether we would want this at + // all, or what its type definition might look like, than TargetStrategy), + // to support running in modes like: + // - Execute serially rather than concurrently. + // - Only return error if greater than some percentage of the targets fail. +} + +// NewVExec returns a new instance suitable for making vexec queries to a given +// keyspace (required) and workflow (optional, omit by providing the empty +// string). The provided topo server is used to look up target tablets for +// queries. A given instance will discover targets exactly once for its +// lifetime, so to force a refresh, create another instance. +func NewVExec(keyspace string, workflow string, ts *topo.Server, tmc tmclient.TabletManagerClient) *VExec { + return &VExec{ + ts: ts, + tmc: tmc, + keyspace: keyspace, + workflow: workflow, + } +} + +// QueryContext executes the given vexec query, returning a mapping of tablet +// to querypb.QueryResult. +// +// On first use, QueryContext will also cause the VExec instance to discover +// target tablets from the topo; that target list will be reused for all future +// queries made by this instance. +// +// For details on query parsing and planning, see GetPlanner and the +// QueryPlanner interface. +func (vx *VExec) QueryContext(ctx context.Context, query string) (map[*topo.TabletInfo]*querypb.QueryResult, error) { + if vx.primaries == nil { + if err := vx.initialize(ctx); err != nil { + return nil, err + } + } + + stmt, err := sqlparser.Parse(query) + if err != nil { + return nil, err + } + + table, err := extractTableName(stmt) + if err != nil { + return nil, err + } + + planner, err := vx.GetPlanner(ctx, table) + if err != nil { + return nil, err + } + + qp, err := planner.PlanQuery(stmt) + if err != nil { + return nil, err + } + + return qp.ExecuteScatter(ctx, vx.primaries...) +} + +func (vx *VExec) initialize(ctx context.Context) error { + vx.primaries = nil + + getShardsCtx, getShardsCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer getShardsCancel() + + shards, err := vx.ts.GetShardNames(getShardsCtx, vx.keyspace) + if err != nil { + return err + } + + if len(shards) == 0 { + return fmt.Errorf("%w %s", ErrNoShardsForKeyspace, vx.keyspace) + } + + primaries := make([]*topo.TabletInfo, 0, len(shards)) + + for _, shard := range shards { + ctx, cancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancel() + + si, err := vx.ts.GetShard(ctx, vx.keyspace, shard) + if err != nil { + return err + } + + if si.MasterAlias == nil { + return fmt.Errorf("%w %s/%s", ErrNoShardPrimary, vx.keyspace, shard) + } + + primary, err := vx.ts.GetTablet(ctx, si.MasterAlias) + if err != nil { + return err + } + + if primary == nil { + return fmt.Errorf("%w %s/%s: tablet %v not found", ErrNoShardPrimary, vx.keyspace, shard, topoproto.TabletAliasString(si.MasterAlias)) + } + + primaries = append(primaries, primary) + } + + vx.primaries = primaries + + return nil +} + +// GetPlanner returns an appropriate implementation of a QueryPlanner, depending +// on the table being queried. +// +// On first use, GetPlanner will also cause the VExec instance to discover +// target tablets from the topo; that target list will be reused for all future +// queries made by this instance. +func (vx *VExec) GetPlanner(ctx context.Context, table string) (QueryPlanner, error) { // TODO: private? + if vx.primaries == nil { + if err := vx.initialize(ctx); err != nil { + return nil, fmt.Errorf("error while initializing target list: %w", err) + } + } + + switch table { + case qualifiedTableName(VReplicationTableName): + return NewVReplicationQueryPlanner(vx.tmc, vx.workflow, vx.primaries[0].DbName()), nil + case qualifiedTableName(SchemaMigrationsTableName): + return nil, errors.New("Schema Migrations not yet supported in new workflow package") + default: + return nil, fmt.Errorf("%w: %v", ErrUnsupportedTable, table) + } +} + +func extractTableName(stmt sqlparser.Statement) (string, error) { + switch stmt := stmt.(type) { + case *sqlparser.Update: + return sqlparser.String(stmt.TableExprs), nil + case *sqlparser.Delete: + return sqlparser.String(stmt.TableExprs), nil + case *sqlparser.Insert: + return sqlparser.String(stmt.Table), nil + case *sqlparser.Select: + return sqlparser.String(stmt.From), nil + } + + return "", fmt.Errorf("%w: %+v", ErrUnsupportedQuery, sqlparser.String(stmt)) +} + +func qualifiedTableName(name string) string { + return fmt.Sprintf("%s.%s", VExecTableQualifier, name) +} diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 361bd4a2083..c44da978bb1 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -22,6 +22,7 @@ option go_package = "vitess.io/vitess/go/vt/proto/vtctldata"; package vtctldata; +import "binlogdata.proto"; import "logutil.proto"; import "mysqlctl.proto"; import "tabletmanagerdata.proto"; @@ -41,6 +42,90 @@ message ExecuteVtctlCommandResponse { logutil.Event event = 1; } +// TableMaterializeSttings contains the settings for one table. +message TableMaterializeSettings { + string target_table = 1; + // source_expression is a select statement. + string source_expression = 2; + // create_ddl contains the DDL to create the target table. + // If empty, the target table must already exist. + // if "copy", the target table DDL is the same as the source table. + string create_ddl = 3; +} + +// MaterializeSettings contains the settings for the Materialize command. +message MaterializeSettings { + // workflow is the name of the workflow. + string workflow = 1; + string source_keyspace = 2; + string target_keyspace = 3; + // stop_after_copy specifies if vreplication should be stopped after copying. + bool stop_after_copy = 4; + repeated TableMaterializeSettings table_settings = 5; + // optional parameters. + string cell = 6; + string tablet_types = 7; + // ExternalCluster is the name of the mounted cluster which has the source keyspace/db for this workflow + // it is of the type + string external_cluster = 8; + +} + +/* Data types for VtctldServer */ + +message Keyspace { + string name = 1; + topodata.Keyspace keyspace = 2; +} + +message Shard { + string keyspace = 1; + string name = 2; + topodata.Shard shard = 3; +} + +// TODO: comment the hell out of this. +message Workflow { + string name = 1; + ReplicationLocation source = 2; + ReplicationLocation target = 3; + int64 max_v_replication_lag = 4; + map shard_streams = 5; + + message ReplicationLocation { + string keyspace = 1; + repeated string shards = 2; + } + + message ShardStream { + repeated Stream streams = 1; + repeated topodata.Shard.TabletControl tablet_controls = 2; + bool is_primary_serving = 3; + } + + message Stream { + int64 id = 1; + string shard = 2; + topodata.TabletAlias tablet = 3; + binlogdata.BinlogSource binlog_source = 4; + string position = 5; + string stop_position = 6; + string state = 7; + string db_name = 8; + vttime.Time transaction_timestamp = 9; + vttime.Time time_updated = 10; + string message = 11; + repeated CopyState copy_states = 12; + + message CopyState { + string table = 1; + string last_pk = 2; + } + } +} + +/* Request/response types for VtctldServer */ + message ChangeTabletTypeRequest { topodata.TabletAlias tablet_alias = 1; topodata.TabletType db_type = 2; @@ -149,6 +234,14 @@ message DeleteTabletsRequest { message DeleteTabletsResponse { } +message FindAllShardsInKeyspaceRequest { + string keyspace = 1; +} + +message FindAllShardsInKeyspaceResponse { + map shards = 1; +} + message GetBackupsRequest { string keyspace = 1; string shard = 2; @@ -266,6 +359,15 @@ message GetVSchemaResponse { vschema.Keyspace v_schema = 1; } +message GetWorkflowsRequest { + string keyspace = 1; + bool active_only = 2; +} + +message GetWorkflowsResponse { + repeated Workflow workflows = 1; +} + message RemoveKeyspaceCellRequest { string keyspace = 1; string cell = 2; @@ -301,46 +403,30 @@ message RemoveShardCellResponse { // and any deleted Tablet objects here. } -message Keyspace { - string name = 1; - topodata.Keyspace keyspace = 2; +message ReparentTabletRequest { + // Tablet is the alias of the tablet that should be reparented under the + // current shard primary. + topodata.TabletAlias tablet = 1; } -message FindAllShardsInKeyspaceRequest { +message ReparentTabletResponse { + // Keyspace is the name of the keyspace the tablet was reparented in. string keyspace = 1; + // Shard is the name of the shard the tablet was reparented in. + string shard = 2; + // Primary is the alias of the tablet that the tablet was reparented under. + topodata.TabletAlias primary = 3; } -message FindAllShardsInKeyspaceResponse { - map shards = 1; +message TabletExternallyReparentedRequest { + // Tablet is the alias of the tablet that was promoted externally and should + // be updated to the shard primary in the topo. + topodata.TabletAlias tablet = 1; } -message Shard { +message TabletExternallyReparentedResponse { string keyspace = 1; - string name = 2; - topodata.Shard shard = 3; -} - -// TableMaterializeSttings contains the settings for one table. -message TableMaterializeSettings { - string target_table = 1; - // source_expression is a select statement. - string source_expression = 2; - // create_ddl contains the DDL to create the target table. - // If empty, the target table must already exist. - // if "copy", the target table DDL is the same as the source table. - string create_ddl = 3; -} - -// MaterializeSettings contains the settings for the Materialize command. -message MaterializeSettings { - // workflow is the name of the workflow. - string workflow = 1; - string source_keyspace = 2; - string target_keyspace = 3; - // stop_after_copy specifies if vreplication should be stopped after copying. - bool stop_after_copy = 4; - repeated TableMaterializeSettings table_settings = 5; - // optional parameters. - string cell = 6; - string tablet_types = 7; + string shard = 2; + topodata.TabletAlias new_primary = 3; + topodata.TabletAlias old_primary = 4; } diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 15b0d6729c9..54cab4a31d4 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -85,6 +85,8 @@ service Vtctld { rpc GetTablets(vtctldata.GetTabletsRequest) returns (vtctldata.GetTabletsResponse) {}; // GetVSchema returns the vschema for a keyspace. rpc GetVSchema(vtctldata.GetVSchemaRequest) returns (vtctldata.GetVSchemaResponse) {}; + // GetWorkflows returns a list of workflows for the given keyspace. + rpc GetWorkflows(vtctldata.GetWorkflowsRequest) returns (vtctldata.GetWorkflowsResponse) {}; // RemoveKeyspaceCell removes the specified cell from the Cells list for all // shards in the specified keyspace, as well as from the SrvKeyspace for that // keyspace in that cell. From db7a79c158f7fafc412c2b232070c9f7fbc30022 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Fri, 5 Mar 2021 10:01:32 -0500 Subject: [PATCH 19/21] Backport GetWorkflows to use old sqlparser types in cherry-pick branch Signed-off-by: Andrew Mason --- go/vt/vtctl/workflow/vexec/query_planner.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go/vt/vtctl/workflow/vexec/query_planner.go b/go/vt/vtctl/workflow/vexec/query_planner.go index a850cc9816a..74dfbb2a876 100644 --- a/go/vt/vtctl/workflow/vexec/query_planner.go +++ b/go/vt/vtctl/workflow/vexec/query_planner.go @@ -265,14 +265,14 @@ func addDefaultWheres(planner QueryPlanner, where *sqlparser.Where) *sqlparser.W Left: &sqlparser.ColName{ Name: sqlparser.NewColIdent(params.DBNameColumn), }, - Operator: sqlparser.EqualOp, - Right: sqlparser.NewStrLiteral([]byte(params.DBName)), + Operator: sqlparser.EqualStr, + Right: sqlparser.NewStrVal([]byte(params.DBName)), } switch newWhere { case nil: newWhere = &sqlparser.Where{ - Type: sqlparser.WhereClause, + Type: sqlparser.WhereStr, Expr: expr, } default: @@ -288,8 +288,8 @@ func addDefaultWheres(planner QueryPlanner, where *sqlparser.Where) *sqlparser.W Left: &sqlparser.ColName{ Name: sqlparser.NewColIdent(params.WorkflowColumn), }, - Operator: sqlparser.EqualOp, - Right: sqlparser.NewStrLiteral([]byte(params.Workflow)), + Operator: sqlparser.EqualStr, + Right: sqlparser.NewStrVal([]byte(params.Workflow)), } newWhere.Expr = &sqlparser.AndExpr{ From 1f6f3226768ba5132c13819098437775d50c264f Mon Sep 17 00:00:00 2001 From: Richard Bailey Date: Fri, 5 Mar 2021 17:30:42 -0800 Subject: [PATCH 20/21] Resolve merge / backport conflicts Signed-off-by: Richard Bailey --- go/vt/vtctl/workflow/vexec/query_planner.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go/vt/vtctl/workflow/vexec/query_planner.go b/go/vt/vtctl/workflow/vexec/query_planner.go index 74dfbb2a876..a850cc9816a 100644 --- a/go/vt/vtctl/workflow/vexec/query_planner.go +++ b/go/vt/vtctl/workflow/vexec/query_planner.go @@ -265,14 +265,14 @@ func addDefaultWheres(planner QueryPlanner, where *sqlparser.Where) *sqlparser.W Left: &sqlparser.ColName{ Name: sqlparser.NewColIdent(params.DBNameColumn), }, - Operator: sqlparser.EqualStr, - Right: sqlparser.NewStrVal([]byte(params.DBName)), + Operator: sqlparser.EqualOp, + Right: sqlparser.NewStrLiteral([]byte(params.DBName)), } switch newWhere { case nil: newWhere = &sqlparser.Where{ - Type: sqlparser.WhereStr, + Type: sqlparser.WhereClause, Expr: expr, } default: @@ -288,8 +288,8 @@ func addDefaultWheres(planner QueryPlanner, where *sqlparser.Where) *sqlparser.W Left: &sqlparser.ColName{ Name: sqlparser.NewColIdent(params.WorkflowColumn), }, - Operator: sqlparser.EqualStr, - Right: sqlparser.NewStrVal([]byte(params.Workflow)), + Operator: sqlparser.EqualOp, + Right: sqlparser.NewStrLiteral([]byte(params.Workflow)), } newWhere.Expr = &sqlparser.AndExpr{ From 196d8502acfd2395e48a4b84d09cff7813c79a07 Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 17 Mar 2021 12:35:05 -0700 Subject: [PATCH 21/21] Vitess v8 VTctld custom branch + sizes-only (#201) * Merge pull request #187 from tinyspeck/backport-am_get_schema_sizes_only Add option to GetSchema to only send the row count and data length over the wire * whitespace! * derp, actually commit rm dead import Signed-off-by: Richard Bailey Co-authored-by: Andrew Mason --- go/vt/vtctl/endtoend/get_schema_test.go | 235 ++++++++++++++++++++++++ go/vt/vtctl/vtctl.go | 3 + 2 files changed, 238 insertions(+) create mode 100644 go/vt/vtctl/endtoend/get_schema_test.go diff --git a/go/vt/vtctl/endtoend/get_schema_test.go b/go/vt/vtctl/endtoend/get_schema_test.go new file mode 100644 index 00000000000..ddb0c204048 --- /dev/null +++ b/go/vt/vtctl/endtoend/get_schema_test.go @@ -0,0 +1,235 @@ +package endtoend + +import ( + "context" + "fmt" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/json2" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtctl" + "vitess.io/vitess/go/vt/vttablet/faketmclient" + "vitess.io/vitess/go/vt/vttablet/tmclient" + "vitess.io/vitess/go/vt/wrangler" + + querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +type fakeTabletManagerClient struct { + tmclient.TabletManagerClient + schemas map[string]*tabletmanagerdatapb.SchemaDefinition +} + +func newTMClient() *fakeTabletManagerClient { + return &fakeTabletManagerClient{ + TabletManagerClient: faketmclient.NewFakeTabletManagerClient(), + schemas: map[string]*tabletmanagerdatapb.SchemaDefinition{}, + } +} + +func (c *fakeTabletManagerClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tablets []string, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { + key := topoproto.TabletAliasString(tablet.Alias) + + schema, ok := c.schemas[key] + if !ok { + return nil, fmt.Errorf("no schemas for %s", key) + } + + return schema, nil +} + +func TestGetSchema(t *testing.T) { + ctx := context.Background() + + topo := memorytopo.NewServer("zone1", "zone2", "zone3") + + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: uuid.New().ID(), + }, + Hostname: "abcd", + Keyspace: "testkeyspace", + Shard: "-", + Type: topodatapb.TabletType_MASTER, + } + require.NoError(t, topo.CreateTablet(ctx, tablet)) + + sd := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "foo", + RowCount: 1000, + DataLength: 1000000, + Schema: `CREATE TABLE foo ( + id INT(11) NOT NULL, + name VARCHAR(255) NOT NULL, + PRIMARY KEY(id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4`, + Columns: []string{ + "id", + "name", + }, + PrimaryKeyColumns: []string{ + "id", + }, + Fields: []*querypb.Field{ + { + Name: "id", + Type: querypb.Type_INT32, + Table: "foo", + OrgTable: "foo", + Database: "vt_testkeyspace", + OrgName: "id", + ColumnLength: 11, + Charset: 63, + Decimals: 0, + }, + { + Name: "name", + Type: querypb.Type_VARCHAR, + Table: "foo", + OrgTable: "foo", + Database: "vt_testkeyspace", + OrgName: "name", + ColumnLength: 1020, + Charset: 45, + Decimals: 0, + }, + }, + }, + { + Name: "bar", + RowCount: 1, + DataLength: 10, + Schema: `CREATE TABLE bar ( + id INT(11) NOT NULL + foo_id INT(11) NOT NULL + is_active TINYINT(1) NOT NULL DEFAULT 1 +) ENGINE=InnoDB`, + Columns: []string{ + "id", + "foo_id", + "is_active", + }, + PrimaryKeyColumns: []string{ + "id", + }, + Fields: []*querypb.Field{ + { + Name: "id", + Type: querypb.Type_INT32, + Table: "bar", + OrgTable: "bar", + Database: "vt_testkeyspace", + OrgName: "id", + ColumnLength: 11, + Charset: 63, + Decimals: 0, + }, + { + Name: "foo_id", + Type: querypb.Type_INT32, + Table: "bar", + OrgTable: "bar", + Database: "vt_testkeyspace", + OrgName: "foo_id", + ColumnLength: 11, + Charset: 63, + Decimals: 0, + }, + { + Name: "is_active", + Type: querypb.Type_INT8, + Table: "bar", + OrgTable: "bar", + Database: "vt_testkeyspace", + OrgName: "is_active", + ColumnLength: 1, + Charset: 63, + Decimals: 0, + }, + }, + }, + }, + } + + tmc := newTMClient() + tmc.schemas[topoproto.TabletAliasString(tablet.Alias)] = sd + + logger := logutil.NewMemoryLogger() + + err := vtctl.RunCommand(ctx, wrangler.New(logger, topo, tmc), []string{ + "GetSchema", + topoproto.TabletAliasString(tablet.Alias), + }) + require.NoError(t, err) + + events := logger.Events + assert.Equal(t, 1, len(events), "expected 1 event from GetSchema") + val := events[0].Value + + actual := &tabletmanagerdatapb.SchemaDefinition{} + err = json2.Unmarshal([]byte(val), actual) + require.NoError(t, err) + + assert.Equal(t, sd, actual) + + // reset for the next invocation, where we verify that passing + // -table_sizes_only does not include the create table statement or columns. + logger.Events = nil + sd = &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "foo", + RowCount: 1000, + DataLength: 1000000, + Columns: []string{}, + PrimaryKeyColumns: []string{}, + Fields: []*querypb.Field{}, + }, + { + Name: "bar", + RowCount: 1, + DataLength: 10, + Columns: []string{}, + PrimaryKeyColumns: []string{}, + Fields: []*querypb.Field{}, + }, + }, + } + + err = vtctl.RunCommand(ctx, wrangler.New(logger, topo, tmc), []string{ + "GetSchema", + "-table_sizes_only", + topoproto.TabletAliasString(tablet.Alias), + }) + require.NoError(t, err) + + events = logger.Events + assert.Equal(t, 1, len(events), "expected 1 event from GetSchema") + val = events[0].Value + + actual = &tabletmanagerdatapb.SchemaDefinition{} + err = json2.Unmarshal([]byte(val), actual) + require.NoError(t, err) + + assert.Equal(t, sd, actual) +} + +func init() { + // enforce we will use the right protocol (gRPC) (note the + // client is unused, but it is initialized, so it needs to exist) + *tmclient.TabletManagerProtocol = "grpc" + tmclient.RegisterTabletManagerClientFactory("grpc", func() tmclient.TabletManagerClient { + return nil + }) +} diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 34e56862112..4b9d89f9f47 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2298,6 +2298,8 @@ func commandGetSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag excludeTables := subFlags.String("exclude_tables", "", "Specifies a comma-separated list of tables to exclude. Each is either an exact match, or a regular expression of the form /regexp/") includeViews := subFlags.Bool("include-views", false, "Includes views in the output") tableNamesOnly := subFlags.Bool("table_names_only", false, "Only displays table names that match") + tableSizesOnly := subFlags.Bool("table_sizes_only", false, "Only displays size information for tables. Ignored if -table_names_only is passed.") + if err := subFlags.Parse(args); err != nil { return err } @@ -2323,6 +2325,7 @@ func commandGetSchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag ExcludeTables: excludeTableArray, IncludeViews: *includeViews, TableNamesOnly: *tableNamesOnly, + TableSizesOnly: *tableSizesOnly, }) if err != nil { return err