diff --git a/bolt/dashboards.go b/bolt/dashboards.go index 1f982359f..1a57d3da1 100644 --- a/bolt/dashboards.go +++ b/bolt/dashboards.go @@ -86,6 +86,7 @@ func (d *DashboardsStore) Add(ctx context.Context, src chronograf.Dashboard) (ch id, _ := b.NextSequence() src.ID = chronograf.DashboardID(id) + // TODO: use FormatInt strID := strconv.Itoa(int(id)) for i, cell := range src.Cells { cid, err := d.IDs.Generate() @@ -95,12 +96,11 @@ func (d *DashboardsStore) Add(ctx context.Context, src chronograf.Dashboard) (ch cell.ID = cid src.Cells[i] = cell } - if v, err := internal.MarshalDashboard(src); err != nil { - return err - } else if err := b.Put([]byte(strID), v); err != nil { + v, err := internal.MarshalDashboard(src) + if err != nil { return err } - return nil + return b.Put([]byte(strID), v) }); err != nil { return chronograf.Dashboard{}, err } diff --git a/bolt/internal/internal.go b/bolt/internal/internal.go index 5bb729ecf..4de7ef6df 100644 --- a/bolt/internal/internal.go +++ b/bolt/internal/internal.go @@ -191,12 +191,26 @@ func MarshalDashboard(d chronograf.Dashboard) ([]byte, error) { if q.Range != nil { r.Upper, r.Lower = q.Range.Upper, q.Range.Lower } + q.Shifts = q.QueryConfig.Shifts queries[j] = &Query{ Command: q.Command, Label: q.Label, Range: r, Source: q.Source, } + + shifts := make([]*TimeShift, len(q.Shifts)) + for k := range q.Shifts { + shift := &TimeShift{ + Label: q.Shifts[k].Label, + Unit: q.Shifts[k].Unit, + Quantity: q.Shifts[k].Quantity, + } + + shifts[k] = shift + } + + queries[j].Shifts = shifts } axes := make(map[string]*Axis, len(c.Axes)) @@ -277,12 +291,26 @@ func UnmarshalDashboard(data []byte, d *chronograf.Dashboard) error { Label: q.Label, Source: q.Source, } + if q.Range.Upper != q.Range.Lower { queries[j].Range = &chronograf.Range{ Upper: q.Range.Upper, Lower: q.Range.Lower, } } + + shifts := make([]chronograf.TimeShift, len(q.Shifts)) + for k := range q.Shifts { + shift := chronograf.TimeShift{ + Label: q.Shifts[k].Label, + Unit: q.Shifts[k].Unit, + Quantity: q.Shifts[k].Quantity, + } + + shifts[k] = shift + } + + queries[j].Shifts = shifts } axes := make(map[string]chronograf.Axis, len(c.Axes)) diff --git a/bolt/internal/internal.pb.go b/bolt/internal/internal.pb.go index 02d757fdc..0683ebe34 100644 --- a/bolt/internal/internal.pb.go +++ b/bolt/internal/internal.pb.go @@ -20,6 +20,7 @@ It has these top-level messages: Layout Cell Query + TimeShift Range AlertRule User @@ -60,6 +61,83 @@ func (m *Source) String() string { return proto.CompactTextString(m) func (*Source) ProtoMessage() {} func (*Source) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{0} } +func (m *Source) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *Source) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Source) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *Source) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + +func (m *Source) GetPassword() string { + if m != nil { + return m.Password + } + return "" +} + +func (m *Source) GetURL() string { + if m != nil { + return m.URL + } + return "" +} + +func (m *Source) GetDefault() bool { + if m != nil { + return m.Default + } + return false +} + +func (m *Source) GetTelegraf() string { + if m != nil { + return m.Telegraf + } + return "" +} + +func (m *Source) GetInsecureSkipVerify() bool { + if m != nil { + return m.InsecureSkipVerify + } + return false +} + +func (m *Source) GetMetaURL() string { + if m != nil { + return m.MetaURL + } + return "" +} + +func (m *Source) GetSharedSecret() string { + if m != nil { + return m.SharedSecret + } + return "" +} + type Dashboard struct { ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` @@ -72,6 +150,20 @@ func (m *Dashboard) String() string { return proto.CompactTextString( func (*Dashboard) ProtoMessage() {} func (*Dashboard) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{1} } +func (m *Dashboard) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *Dashboard) GetName() string { + if m != nil { + return m.Name + } + return "" +} + func (m *Dashboard) GetCells() []*DashboardCell { if m != nil { return m.Cells @@ -103,6 +195,34 @@ func (m *DashboardCell) String() string { return proto.CompactTextStr func (*DashboardCell) ProtoMessage() {} func (*DashboardCell) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{2} } +func (m *DashboardCell) GetX() int32 { + if m != nil { + return m.X + } + return 0 +} + +func (m *DashboardCell) GetY() int32 { + if m != nil { + return m.Y + } + return 0 +} + +func (m *DashboardCell) GetW() int32 { + if m != nil { + return m.W + } + return 0 +} + +func (m *DashboardCell) GetH() int32 { + if m != nil { + return m.H + } + return 0 +} + func (m *DashboardCell) GetQueries() []*Query { if m != nil { return m.Queries @@ -110,6 +230,27 @@ func (m *DashboardCell) GetQueries() []*Query { return nil } +func (m *DashboardCell) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *DashboardCell) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *DashboardCell) GetID() string { + if m != nil { + return m.ID + } + return "" +} + func (m *DashboardCell) GetAxes() map[string]*Axis { if m != nil { return m.Axes @@ -118,7 +259,7 @@ func (m *DashboardCell) GetAxes() map[string]*Axis { } type Axis struct { - LegacyBounds []int64 `protobuf:"varint,1,rep,name=legacyBounds" json:"legacyBounds,omitempty"` + LegacyBounds []int64 `protobuf:"varint,1,rep,packed,name=legacyBounds" json:"legacyBounds,omitempty"` Bounds []string `protobuf:"bytes,2,rep,name=bounds" json:"bounds,omitempty"` Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"` Prefix string `protobuf:"bytes,4,opt,name=prefix,proto3" json:"prefix,omitempty"` @@ -132,6 +273,55 @@ func (m *Axis) String() string { return proto.CompactTextString(m) } func (*Axis) ProtoMessage() {} func (*Axis) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{3} } +func (m *Axis) GetLegacyBounds() []int64 { + if m != nil { + return m.LegacyBounds + } + return nil +} + +func (m *Axis) GetBounds() []string { + if m != nil { + return m.Bounds + } + return nil +} + +func (m *Axis) GetLabel() string { + if m != nil { + return m.Label + } + return "" +} + +func (m *Axis) GetPrefix() string { + if m != nil { + return m.Prefix + } + return "" +} + +func (m *Axis) GetSuffix() string { + if m != nil { + return m.Suffix + } + return "" +} + +func (m *Axis) GetBase() string { + if m != nil { + return m.Base + } + return "" +} + +func (m *Axis) GetScale() string { + if m != nil { + return m.Scale + } + return "" +} + type Template struct { ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` TempVar string `protobuf:"bytes,2,opt,name=temp_var,json=tempVar,proto3" json:"temp_var,omitempty"` @@ -146,6 +336,20 @@ func (m *Template) String() string { return proto.CompactTextString(m func (*Template) ProtoMessage() {} func (*Template) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{4} } +func (m *Template) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *Template) GetTempVar() string { + if m != nil { + return m.TempVar + } + return "" +} + func (m *Template) GetValues() []*TemplateValue { if m != nil { return m.Values @@ -153,6 +357,20 @@ func (m *Template) GetValues() []*TemplateValue { return nil } +func (m *Template) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *Template) GetLabel() string { + if m != nil { + return m.Label + } + return "" +} + func (m *Template) GetQuery() *TemplateQuery { if m != nil { return m.Query @@ -171,6 +389,27 @@ func (m *TemplateValue) String() string { return proto.CompactTextStr func (*TemplateValue) ProtoMessage() {} func (*TemplateValue) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{5} } +func (m *TemplateValue) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *TemplateValue) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *TemplateValue) GetSelected() bool { + if m != nil { + return m.Selected + } + return false +} + type TemplateQuery struct { Command string `protobuf:"bytes,1,opt,name=command,proto3" json:"command,omitempty"` Db string `protobuf:"bytes,2,opt,name=db,proto3" json:"db,omitempty"` @@ -185,6 +424,48 @@ func (m *TemplateQuery) String() string { return proto.CompactTextStr func (*TemplateQuery) ProtoMessage() {} func (*TemplateQuery) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{6} } +func (m *TemplateQuery) GetCommand() string { + if m != nil { + return m.Command + } + return "" +} + +func (m *TemplateQuery) GetDb() string { + if m != nil { + return m.Db + } + return "" +} + +func (m *TemplateQuery) GetRp() string { + if m != nil { + return m.Rp + } + return "" +} + +func (m *TemplateQuery) GetMeasurement() string { + if m != nil { + return m.Measurement + } + return "" +} + +func (m *TemplateQuery) GetTagKey() string { + if m != nil { + return m.TagKey + } + return "" +} + +func (m *TemplateQuery) GetFieldKey() string { + if m != nil { + return m.FieldKey + } + return "" +} + type Server struct { ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` @@ -200,6 +481,55 @@ func (m *Server) String() string { return proto.CompactTextString(m) func (*Server) ProtoMessage() {} func (*Server) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{7} } +func (m *Server) GetID() int64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *Server) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Server) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + +func (m *Server) GetPassword() string { + if m != nil { + return m.Password + } + return "" +} + +func (m *Server) GetURL() string { + if m != nil { + return m.URL + } + return "" +} + +func (m *Server) GetSrcID() int64 { + if m != nil { + return m.SrcID + } + return 0 +} + +func (m *Server) GetActive() bool { + if m != nil { + return m.Active + } + return false +} + type Layout struct { ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` Application string `protobuf:"bytes,2,opt,name=Application,proto3" json:"Application,omitempty"` @@ -213,6 +543,27 @@ func (m *Layout) String() string { return proto.CompactTextString(m) func (*Layout) ProtoMessage() {} func (*Layout) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{8} } +func (m *Layout) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *Layout) GetApplication() string { + if m != nil { + return m.Application + } + return "" +} + +func (m *Layout) GetMeasurement() string { + if m != nil { + return m.Measurement + } + return "" +} + func (m *Layout) GetCells() []*Cell { if m != nil { return m.Cells @@ -220,6 +571,13 @@ func (m *Layout) GetCells() []*Cell { return nil } +func (m *Layout) GetAutoflow() bool { + if m != nil { + return m.Autoflow + } + return false +} + type Cell struct { X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"` Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"` @@ -228,7 +586,7 @@ type Cell struct { Queries []*Query `protobuf:"bytes,5,rep,name=queries" json:"queries,omitempty"` I string `protobuf:"bytes,6,opt,name=i,proto3" json:"i,omitempty"` Name string `protobuf:"bytes,7,opt,name=name,proto3" json:"name,omitempty"` - Yranges []int64 `protobuf:"varint,8,rep,name=yranges" json:"yranges,omitempty"` + Yranges []int64 `protobuf:"varint,8,rep,packed,name=yranges" json:"yranges,omitempty"` Ylabels []string `protobuf:"bytes,9,rep,name=ylabels" json:"ylabels,omitempty"` Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type,omitempty"` Axes map[string]*Axis `protobuf:"bytes,11,rep,name=axes" json:"axes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"` @@ -239,6 +597,34 @@ func (m *Cell) String() string { return proto.CompactTextString(m) } func (*Cell) ProtoMessage() {} func (*Cell) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{9} } +func (m *Cell) GetX() int32 { + if m != nil { + return m.X + } + return 0 +} + +func (m *Cell) GetY() int32 { + if m != nil { + return m.Y + } + return 0 +} + +func (m *Cell) GetW() int32 { + if m != nil { + return m.W + } + return 0 +} + +func (m *Cell) GetH() int32 { + if m != nil { + return m.H + } + return 0 +} + func (m *Cell) GetQueries() []*Query { if m != nil { return m.Queries @@ -246,6 +632,41 @@ func (m *Cell) GetQueries() []*Query { return nil } +func (m *Cell) GetI() string { + if m != nil { + return m.I + } + return "" +} + +func (m *Cell) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Cell) GetYranges() []int64 { + if m != nil { + return m.Yranges + } + return nil +} + +func (m *Cell) GetYlabels() []string { + if m != nil { + return m.Ylabels + } + return nil +} + +func (m *Cell) GetType() string { + if m != nil { + return m.Type + } + return "" +} + func (m *Cell) GetAxes() map[string]*Axis { if m != nil { return m.Axes @@ -254,14 +675,15 @@ func (m *Cell) GetAxes() map[string]*Axis { } type Query struct { - Command string `protobuf:"bytes,1,opt,name=Command,proto3" json:"Command,omitempty"` - DB string `protobuf:"bytes,2,opt,name=DB,proto3" json:"DB,omitempty"` - RP string `protobuf:"bytes,3,opt,name=RP,proto3" json:"RP,omitempty"` - GroupBys []string `protobuf:"bytes,4,rep,name=GroupBys" json:"GroupBys,omitempty"` - Wheres []string `protobuf:"bytes,5,rep,name=Wheres" json:"Wheres,omitempty"` - Label string `protobuf:"bytes,6,opt,name=Label,proto3" json:"Label,omitempty"` - Range *Range `protobuf:"bytes,7,opt,name=Range" json:"Range,omitempty"` - Source string `protobuf:"bytes,8,opt,name=Source,proto3" json:"Source,omitempty"` + Command string `protobuf:"bytes,1,opt,name=Command,proto3" json:"Command,omitempty"` + DB string `protobuf:"bytes,2,opt,name=DB,proto3" json:"DB,omitempty"` + RP string `protobuf:"bytes,3,opt,name=RP,proto3" json:"RP,omitempty"` + GroupBys []string `protobuf:"bytes,4,rep,name=GroupBys" json:"GroupBys,omitempty"` + Wheres []string `protobuf:"bytes,5,rep,name=Wheres" json:"Wheres,omitempty"` + Label string `protobuf:"bytes,6,opt,name=Label,proto3" json:"Label,omitempty"` + Range *Range `protobuf:"bytes,7,opt,name=Range" json:"Range,omitempty"` + Source string `protobuf:"bytes,8,opt,name=Source,proto3" json:"Source,omitempty"` + Shifts []*TimeShift `protobuf:"bytes,9,rep,name=Shifts" json:"Shifts,omitempty"` } func (m *Query) Reset() { *m = Query{} } @@ -269,6 +691,48 @@ func (m *Query) String() string { return proto.CompactTextString(m) } func (*Query) ProtoMessage() {} func (*Query) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{10} } +func (m *Query) GetCommand() string { + if m != nil { + return m.Command + } + return "" +} + +func (m *Query) GetDB() string { + if m != nil { + return m.DB + } + return "" +} + +func (m *Query) GetRP() string { + if m != nil { + return m.RP + } + return "" +} + +func (m *Query) GetGroupBys() []string { + if m != nil { + return m.GroupBys + } + return nil +} + +func (m *Query) GetWheres() []string { + if m != nil { + return m.Wheres + } + return nil +} + +func (m *Query) GetLabel() string { + if m != nil { + return m.Label + } + return "" +} + func (m *Query) GetRange() *Range { if m != nil { return m.Range @@ -276,6 +740,52 @@ func (m *Query) GetRange() *Range { return nil } +func (m *Query) GetSource() string { + if m != nil { + return m.Source + } + return "" +} + +func (m *Query) GetShifts() []*TimeShift { + if m != nil { + return m.Shifts + } + return nil +} + +type TimeShift struct { + Label string `protobuf:"bytes,1,opt,name=Label,proto3" json:"Label,omitempty"` + Unit string `protobuf:"bytes,2,opt,name=Unit,proto3" json:"Unit,omitempty"` + Quantity string `protobuf:"bytes,3,opt,name=Quantity,proto3" json:"Quantity,omitempty"` +} + +func (m *TimeShift) Reset() { *m = TimeShift{} } +func (m *TimeShift) String() string { return proto.CompactTextString(m) } +func (*TimeShift) ProtoMessage() {} +func (*TimeShift) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{11} } + +func (m *TimeShift) GetLabel() string { + if m != nil { + return m.Label + } + return "" +} + +func (m *TimeShift) GetUnit() string { + if m != nil { + return m.Unit + } + return "" +} + +func (m *TimeShift) GetQuantity() string { + if m != nil { + return m.Quantity + } + return "" +} + type Range struct { Upper int64 `protobuf:"varint,1,opt,name=Upper,proto3" json:"Upper,omitempty"` Lower int64 `protobuf:"varint,2,opt,name=Lower,proto3" json:"Lower,omitempty"` @@ -284,7 +794,21 @@ type Range struct { func (m *Range) Reset() { *m = Range{} } func (m *Range) String() string { return proto.CompactTextString(m) } func (*Range) ProtoMessage() {} -func (*Range) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{11} } +func (*Range) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{12} } + +func (m *Range) GetUpper() int64 { + if m != nil { + return m.Upper + } + return 0 +} + +func (m *Range) GetLower() int64 { + if m != nil { + return m.Lower + } + return 0 +} type AlertRule struct { ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` @@ -296,7 +820,35 @@ type AlertRule struct { func (m *AlertRule) Reset() { *m = AlertRule{} } func (m *AlertRule) String() string { return proto.CompactTextString(m) } func (*AlertRule) ProtoMessage() {} -func (*AlertRule) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{12} } +func (*AlertRule) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{13} } + +func (m *AlertRule) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *AlertRule) GetJSON() string { + if m != nil { + return m.JSON + } + return "" +} + +func (m *AlertRule) GetSrcID() int64 { + if m != nil { + return m.SrcID + } + return 0 +} + +func (m *AlertRule) GetKapaID() int64 { + if m != nil { + return m.KapaID + } + return 0 +} type User struct { ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` @@ -306,7 +858,21 @@ type User struct { func (m *User) Reset() { *m = User{} } func (m *User) String() string { return proto.CompactTextString(m) } func (*User) ProtoMessage() {} -func (*User) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{13} } +func (*User) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{14} } + +func (m *User) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *User) GetName() string { + if m != nil { + return m.Name + } + return "" +} func init() { proto.RegisterType((*Source)(nil), "internal.Source") @@ -320,6 +886,7 @@ func init() { proto.RegisterType((*Layout)(nil), "internal.Layout") proto.RegisterType((*Cell)(nil), "internal.Cell") proto.RegisterType((*Query)(nil), "internal.Query") + proto.RegisterType((*TimeShift)(nil), "internal.TimeShift") proto.RegisterType((*Range)(nil), "internal.Range") proto.RegisterType((*AlertRule)(nil), "internal.AlertRule") proto.RegisterType((*User)(nil), "internal.User") @@ -328,70 +895,73 @@ func init() { func init() { proto.RegisterFile("internal.proto", fileDescriptorInternal) } var fileDescriptorInternal = []byte{ - // 1028 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0xd7, 0xf8, 0x4f, 0x12, 0xbf, 0x74, 0x0b, 0x1a, 0xad, 0x58, 0xb3, 0x5c, 0x82, 0x05, 0x52, - 0x40, 0x6c, 0x41, 0xbb, 0x42, 0x42, 0xdc, 0xd2, 0x06, 0xad, 0x4a, 0xbb, 0x4b, 0x99, 0xb4, 0xe5, - 0x84, 0x56, 0x13, 0xe7, 0xa5, 0xb5, 0xd6, 0x89, 0xcd, 0xd8, 0x6e, 0xe3, 0x6f, 0xc1, 0x27, 0x40, - 0x42, 0xe2, 0xc4, 0x81, 0x03, 0x5f, 0x80, 0xfb, 0x7e, 0x2a, 0xf4, 0x66, 0xc6, 0x8e, 0xc3, 0x76, - 0xd1, 0x5e, 0xe0, 0x36, 0xbf, 0xf7, 0xc6, 0x6f, 0x66, 0xde, 0xef, 0xfd, 0x7e, 0x09, 0xec, 0x27, - 0xeb, 0x12, 0xd5, 0x5a, 0xa6, 0x07, 0xb9, 0xca, 0xca, 0x8c, 0x0f, 0x1a, 0x1c, 0xfd, 0xe1, 0x40, - 0x6f, 0x96, 0x55, 0x2a, 0x46, 0xbe, 0x0f, 0xce, 0xf1, 0x34, 0x64, 0x23, 0x36, 0x76, 0x85, 0x73, - 0x3c, 0xe5, 0x1c, 0xbc, 0xe7, 0x72, 0x85, 0xa1, 0x33, 0x62, 0xe3, 0x40, 0xe8, 0x35, 0xc5, 0xce, - 0xeb, 0x1c, 0x43, 0xd7, 0xc4, 0x68, 0xcd, 0x1f, 0xc2, 0xe0, 0xa2, 0xa0, 0x6a, 0x2b, 0x0c, 0x3d, - 0x1d, 0x6f, 0x31, 0xe5, 0xce, 0x64, 0x51, 0xdc, 0x66, 0x6a, 0x11, 0xfa, 0x26, 0xd7, 0x60, 0xfe, - 0x2e, 0xb8, 0x17, 0xe2, 0x34, 0xec, 0xe9, 0x30, 0x2d, 0x79, 0x08, 0xfd, 0x29, 0x2e, 0x65, 0x95, - 0x96, 0x61, 0x7f, 0xc4, 0xc6, 0x03, 0xd1, 0x40, 0xaa, 0x73, 0x8e, 0x29, 0x5e, 0x29, 0xb9, 0x0c, - 0x07, 0xa6, 0x4e, 0x83, 0xf9, 0x01, 0xf0, 0xe3, 0x75, 0x81, 0x71, 0xa5, 0x70, 0xf6, 0x32, 0xc9, - 0x2f, 0x51, 0x25, 0xcb, 0x3a, 0x0c, 0x74, 0x81, 0x3b, 0x32, 0x74, 0xca, 0x33, 0x2c, 0x25, 0x9d, - 0x0d, 0xba, 0x54, 0x03, 0x79, 0x04, 0x7b, 0xb3, 0x6b, 0xa9, 0x70, 0x31, 0xc3, 0x58, 0x61, 0x19, - 0x0e, 0x75, 0x7a, 0x27, 0x16, 0xfd, 0xcc, 0x20, 0x98, 0xca, 0xe2, 0x7a, 0x9e, 0x49, 0xb5, 0x78, - 0xab, 0x9e, 0x3d, 0x02, 0x3f, 0xc6, 0x34, 0x2d, 0x42, 0x77, 0xe4, 0x8e, 0x87, 0x8f, 0x1f, 0x1c, - 0xb4, 0x64, 0xb4, 0x75, 0x8e, 0x30, 0x4d, 0x85, 0xd9, 0xc5, 0xbf, 0x80, 0xa0, 0xc4, 0x55, 0x9e, - 0xca, 0x12, 0x8b, 0xd0, 0xd3, 0x9f, 0xf0, 0xed, 0x27, 0xe7, 0x36, 0x25, 0xb6, 0x9b, 0xa2, 0xdf, - 0x1d, 0xb8, 0xb7, 0x53, 0x8a, 0xef, 0x01, 0xdb, 0xe8, 0x5b, 0xf9, 0x82, 0x6d, 0x08, 0xd5, 0xfa, - 0x46, 0xbe, 0x60, 0x35, 0xa1, 0x5b, 0xcd, 0x9f, 0x2f, 0xd8, 0x2d, 0xa1, 0x6b, 0xcd, 0x9a, 0x2f, - 0xd8, 0x35, 0xff, 0x04, 0xfa, 0x3f, 0x55, 0xa8, 0x12, 0x2c, 0x42, 0x5f, 0x9f, 0xfc, 0xce, 0xf6, - 0xe4, 0xef, 0x2b, 0x54, 0xb5, 0x68, 0xf2, 0xf4, 0x52, 0xcd, 0xb8, 0xa1, 0x4f, 0xaf, 0x29, 0x56, - 0xd2, 0x74, 0xf4, 0x4d, 0x8c, 0xd6, 0xb6, 0x43, 0x86, 0x33, 0xea, 0xd0, 0x97, 0xe0, 0xc9, 0x0d, - 0x16, 0x61, 0xa0, 0xeb, 0x7f, 0xf8, 0x86, 0x66, 0x1c, 0x4c, 0x36, 0x58, 0x7c, 0xb3, 0x2e, 0x55, - 0x2d, 0xf4, 0xf6, 0x87, 0x4f, 0x21, 0x68, 0x43, 0x34, 0x39, 0x2f, 0xb1, 0xd6, 0x0f, 0x0c, 0x04, - 0x2d, 0xf9, 0x47, 0xe0, 0xdf, 0xc8, 0xb4, 0x32, 0x8d, 0x1f, 0x3e, 0xde, 0xdf, 0x96, 0x9d, 0x6c, - 0x92, 0x42, 0x98, 0xe4, 0xd7, 0xce, 0x57, 0x2c, 0xfa, 0x93, 0x81, 0x47, 0x31, 0x22, 0x3b, 0xc5, - 0x2b, 0x19, 0xd7, 0x87, 0x59, 0xb5, 0x5e, 0x14, 0x21, 0x1b, 0xb9, 0x63, 0x57, 0xec, 0xc4, 0xf8, - 0x7b, 0xd0, 0x9b, 0x9b, 0xac, 0x33, 0x72, 0xc7, 0x81, 0xb0, 0x88, 0xdf, 0x07, 0x3f, 0x95, 0x73, - 0x4c, 0xad, 0x0e, 0x0c, 0xa0, 0xdd, 0xb9, 0xc2, 0x65, 0xb2, 0xb1, 0x32, 0xb0, 0x88, 0xe2, 0x45, - 0xb5, 0xa4, 0xb8, 0x91, 0x80, 0x45, 0xd4, 0xae, 0xb9, 0x2c, 0xda, 0x16, 0xd2, 0x9a, 0x2a, 0x17, - 0xb1, 0x4c, 0x9b, 0x1e, 0x1a, 0x10, 0xfd, 0xc5, 0x68, 0xfe, 0x0d, 0xdf, 0x9d, 0x99, 0x33, 0x1d, - 0x7d, 0x1f, 0x06, 0x34, 0x0b, 0x2f, 0x6e, 0xa4, 0xb2, 0x73, 0xd7, 0x27, 0x7c, 0x29, 0x15, 0xff, - 0x1c, 0x7a, 0xfa, 0xe5, 0x77, 0xcc, 0x5e, 0x53, 0xee, 0x92, 0xf2, 0xc2, 0x6e, 0x6b, 0x19, 0xf4, - 0x3a, 0x0c, 0xb6, 0x8f, 0xf5, 0xbb, 0x8f, 0x7d, 0x04, 0x3e, 0x8d, 0x42, 0xad, 0x6f, 0x7f, 0x67, - 0x65, 0x33, 0x30, 0x66, 0x57, 0x74, 0x01, 0xf7, 0x76, 0x4e, 0x6c, 0x4f, 0x62, 0xbb, 0x27, 0x6d, - 0x59, 0x0c, 0x2c, 0x6b, 0xa4, 0xfd, 0x02, 0x53, 0x8c, 0x4b, 0x5c, 0xe8, 0x7e, 0x0f, 0x44, 0x8b, - 0xa3, 0x5f, 0xd9, 0xb6, 0xae, 0x3e, 0x8f, 0xd4, 0x1d, 0x67, 0xab, 0x95, 0x5c, 0x2f, 0x6c, 0xe9, - 0x06, 0x52, 0xdf, 0x16, 0x73, 0x5b, 0xda, 0x59, 0xcc, 0x09, 0xab, 0xdc, 0x32, 0xe8, 0xa8, 0x9c, - 0x8f, 0x60, 0xb8, 0x42, 0x59, 0x54, 0x0a, 0x57, 0xb8, 0x2e, 0x6d, 0x0b, 0xba, 0x21, 0xfe, 0x00, - 0xfa, 0xa5, 0xbc, 0x7a, 0x41, 0xb3, 0x67, 0x99, 0x2c, 0xe5, 0xd5, 0x09, 0xd6, 0xfc, 0x03, 0x08, - 0x96, 0x09, 0xa6, 0x0b, 0x9d, 0x32, 0x74, 0x0e, 0x74, 0xe0, 0x04, 0xeb, 0xe8, 0x37, 0x06, 0xbd, - 0x19, 0xaa, 0x1b, 0x54, 0x6f, 0x65, 0x17, 0x5d, 0x3b, 0x75, 0xff, 0xc5, 0x4e, 0xbd, 0xbb, 0xed, - 0xd4, 0xdf, 0xda, 0xe9, 0x7d, 0xf0, 0x67, 0x2a, 0x3e, 0x9e, 0xea, 0x1b, 0xb9, 0xc2, 0x00, 0x9a, - 0xc6, 0x49, 0x5c, 0x26, 0x37, 0x68, 0x3d, 0xd6, 0xa2, 0xe8, 0x17, 0x06, 0xbd, 0x53, 0x59, 0x67, - 0x55, 0xf9, 0xda, 0x84, 0x8d, 0x60, 0x38, 0xc9, 0xf3, 0x34, 0x89, 0x65, 0x99, 0x64, 0x6b, 0x7b, - 0xdb, 0x6e, 0x88, 0x76, 0x3c, 0xeb, 0xf4, 0xce, 0xdc, 0xbb, 0x1b, 0x22, 0x85, 0x1e, 0x69, 0x17, - 0x34, 0x96, 0xd6, 0x51, 0xa8, 0x31, 0x3f, 0x9d, 0xa4, 0x07, 0x4e, 0xaa, 0x32, 0x5b, 0xa6, 0xd9, - 0xad, 0x7e, 0xc9, 0x40, 0xb4, 0x38, 0x7a, 0xe5, 0x80, 0xf7, 0x7f, 0xb9, 0xdb, 0x1e, 0xb0, 0xc4, - 0x12, 0xc9, 0x92, 0xd6, 0xeb, 0xfa, 0x1d, 0xaf, 0x0b, 0xa1, 0x5f, 0x2b, 0xb9, 0xbe, 0xc2, 0x22, - 0x1c, 0x68, 0xe7, 0x68, 0xa0, 0xce, 0x68, 0x8d, 0x18, 0x93, 0x0b, 0x44, 0x03, 0xdb, 0x99, 0x87, - 0xce, 0xcc, 0x7f, 0x66, 0xfd, 0x70, 0xa8, 0x6f, 0x14, 0xee, 0xb6, 0xe5, 0xbf, 0xb3, 0xc1, 0x57, - 0x0c, 0xfc, 0x56, 0x30, 0x47, 0xbb, 0x82, 0x39, 0xda, 0x0a, 0x66, 0x7a, 0xd8, 0x08, 0x66, 0x7a, - 0x48, 0x58, 0x9c, 0x35, 0x82, 0x11, 0x67, 0x44, 0xd6, 0x53, 0x95, 0x55, 0xf9, 0x61, 0x6d, 0x58, - 0x0d, 0x44, 0x8b, 0x69, 0xca, 0x7e, 0xb8, 0x46, 0x65, 0x5b, 0x1d, 0x08, 0x8b, 0x68, 0x26, 0x4f, - 0xb5, 0x99, 0x98, 0xe6, 0x1a, 0xc0, 0x3f, 0x06, 0x5f, 0x50, 0xf3, 0x74, 0x87, 0x77, 0x78, 0xd1, - 0x61, 0x61, 0xb2, 0x54, 0xd4, 0xfc, 0x57, 0xb1, 0xbf, 0x27, 0x16, 0x45, 0x4f, 0xec, 0xe7, 0x54, - 0xfd, 0x22, 0xcf, 0x51, 0x59, 0x89, 0x19, 0xa0, 0xcf, 0xcc, 0x6e, 0xd1, 0xb8, 0xa3, 0x2b, 0x0c, - 0x88, 0x7e, 0x84, 0x60, 0x92, 0xa2, 0x2a, 0x45, 0x95, 0xbe, 0xee, 0xa9, 0x1c, 0xbc, 0x6f, 0x67, - 0xdf, 0x3d, 0x6f, 0x84, 0x49, 0xeb, 0xad, 0x9c, 0xdc, 0x7f, 0xc8, 0xe9, 0x44, 0xe6, 0xf2, 0x78, - 0xaa, 0xe7, 0xcc, 0x15, 0x16, 0x45, 0x9f, 0x82, 0x47, 0xb2, 0xed, 0x54, 0xf6, 0xde, 0x24, 0xf9, - 0x79, 0x4f, 0xff, 0x2b, 0x7b, 0xf2, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x59, 0x2e, 0xc0, - 0xa7, 0x09, 0x00, 0x00, + // 1082 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x8e, 0xe3, 0xc4, + 0x13, 0x96, 0x63, 0x3b, 0x89, 0x2b, 0xb3, 0xf3, 0xfb, 0xa9, 0x59, 0xb1, 0x66, 0xb9, 0x04, 0x0b, + 0xa4, 0xf0, 0x67, 0x07, 0xb4, 0x2b, 0x24, 0xc4, 0x2d, 0x33, 0x41, 0xab, 0x61, 0x66, 0x97, 0x99, + 0xce, 0xcc, 0x70, 0x42, 0xab, 0x4e, 0x52, 0x99, 0x58, 0xeb, 0xd8, 0xa6, 0xdd, 0x9e, 0x89, 0xdf, + 0x82, 0x27, 0x40, 0x42, 0xe2, 0xc4, 0x81, 0x03, 0x2f, 0xc0, 0x9d, 0x17, 0xe2, 0x8a, 0xaa, 0xbb, + 0xed, 0x38, 0xec, 0x2c, 0xda, 0x0b, 0xdc, 0xfa, 0xab, 0xea, 0x54, 0x55, 0xd7, 0x57, 0xf5, 0xc5, + 0xb0, 0x1f, 0xa7, 0x0a, 0x65, 0x2a, 0x92, 0x83, 0x5c, 0x66, 0x2a, 0x63, 0xfd, 0x1a, 0x47, 0xbf, + 0x76, 0xa0, 0x3b, 0xcd, 0x4a, 0x39, 0x47, 0xb6, 0x0f, 0x9d, 0xe3, 0x49, 0xe8, 0x0c, 0x9d, 0x91, + 0xcb, 0x3b, 0xc7, 0x13, 0xc6, 0xc0, 0x7b, 0x2e, 0xd6, 0x18, 0x76, 0x86, 0xce, 0x28, 0xe0, 0xfa, + 0x4c, 0xb6, 0x8b, 0x2a, 0xc7, 0xd0, 0x35, 0x36, 0x3a, 0xb3, 0x87, 0xd0, 0xbf, 0x2c, 0x28, 0xda, + 0x1a, 0x43, 0x4f, 0xdb, 0x1b, 0x4c, 0xbe, 0x33, 0x51, 0x14, 0xb7, 0x99, 0x5c, 0x84, 0xbe, 0xf1, + 0xd5, 0x98, 0xfd, 0x1f, 0xdc, 0x4b, 0x7e, 0x1a, 0x76, 0xb5, 0x99, 0x8e, 0x2c, 0x84, 0xde, 0x04, + 0x97, 0xa2, 0x4c, 0x54, 0xd8, 0x1b, 0x3a, 0xa3, 0x3e, 0xaf, 0x21, 0xc5, 0xb9, 0xc0, 0x04, 0xaf, + 0xa5, 0x58, 0x86, 0x7d, 0x13, 0xa7, 0xc6, 0xec, 0x00, 0xd8, 0x71, 0x5a, 0xe0, 0xbc, 0x94, 0x38, + 0x7d, 0x19, 0xe7, 0x57, 0x28, 0xe3, 0x65, 0x15, 0x06, 0x3a, 0xc0, 0x1d, 0x1e, 0xca, 0xf2, 0x0c, + 0x95, 0xa0, 0xdc, 0xa0, 0x43, 0xd5, 0x90, 0x45, 0xb0, 0x37, 0x5d, 0x09, 0x89, 0x8b, 0x29, 0xce, + 0x25, 0xaa, 0x70, 0xa0, 0xdd, 0x3b, 0xb6, 0xe8, 0x07, 0x07, 0x82, 0x89, 0x28, 0x56, 0xb3, 0x4c, + 0xc8, 0xc5, 0x1b, 0xf5, 0xec, 0x11, 0xf8, 0x73, 0x4c, 0x92, 0x22, 0x74, 0x87, 0xee, 0x68, 0xf0, + 0xf8, 0xc1, 0x41, 0x43, 0x46, 0x13, 0xe7, 0x08, 0x93, 0x84, 0x9b, 0x5b, 0xec, 0x33, 0x08, 0x14, + 0xae, 0xf3, 0x44, 0x28, 0x2c, 0x42, 0x4f, 0xff, 0x84, 0x6d, 0x7f, 0x72, 0x61, 0x5d, 0x7c, 0x7b, + 0x29, 0xfa, 0xa5, 0x03, 0xf7, 0x76, 0x42, 0xb1, 0x3d, 0x70, 0x36, 0xba, 0x2a, 0x9f, 0x3b, 0x1b, + 0x42, 0x95, 0xae, 0xc8, 0xe7, 0x4e, 0x45, 0xe8, 0x56, 0xf3, 0xe7, 0x73, 0xe7, 0x96, 0xd0, 0x4a, + 0xb3, 0xe6, 0x73, 0x67, 0xc5, 0x3e, 0x84, 0xde, 0xf7, 0x25, 0xca, 0x18, 0x8b, 0xd0, 0xd7, 0x99, + 0xff, 0xb7, 0xcd, 0x7c, 0x5e, 0xa2, 0xac, 0x78, 0xed, 0xa7, 0x97, 0x6a, 0xc6, 0x0d, 0x7d, 0xfa, + 0x4c, 0x36, 0x45, 0xd3, 0xd1, 0x33, 0x36, 0x3a, 0xdb, 0x0e, 0x19, 0xce, 0xa8, 0x43, 0x9f, 0x83, + 0x27, 0x36, 0x58, 0x84, 0x81, 0x8e, 0xff, 0xde, 0x6b, 0x9a, 0x71, 0x30, 0xde, 0x60, 0xf1, 0x55, + 0xaa, 0x64, 0xc5, 0xf5, 0xf5, 0x87, 0x4f, 0x21, 0x68, 0x4c, 0x34, 0x39, 0x2f, 0xb1, 0xd2, 0x0f, + 0x0c, 0x38, 0x1d, 0xd9, 0xfb, 0xe0, 0xdf, 0x88, 0xa4, 0x34, 0x8d, 0x1f, 0x3c, 0xde, 0xdf, 0x86, + 0x1d, 0x6f, 0xe2, 0x82, 0x1b, 0xe7, 0x97, 0x9d, 0x2f, 0x9c, 0xe8, 0x37, 0x07, 0x3c, 0xb2, 0x11, + 0xd9, 0x09, 0x5e, 0x8b, 0x79, 0x75, 0x98, 0x95, 0xe9, 0xa2, 0x08, 0x9d, 0xa1, 0x3b, 0x72, 0xf9, + 0x8e, 0x8d, 0xbd, 0x0d, 0xdd, 0x99, 0xf1, 0x76, 0x86, 0xee, 0x28, 0xe0, 0x16, 0xb1, 0xfb, 0xe0, + 0x27, 0x62, 0x86, 0x89, 0xdd, 0x03, 0x03, 0xe8, 0x76, 0x2e, 0x71, 0x19, 0x6f, 0xec, 0x1a, 0x58, + 0x44, 0xf6, 0xa2, 0x5c, 0x92, 0xdd, 0xac, 0x80, 0x45, 0xd4, 0xae, 0x99, 0x28, 0x9a, 0x16, 0xd2, + 0x99, 0x22, 0x17, 0x73, 0x91, 0xd4, 0x3d, 0x34, 0x20, 0xfa, 0xdd, 0xa1, 0xf9, 0x37, 0x7c, 0xb7, + 0x66, 0xce, 0x74, 0xf4, 0x1d, 0xe8, 0xd3, 0x2c, 0xbc, 0xb8, 0x11, 0xd2, 0xce, 0x5d, 0x8f, 0xf0, + 0x95, 0x90, 0xec, 0x53, 0xe8, 0xea, 0x97, 0xdf, 0x31, 0x7b, 0x75, 0xb8, 0x2b, 0xf2, 0x73, 0x7b, + 0xad, 0x61, 0xd0, 0x6b, 0x31, 0xd8, 0x3c, 0xd6, 0x6f, 0x3f, 0xf6, 0x11, 0xf8, 0x34, 0x0a, 0x95, + 0xae, 0xfe, 0xce, 0xc8, 0x66, 0x60, 0xcc, 0xad, 0xe8, 0x12, 0xee, 0xed, 0x64, 0x6c, 0x32, 0x39, + 0xbb, 0x99, 0xb6, 0x2c, 0x06, 0x96, 0x35, 0xda, 0xfd, 0x02, 0x13, 0x9c, 0x2b, 0x5c, 0xe8, 0x7e, + 0xf7, 0x79, 0x83, 0xa3, 0x9f, 0x9c, 0x6d, 0x5c, 0x9d, 0x8f, 0xb6, 0x7b, 0x9e, 0xad, 0xd7, 0x22, + 0x5d, 0xd8, 0xd0, 0x35, 0xa4, 0xbe, 0x2d, 0x66, 0x36, 0x74, 0x67, 0x31, 0x23, 0x2c, 0x73, 0xcb, + 0x60, 0x47, 0xe6, 0x6c, 0x08, 0x83, 0x35, 0x8a, 0xa2, 0x94, 0xb8, 0xc6, 0x54, 0xd9, 0x16, 0xb4, + 0x4d, 0xec, 0x01, 0xf4, 0x94, 0xb8, 0x7e, 0x41, 0xb3, 0x67, 0x99, 0x54, 0xe2, 0xfa, 0x04, 0x2b, + 0xf6, 0x2e, 0x04, 0xcb, 0x18, 0x93, 0x85, 0x76, 0x19, 0x3a, 0xfb, 0xda, 0x70, 0x82, 0x55, 0xf4, + 0xb3, 0x03, 0xdd, 0x29, 0xca, 0x1b, 0x94, 0x6f, 0x24, 0x17, 0x6d, 0x39, 0x75, 0xff, 0x41, 0x4e, + 0xbd, 0xbb, 0xe5, 0xd4, 0xdf, 0xca, 0xe9, 0x7d, 0xf0, 0xa7, 0x72, 0x7e, 0x3c, 0xd1, 0x15, 0xb9, + 0xdc, 0x00, 0x9a, 0xc6, 0xf1, 0x5c, 0xc5, 0x37, 0x68, 0x35, 0xd6, 0xa2, 0xe8, 0x47, 0x07, 0xba, + 0xa7, 0xa2, 0xca, 0x4a, 0xf5, 0xca, 0x84, 0x0d, 0x61, 0x30, 0xce, 0xf3, 0x24, 0x9e, 0x0b, 0x15, + 0x67, 0xa9, 0xad, 0xb6, 0x6d, 0xa2, 0x1b, 0xcf, 0x5a, 0xbd, 0x33, 0x75, 0xb7, 0x4d, 0xb4, 0xa1, + 0x47, 0x5a, 0x05, 0x8d, 0xa4, 0xb5, 0x36, 0xd4, 0x88, 0x9f, 0x76, 0xd2, 0x03, 0xc7, 0xa5, 0xca, + 0x96, 0x49, 0x76, 0xab, 0x5f, 0xd2, 0xe7, 0x0d, 0x8e, 0xfe, 0xe8, 0x80, 0xf7, 0x5f, 0xa9, 0xdb, + 0x1e, 0x38, 0xb1, 0x25, 0xd2, 0x89, 0x1b, 0xad, 0xeb, 0xb5, 0xb4, 0x2e, 0x84, 0x5e, 0x25, 0x45, + 0x7a, 0x8d, 0x45, 0xd8, 0xd7, 0xca, 0x51, 0x43, 0xed, 0xd1, 0x3b, 0x62, 0x44, 0x2e, 0xe0, 0x35, + 0x6c, 0x66, 0x1e, 0x5a, 0x33, 0xff, 0x89, 0xd5, 0xc3, 0x81, 0xae, 0x28, 0xdc, 0x6d, 0xcb, 0xbf, + 0x27, 0x83, 0x7f, 0x3a, 0xe0, 0x37, 0x0b, 0x73, 0xb4, 0xbb, 0x30, 0x47, 0xdb, 0x85, 0x99, 0x1c, + 0xd6, 0x0b, 0x33, 0x39, 0x24, 0xcc, 0xcf, 0xea, 0x85, 0xe1, 0x67, 0x44, 0xd6, 0x53, 0x99, 0x95, + 0xf9, 0x61, 0x65, 0x58, 0x0d, 0x78, 0x83, 0x69, 0xca, 0xbe, 0x5d, 0xa1, 0xb4, 0xad, 0x0e, 0xb8, + 0x45, 0x34, 0x93, 0xa7, 0x5a, 0x4c, 0x4c, 0x73, 0x0d, 0x60, 0x1f, 0x80, 0xcf, 0xa9, 0x79, 0xba, + 0xc3, 0x3b, 0xbc, 0x68, 0x33, 0x37, 0x5e, 0x0a, 0x6a, 0xbe, 0x55, 0xec, 0xff, 0x49, 0xfd, 0xe5, + 0xf2, 0x31, 0x74, 0xa7, 0xab, 0x78, 0xa9, 0xea, 0x7f, 0x95, 0xb7, 0x5a, 0x62, 0x14, 0xaf, 0x51, + 0xfb, 0xb8, 0xbd, 0x12, 0x9d, 0x43, 0xd0, 0x18, 0xb7, 0xe5, 0x38, 0xed, 0x72, 0x18, 0x78, 0x97, + 0x69, 0xac, 0xea, 0xb5, 0xa4, 0x33, 0x3d, 0xf6, 0xbc, 0x14, 0xa9, 0x8a, 0x55, 0x55, 0xaf, 0x65, + 0x8d, 0xa3, 0x27, 0xb6, 0x7c, 0x0a, 0x77, 0x99, 0xe7, 0x28, 0xed, 0x8a, 0x1b, 0xa0, 0x93, 0x64, + 0xb7, 0x68, 0xd4, 0xd9, 0xe5, 0x06, 0x44, 0xdf, 0x41, 0x30, 0x4e, 0x50, 0x2a, 0x5e, 0x26, 0xaf, + 0x6a, 0x3a, 0x03, 0xef, 0xeb, 0xe9, 0x37, 0xcf, 0xeb, 0x0a, 0xe8, 0xbc, 0x5d, 0x67, 0xf7, 0x6f, + 0xeb, 0x7c, 0x22, 0x72, 0x71, 0x3c, 0xd1, 0x73, 0xee, 0x72, 0x8b, 0xa2, 0x8f, 0xc0, 0x23, 0xd9, + 0x68, 0x45, 0xf6, 0x5e, 0x27, 0x39, 0xb3, 0xae, 0xfe, 0x2a, 0x7c, 0xf2, 0x57, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xda, 0x20, 0xfc, 0x99, 0x27, 0x0a, 0x00, 0x00, } diff --git a/bolt/internal/internal.proto b/bolt/internal/internal.proto index 9cd762d39..660a9c198 100644 --- a/bolt/internal/internal.proto +++ b/bolt/internal/internal.proto @@ -23,15 +23,15 @@ message Dashboard { } message DashboardCell { - int32 x = 1; // X-coordinate of Cell in the Dashboard - int32 y = 2; // Y-coordinate of Cell in the Dashboard - int32 w = 3; // Width of Cell in the Dashboard - int32 h = 4; // Height of Cell in the Dashboard - repeated Query queries = 5; // Time-series data queries for Dashboard - string name = 6; // User-facing name for this Dashboard - string type = 7; // Dashboard visualization type - string ID = 8; // id is the unique id of the dashboard. MIGRATED FIELD added in 1.2.0-beta6 - map axes = 9; // Axes represent the graphical viewport for a cell's visualizations + int32 x = 1; // X-coordinate of Cell in the Dashboard + int32 y = 2; // Y-coordinate of Cell in the Dashboard + int32 w = 3; // Width of Cell in the Dashboard + int32 h = 4; // Height of Cell in the Dashboard + repeated Query queries = 5; // Time-series data queries for Dashboard + string name = 6; // User-facing name for this Dashboard + string type = 7; // Dashboard visualization type + string ID = 8; // id is the unique id of the dashboard. MIGRATED FIELD added in 1.2.0-beta6 + map axes = 9; // Axes represent the graphical viewport for a cell's visualizations } message Axis { @@ -54,18 +54,18 @@ message Template { } message TemplateValue { - string type = 1; // Type can be tagKey, tagValue, fieldKey, csv, measurement, database, constant - string value = 2; // Value is the specific value used to replace a template in an InfluxQL query - bool selected = 3; // Selected states that this variable has been picked to use for replacement + string type = 1; // Type can be tagKey, tagValue, fieldKey, csv, measurement, database, constant + string value = 2; // Value is the specific value used to replace a template in an InfluxQL query + bool selected = 3; // Selected states that this variable has been picked to use for replacement } message TemplateQuery { - string command = 1; // Command is the query itself - string db = 2; // DB the database for the query (optional) - string rp = 3; // RP is a retention policy and optional; - string measurement = 4; // Measurement is the optinally selected measurement for the query - string tag_key = 5; // TagKey is the optionally selected tag key for the query - string field_key = 6; // FieldKey is the optionally selected field key for the query + string command = 1; // Command is the query itself + string db = 2; // DB the database for the query (optional) + string rp = 3; // RP is a retention policy and optional; + string measurement = 4; // Measurement is the optinally selected measurement for the query + string tag_key = 5; // TagKey is the optionally selected tag key for the query + string field_key = 6; // FieldKey is the optionally selected field key for the query } message Server { @@ -101,31 +101,38 @@ message Cell { } message Query { - string Command = 1; // Command is the query itself - string DB = 2; // DB the database for the query (optional) - string RP = 3; // RP is a retention policy and optional; - repeated string GroupBys= 4; // GroupBys define the groups to combine in the query - repeated string Wheres = 5; // Wheres define the restrictions on the query - string Label = 6; // Label is the name of the Y-Axis - Range Range = 7; // Range is the upper and lower bound of the Y-Axis - string Source = 8; // Source is the optional URI to the data source + string Command = 1; // Command is the query itself + string DB = 2; // DB the database for the query (optional) + string RP = 3; // RP is a retention policy and optional; + repeated string GroupBys = 4; // GroupBys define the groups to combine in the query + repeated string Wheres = 5; // Wheres define the restrictions on the query + string Label = 6; // Label is the name of the Y-Axis + Range Range = 7; // Range is the upper and lower bound of the Y-Axis + string Source = 8; // Source is the optional URI to the data source + repeated TimeShift Shifts = 9; // TimeShift represents a shift to apply to an influxql query's time range +} + +message TimeShift { + string Label = 1; // user facing description + string Unit = 2; // influxql time unit representation i.e. ms, s, m, h, d + string Quantity = 3; // number of units } message Range { - int64 Upper = 1; // Upper is the upper-bound of the range - int64 Lower = 2; // Lower is the lower-bound of the range + int64 Upper = 1; // Upper is the upper-bound of the range + int64 Lower = 2; // Lower is the lower-bound of the range } message AlertRule { - string ID = 1; // ID is the unique ID of this alert rule - string JSON = 2; // JSON byte representation of the alert - int64 SrcID = 3; // SrcID is the id of the source this alert is associated with - int64 KapaID = 4; // KapaID is the id of the kapacitor this alert is associated with + string ID = 1; // ID is the unique ID of this alert rule + string JSON = 2; // JSON byte representation of the alert + int64 SrcID = 3; // SrcID is the id of the source this alert is associated with + int64 KapaID = 4; // KapaID is the id of the kapacitor this alert is associated with } message User { - uint64 ID = 1; // ID is the unique ID of this user - string Name = 2; // Name is the user's login name + uint64 ID = 1; // ID is the unique ID of this user + string Name = 2; // Name is the user's login name } // The following is a vim modeline, it autoconfigures vim to have the diff --git a/bolt/internal/internal_test.go b/bolt/internal/internal_test.go index 244dd471c..4ca7ae420 100644 --- a/bolt/internal/internal_test.go +++ b/bolt/internal/internal_test.go @@ -163,6 +163,13 @@ func Test_MarshalDashboard(t *testing.T) { Upper: int64(100), }, Source: "/chronograf/v1/sources/1", + Shifts: []chronograf.TimeShift{ + { + Label: "Best Week Ever", + Unit: "d", + Quantity: "7", + }, + }, }, }, Axes: map[string]chronograf.Axis{ @@ -210,6 +217,7 @@ func Test_MarshalDashboard_WithLegacyBounds(t *testing.T) { Range: &chronograf.Range{ Upper: int64(100), }, + Shifts: []chronograf.TimeShift{}, }, }, Axes: map[string]chronograf.Axis{ @@ -241,6 +249,7 @@ func Test_MarshalDashboard_WithLegacyBounds(t *testing.T) { Range: &chronograf.Range{ Upper: int64(100), }, + Shifts: []chronograf.TimeShift{}, }, }, Axes: map[string]chronograf.Axis{ @@ -285,6 +294,7 @@ func Test_MarshalDashboard_WithEmptyLegacyBounds(t *testing.T) { Range: &chronograf.Range{ Upper: int64(100), }, + Shifts: []chronograf.TimeShift{}, }, }, Axes: map[string]chronograf.Axis{ @@ -316,6 +326,7 @@ func Test_MarshalDashboard_WithEmptyLegacyBounds(t *testing.T) { Range: &chronograf.Range{ Upper: int64(100), }, + Shifts: []chronograf.TimeShift{}, }, }, Axes: map[string]chronograf.Axis{ diff --git a/chronograf.go b/chronograf.go index b6e314742..0ea3592d6 100644 --- a/chronograf.go +++ b/chronograf.go @@ -171,6 +171,7 @@ type DashboardQuery struct { Range *Range `json:"range,omitempty"` // Range is the default Y-Axis range for the data QueryConfig QueryConfig `json:"queryConfig,omitempty"` // QueryConfig represents the query state that is understood by the data explorer Source string `json:"source"` // Source is the optional URI to the data source for this queryConfig + Shifts []TimeShift `json:"-"` // Shifts represents shifts to apply to an influxql query's time range. Clients expect the shift to be in the generated QueryConfig } // TemplateQuery is used to retrieve choices for template replacement @@ -284,6 +285,13 @@ type DurationRange struct { Lower string `json:"lower"` } +// TimeShift represents a shift to apply to an influxql query's time range +type TimeShift struct { + Label string `json:"label"` // user facing description + Unit string `json:"unit"` // influxql time unit representation i.e. ms, s, m, h, d + Quantity string `json:"quantity"` // number of units +} + // QueryConfig represents UI query from the data explorer type QueryConfig struct { ID string `json:"id,omitempty"` @@ -297,6 +305,7 @@ type QueryConfig struct { Fill string `json:"fill,omitempty"` RawText *string `json:"rawText"` Range *DurationRange `json:"range"` + Shifts []TimeShift `json:"shifts"` } // KapacitorNode adds arguments and properties to an alert diff --git a/server/cells.go b/server/cells.go index 2d01b406c..0bed1a4d9 100644 --- a/server/cells.go +++ b/server/cells.go @@ -31,7 +31,6 @@ func newCellResponses(dID chronograf.DashboardID, dcells []chronograf.DashboardC cells := make([]dashboardCellResponse, len(dcells)) for i, cell := range dcells { newCell := chronograf.DashboardCell{} - newCell.Queries = make([]chronograf.DashboardQuery, len(cell.Queries)) copy(newCell.Queries, cell.Queries) @@ -121,6 +120,8 @@ func CorrectWidthHeight(c *chronograf.DashboardCell) { func AddQueryConfig(c *chronograf.DashboardCell) { for i, q := range c.Queries { qc := ToQueryConfig(q.Command) + qc.Shifts = append([]chronograf.TimeShift(nil), q.Shifts...) + q.Shifts = nil q.QueryConfig = qc c.Queries[i] = q } diff --git a/server/cells_test.go b/server/cells_test.go index 12b109679..2f6060bf1 100644 --- a/server/cells_test.go +++ b/server/cells_test.go @@ -162,14 +162,14 @@ func Test_Service_DashboardCells(t *testing.T) { http.StatusOK, }, { - "cell axes should always be \"x\", \"y\", and \"y2\"", - &url.URL{ + name: "cell axes should always be \"x\", \"y\", and \"y2\"", + reqURL: &url.URL{ Path: "/chronograf/v1/dashboards/1/cells", }, - map[string]string{ + ctxParams: map[string]string{ "id": "1", }, - []chronograf.DashboardCell{ + mockResponse: []chronograf.DashboardCell{ { ID: "3899be5a-f6eb-4347-b949-de2f4fbea859", X: 0, @@ -182,7 +182,7 @@ func Test_Service_DashboardCells(t *testing.T) { Axes: map[string]chronograf.Axis{}, }, }, - []chronograf.DashboardCell{ + expected: []chronograf.DashboardCell{ { ID: "3899be5a-f6eb-4347-b949-de2f4fbea859", X: 0, @@ -205,7 +205,7 @@ func Test_Service_DashboardCells(t *testing.T) { }, }, }, - http.StatusOK, + expectedCode: http.StatusOK, }, } diff --git a/server/dashboards_test.go b/server/dashboards_test.go index 622393757..04f72fda4 100644 --- a/server/dashboards_test.go +++ b/server/dashboards_test.go @@ -219,6 +219,13 @@ func Test_newDashboardResponse(t *testing.T) { { Source: "/chronograf/v1/sources/1", Command: "SELECT donors from hill_valley_preservation_society where time > '1985-10-25 08:00:00'", + Shifts: []chronograf.TimeShift{ + { + Label: "Best Week Evar", + Unit: "d", + Quantity: "7", + }, + }, }, }, Axes: map[string]chronograf.Axis{ @@ -267,6 +274,13 @@ func Test_newDashboardResponse(t *testing.T) { }, Tags: make(map[string][]string, 0), AreTagsAccepted: false, + Shifts: []chronograf.TimeShift{ + { + Label: "Best Week Evar", + Unit: "d", + Quantity: "7", + }, + }, }, }, }, diff --git a/server/queries.go b/server/queries.go index 76e5ad4b5..38e937b34 100644 --- a/server/queries.go +++ b/server/queries.go @@ -84,6 +84,7 @@ func (s *Service) Queries(w http.ResponseWriter, r *http.Request) { Error(w, http.StatusBadRequest, err.Error(), s.Logger) return } + qc.Shifts = []chronograf.TimeShift{} qr.QueryConfig = qc if stmt, err := queries.ParseSelect(query); err == nil { diff --git a/server/queries_test.go b/server/queries_test.go index 83967a7e7..14e0c794a 100644 --- a/server/queries_test.go +++ b/server/queries_test.go @@ -60,7 +60,7 @@ func TestService_Queries(t *testing.T) { "id": "82b60d37-251e-4afe-ac93-ca20a3642b11" } ]}`))), - want: `{"queries":[{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","query":"SELECT \"pingReq\" FROM db.\"monitor\".\"httpd\" WHERE time \u003e now() - 1m","queryConfig":{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","database":"db","measurement":"httpd","retentionPolicy":"monitor","fields":[{"value":"pingReq","type":"field","alias":""}],"tags":{},"groupBy":{"time":"","tags":[]},"areTagsAccepted":false,"rawText":null,"range":{"upper":"","lower":"now() - 1m"}},"queryAST":{"condition":{"expr":"binary","op":"\u003e","lhs":{"expr":"reference","val":"time"},"rhs":{"expr":"binary","op":"-","lhs":{"expr":"call","name":"now"},"rhs":{"expr":"literal","val":"1m","type":"duration"}}},"fields":[{"column":{"expr":"reference","val":"pingReq"}}],"sources":[{"database":"db","retentionPolicy":"monitor","name":"httpd","type":"measurement"}]}}]} + want: `{"queries":[{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","query":"SELECT \"pingReq\" FROM db.\"monitor\".\"httpd\" WHERE time \u003e now() - 1m","queryConfig":{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","database":"db","measurement":"httpd","retentionPolicy":"monitor","fields":[{"value":"pingReq","type":"field","alias":""}],"tags":{},"groupBy":{"time":"","tags":[]},"areTagsAccepted":false,"rawText":null,"range":{"upper":"","lower":"now() - 1m"},"shifts":[]},"queryAST":{"condition":{"expr":"binary","op":"\u003e","lhs":{"expr":"reference","val":"time"},"rhs":{"expr":"binary","op":"-","lhs":{"expr":"call","name":"now"},"rhs":{"expr":"literal","val":"1m","type":"duration"}}},"fields":[{"column":{"expr":"reference","val":"pingReq"}}],"sources":[{"database":"db","retentionPolicy":"monitor","name":"httpd","type":"measurement"}]}}]} `, }, { @@ -81,7 +81,7 @@ func TestService_Queries(t *testing.T) { "id": "82b60d37-251e-4afe-ac93-ca20a3642b11" } ]}`))), - want: `{"queries":[{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","query":"SHOW DATABASES","queryConfig":{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","database":"","measurement":"","retentionPolicy":"","fields":[],"tags":{},"groupBy":{"time":"","tags":[]},"areTagsAccepted":false,"rawText":"SHOW DATABASES","range":null}}]} + want: `{"queries":[{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","query":"SHOW DATABASES","queryConfig":{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","database":"","measurement":"","retentionPolicy":"","fields":[],"tags":{},"groupBy":{"time":"","tags":[]},"areTagsAccepted":false,"rawText":"SHOW DATABASES","range":null,"shifts":[]}}]} `, }, { @@ -166,7 +166,7 @@ func TestService_Queries(t *testing.T) { } ] }`))), - want: `{"queries":[{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","query":"SELECT \"pingReq\" FROM :dbs:.\"monitor\".\"httpd\" WHERE time \u003e :dashboardTime: AND time \u003c :upperDashboardTime: GROUP BY :interval:","queryConfig":{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","database":"","measurement":"","retentionPolicy":"","fields":[],"tags":{},"groupBy":{"time":"","tags":[]},"areTagsAccepted":false,"rawText":"SELECT \"pingReq\" FROM :dbs:.\"monitor\".\"httpd\" WHERE time \u003e :dashboardTime: AND time \u003c :upperDashboardTime: GROUP BY :interval:","range":null},"queryTemplated":"SELECT \"pingReq\" FROM \"_internal\".\"monitor\".\"httpd\" WHERE time \u003e now() - 15m AND time \u003c now() GROUP BY time(2s)","tempVars":[{"tempVar":":upperDashboardTime:","values":[{"value":"now()","type":"constant","selected":true}]},{"tempVar":":dashboardTime:","values":[{"value":"now() - 15m","type":"constant","selected":true}]},{"tempVar":":dbs:","values":[{"value":"_internal","type":"database","selected":true}]},{"tempVar":":interval:","values":[{"value":"1000","type":"resolution","selected":false},{"value":"3","type":"pointsPerPixel","selected":false}]}]}]} + want: `{"queries":[{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","query":"SELECT \"pingReq\" FROM :dbs:.\"monitor\".\"httpd\" WHERE time \u003e :dashboardTime: AND time \u003c :upperDashboardTime: GROUP BY :interval:","queryConfig":{"id":"82b60d37-251e-4afe-ac93-ca20a3642b11","database":"","measurement":"","retentionPolicy":"","fields":[],"tags":{},"groupBy":{"time":"","tags":[]},"areTagsAccepted":false,"rawText":"SELECT \"pingReq\" FROM :dbs:.\"monitor\".\"httpd\" WHERE time \u003e :dashboardTime: AND time \u003c :upperDashboardTime: GROUP BY :interval:","range":null,"shifts":[]},"queryTemplated":"SELECT \"pingReq\" FROM \"_internal\".\"monitor\".\"httpd\" WHERE time \u003e now() - 15m AND time \u003c now() GROUP BY time(2s)","tempVars":[{"tempVar":":upperDashboardTime:","values":[{"value":"now()","type":"constant","selected":true}]},{"tempVar":":dashboardTime:","values":[{"value":"now() - 15m","type":"constant","selected":true}]},{"tempVar":":dbs:","values":[{"value":"_internal","type":"database","selected":true}]},{"tempVar":":interval:","values":[{"value":"1000","type":"resolution","selected":false},{"value":"3","type":"pointsPerPixel","selected":false}]}]}]} `, }, }