From 1be28d6f29512c0a7b652e25529840ac5e1f7b6b Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Thu, 25 Aug 2016 12:35:18 -0600 Subject: [PATCH] feat(*): add 'helm list --all' and related flags This adds support for the following 'helm list' flags: - all: show all release types - deleted: show deleted releases - deployed: show deployed releases - failed: show failed releases These flags can be toggled. Only '--deployed' is turned on by default. On the server side, Tiller's list function can now filter based on a slice of release.Status_Code filters. While the client only supports a subset, the server supports all known release.Status_Code types. Closes #973 --- _proto/hapi/services/tiller.proto | 4 + cmd/helm/helm_test.go | 14 +++- cmd/helm/list.go | 69 ++++++++++++++--- cmd/helm/list_test.go | 22 +++++- cmd/tiller/release_server.go | 15 +++- cmd/tiller/release_server_test.go | 73 ++++++++++++++++- pkg/helm/option.go | 11 +++ pkg/proto/hapi/services/tiller.pb.go | 112 ++++++++++++++------------- 8 files changed, 250 insertions(+), 70 deletions(-) diff --git a/_proto/hapi/services/tiller.proto b/_proto/hapi/services/tiller.proto index db791ea63..549f128f6 100644 --- a/_proto/hapi/services/tiller.proto +++ b/_proto/hapi/services/tiller.proto @@ -20,6 +20,7 @@ import "hapi/chart/chart.proto"; import "hapi/chart/config.proto"; import "hapi/release/release.proto"; import "hapi/release/info.proto"; +import "hapi/release/status.proto"; option go_package = "services"; @@ -90,7 +91,10 @@ message ListReleasesRequest { // Anything that matches the regexp will be included in the results. string filter = 4; + // SortOrder is the ordering directive used for sorting. ListSort.SortOrder sort_order = 5; + + repeated hapi.release.Status.Code status_codes = 6; } // ListSort defines sorting fields on a release list. diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index 5af98960d..9c62fe9dd 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -46,9 +46,10 @@ metadata: ` type releaseOptions struct { - name string - version int32 - chart *chart.Chart + name string + version int32 + chart *chart.Chart + statusCode release.Status_Code } func releaseMock(opts *releaseOptions) *release.Release { @@ -77,12 +78,17 @@ func releaseMock(opts *releaseOptions) *release.Release { } } + scode := release.Status_DEPLOYED + if opts.statusCode > 0 { + scode = opts.statusCode + } + return &release.Release{ Name: name, Info: &release.Info{ FirstDeployed: &date, LastDeployed: &date, - Status: &release.Status{Code: release.Status_DEPLOYED}, + Status: &release.Status{Code: scode}, }, Chart: ch, Config: &chart.Config{Raw: `name: "value"`}, diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 058932766..64d7ff908 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -31,7 +31,10 @@ import ( ) var listHelp = ` -This command lists all of the currently deployed releases. +This command lists all of the releases. + +By default, it lists only releases that are deployed. Flags like '--delete' and +'--all' will alter this behavior. Such flags can be combined: '--deleted --failed'. By default, items are sorted alphabetically. Use the '-d' flag to sort by release date. @@ -54,14 +57,19 @@ flag with the '--offset' flag allows you to page through results. ` type listCmd struct { - filter string - long bool - limit int - offset string - byDate bool - sortDesc bool - out io.Writer - client helm.Interface + filter string + long bool + limit int + offset string + byDate bool + sortDesc bool + out io.Writer + all bool + deleted bool + deployed bool + failed bool + superseded bool + client helm.Interface } func newListCmd(client helm.Interface, out io.Writer) *cobra.Command { @@ -91,6 +99,12 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command { f.BoolVarP(&list.sortDesc, "reverse", "r", false, "reverse the sort order") f.IntVarP(&list.limit, "max", "m", 256, "maximum number of releases to fetch") f.StringVarP(&list.offset, "offset", "o", "", "the next release name in the list, used to offset from start value") + f.BoolVar(&list.all, "all", false, "show all releases, not just the ones marked DEPLOYED") + f.BoolVar(&list.deleted, "deleted", false, "show deleted releases") + f.BoolVar(&list.deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled") + f.BoolVar(&list.failed, "failed", false, "show failed releases") + // TODO: Do we want this as a feature of 'helm list'? + //f.BoolVar(&list.superseded, "history", true, "show historical releases") return cmd } @@ -105,12 +119,15 @@ func (l *listCmd) run() error { sortOrder = services.ListSort_DESC } + stats := l.statusCodes() + res, err := l.client.ListReleases( helm.ReleaseListLimit(l.limit), helm.ReleaseListOffset(l.offset), helm.ReleaseListFilter(l.filter), helm.ReleaseListSort(int32(sortBy)), helm.ReleaseListOrder(int32(sortOrder)), + helm.ReleaseListStatuses(stats), ) if err != nil { @@ -138,6 +155,40 @@ func (l *listCmd) run() error { return nil } +// statusCodes gets the list of status codes that are to be included in the results. +func (l *listCmd) statusCodes() []release.Status_Code { + if l.all { + return []release.Status_Code{ + release.Status_UNKNOWN, + release.Status_DEPLOYED, + release.Status_DELETED, + // TODO: Should we return superseded records? These are records + // that were replaced by an upgrade. + //release.Status_SUPERSEDED, + release.Status_FAILED, + } + } + status := []release.Status_Code{} + if l.deployed { + status = append(status, release.Status_DEPLOYED) + } + if l.deleted { + status = append(status, release.Status_DELETED) + } + if l.failed { + status = append(status, release.Status_FAILED) + } + if l.superseded { + status = append(status, release.Status_SUPERSEDED) + } + + // Default case. + if len(status) == 0 { + status = append(status, release.Status_DEPLOYED) + } + return status +} + func formatList(rels []*release.Release) string { table := uitable.New() table.MaxColWidth = 30 diff --git a/cmd/helm/list_test.go b/cmd/helm/list_test.go index b12d41408..c2ea487df 100644 --- a/cmd/helm/list_test.go +++ b/cmd/helm/list_test.go @@ -41,13 +41,33 @@ func TestListCmd(t *testing.T) { }, { name: "list --long", - //flags: map[string]string{"long": "1"}, args: []string{"--long"}, resp: []*release.Release{ releaseMock(&releaseOptions{name: "atlas"}), }, expected: "NAME \tVERSION\tUPDATED \tSTATUS \tCHART \natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\n", }, + { + name: "with a release, multiple flags", + args: []string{"--deleted", "--deployed", "--failed"}, + resp: []*release.Release{ + releaseMock(&releaseOptions{name: "thomas-guide", statusCode: release.Status_DELETED}), + releaseMock(&releaseOptions{name: "atlas-guide", statusCode: release.Status_DEPLOYED}), + }, + // Note: We're really only testing that the flags parsed correctly. Which results are returned + // depends on the backend. And until pkg/helm is done, we can't mock this. + expected: "thomas-guide\natlas-guide", + }, + { + name: "with a release, multiple flags", + args: []string{"--all"}, + resp: []*release.Release{ + releaseMock(&releaseOptions{name: "thomas-guide", statusCode: release.Status_DELETED}), + releaseMock(&releaseOptions{name: "atlas-guide", statusCode: release.Status_DEPLOYED}), + }, + // See note on previous test. + expected: "thomas-guide\natlas-guide", + }, } var buf bytes.Buffer diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go index 69a575a3e..b513f9043 100644 --- a/cmd/tiller/release_server.go +++ b/cmd/tiller/release_server.go @@ -68,7 +68,20 @@ type releaseServer struct { } func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error { - rels, err := s.env.Releases.ListDeployed() + + if len(req.StatusCodes) == 0 { + req.StatusCodes = []release.Status_Code{release.Status_DEPLOYED} + } + + //rels, err := s.env.Releases.ListDeployed() + rels, err := s.env.Releases.ListFilterAll(func(r *release.Release) bool { + for _, sc := range req.StatusCodes { + if sc == r.Info.Status.Code { + return true + } + } + return false + }) if err != nil { return err } diff --git a/cmd/tiller/release_server_test.go b/cmd/tiller/release_server_test.go index cfb963e9d..3b86c2232 100644 --- a/cmd/tiller/release_server_test.go +++ b/cmd/tiller/release_server_test.go @@ -82,13 +82,17 @@ func chartStub() *chart.Chart { // releaseStub creates a release stub, complete with the chartStub as its chart. func releaseStub() *release.Release { + return namedReleaseStub("angry-panda", release.Status_DEPLOYED) +} + +func namedReleaseStub(name string, status release.Status_Code) *release.Release { date := timestamp.Timestamp{Seconds: 242085845, Nanos: 0} return &release.Release{ - Name: "angry-panda", + Name: name, Info: &release.Info{ FirstDeployed: &date, LastDeployed: &date, - Status: &release.Status{Code: release.Status_DEPLOYED}, + Status: &release.Status{Code: status}, }, Chart: chartStub(), Config: &chart.Config{Raw: `name = "value"`}, @@ -581,6 +585,71 @@ func TestListReleases(t *testing.T) { } } +func TestListReleasesByStatus(t *testing.T) { + rs := rsFixture() + stubs := []*release.Release{ + namedReleaseStub("kamal", release.Status_DEPLOYED), + namedReleaseStub("astrolabe", release.Status_DELETED), + namedReleaseStub("octant", release.Status_FAILED), + namedReleaseStub("sextant", release.Status_UNKNOWN), + } + for _, stub := range stubs { + if err := rs.env.Releases.Create(stub); err != nil { + t.Fatalf("Could not create stub: %s", err) + } + } + + tests := []struct { + statusCodes []release.Status_Code + names []string + }{ + { + names: []string{"kamal"}, + statusCodes: []release.Status_Code{release.Status_DEPLOYED}, + }, + { + names: []string{"astrolabe"}, + statusCodes: []release.Status_Code{release.Status_DELETED}, + }, + { + names: []string{"kamal", "octant"}, + statusCodes: []release.Status_Code{release.Status_DEPLOYED, release.Status_FAILED}, + }, + { + names: []string{"kamal", "astrolabe", "octant", "sextant"}, + statusCodes: []release.Status_Code{ + release.Status_DEPLOYED, + release.Status_DELETED, + release.Status_FAILED, + release.Status_UNKNOWN, + }, + }, + } + + for i, tt := range tests { + mrs := &mockListServer{} + if err := rs.ListReleases(&services.ListReleasesRequest{StatusCodes: tt.statusCodes, Offset: "", Limit: 64}, mrs); err != nil { + t.Fatalf("Failed listing %d: %s", i, err) + } + + if len(tt.names) != len(mrs.val.Releases) { + t.Fatalf("Expected %d releases, got %d", len(tt.names), len(mrs.val.Releases)) + } + + for _, name := range tt.names { + found := false + for _, rel := range mrs.val.Releases { + if rel.Name == name { + found = true + } + } + if !found { + t.Errorf("%d: Did not find name %q", i, name) + } + } + } +} + func TestListReleasesSort(t *testing.T) { rs := rsFixture() diff --git a/pkg/helm/option.go b/pkg/helm/option.go index 73a478574..dff6acbd3 100644 --- a/pkg/helm/option.go +++ b/pkg/helm/option.go @@ -19,6 +19,7 @@ package helm import ( "golang.org/x/net/context" cpb "k8s.io/helm/pkg/proto/hapi/chart" + "k8s.io/helm/pkg/proto/hapi/release" rls "k8s.io/helm/pkg/proto/hapi/services" ) @@ -105,6 +106,16 @@ func ReleaseListSort(sort int32) ReleaseListOption { } } +// ReleaseListStatuses specifies which status codes should be returned. +func ReleaseListStatuses(statuses []release.Status_Code) ReleaseListOption { + return func(opts *options) { + if len(statuses) == 0 { + statuses = []release.Status_Code{release.Status_DEPLOYED} + } + opts.listReq.StatusCodes = statuses + } +} + // InstallOption allows specifying various settings // configurable by the helm client user for overriding // the defaults used when running the `helm install` command. diff --git a/pkg/proto/hapi/services/tiller.pb.go b/pkg/proto/hapi/services/tiller.pb.go index 5d93ceeb4..4b497fdd7 100644 --- a/pkg/proto/hapi/services/tiller.pb.go +++ b/pkg/proto/hapi/services/tiller.pb.go @@ -32,6 +32,7 @@ import hapi_chart3 "k8s.io/helm/pkg/proto/hapi/chart" import hapi_chart "k8s.io/helm/pkg/proto/hapi/chart" import hapi_release3 "k8s.io/helm/pkg/proto/hapi/release" import hapi_release2 "k8s.io/helm/pkg/proto/hapi/release" +import hapi_release1 "k8s.io/helm/pkg/proto/hapi/release" import ( context "golang.org/x/net/context" @@ -113,8 +114,10 @@ type ListReleasesRequest struct { // Filter is a regular expression used to filter which releases should be listed. // // Anything that matches the regexp will be included in the results. - Filter string `protobuf:"bytes,4,opt,name=filter" json:"filter,omitempty"` - SortOrder ListSort_SortOrder `protobuf:"varint,5,opt,name=sort_order,json=sortOrder,enum=hapi.services.tiller.ListSort_SortOrder" json:"sort_order,omitempty"` + Filter string `protobuf:"bytes,4,opt,name=filter" json:"filter,omitempty"` + // SortOrder is the ordering directive used for sorting. + SortOrder ListSort_SortOrder `protobuf:"varint,5,opt,name=sort_order,json=sortOrder,enum=hapi.services.tiller.ListSort_SortOrder" json:"sort_order,omitempty"` + StatusCodes []hapi_release1.Status_Code `protobuf:"varint,6,rep,name=status_codes,json=statusCodes,enum=hapi.release.Status_Code" json:"status_codes,omitempty"` } func (m *ListReleasesRequest) Reset() { *m = ListReleasesRequest{} } @@ -330,7 +333,7 @@ type UninstallReleaseRequest struct { Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` // DisableHooks causes the server to skip running any hooks for the uninstall. DisableHooks bool `protobuf:"varint,2,opt,name=disable_hooks,json=disableHooks" json:"disable_hooks,omitempty"` - // Remove the release from the store and make its name free for later use. + // Purge removes the release from the store and make its name free for later use. Purge bool `protobuf:"varint,3,opt,name=purge" json:"purge,omitempty"` } @@ -628,54 +631,57 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{ } var fileDescriptor0 = []byte{ - // 783 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x56, 0xcb, 0x6e, 0xd3, 0x4c, - 0x14, 0xae, 0x93, 0x34, 0x97, 0xd3, 0x8b, 0xd2, 0xf9, 0xdb, 0x26, 0xbf, 0x05, 0x08, 0x19, 0x01, - 0xa5, 0x50, 0x07, 0xc2, 0x1e, 0x29, 0x6d, 0xa3, 0xb6, 0x6a, 0x48, 0x25, 0x87, 0x82, 0xc4, 0x82, - 0xc8, 0x4d, 0x26, 0x8d, 0xc1, 0xb5, 0x83, 0x67, 0x52, 0xd1, 0x47, 0xe0, 0x8d, 0xd8, 0xf0, 0x36, - 0xbc, 0x05, 0x1b, 0xe6, 0xe2, 0x31, 0x71, 0x62, 0x83, 0xe9, 0xc6, 0x99, 0x33, 0xe7, 0x9b, 0x73, - 0xf9, 0xce, 0xa5, 0x05, 0x7d, 0x6c, 0x4f, 0x9c, 0x06, 0xc1, 0xc1, 0xb5, 0x33, 0xc0, 0xa4, 0x41, - 0x1d, 0xd7, 0xc5, 0x81, 0x39, 0x09, 0x7c, 0xea, 0xa3, 0x4d, 0xae, 0x33, 0x95, 0xce, 0x94, 0x3a, - 0x7d, 0x5b, 0xbc, 0x18, 0x8c, 0xed, 0x80, 0xca, 0xaf, 0x44, 0xeb, 0xb5, 0xd9, 0x7b, 0xdf, 0x1b, - 0x39, 0x97, 0xa1, 0x42, 0xba, 0x08, 0xb0, 0x8b, 0x6d, 0x82, 0xd5, 0x6f, 0xec, 0x91, 0xd2, 0x39, - 0xde, 0xc8, 0x97, 0x0a, 0xe3, 0x87, 0x06, 0xff, 0x75, 0x1c, 0x42, 0x2d, 0xa9, 0x22, 0x16, 0xfe, - 0x3c, 0xc5, 0x84, 0xa2, 0x4d, 0x58, 0x76, 0x9d, 0x2b, 0x87, 0xd6, 0xb5, 0xfb, 0xda, 0x4e, 0xde, - 0x92, 0x02, 0xda, 0x86, 0xa2, 0x3f, 0x1a, 0x11, 0x4c, 0xeb, 0x39, 0x76, 0x5d, 0xb1, 0x42, 0x09, - 0xbd, 0x82, 0x12, 0xf1, 0x03, 0xda, 0xbf, 0xb8, 0xa9, 0xe7, 0x99, 0x62, 0xbd, 0xf9, 0xd0, 0x4c, - 0xca, 0xc9, 0xe4, 0x9e, 0x7a, 0x0c, 0x68, 0xf2, 0xcf, 0xfe, 0x8d, 0x55, 0x24, 0xe2, 0x97, 0xdb, - 0x1d, 0x39, 0x2e, 0xc5, 0x41, 0xbd, 0x20, 0xed, 0x4a, 0x09, 0x1d, 0x01, 0x08, 0xbb, 0x7e, 0x30, - 0x64, 0xba, 0x65, 0x61, 0x7a, 0x27, 0x83, 0xe9, 0x33, 0x8e, 0xb7, 0x2a, 0x44, 0x1d, 0x8d, 0x0f, - 0x50, 0x56, 0x00, 0xa3, 0x09, 0x45, 0xe9, 0x1e, 0xad, 0x40, 0xe9, 0xbc, 0x7b, 0xda, 0x3d, 0x7b, - 0xd7, 0xad, 0x2e, 0xa1, 0x32, 0x14, 0xba, 0xad, 0xd7, 0xed, 0xaa, 0x86, 0x36, 0x60, 0xad, 0xd3, - 0xea, 0xbd, 0xe9, 0x5b, 0xed, 0x4e, 0xbb, 0xd5, 0x6b, 0x1f, 0x56, 0x73, 0xc6, 0x3d, 0xa8, 0x44, - 0x76, 0x51, 0x09, 0xf2, 0xad, 0xde, 0x81, 0x7c, 0x72, 0xd8, 0x66, 0x27, 0xcd, 0xf8, 0xaa, 0xc1, - 0x66, 0x9c, 0x46, 0x32, 0xf1, 0x3d, 0x82, 0x39, 0x8f, 0x03, 0x7f, 0xea, 0x45, 0x3c, 0x0a, 0x01, - 0x21, 0x28, 0x78, 0xf8, 0x8b, 0x62, 0x51, 0x9c, 0x39, 0x92, 0xfa, 0xd4, 0x76, 0x05, 0x83, 0x0c, - 0x29, 0x04, 0xf4, 0x02, 0xca, 0x61, 0xd5, 0x08, 0xe3, 0x26, 0xbf, 0xb3, 0xd2, 0xdc, 0x92, 0xf9, - 0xab, 0xfa, 0x86, 0x1e, 0xad, 0x08, 0x66, 0xec, 0x41, 0xed, 0x08, 0xab, 0x48, 0x7a, 0xd4, 0xa6, - 0xd3, 0xa8, 0xaa, 0xdc, 0xaf, 0x7d, 0x85, 0x45, 0x30, 0xdc, 0x2f, 0x3b, 0x1b, 0x6f, 0xa1, 0xbe, - 0x08, 0x0f, 0xa3, 0x4f, 0xc0, 0xa3, 0x47, 0x50, 0xe0, 0xfd, 0x23, 0x62, 0x5f, 0x69, 0xa2, 0x78, - 0x34, 0x27, 0x4c, 0x63, 0x09, 0xbd, 0x61, 0xce, 0xda, 0x3d, 0xf0, 0x3d, 0x8a, 0x3d, 0xfa, 0xa7, - 0x38, 0x3a, 0xf0, 0x7f, 0x02, 0x3e, 0x0c, 0xa4, 0x01, 0xa5, 0xd0, 0x85, 0x78, 0x93, 0xca, 0x82, - 0x42, 0x19, 0xdf, 0x59, 0x41, 0xce, 0x27, 0x43, 0x9b, 0x62, 0xa5, 0x4a, 0x77, 0x8d, 0x1e, 0xb3, - 0x22, 0xf1, 0x79, 0x0a, 0x73, 0xda, 0x90, 0xb6, 0xe5, 0xd0, 0x1d, 0xf0, 0xaf, 0x25, 0xf5, 0x68, - 0x17, 0x8a, 0xd7, 0xb6, 0xcb, 0xec, 0x88, 0x22, 0x45, 0xd9, 0x87, 0x48, 0x31, 0x8c, 0x56, 0x88, - 0x40, 0x35, 0x28, 0x0d, 0x83, 0x9b, 0x7e, 0x30, 0xf5, 0x44, 0x53, 0x97, 0xad, 0x22, 0x13, 0xad, - 0xa9, 0x87, 0x1e, 0xc0, 0xda, 0xd0, 0x21, 0xf6, 0x85, 0x8b, 0xfb, 0x63, 0xdf, 0xff, 0x44, 0x44, - 0x5f, 0x97, 0xad, 0xd5, 0xf0, 0xf2, 0x98, 0xdf, 0x19, 0xc7, 0xb0, 0x35, 0x17, 0xfe, 0x6d, 0x99, - 0xf8, 0xa9, 0xc1, 0xd6, 0x89, 0x47, 0x58, 0x33, 0xb9, 0x73, 0x54, 0x44, 0x69, 0x6b, 0x99, 0xd3, - 0xce, 0xfd, 0x4b, 0xda, 0xf9, 0x58, 0xda, 0x8a, 0xf8, 0xc2, 0x0c, 0xf1, 0x59, 0xa8, 0x40, 0x77, - 0xa0, 0xc2, 0xc1, 0x64, 0x62, 0x0f, 0x70, 0xbd, 0x28, 0x5e, 0xff, 0xbe, 0x40, 0x77, 0x01, 0x02, - 0x3c, 0x25, 0xb8, 0x2f, 0x8c, 0x97, 0xc4, 0xfb, 0x8a, 0xb8, 0xe9, 0xf2, 0xae, 0x3a, 0x81, 0xed, - 0xf9, 0xe4, 0x6f, 0x4b, 0xe4, 0x18, 0x6a, 0xe7, 0x9e, 0x93, 0xc8, 0x64, 0x52, 0x53, 0x2d, 0xe4, - 0x96, 0x4b, 0xc8, 0x8d, 0x0d, 0xfd, 0x64, 0x1a, 0x5c, 0xe2, 0x90, 0x2b, 0x29, 0x18, 0xa7, 0x50, - 0x5f, 0xf4, 0x74, 0xcb, 0xb0, 0x9b, 0xdf, 0x96, 0x61, 0x5d, 0x4d, 0xb7, 0xdc, 0x99, 0xc8, 0x81, - 0xd5, 0xd9, 0x65, 0x85, 0x9e, 0xa4, 0xaf, 0xd4, 0xb9, 0xbf, 0x0b, 0xfa, 0x6e, 0x16, 0xa8, 0x0c, - 0xd5, 0x58, 0x7a, 0xae, 0x21, 0x02, 0xd5, 0xf9, 0xed, 0x82, 0xf6, 0x92, 0x6d, 0xa4, 0x2c, 0x2d, - 0xdd, 0xcc, 0x0a, 0x57, 0x6e, 0xd1, 0x35, 0x6c, 0x2c, 0xac, 0x12, 0xf4, 0x57, 0x33, 0xf1, 0x1d, - 0xa5, 0x37, 0x32, 0xe3, 0x23, 0xbf, 0x1f, 0x61, 0x2d, 0x36, 0xb4, 0x28, 0x85, 0xad, 0xa4, 0xc5, - 0xa4, 0x3f, 0xcd, 0x84, 0x8d, 0x7c, 0x5d, 0xc1, 0x7a, 0xbc, 0xb1, 0x51, 0x8a, 0x81, 0xc4, 0xd9, - 0xd7, 0x9f, 0x65, 0x03, 0x47, 0xee, 0x58, 0x1d, 0xe7, 0x5b, 0x32, 0xad, 0x8e, 0x29, 0x43, 0x92, - 0x56, 0xc7, 0xb4, 0x4e, 0x37, 0x96, 0xf6, 0xe1, 0x7d, 0x59, 0xa1, 0x2f, 0x8a, 0xe2, 0xff, 0x95, - 0x97, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x46, 0xba, 0xf9, 0x49, 0x09, 0x00, 0x00, + // 821 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x52, 0xd3, 0x40, + 0x14, 0x26, 0x6d, 0xe9, 0xcf, 0x29, 0x30, 0x65, 0x05, 0x5a, 0x32, 0xea, 0x30, 0x71, 0x54, 0x44, + 0x49, 0xb5, 0xde, 0x3a, 0xce, 0x94, 0xd2, 0x01, 0x86, 0x5a, 0x66, 0x52, 0xd1, 0x19, 0x2f, 0xec, + 0x84, 0x76, 0x4b, 0xa3, 0x21, 0xa9, 0xd9, 0x2d, 0x23, 0x8f, 0xe0, 0x6b, 0xf8, 0x14, 0xde, 0xf8, + 0x64, 0xde, 0xb8, 0x3f, 0x49, 0x6c, 0xda, 0x44, 0x23, 0x37, 0xe9, 0xee, 0x9e, 0x6f, 0xbf, 0x73, + 0xce, 0x77, 0xf6, 0x1c, 0x00, 0x75, 0x6c, 0x4e, 0xac, 0x3a, 0xc1, 0xde, 0xb5, 0x35, 0xc0, 0xa4, + 0x4e, 0x2d, 0xdb, 0xc6, 0x9e, 0x3e, 0xf1, 0x5c, 0xea, 0xa2, 0x0d, 0x6e, 0xd3, 0x03, 0x9b, 0x2e, + 0x6d, 0xea, 0x96, 0xb8, 0x31, 0x18, 0x9b, 0x1e, 0x95, 0x5f, 0x89, 0x56, 0xab, 0xb3, 0xe7, 0xae, + 0x33, 0xb2, 0x2e, 0x7d, 0x83, 0x74, 0xe1, 0x61, 0x1b, 0x9b, 0x04, 0x07, 0xbf, 0x91, 0x4b, 0x81, + 0xcd, 0x72, 0x46, 0xae, 0x6f, 0xd8, 0x8e, 0x18, 0x08, 0x35, 0xe9, 0x94, 0x48, 0x93, 0xf6, 0x3d, + 0x03, 0x77, 0x3a, 0x16, 0xa1, 0x86, 0x34, 0x12, 0x03, 0x7f, 0x99, 0x62, 0x42, 0xd1, 0x06, 0x2c, + 0xdb, 0xd6, 0x95, 0x45, 0x6b, 0xca, 0x8e, 0xb2, 0x9b, 0x35, 0xe4, 0x06, 0x6d, 0x41, 0xde, 0x1d, + 0x8d, 0x08, 0xa6, 0xb5, 0x0c, 0x3b, 0x2e, 0x19, 0xfe, 0x0e, 0xbd, 0x86, 0x02, 0x71, 0x3d, 0xda, + 0xbf, 0xb8, 0xa9, 0x65, 0x99, 0x61, 0xad, 0xf1, 0x50, 0x8f, 0x4b, 0x57, 0xe7, 0x9e, 0x7a, 0x0c, + 0xa8, 0xf3, 0xcf, 0xc1, 0x8d, 0x91, 0x27, 0xe2, 0x97, 0xf3, 0x8e, 0x2c, 0x9b, 0x62, 0xaf, 0x96, + 0x93, 0xbc, 0x72, 0x87, 0x8e, 0x00, 0x04, 0xaf, 0xeb, 0x0d, 0x99, 0x6d, 0x59, 0x50, 0xef, 0xa6, + 0xa0, 0x3e, 0xe3, 0x78, 0xa3, 0x44, 0x82, 0x25, 0x7a, 0x05, 0x2b, 0x32, 0xed, 0xfe, 0xc0, 0x1d, + 0x62, 0x52, 0xcb, 0xef, 0x64, 0x19, 0xd5, 0xb6, 0xa4, 0x0a, 0x54, 0xec, 0x49, 0x61, 0x5a, 0x0c, + 0x61, 0x94, 0x25, 0x9c, 0xaf, 0x89, 0xf6, 0x11, 0x8a, 0x01, 0xbd, 0xd6, 0x80, 0xbc, 0x0c, 0x1e, + 0x95, 0xa1, 0x70, 0xde, 0x3d, 0xed, 0x9e, 0xbd, 0xef, 0x56, 0x96, 0x50, 0x11, 0x72, 0xdd, 0xe6, + 0x9b, 0x76, 0x45, 0x41, 0xeb, 0xb0, 0xda, 0x69, 0xf6, 0xde, 0xf6, 0x8d, 0x76, 0xa7, 0xdd, 0xec, + 0xb5, 0x0f, 0x2b, 0x19, 0xed, 0x3e, 0x94, 0xc2, 0xa8, 0x50, 0x01, 0xb2, 0xcd, 0x5e, 0x4b, 0x5e, + 0x39, 0x6c, 0xb3, 0x95, 0xa2, 0x7d, 0x53, 0x60, 0x23, 0x5a, 0x04, 0x32, 0x71, 0x1d, 0x82, 0x79, + 0x15, 0x06, 0xee, 0xd4, 0x09, 0xab, 0x20, 0x36, 0x08, 0x41, 0xce, 0xc1, 0x5f, 0x83, 0x1a, 0x88, + 0x35, 0x47, 0x52, 0x97, 0x9a, 0xb6, 0xd0, 0x9f, 0x21, 0xc5, 0x06, 0xbd, 0x80, 0xa2, 0x9f, 0x1c, + 0x61, 0xca, 0x66, 0x77, 0xcb, 0x8d, 0xcd, 0x68, 0xca, 0xbe, 0x47, 0x23, 0x84, 0x69, 0xfb, 0x50, + 0x3d, 0xc2, 0x41, 0x24, 0x52, 0x91, 0xe0, 0x4d, 0x70, 0xbf, 0xe6, 0x15, 0x16, 0xc1, 0x70, 0xbf, + 0x6c, 0xad, 0xbd, 0x83, 0xda, 0x22, 0xdc, 0x8f, 0x3e, 0x06, 0x8f, 0x1e, 0x41, 0x8e, 0x3f, 0x4c, + 0x11, 0x7b, 0xb9, 0x81, 0xa2, 0xd1, 0x9c, 0x30, 0x8b, 0x21, 0xec, 0x9a, 0x3e, 0xcb, 0xdb, 0x72, + 0x1d, 0x8a, 0x1d, 0xfa, 0xb7, 0x38, 0x3a, 0xb0, 0x1d, 0x83, 0xf7, 0x03, 0xa9, 0x43, 0xc1, 0x77, + 0x21, 0xee, 0x24, 0xaa, 0x10, 0xa0, 0xb4, 0x9f, 0xac, 0x20, 0xe7, 0x93, 0xa1, 0x49, 0x71, 0x60, + 0x4a, 0x76, 0x8d, 0x1e, 0xb3, 0x22, 0xf1, 0x46, 0xf5, 0x73, 0x5a, 0x97, 0xdc, 0xb2, 0x9b, 0x5b, + 0xfc, 0x6b, 0x48, 0x3b, 0xda, 0x83, 0xfc, 0xb5, 0x69, 0x33, 0x1e, 0x51, 0xa4, 0x30, 0x7b, 0x1f, + 0x29, 0xba, 0xdc, 0xf0, 0x11, 0xa8, 0x0a, 0x85, 0xa1, 0x77, 0xd3, 0xf7, 0xa6, 0x8e, 0x68, 0x89, + 0xa2, 0x91, 0x67, 0x5b, 0x63, 0xea, 0xa0, 0x07, 0xb0, 0x3a, 0xb4, 0x88, 0x79, 0x61, 0xe3, 0xfe, + 0xd8, 0x75, 0x3f, 0x13, 0xd1, 0x15, 0x45, 0x63, 0xc5, 0x3f, 0x3c, 0xe6, 0x67, 0xda, 0x31, 0x6c, + 0xce, 0x85, 0x7f, 0x5b, 0x25, 0x7e, 0x29, 0xb0, 0x79, 0xe2, 0xb0, 0x66, 0xb0, 0xed, 0x39, 0x29, + 0xc2, 0xb4, 0x95, 0xd4, 0x69, 0x67, 0xfe, 0x27, 0xed, 0x6c, 0x24, 0xed, 0x40, 0xf8, 0xdc, 0x8c, + 0xf0, 0x69, 0xa4, 0x40, 0x77, 0xa1, 0xc4, 0xc1, 0x64, 0x62, 0x0e, 0x30, 0x6b, 0x7b, 0x7e, 0xfb, + 0xcf, 0x01, 0xba, 0x07, 0xe0, 0xe1, 0x29, 0xc1, 0x7d, 0x41, 0x5e, 0x10, 0xf7, 0x4b, 0xe2, 0xa4, + 0xcb, 0x5f, 0xd5, 0x09, 0x6c, 0xcd, 0x27, 0x7f, 0x5b, 0x21, 0xc7, 0x50, 0x3d, 0x77, 0xac, 0x58, + 0x25, 0xe3, 0x1e, 0xd5, 0x42, 0x6e, 0x99, 0x98, 0xdc, 0x58, 0xd3, 0x4f, 0xa6, 0xde, 0x25, 0xf6, + 0xb5, 0x92, 0x1b, 0xed, 0x14, 0x6a, 0x8b, 0x9e, 0x6e, 0x19, 0x76, 0xe3, 0xc7, 0x32, 0xac, 0x05, + 0xdd, 0x2d, 0x27, 0x2e, 0xb2, 0x60, 0x65, 0x76, 0x58, 0xa1, 0x27, 0xc9, 0x03, 0x79, 0xee, 0xaf, + 0x8a, 0xba, 0x97, 0x06, 0x2a, 0x43, 0xd5, 0x96, 0x9e, 0x2b, 0x88, 0x40, 0x65, 0x7e, 0xba, 0xa0, + 0xfd, 0x78, 0x8e, 0x84, 0xa1, 0xa5, 0xea, 0x69, 0xe1, 0x81, 0x5b, 0x74, 0x0d, 0xeb, 0x0b, 0xa3, + 0x04, 0xfd, 0x93, 0x26, 0x3a, 0xa3, 0xd4, 0x7a, 0x6a, 0x7c, 0xe8, 0xf7, 0x13, 0xac, 0x46, 0x9a, + 0x16, 0x25, 0xa8, 0x15, 0x37, 0x98, 0xd4, 0xa7, 0xa9, 0xb0, 0xa1, 0xaf, 0x2b, 0x58, 0x8b, 0x3e, + 0x6c, 0x94, 0x40, 0x10, 0xdb, 0xfb, 0xea, 0xb3, 0x74, 0xe0, 0xd0, 0x1d, 0xab, 0xe3, 0xfc, 0x93, + 0x4c, 0xaa, 0x63, 0x42, 0x93, 0x24, 0xd5, 0x31, 0xe9, 0xa5, 0x6b, 0x4b, 0x07, 0xf0, 0xa1, 0x18, + 0xa0, 0x2f, 0xf2, 0xe2, 0xbf, 0x9d, 0x97, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x44, 0xdd, 0xaf, + 0x38, 0xa2, 0x09, 0x00, 0x00, }