diff --git a/backend/app/instance_provider.go b/backend/app/instance_provider.go index 595672756..a4dfdaa05 100644 --- a/backend/app/instance_provider.go +++ b/backend/app/instance_provider.go @@ -2,6 +2,7 @@ package app import ( "context" + "errors" "fmt" "github.com/grafana/grafana-plugin-sdk-go/backend" @@ -10,7 +11,7 @@ import ( ) // InstanceFactoryFunc factory method for creating app instances. -type InstanceFactoryFunc func(settings backend.AppInstanceSettings) (instancemgmt.Instance, error) +type InstanceFactoryFunc func(ctx context.Context, settings backend.AppInstanceSettings) (instancemgmt.Instance, error) // NewInstanceManager creates a new app instance manager, // @@ -44,8 +45,7 @@ type instanceProvider struct { func (ip *instanceProvider) GetKey(ctx context.Context, pluginContext backend.PluginContext) (interface{}, error) { if pluginContext.AppInstanceSettings == nil { - // fail fast if there is no app settings - return nil, fmt.Errorf("app instance settings cannot be nil") + return nil, errors.New("app instance settings cannot be nil") } // The instance key generated for app plugins should include both plugin ID, and the OrgID, since for a single @@ -59,11 +59,17 @@ func (ip *instanceProvider) GetKey(ctx context.Context, pluginContext backend.Pl } func (ip *instanceProvider) NeedsUpdate(_ context.Context, pluginContext backend.PluginContext, cachedInstance instancemgmt.CachedInstance) bool { - curSettings := pluginContext.AppInstanceSettings - cachedSettings := cachedInstance.PluginContext.AppInstanceSettings - return !curSettings.Updated.Equal(cachedSettings.Updated) + curConfig := pluginContext.GrafanaConfig + cachedConfig := cachedInstance.PluginContext.GrafanaConfig + configUpdated := !cachedConfig.Equal(curConfig) + + cachedAppSettings := cachedInstance.PluginContext.AppInstanceSettings + curAppSettings := pluginContext.AppInstanceSettings + appUpdated := !curAppSettings.Updated.Equal(cachedAppSettings.Updated) + + return appUpdated || configUpdated } -func (ip *instanceProvider) NewInstance(_ context.Context, pluginContext backend.PluginContext) (instancemgmt.Instance, error) { - return ip.factory(*pluginContext.AppInstanceSettings) +func (ip *instanceProvider) NewInstance(ctx context.Context, pluginContext backend.PluginContext) (instancemgmt.Instance, error) { + return ip.factory(ctx, *pluginContext.AppInstanceSettings) } diff --git a/backend/app/instance_provider_test.go b/backend/app/instance_provider_test.go index c41169cc1..8a6fb125a 100644 --- a/backend/app/instance_provider_test.go +++ b/backend/app/instance_provider_test.go @@ -19,11 +19,11 @@ func TestInstanceProvider(t *testing.T) { type testInstance struct { value string } - ip := NewInstanceProvider(func(settings backend.AppInstanceSettings) (instancemgmt.Instance, error) { + ip := NewInstanceProvider(func(ctx context.Context, settings backend.AppInstanceSettings) (instancemgmt.Instance, error) { return testInstance{value: "what an app"}, nil }) - t.Run("When data source instance settings not provided should return error", func(t *testing.T) { + t.Run("When app instance settings not provided should return error", func(t *testing.T) { _, err := ip.GetKey(context.Background(), backend.PluginContext{}) require.Error(t, err) }) @@ -38,38 +38,66 @@ func TestInstanceProvider(t *testing.T) { require.Equal(t, "super-app-plugin#42", key) }) - t.Run("When current app instance settings compared to cached instance haven't been updated should return false", func(t *testing.T) { + t.Run("When both the configuration and updated field of current app instance settings are equal to the cache, should return false", func(t *testing.T) { + config := map[string]string{ + "foo": "bar", + } + curSettings := backend.PluginContext{ AppInstanceSettings: &backend.AppInstanceSettings{ Updated: time.Now(), }, + GrafanaConfig: backend.NewGrafanaCfg(config), } - cachedInstance := instancemgmt.CachedInstance{ - PluginContext: backend.PluginContext{ - AppInstanceSettings: &backend.AppInstanceSettings{ - Updated: curSettings.AppInstanceSettings.Updated, - }, + + cachedSettings := backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: curSettings.AppInstanceSettings.Updated, }, + GrafanaConfig: backend.NewGrafanaCfg(config), + } + + cachedInstance := instancemgmt.CachedInstance{ + PluginContext: cachedSettings, } needsUpdate := ip.NeedsUpdate(context.Background(), curSettings, cachedInstance) require.False(t, needsUpdate) }) - t.Run("When current app instance settings compared to cached instance have been updated should return true", func(t *testing.T) { + t.Run("When either the config or updated field of current app instance settings are not equal to the cache, should return true", func(t *testing.T) { curSettings := backend.PluginContext{ AppInstanceSettings: &backend.AppInstanceSettings{ Updated: time.Now(), }, } - cachedInstance := instancemgmt.CachedInstance{ - PluginContext: backend.PluginContext{ - AppInstanceSettings: &backend.AppInstanceSettings{ - Updated: curSettings.AppInstanceSettings.Updated.Add(time.Second), - }, + + cachedSettings := backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: curSettings.AppInstanceSettings.Updated.Add(time.Second), }, } + + cachedInstance := instancemgmt.CachedInstance{ + PluginContext: cachedSettings, + } needsUpdate := ip.NeedsUpdate(context.Background(), curSettings, cachedInstance) require.True(t, needsUpdate) + + t.Run("Should return true when cached config is changed", func(t *testing.T) { + curSettings.GrafanaConfig = backend.NewGrafanaCfg(map[string]string{ + "foo": "bar", + }) + + cachedSettings.GrafanaConfig = backend.NewGrafanaCfg(map[string]string{ + "baz": "qux", + }) + + cachedInstance = instancemgmt.CachedInstance{ + PluginContext: cachedSettings, + } + needsUpdate = ip.NeedsUpdate(context.Background(), curSettings, cachedInstance) + require.True(t, needsUpdate) + }) }) t.Run("When creating a new instance should return expected instance", func(t *testing.T) { @@ -83,3 +111,115 @@ func TestInstanceProvider(t *testing.T) { require.Equal(t, "what an app", i.(testInstance).value) }) } + +func Test_instanceProvider_NeedsUpdate(t *testing.T) { + ts := time.Now() + + type args struct { + pluginContext backend.PluginContext + cachedInstance instancemgmt.CachedInstance + } + tests := []struct { + name string + args args + expected bool + }{ + { + name: "Empty instance settings should return false", + args: args{ + pluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{}, + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{}, + }, + }, + }, + expected: false, + }, + { + name: "Instance settings with identical updated field should return false", + args: args{ + pluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: ts, + }, + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: ts, + }, + }, + }, + }, + expected: false, + }, + { + name: "Instance settings with identical updated field and config should return false", + args: args{ + pluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: ts, + }, + GrafanaConfig: backend.NewGrafanaCfg(map[string]string{"foo": "bar", "baz": "qux"}), + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: ts, + }, + GrafanaConfig: backend.NewGrafanaCfg(map[string]string{"foo": "bar", "baz": "qux"}), + }, + }, + }, + expected: false, + }, + { + name: "Instance settings with different updated field should return true", + args: args{ + pluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: ts, + }, + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: ts.Add(time.Millisecond), + }, + }, + }, + }, + expected: true, + }, + { + name: "Instance settings with identical updated field and different config should return true", + args: args{ + pluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: ts, + }, + GrafanaConfig: backend.NewGrafanaCfg(map[string]string{"foo": "bar"}), + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + AppInstanceSettings: &backend.AppInstanceSettings{ + Updated: ts, + }, + }, + }, + }, + expected: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ip := &instanceProvider{} + if got := ip.NeedsUpdate(context.Background(), tt.args.pluginContext, tt.args.cachedInstance); got != tt.expected { + t.Errorf("NeedsUpdate() = %v, expected %v", got, tt.expected) + } + }) + } +} diff --git a/backend/common.go b/backend/common.go index 8ea36b1ba..4827ed606 100644 --- a/backend/common.go +++ b/backend/common.go @@ -162,6 +162,9 @@ type PluginContext struct { // // Will only be set if request targeting a data source instance. DataSourceInstanceSettings *DataSourceInstanceSettings + + // GrafanaConfig is the configuration settings provided by Grafana. + GrafanaConfig *GrafanaCfg } func setCustomOptionsFromHTTPSettings(opts *httpclient.Options, httpSettings *HTTPSettings) { diff --git a/backend/config.go b/backend/config.go new file mode 100644 index 000000000..693e5a513 --- /dev/null +++ b/backend/config.go @@ -0,0 +1,111 @@ +package backend + +import ( + "context" + "strconv" + "strings" + + "github.com/grafana/grafana-plugin-sdk-go/backend/proxy" + "github.com/grafana/grafana-plugin-sdk-go/experimental/featuretoggles" +) + +type configKey struct{} + +// GrafanaConfigFromContext returns Grafana config from context. +func GrafanaConfigFromContext(ctx context.Context) *GrafanaCfg { + v := ctx.Value(configKey{}) + if v == nil { + return NewGrafanaCfg(nil) + } + + return v.(*GrafanaCfg) +} + +// withGrafanaConfig injects supplied Grafana config into context. +func withGrafanaConfig(ctx context.Context, cfg *GrafanaCfg) context.Context { + ctx = context.WithValue(ctx, configKey{}, cfg) + return ctx +} + +type GrafanaCfg struct { + config map[string]string +} + +func NewGrafanaCfg(cfg map[string]string) *GrafanaCfg { + return &GrafanaCfg{config: cfg} +} + +func (c *GrafanaCfg) Get(key string) string { + return c.config[key] +} + +func (c *GrafanaCfg) FeatureToggles() FeatureToggles { + features, exists := c.config[featuretoggles.EnabledFeatures] + if !exists { + return FeatureToggles{} + } + + fs := strings.Split(features, ",") + enabledFeatures := make(map[string]struct{}, len(fs)) + for _, f := range fs { + enabledFeatures[f] = struct{}{} + } + + return FeatureToggles{ + enabled: enabledFeatures, + } +} + +func (c *GrafanaCfg) Equal(c2 *GrafanaCfg) bool { + if c == nil && c2 == nil { + return true + } + if c == nil || c2 == nil { + return false + } + + if len(c.config) != len(c2.config) { + return false + } + for k, v1 := range c.config { + if v2, ok := c2.config[k]; !ok || v1 != v2 { + return false + } + } + return true +} + +type FeatureToggles struct { + // enabled is a set-like map of feature flags that are enabled. + enabled map[string]struct{} +} + +// IsEnabled returns true if feature f is contained in ft.enabled. +func (ft FeatureToggles) IsEnabled(f string) bool { + _, exists := ft.enabled[f] + return exists +} + +type Proxy struct { + clientCfg proxy.ClientCfg +} + +func (pc Proxy) ClientConfig() proxy.ClientCfg { + return pc.clientCfg +} + +func (c *GrafanaCfg) Proxy() Proxy { + if v, exists := c.config[proxy.PluginSecureSocksProxyEnabled]; exists && v == strconv.FormatBool(true) { + return Proxy{ + clientCfg: proxy.ClientCfg{ + Enabled: true, + ClientCert: c.Get(proxy.PluginSecureSocksProxyClientCert), + ClientKey: c.Get(proxy.PluginSecureSocksProxyClientKey), + RootCA: c.Get(proxy.PluginSecureSocksProxyRootCACert), + ProxyAddress: c.Get(proxy.PluginSecureSocksProxyProxyAddress), + ServerName: c.Get(proxy.PluginSecureSocksProxyServerName), + }, + } + } + return Proxy{clientCfg: proxy.ClientCfg{}} +} diff --git a/backend/convert_from_protobuf.go b/backend/convert_from_protobuf.go index 2c190795f..4df74c313 100644 --- a/backend/convert_from_protobuf.go +++ b/backend/convert_from_protobuf.go @@ -78,6 +78,7 @@ func (f ConvertFromProtobuf) PluginContext(proto *pluginv2.PluginContext) Plugin User: f.User(proto.User), AppInstanceSettings: f.AppInstanceSettings(proto.AppInstanceSettings), DataSourceInstanceSettings: f.DataSourceInstanceSettings(proto.DataSourceInstanceSettings, proto.PluginId), + GrafanaConfig: f.GrafanaConfig(proto.GrafanaConfig), } } @@ -276,3 +277,7 @@ func (f ConvertFromProtobuf) StreamPacket(protoReq *pluginv2.StreamPacket) *Stre Data: protoReq.GetData(), } } + +func (f ConvertFromProtobuf) GrafanaConfig(cfg map[string]string) *GrafanaCfg { + return NewGrafanaCfg(cfg) +} diff --git a/backend/convert_from_protobuf_test.go b/backend/convert_from_protobuf_test.go index 1a0e7d89b..dac32e89e 100644 --- a/backend/convert_from_protobuf_test.go +++ b/backend/convert_from_protobuf_test.go @@ -172,8 +172,7 @@ func TestConvertFromProtobufDataSourceInstanceSettings(t *testing.T) { t.Fatalf(unsetErrFmt, "sdk", "DataSourceInstanceSettings", sdkWalker.ZeroValueFieldCount, sdkWalker.FieldCount) } - // adding +1 to the proto field count to account for the Type field in the SDK - require.Equal(t, protoWalker.FieldCount+1, sdkWalker.FieldCount) + require.Equal(t, protoWalker.FieldCount+datasourceInstanceProtoFieldCountDelta(), sdkWalker.FieldCount) requireCounter := &requireCounter{} @@ -204,6 +203,9 @@ var protoPluginContext = &pluginv2.PluginContext{ }, AppInstanceSettings: protoAppInstanceSettings, DataSourceInstanceSettings: protoDataSourceInstanceSettings, + GrafanaConfig: map[string]string{ + "foo": "bar", + }, } func TestConvertFromProtobufPluginContext(t *testing.T) { @@ -226,8 +228,7 @@ func TestConvertFromProtobufPluginContext(t *testing.T) { t.Fatalf(unsetErrFmt, "sdk", "DataSourceInstanceSettings", sdkWalker.ZeroValueFieldCount, sdkWalker.FieldCount) } - // adding +1 to the proto field count to account for the Type field in the SDK - require.Equal(t, protoWalker.FieldCount+1, sdkWalker.FieldCount) + require.Equal(t, protoWalker.FieldCount+datasourceInstanceProtoFieldCountDelta(), sdkWalker.FieldCount) requireCounter := &requireCounter{} @@ -259,6 +260,8 @@ func TestConvertFromProtobufPluginContext(t *testing.T) { requireCounter.Equal(t, map[string]string{"secret": "quiet"}, sdkCtx.DataSourceInstanceSettings.DecryptedSecureJSONData) requireCounter.Equal(t, time.Unix(0, 86400*2*1e9), sdkCtx.DataSourceInstanceSettings.Updated) + requireCounter.Equal(t, protoCtx.GrafanaConfig, sdkCtx.GrafanaConfig.config) + require.Equal(t, requireCounter.Count, sdkWalker.FieldCount-3, "untested fields in conversion") // -3 Struct Fields } @@ -379,8 +382,7 @@ func TestConvertFromProtobufQueryDataRequest(t *testing.T) { t.Fatalf(unsetErrFmt, "sdk", "QueryDataRequest", sdkWalker.ZeroValueFieldCount, sdkWalker.FieldCount) } - // adding +1 to the proto field count to account for the Type field in the SDK - require.Equal(t, protoWalker.FieldCount+1, sdkWalker.FieldCount) + require.Equal(t, protoWalker.FieldCount+datasourceInstanceProtoFieldCountDelta(), sdkWalker.FieldCount) requireCounter := &requireCounter{} @@ -423,12 +425,12 @@ func TestConvertFromProtobufQueryDataRequest(t *testing.T) { requireCounter.Equal(t, sdkTimeRange.To, sdkQDR.Queries[0].TimeRange.To) requireCounter.Equal(t, json.RawMessage(protoQDR.Queries[0].Json), sdkQDR.Queries[0].JSON) - // -6 is: + // -7 is: // PluginContext, .User, .AppInstanceSettings, .DataSourceInstanceSettings - // DataQuery, .TimeRange + // DataQuery, .TimeRange, .GrafanaConfig // // - require.Equal(t, requireCounter.Count, sdkWalker.FieldCount-6, "untested fields in conversion") // -6 Struct Fields + require.Equal(t, requireCounter.Count, sdkWalker.FieldCount-7, "untested fields in conversion") // -6 Struct Fields } func TestConvertFromProtobufCheckHealthRequest(t *testing.T) { @@ -490,3 +492,9 @@ func TestConvertFromProtobufDataResponse(t *testing.T) { } }) } + +// datasourceInstanceProtoFieldCountDelta returns the extra number of SDK fields that do not exist in the protobuf. +func datasourceInstanceProtoFieldCountDelta() int64 { + // returning 1 to account for the Type field in the SDK that is not in the protobuf + return int64(1) +} diff --git a/backend/convert_to_protobuf.go b/backend/convert_to_protobuf.go index 03e7868f1..e223b6608 100644 --- a/backend/convert_to_protobuf.go +++ b/backend/convert_to_protobuf.go @@ -76,6 +76,7 @@ func (t ConvertToProtobuf) PluginContext(pluginCtx PluginContext) *pluginv2.Plug User: t.User(pluginCtx.User), AppInstanceSettings: t.AppInstanceSettings(pluginCtx.AppInstanceSettings), DataSourceInstanceSettings: t.DataSourceInstanceSettings(pluginCtx.DataSourceInstanceSettings), + GrafanaConfig: t.GrafanaConfig(pluginCtx.GrafanaConfig), } } @@ -280,3 +281,11 @@ func (t ConvertToProtobuf) CollectMetricsResult(res *CollectMetricsResult) *plug }, } } + +// GrafanaConfig converts the SDK version of a GrafanaCfg to the protobuf version. +func (t ConvertToProtobuf) GrafanaConfig(cfg *GrafanaCfg) map[string]string { + if cfg == nil { + return map[string]string{} + } + return cfg.config +} diff --git a/backend/data_adapter.go b/backend/data_adapter.go index 57f6b9d25..b98e2fe52 100644 --- a/backend/data_adapter.go +++ b/backend/data_adapter.go @@ -45,6 +45,7 @@ func withHeaderMiddleware(ctx context.Context, headers http.Header) context.Cont func (a *dataSDKAdapter) QueryData(ctx context.Context, req *pluginv2.QueryDataRequest) (*pluginv2.QueryDataResponse, error) { ctx = propagateTenantIDIfPresent(ctx) + ctx = withGrafanaConfig(ctx, NewGrafanaCfg(req.PluginContext.GrafanaConfig)) parsedRequest := FromProto().QueryDataRequest(req) ctx = withHeaderMiddleware(ctx, parsedRequest.GetHTTPHeaders()) resp, err := a.queryDataHandler.QueryData(ctx, parsedRequest) diff --git a/backend/datasource/instance_provider.go b/backend/datasource/instance_provider.go index 0c8e19cd0..6b35b6089 100644 --- a/backend/datasource/instance_provider.go +++ b/backend/datasource/instance_provider.go @@ -2,6 +2,7 @@ package datasource import ( "context" + "errors" "fmt" "github.com/prometheus/client_golang/prometheus" @@ -21,7 +22,7 @@ var ( ) // InstanceFactoryFunc factory method for creating data source instances. -type InstanceFactoryFunc func(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) +type InstanceFactoryFunc func(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) // NewInstanceManager creates a new data source instance manager, // @@ -55,7 +56,7 @@ type instanceProvider struct { func (ip *instanceProvider) GetKey(ctx context.Context, pluginContext backend.PluginContext) (interface{}, error) { if pluginContext.DataSourceInstanceSettings == nil { - return nil, fmt.Errorf("data source instance settings cannot be nil") + return nil, errors.New("data source instance settings cannot be nil") } defaultKey := pluginContext.DataSourceInstanceSettings.ID @@ -67,12 +68,18 @@ func (ip *instanceProvider) GetKey(ctx context.Context, pluginContext backend.Pl } func (ip *instanceProvider) NeedsUpdate(_ context.Context, pluginContext backend.PluginContext, cachedInstance instancemgmt.CachedInstance) bool { - curSettings := pluginContext.DataSourceInstanceSettings - cachedSettings := cachedInstance.PluginContext.DataSourceInstanceSettings - return !curSettings.Updated.Equal(cachedSettings.Updated) + curConfig := pluginContext.GrafanaConfig + cachedConfig := cachedInstance.PluginContext.GrafanaConfig + configUpdated := !cachedConfig.Equal(curConfig) + + curDataSourceSettings := pluginContext.DataSourceInstanceSettings + cachedDataSourceSettings := cachedInstance.PluginContext.DataSourceInstanceSettings + dsUpdated := !curDataSourceSettings.Updated.Equal(cachedDataSourceSettings.Updated) + + return dsUpdated || configUpdated } -func (ip *instanceProvider) NewInstance(_ context.Context, pluginContext backend.PluginContext) (instancemgmt.Instance, error) { +func (ip *instanceProvider) NewInstance(ctx context.Context, pluginContext backend.PluginContext) (instancemgmt.Instance, error) { datasourceInstancesCreated.Inc() - return ip.factory(*pluginContext.DataSourceInstanceSettings) + return ip.factory(ctx, *pluginContext.DataSourceInstanceSettings) } diff --git a/backend/datasource/instance_provider_test.go b/backend/datasource/instance_provider_test.go index 6c4fba4bd..4f8212f4c 100644 --- a/backend/datasource/instance_provider_test.go +++ b/backend/datasource/instance_provider_test.go @@ -14,7 +14,7 @@ func TestInstanceProvider(t *testing.T) { type testInstance struct { value string } - ip := NewInstanceProvider(func(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { + ip := NewInstanceProvider(func(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return testInstance{value: "hello"}, nil }) @@ -33,38 +33,66 @@ func TestInstanceProvider(t *testing.T) { require.Equal(t, int64(4), key) }) - t.Run("When current data source instance settings compared to cached instance haven't been updated should return false", func(t *testing.T) { + t.Run("When both the configuration and updated field of current data source instance settings are equal to the cache, should return false", func(t *testing.T) { + config := map[string]string{ + "foo": "bar", + "baz": "qux", + } + curSettings := backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ Updated: time.Now(), }, + GrafanaConfig: backend.NewGrafanaCfg(config), } - cachedInstance := instancemgmt.CachedInstance{ - PluginContext: backend.PluginContext{ - DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ - Updated: curSettings.DataSourceInstanceSettings.Updated, - }, + + cachedSettings := backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: curSettings.DataSourceInstanceSettings.Updated, }, + GrafanaConfig: backend.NewGrafanaCfg(config), + } + + cachedInstance := instancemgmt.CachedInstance{ + PluginContext: cachedSettings, } needsUpdate := ip.NeedsUpdate(context.Background(), curSettings, cachedInstance) require.False(t, needsUpdate) }) - t.Run("When current data source instance settings compared to cached instance have been updated should return true", func(t *testing.T) { + t.Run("When either the config or updated field of current data source instance settings are not equal to the cache, should return tru", func(t *testing.T) { curSettings := backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ Updated: time.Now(), }, } - cachedInstance := instancemgmt.CachedInstance{ - PluginContext: backend.PluginContext{ - DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ - Updated: curSettings.DataSourceInstanceSettings.Updated.Add(time.Second), - }, + cachedSettings := backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: curSettings.DataSourceInstanceSettings.Updated.Add(time.Second), }, } + + cachedInstance := instancemgmt.CachedInstance{ + PluginContext: cachedSettings, + } needsUpdate := ip.NeedsUpdate(context.Background(), curSettings, cachedInstance) require.True(t, needsUpdate) + + t.Run("Should return true when cached config is changed", func(t *testing.T) { + curSettings.GrafanaConfig = backend.NewGrafanaCfg(map[string]string{ + "foo": "true", + }) + + cachedSettings.GrafanaConfig = backend.NewGrafanaCfg(map[string]string{ + "foo": "false", + }) + + cachedInstance = instancemgmt.CachedInstance{ + PluginContext: cachedSettings, + } + needsUpdate = ip.NeedsUpdate(context.Background(), curSettings, cachedInstance) + require.True(t, needsUpdate) + }) }) t.Run("When creating a new instance should return expected instance", func(t *testing.T) { @@ -76,3 +104,123 @@ func TestInstanceProvider(t *testing.T) { require.Equal(t, "hello", i.(testInstance).value) }) } + +func Test_instanceProvider_NeedsUpdate(t *testing.T) { + ts := time.Now() + + type args struct { + pluginContext backend.PluginContext + cachedInstance instancemgmt.CachedInstance + } + tests := []struct { + name string + args args + expected bool + }{ + { + name: "Empty instance settings should return false", + args: args{ + pluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, + }, + }, + }, + expected: false, + }, + { + name: "Instance settings with identical updated field should return false", + args: args{ + pluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: ts, + }, + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: ts, + }, + }, + }, + }, + expected: false, + }, + { + name: "Instance settings with identical updated field and config should return false", + args: args{ + pluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: ts, + }, + GrafanaConfig: backend.NewGrafanaCfg(map[string]string{ + "foo": "bar", + "baz": "qux", + }), + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: ts, + }, + GrafanaConfig: backend.NewGrafanaCfg(map[string]string{ + "baz": "qux", + "foo": "bar", + }), + }, + }, + }, + expected: false, + }, + { + name: "Instance settings with different updated field should return true", + args: args{ + pluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: ts, + }, + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: ts.Add(time.Millisecond), + }, + }, + }, + }, + expected: true, + }, + { + name: "Instance settings with identical updated field and different config should return true", + args: args{ + pluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: ts, + }, + GrafanaConfig: backend.NewGrafanaCfg(map[string]string{ + "foo": "bar", + }), + }, + cachedInstance: instancemgmt.CachedInstance{ + PluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Updated: ts, + }, + }, + }, + }, + expected: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ip := &instanceProvider{} + if got := ip.NeedsUpdate(context.Background(), tt.args.pluginContext, tt.args.cachedInstance); got != tt.expected { + t.Errorf("NeedsUpdate() = %v, expected %v", got, tt.expected) + } + }) + } +} diff --git a/backend/datasource/serve_example_test.go b/backend/datasource/serve_example_test.go index 67d6a9c3f..1a61fc04f 100644 --- a/backend/datasource/serve_example_test.go +++ b/backend/datasource/serve_example_test.go @@ -16,8 +16,8 @@ type testDataSourceInstanceSettings struct { httpClient *http.Client } -func newDataSourceInstance(setting backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { - opts, err := setting.HTTPClientOptions() +func newDataSourceInstance(_ context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { + opts, err := settings.HTTPClientOptions() if err != nil { return nil, err } diff --git a/backend/diagnostics_adapter.go b/backend/diagnostics_adapter.go index 5b80fc0b7..dbf011c11 100644 --- a/backend/diagnostics_adapter.go +++ b/backend/diagnostics_adapter.go @@ -47,6 +47,7 @@ func (a *diagnosticsSDKAdapter) CollectMetrics(_ context.Context, _ *pluginv2.Co func (a *diagnosticsSDKAdapter) CheckHealth(ctx context.Context, protoReq *pluginv2.CheckHealthRequest) (*pluginv2.CheckHealthResponse, error) { if a.checkHealthHandler != nil { ctx = propagateTenantIDIfPresent(ctx) + ctx = withGrafanaConfig(ctx, NewGrafanaCfg(protoReq.PluginContext.GrafanaConfig)) parsedReq := FromProto().CheckHealthRequest(protoReq) ctx = withHeaderMiddleware(ctx, parsedReq.GetHTTPHeaders()) res, err := a.checkHealthHandler.CheckHealth(ctx, parsedReq) diff --git a/backend/resource_adapter.go b/backend/resource_adapter.go index 29167f00c..c32fcbdd0 100644 --- a/backend/resource_adapter.go +++ b/backend/resource_adapter.go @@ -36,6 +36,7 @@ func (a *resourceSDKAdapter) CallResource(protoReq *pluginv2.CallResourceRequest ctx := protoSrv.Context() ctx = propagateTenantIDIfPresent(ctx) + ctx = withGrafanaConfig(ctx, NewGrafanaCfg(protoReq.PluginContext.GrafanaConfig)) parsedReq := FromProto().CallResourceRequest(protoReq) ctx = withHeaderMiddleware(ctx, parsedReq.GetHTTPHeaders()) return a.callResourceHandler.CallResource(ctx, parsedReq, fn) diff --git a/backend/stream_adapter.go b/backend/stream_adapter.go index 7605f494f..f3d2af18d 100644 --- a/backend/stream_adapter.go +++ b/backend/stream_adapter.go @@ -25,6 +25,7 @@ func (a *streamSDKAdapter) SubscribeStream(ctx context.Context, protoReq *plugin return nil, status.Error(codes.Unimplemented, "not implemented") } ctx = propagateTenantIDIfPresent(ctx) + ctx = withGrafanaConfig(ctx, NewGrafanaCfg(protoReq.PluginContext.GrafanaConfig)) resp, err := a.streamHandler.SubscribeStream(ctx, FromProto().SubscribeStreamRequest(protoReq)) if err != nil { return nil, err @@ -37,6 +38,7 @@ func (a *streamSDKAdapter) PublishStream(ctx context.Context, protoReq *pluginv2 return nil, status.Error(codes.Unimplemented, "not implemented") } ctx = propagateTenantIDIfPresent(ctx) + ctx = withGrafanaConfig(ctx, NewGrafanaCfg(protoReq.PluginContext.GrafanaConfig)) resp, err := a.streamHandler.PublishStream(ctx, FromProto().PublishStreamRequest(protoReq)) if err != nil { return nil, err @@ -58,6 +60,7 @@ func (a *streamSDKAdapter) RunStream(protoReq *pluginv2.RunStreamRequest, protoS } ctx := protoSrv.Context() ctx = propagateTenantIDIfPresent(ctx) + ctx = withGrafanaConfig(ctx, NewGrafanaCfg(protoReq.PluginContext.GrafanaConfig)) sender := NewStreamSender(&runStreamServer{protoSrv: protoSrv}) return a.streamHandler.RunStream(ctx, FromProto().RunStreamRequest(protoReq), sender) } diff --git a/experimental/featuretoggles/featuretoggles.go b/experimental/featuretoggles/featuretoggles.go index e07b347b7..907fda18d 100644 --- a/experimental/featuretoggles/featuretoggles.go +++ b/experimental/featuretoggles/featuretoggles.go @@ -5,8 +5,9 @@ import ( "strings" ) -// envFeatureTogglesEnable is the environment variable set by Grafana containing the list of enabled feature toggles. -const envFeatureTogglesEnable = "GF_INSTANCE_FEATURE_TOGGLES_ENABLE" +const ( + EnabledFeatures = "GF_INSTANCE_FEATURE_TOGGLES_ENABLE" +) // FeatureToggles can check if feature toggles are enabled on the Grafana instance. type FeatureToggles interface { @@ -34,7 +35,7 @@ func newFeatureTogglesFromEnv() featureToggles { // flagsMapFromEnv returns a new set-like map[string]struct{}, where the keys are the comma-separated names in // the `envFeatureTogglesEnable` env var. func flagsMapFromEnv() map[string]struct{} { - flags := strings.Split(os.Getenv(envFeatureTogglesEnable), ",") + flags := strings.Split(os.Getenv(EnabledFeatures), ",") r := make(map[string]struct{}, len(flags)) for _, flag := range flags { r[flag] = struct{}{} diff --git a/experimental/featuretoggles/featuretoggles_test.go b/experimental/featuretoggles/featuretoggles_test.go index 2d0bb734f..f815fe174 100644 --- a/experimental/featuretoggles/featuretoggles_test.go +++ b/experimental/featuretoggles/featuretoggles_test.go @@ -8,20 +8,20 @@ import ( func TestEnvFeatureToggles(t *testing.T) { t.Run("should work when flag is provided", func(t *testing.T) { - t.Setenv(envFeatureTogglesEnable, "") + t.Setenv(EnabledFeatures, "") flags := newFeatureTogglesFromEnv() require.False(t, flags.IsEnabled("abc")) }) t.Run("should work when single flag is provided", func(t *testing.T) { - t.Setenv(envFeatureTogglesEnable, "abc") + t.Setenv(EnabledFeatures, "abc") flags := newFeatureTogglesFromEnv() require.True(t, flags.IsEnabled("abc")) require.False(t, flags.IsEnabled("def")) }) t.Run("should work when multiple flags are provided", func(t *testing.T) { - t.Setenv(envFeatureTogglesEnable, "abc,def") + t.Setenv(EnabledFeatures, "abc,def") flags := newFeatureTogglesFromEnv() require.True(t, flags.IsEnabled("abc")) require.True(t, flags.IsEnabled("def")) diff --git a/experimental/oauthtokenretriever/token.go b/experimental/oauthtokenretriever/token.go index 37f263592..167664a0e 100644 --- a/experimental/oauthtokenretriever/token.go +++ b/experimental/oauthtokenretriever/token.go @@ -13,6 +13,15 @@ import ( "golang.org/x/oauth2/clientcredentials" ) +const ( + AppURL = "GF_APP_URL" + AppClientID = "GF_PLUGIN_APP_CLIENT_ID" + AppPrivateKey = "GF_PLUGIN_APP_PRIVATE_KEY" + // nolint:gosec + // AppClientSecret constant represents a string index value for the secret, not the secret itself. + AppClientSecret = "GF_PLUGIN_APP_CLIENT_SECRET" +) + type TokenRetriever interface { OnBehalfOfUser(ctx context.Context, userID string) (string, error) Self(ctx context.Context) (string, error) @@ -68,23 +77,23 @@ func (t *tokenRetriever) OnBehalfOfUser(ctx context.Context, userID string) (str func New() (TokenRetriever, error) { // The Grafana URL is required to obtain tokens later on - grafanaAppURL := strings.TrimRight(os.Getenv("GF_APP_URL"), "/") + grafanaAppURL := strings.TrimRight(os.Getenv(AppURL), "/") if grafanaAppURL == "" { // For debugging purposes only grafanaAppURL = "http://localhost:3000" } - clientID := os.Getenv("GF_PLUGIN_APP_CLIENT_ID") + clientID := os.Getenv(AppClientID) if clientID == "" { return nil, fmt.Errorf("GF_PLUGIN_APP_CLIENT_ID is required") } - clientSecret := os.Getenv("GF_PLUGIN_APP_CLIENT_SECRET") + clientSecret := os.Getenv(AppClientSecret) if clientSecret == "" { return nil, fmt.Errorf("GF_PLUGIN_APP_CLIENT_SECRET is required") } - privateKey := os.Getenv("GF_PLUGIN_APP_PRIVATE_KEY") + privateKey := os.Getenv(AppPrivateKey) if privateKey == "" { return nil, fmt.Errorf("GF_PLUGIN_APP_PRIVATE_KEY is required") } diff --git a/genproto/pluginv2/backend.pb.go b/genproto/pluginv2/backend.pb.go index b36c60d29..4efccf5d2 100644 --- a/genproto/pluginv2/backend.pb.go +++ b/genproto/pluginv2/backend.pb.go @@ -453,6 +453,8 @@ type PluginContext struct { // // Will only be set if request targeting a data source instance. DataSourceInstanceSettings *DataSourceInstanceSettings `protobuf:"bytes,5,opt,name=dataSourceInstanceSettings,proto3" json:"dataSourceInstanceSettings,omitempty"` + // The grafana configuration as a map of key/value pairs. + GrafanaConfig map[string]string `protobuf:"bytes,6,rep,name=grafanaConfig,proto3" json:"grafanaConfig,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *PluginContext) Reset() { @@ -522,6 +524,13 @@ func (x *PluginContext) GetDataSourceInstanceSettings() *DataSourceInstanceSetti return nil } +func (x *PluginContext) GetGrafanaConfig() map[string]string { + if x != nil { + return x.GrafanaConfig + } + return nil +} + type StringList struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1646,7 +1655,7 @@ type CollectMetricsResponse_Payload struct { func (x *CollectMetricsResponse_Payload) Reset() { *x = CollectMetricsResponse_Payload{} if protoimpl.UnsafeEnabled { - mi := &file_backend_proto_msgTypes[28] + mi := &file_backend_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1659,7 +1668,7 @@ func (x *CollectMetricsResponse_Payload) String() string { func (*CollectMetricsResponse_Payload) ProtoMessage() {} func (x *CollectMetricsResponse_Payload) ProtoReflect() protoreflect.Message { - mi := &file_backend_proto_msgTypes[28] + mi := &file_backend_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1741,7 +1750,7 @@ var file_backend_proto_rawDesc = []byte{ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x9c, 0x02, 0x0a, 0x0d, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0xb0, 0x03, 0x0a, 0x0d, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, @@ -1759,221 +1768,230 @@ var file_backend_proto_rawDesc = []byte{ 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x1a, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x22, 0x24, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xbe, 0x02, 0x0a, 0x13, 0x43, - 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x10, 0x0a, - 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, - 0x44, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2a, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x61, 0x6c, 0x6c, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x50, 0x0a, 0x0c, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd7, 0x01, 0x0a, 0x14, - 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x45, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, - 0x6f, 0x64, 0x79, 0x1a, 0x50, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4b, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x4d, - 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x45, 0x70, 0x6f, - 0x63, 0x68, 0x4d, 0x53, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x4d, - 0x53, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x6f, 0x45, 0x70, 0x6f, 0x63, 0x68, - 0x4d, 0x53, 0x22, 0xcc, 0x01, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x66, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x72, 0x65, 0x66, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x44, 0x61, 0x74, - 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, - 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0a, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x53, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x53, 0x12, 0x31, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, - 0x61, 0x6e, 0x67, 0x65, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, - 0x73, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, - 0x65, 0x22, 0xff, 0x01, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, + 0x69, 0x6e, 0x67, 0x73, 0x12, 0x50, 0x0a, 0x0d, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x2e, 0x47, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x40, 0x0a, 0x12, 0x47, 0x72, 0x61, 0x66, 0x61, 0x6e, + 0x61, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x24, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xbe, + 0x02, 0x0a, 0x13, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x41, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, - 0x32, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, - 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x07, - 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x12, 0x44, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, + 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, + 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x50, 0x0a, + 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xd7, 0x01, 0x0a, 0x14, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x45, 0x0a, 0x07, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x50, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0xb3, 0x01, 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x09, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x73, 0x1a, 0x54, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, - 0x32, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x70, 0x0a, 0x0c, 0x44, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x72, 0x61, - 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, - 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x4d, - 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x4d, - 0x65, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x56, 0x0a, 0x15, 0x43, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4b, 0x0a, 0x09, 0x54, 0x69, 0x6d, + 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x45, 0x70, + 0x6f, 0x63, 0x68, 0x4d, 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x66, 0x72, 0x6f, + 0x6d, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x4d, 0x53, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x45, 0x70, + 0x6f, 0x63, 0x68, 0x4d, 0x53, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x6f, 0x45, + 0x70, 0x6f, 0x63, 0x68, 0x4d, 0x53, 0x22, 0xcc, 0x01, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x66, 0x49, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x66, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x61, + 0x78, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, + 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x53, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x53, + 0x12, 0x31, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x54, 0x79, 0x70, 0x65, 0x22, 0xff, 0x01, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x41, 0x0a, 0x07, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x07, + 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb3, 0x01, 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, + 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x1a, 0x54, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x70, 0x0a, + 0x0c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x66, + 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x6a, + 0x73, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6a, + 0x73, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, + 0x56, 0x0a, 0x15, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x87, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x07, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x29, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, + 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x12, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x43, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc5, 0x01, 0x0a, 0x13, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x42, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2a, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x22, 0x2e, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x06, 0x0a, + 0x02, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, + 0x22, 0x7f, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x22, 0xa7, 0x01, 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0x36, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a, + 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, + 0x4e, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, + 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x02, 0x22, 0x7d, 0x0a, 0x14, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa3, 0x01, 0x0a, 0x15, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x36, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, + 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x45, 0x52, + 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x02, + 0x22, 0x79, 0x0a, 0x10, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x22, 0x87, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, - 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, - 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x1a, 0x29, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1e, 0x0a, - 0x0a, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x22, 0xd4, 0x01, - 0x0a, 0x12, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x12, 0x43, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc5, 0x01, 0x0a, 0x13, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6a, 0x73, - 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x2e, 0x0a, 0x0c, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, - 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x22, 0x7f, 0x0a, 0x16, - 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa7, 0x01, - 0x0a, 0x17, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x36, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, - 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x01, - 0x12, 0x15, 0x0a, 0x11, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, - 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x02, 0x22, 0x7d, 0x0a, 0x14, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, - 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, - 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa3, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x26, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x22, 0x36, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, - 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, - 0x55, 0x4e, 0x44, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, - 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x02, 0x22, 0x79, 0x0a, 0x10, - 0x52, 0x75, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x3d, 0x0a, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x76, 0x32, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x52, 0x0d, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x22, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x5b, 0x0a, 0x08, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6c, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x76, 0x32, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, - 0x32, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x32, 0x4c, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, - 0x12, 0x44, 0x0a, 0x09, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x2e, + 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x22, 0x0a, 0x0c, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, + 0x5b, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x0c, 0x43, + 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x32, 0x4c, 0x0a, 0x04, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x44, 0x0a, 0x09, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x1a, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xae, 0x01, 0x0a, 0x0b, 0x44, 0x69, 0x61, 0x67, 0x6e, - 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1c, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, - 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, - 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, - 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf5, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x12, 0x56, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x20, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, - 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x76, 0x32, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x52, 0x75, - 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1a, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x76, 0x32, 0x2e, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x30, 0x01, 0x12, 0x50, 0x0a, - 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1e, - 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, - 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, - 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, - 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, - 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xae, 0x01, 0x0a, 0x0b, 0x44, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1c, 0x2e, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x76, 0x32, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, + 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf5, 0x01, 0x0a, 0x06, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x56, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x62, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x20, 0x2e, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, + 0x0a, 0x09, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1a, 0x2e, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x76, 0x32, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x30, + 0x01, 0x12, 0x50, 0x0a, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x12, 0x1e, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x76, 0x32, 0x2e, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x76, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1989,7 +2007,7 @@ func file_backend_proto_rawDescGZIP() []byte { } var file_backend_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_backend_proto_msgTypes = make([]protoimpl.MessageInfo, 30) +var file_backend_proto_msgTypes = make([]protoimpl.MessageInfo, 31) var file_backend_proto_goTypes = []interface{}{ (CheckHealthResponse_HealthStatus)(0), // 0: pluginv2.CheckHealthResponse.HealthStatus (SubscribeStreamResponse_Status)(0), // 1: pluginv2.SubscribeStreamResponse.Status @@ -2018,12 +2036,13 @@ var file_backend_proto_goTypes = []interface{}{ (*StreamPacket)(nil), // 24: pluginv2.StreamPacket nil, // 25: pluginv2.AppInstanceSettings.DecryptedSecureJsonDataEntry nil, // 26: pluginv2.DataSourceInstanceSettings.DecryptedSecureJsonDataEntry - nil, // 27: pluginv2.CallResourceRequest.HeadersEntry - nil, // 28: pluginv2.CallResourceResponse.HeadersEntry - nil, // 29: pluginv2.QueryDataRequest.HeadersEntry - nil, // 30: pluginv2.QueryDataResponse.ResponsesEntry - (*CollectMetricsResponse_Payload)(nil), // 31: pluginv2.CollectMetricsResponse.Payload - nil, // 32: pluginv2.CheckHealthRequest.HeadersEntry + nil, // 27: pluginv2.PluginContext.GrafanaConfigEntry + nil, // 28: pluginv2.CallResourceRequest.HeadersEntry + nil, // 29: pluginv2.CallResourceResponse.HeadersEntry + nil, // 30: pluginv2.QueryDataRequest.HeadersEntry + nil, // 31: pluginv2.QueryDataResponse.ResponsesEntry + (*CollectMetricsResponse_Payload)(nil), // 32: pluginv2.CollectMetricsResponse.Payload + nil, // 33: pluginv2.CheckHealthRequest.HeadersEntry } var file_backend_proto_depIdxs = []int32{ 25, // 0: pluginv2.AppInstanceSettings.decryptedSecureJsonData:type_name -> pluginv2.AppInstanceSettings.DecryptedSecureJsonDataEntry @@ -2031,46 +2050,47 @@ var file_backend_proto_depIdxs = []int32{ 5, // 2: pluginv2.PluginContext.user:type_name -> pluginv2.User 3, // 3: pluginv2.PluginContext.appInstanceSettings:type_name -> pluginv2.AppInstanceSettings 4, // 4: pluginv2.PluginContext.dataSourceInstanceSettings:type_name -> pluginv2.DataSourceInstanceSettings - 6, // 5: pluginv2.CallResourceRequest.pluginContext:type_name -> pluginv2.PluginContext - 27, // 6: pluginv2.CallResourceRequest.headers:type_name -> pluginv2.CallResourceRequest.HeadersEntry - 28, // 7: pluginv2.CallResourceResponse.headers:type_name -> pluginv2.CallResourceResponse.HeadersEntry - 10, // 8: pluginv2.DataQuery.timeRange:type_name -> pluginv2.TimeRange - 6, // 9: pluginv2.QueryDataRequest.pluginContext:type_name -> pluginv2.PluginContext - 29, // 10: pluginv2.QueryDataRequest.headers:type_name -> pluginv2.QueryDataRequest.HeadersEntry - 11, // 11: pluginv2.QueryDataRequest.queries:type_name -> pluginv2.DataQuery - 30, // 12: pluginv2.QueryDataResponse.responses:type_name -> pluginv2.QueryDataResponse.ResponsesEntry - 6, // 13: pluginv2.CollectMetricsRequest.pluginContext:type_name -> pluginv2.PluginContext - 31, // 14: pluginv2.CollectMetricsResponse.metrics:type_name -> pluginv2.CollectMetricsResponse.Payload - 6, // 15: pluginv2.CheckHealthRequest.pluginContext:type_name -> pluginv2.PluginContext - 32, // 16: pluginv2.CheckHealthRequest.headers:type_name -> pluginv2.CheckHealthRequest.HeadersEntry - 0, // 17: pluginv2.CheckHealthResponse.status:type_name -> pluginv2.CheckHealthResponse.HealthStatus - 6, // 18: pluginv2.SubscribeStreamRequest.pluginContext:type_name -> pluginv2.PluginContext - 1, // 19: pluginv2.SubscribeStreamResponse.status:type_name -> pluginv2.SubscribeStreamResponse.Status - 6, // 20: pluginv2.PublishStreamRequest.pluginContext:type_name -> pluginv2.PluginContext - 2, // 21: pluginv2.PublishStreamResponse.status:type_name -> pluginv2.PublishStreamResponse.Status - 6, // 22: pluginv2.RunStreamRequest.pluginContext:type_name -> pluginv2.PluginContext - 7, // 23: pluginv2.CallResourceRequest.HeadersEntry.value:type_name -> pluginv2.StringList - 7, // 24: pluginv2.CallResourceResponse.HeadersEntry.value:type_name -> pluginv2.StringList - 14, // 25: pluginv2.QueryDataResponse.ResponsesEntry.value:type_name -> pluginv2.DataResponse - 8, // 26: pluginv2.Resource.CallResource:input_type -> pluginv2.CallResourceRequest - 12, // 27: pluginv2.Data.QueryData:input_type -> pluginv2.QueryDataRequest - 17, // 28: pluginv2.Diagnostics.CheckHealth:input_type -> pluginv2.CheckHealthRequest - 15, // 29: pluginv2.Diagnostics.CollectMetrics:input_type -> pluginv2.CollectMetricsRequest - 19, // 30: pluginv2.Stream.SubscribeStream:input_type -> pluginv2.SubscribeStreamRequest - 23, // 31: pluginv2.Stream.RunStream:input_type -> pluginv2.RunStreamRequest - 21, // 32: pluginv2.Stream.PublishStream:input_type -> pluginv2.PublishStreamRequest - 9, // 33: pluginv2.Resource.CallResource:output_type -> pluginv2.CallResourceResponse - 13, // 34: pluginv2.Data.QueryData:output_type -> pluginv2.QueryDataResponse - 18, // 35: pluginv2.Diagnostics.CheckHealth:output_type -> pluginv2.CheckHealthResponse - 16, // 36: pluginv2.Diagnostics.CollectMetrics:output_type -> pluginv2.CollectMetricsResponse - 20, // 37: pluginv2.Stream.SubscribeStream:output_type -> pluginv2.SubscribeStreamResponse - 24, // 38: pluginv2.Stream.RunStream:output_type -> pluginv2.StreamPacket - 22, // 39: pluginv2.Stream.PublishStream:output_type -> pluginv2.PublishStreamResponse - 33, // [33:40] is the sub-list for method output_type - 26, // [26:33] is the sub-list for method input_type - 26, // [26:26] is the sub-list for extension type_name - 26, // [26:26] is the sub-list for extension extendee - 0, // [0:26] is the sub-list for field type_name + 27, // 5: pluginv2.PluginContext.grafanaConfig:type_name -> pluginv2.PluginContext.GrafanaConfigEntry + 6, // 6: pluginv2.CallResourceRequest.pluginContext:type_name -> pluginv2.PluginContext + 28, // 7: pluginv2.CallResourceRequest.headers:type_name -> pluginv2.CallResourceRequest.HeadersEntry + 29, // 8: pluginv2.CallResourceResponse.headers:type_name -> pluginv2.CallResourceResponse.HeadersEntry + 10, // 9: pluginv2.DataQuery.timeRange:type_name -> pluginv2.TimeRange + 6, // 10: pluginv2.QueryDataRequest.pluginContext:type_name -> pluginv2.PluginContext + 30, // 11: pluginv2.QueryDataRequest.headers:type_name -> pluginv2.QueryDataRequest.HeadersEntry + 11, // 12: pluginv2.QueryDataRequest.queries:type_name -> pluginv2.DataQuery + 31, // 13: pluginv2.QueryDataResponse.responses:type_name -> pluginv2.QueryDataResponse.ResponsesEntry + 6, // 14: pluginv2.CollectMetricsRequest.pluginContext:type_name -> pluginv2.PluginContext + 32, // 15: pluginv2.CollectMetricsResponse.metrics:type_name -> pluginv2.CollectMetricsResponse.Payload + 6, // 16: pluginv2.CheckHealthRequest.pluginContext:type_name -> pluginv2.PluginContext + 33, // 17: pluginv2.CheckHealthRequest.headers:type_name -> pluginv2.CheckHealthRequest.HeadersEntry + 0, // 18: pluginv2.CheckHealthResponse.status:type_name -> pluginv2.CheckHealthResponse.HealthStatus + 6, // 19: pluginv2.SubscribeStreamRequest.pluginContext:type_name -> pluginv2.PluginContext + 1, // 20: pluginv2.SubscribeStreamResponse.status:type_name -> pluginv2.SubscribeStreamResponse.Status + 6, // 21: pluginv2.PublishStreamRequest.pluginContext:type_name -> pluginv2.PluginContext + 2, // 22: pluginv2.PublishStreamResponse.status:type_name -> pluginv2.PublishStreamResponse.Status + 6, // 23: pluginv2.RunStreamRequest.pluginContext:type_name -> pluginv2.PluginContext + 7, // 24: pluginv2.CallResourceRequest.HeadersEntry.value:type_name -> pluginv2.StringList + 7, // 25: pluginv2.CallResourceResponse.HeadersEntry.value:type_name -> pluginv2.StringList + 14, // 26: pluginv2.QueryDataResponse.ResponsesEntry.value:type_name -> pluginv2.DataResponse + 8, // 27: pluginv2.Resource.CallResource:input_type -> pluginv2.CallResourceRequest + 12, // 28: pluginv2.Data.QueryData:input_type -> pluginv2.QueryDataRequest + 17, // 29: pluginv2.Diagnostics.CheckHealth:input_type -> pluginv2.CheckHealthRequest + 15, // 30: pluginv2.Diagnostics.CollectMetrics:input_type -> pluginv2.CollectMetricsRequest + 19, // 31: pluginv2.Stream.SubscribeStream:input_type -> pluginv2.SubscribeStreamRequest + 23, // 32: pluginv2.Stream.RunStream:input_type -> pluginv2.RunStreamRequest + 21, // 33: pluginv2.Stream.PublishStream:input_type -> pluginv2.PublishStreamRequest + 9, // 34: pluginv2.Resource.CallResource:output_type -> pluginv2.CallResourceResponse + 13, // 35: pluginv2.Data.QueryData:output_type -> pluginv2.QueryDataResponse + 18, // 36: pluginv2.Diagnostics.CheckHealth:output_type -> pluginv2.CheckHealthResponse + 16, // 37: pluginv2.Diagnostics.CollectMetrics:output_type -> pluginv2.CollectMetricsResponse + 20, // 38: pluginv2.Stream.SubscribeStream:output_type -> pluginv2.SubscribeStreamResponse + 24, // 39: pluginv2.Stream.RunStream:output_type -> pluginv2.StreamPacket + 22, // 40: pluginv2.Stream.PublishStream:output_type -> pluginv2.PublishStreamResponse + 34, // [34:41] is the sub-list for method output_type + 27, // [27:34] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name } func init() { file_backend_proto_init() } @@ -2343,7 +2363,7 @@ func file_backend_proto_init() { return nil } } - file_backend_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + file_backend_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CollectMetricsResponse_Payload); i { case 0: return &v.state @@ -2362,7 +2382,7 @@ func file_backend_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_backend_proto_rawDesc, NumEnums: 3, - NumMessages: 30, + NumMessages: 31, NumExtensions: 0, NumServices: 4, }, diff --git a/go.sum b/go.sum index 7bffedd92..f70d3a081 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elazarl/goproxy v0.0.0-20220115173737-adb46da277ac h1:XDAn206aIqKPdF5YczuuJXSQPx+WOen0Pxbxp5Fq8Pg= -github.com/elazarl/goproxy v0.0.0-20220115173737-adb46da277ac/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 h1:1L0aalTpPz7YlMxETKpmQoWMBkeiuorElZIXoNmgiPE= github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= @@ -75,7 +73,6 @@ github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxF github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -148,12 +145,10 @@ github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdi github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 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= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -200,7 +195,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= diff --git a/internal/tenant/tenanttest/tenant_test.go b/internal/tenant/tenanttest/tenant_test.go index 30f125f15..b7e06744d 100644 --- a/internal/tenant/tenanttest/tenant_test.go +++ b/internal/tenant/tenanttest/tenant_test.go @@ -23,7 +23,7 @@ const ( // A test to verify the impact tenant ID (passed via context) has on plugin instance management func TestTenantWithPluginInstanceManagement(t *testing.T) { factoryInvocations := 0 - factory := datasource.InstanceFactoryFunc(func(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { + factory := datasource.InstanceFactoryFunc(func(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { factoryInvocations++ return &testPlugin{}, nil }) diff --git a/proto/backend.proto b/proto/backend.proto index 26ab61c05..777a79c32 100644 --- a/proto/backend.proto +++ b/proto/backend.proto @@ -59,6 +59,9 @@ message PluginContext { // // Will only be set if request targeting a data source instance. DataSourceInstanceSettings dataSourceInstanceSettings = 5; + + // The grafana configuration as a map of key/value pairs. + map grafanaConfig = 6; } //--------------------------------------------------------- @@ -84,7 +87,7 @@ message CallResourceRequest { message CallResourceResponse { // Maps to raw HTTP status codes when passed over HTTP - int32 code = 1; + int32 code = 1; // Raw HTTP headers sent to the client map headers = 2; @@ -145,7 +148,7 @@ message DataResponse { // When errors exist or a non 2XX status, clients will be passed a 207 HTTP error code in /ds/query // The status codes should match values from standard HTTP status codes // If not set explicitly, it will be marshaled to 200 if no error exists, or 500 if one does - int32 status = 4; + int32 status = 4; } //-----------------------------------------------