diff --git a/README.md b/README.md index 4203710..6cb9e59 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Grafana Redis Datasource +# Redis Data Source for Grafana ![Dashboard](https://raw.githubusercontent.com/RedisTimeSeries/grafana-redis-datasource/master/src/img/redis-dashboard.png) @@ -21,33 +21,33 @@ ## Introduction -### What is the Grafana Redis Datasource? +### What is the Redis Data Source for Grafana? -The Grafana Redis Datasource, is a plugin that allows users to connect to Redis database and build dashboards in Grafana to easily monitor Redis data. It provides out-of-the box predefined dashboards - but the plugin allows to build entirely customized dashboards, tuned to your needs. +If you’re not familiar with Grafana, it’s a very popular tool used to build dashboards to monitor applications, infrastructures, and software components. The Redis Data Source for Grafana is a plug-in that allows users to connect to the Redis database and build dashboards in Grafana to easily monitor Redis data. It provides an out-of-the-box predefined dashboard, but also lets you build customized dashboards tuned to your specific needs. -### What is Grafana? +### What Grafana version is supported? -If you are not familiar with Grafana yet, it is a very popular tool used to build dashboards allowing to monitor applications, infrastructures and any kind of software components. +Grafana 7.1 and later with a new plug-in platform supported. -### What Grafana version is supported? +### Does this Data Source require anything special configured on the Redis databases? -Only Grafana 7.0 and later with a new plugin platform supported. +Data Source can connect to any Redis database. No special configuration is required. -### Does this datasource require anything special configured on the Redis databases? +### Does this Data Source support [Redis Cluster](https://redis.io/topics/cluster-tutorial) and [Sentinel](https://redis.io/topics/sentinel)? -Datasource can connect to any Redis database. No special configuration is required. +Yes, Redis Cluster and Sentinel supported since version 1.2. ### How to connect to Redis logical database? -Please use `/db-number` or `?db=db-number` in the datasource URL to specify the database number as defined in the [Schema](https://www.iana.org/assignments/uri-schemes/prov/redis). +Please use `/db-number` or `?db=db-number` in the Data Source URL to specify the database number as defined in the [Schema](https://www.iana.org/assignments/uri-schemes/prov/redis). ``` redis://redis-server:6379/0 ``` -### Build datasource +### Build Data Source -To learn step by step how to build Redis Datasource from scratch and register in new or existing Grafana please take a look at [BUILD](https://github.com/RedisTimeSeries/grafana-redis-datasource/blob/master/BUILD.md) instructions. +To learn step by step how to build Redis Data Source from scratch and register in new or existing Grafana please take a look at [BUILD](https://github.com/RedisTimeSeries/grafana-redis-datasource/blob/master/BUILD.md) instructions. ## Getting Started @@ -73,14 +73,14 @@ Project provides `docker-compose.yml` to start Redis with RedisTimeSeries module docker-compose up ``` -Open Grafana in your browser [http://localhost:3000](http://localhost:3000) and configure datasource. You can add as many datasources as you want to support multiple Redis databases. +Open Grafana in your browser [http://localhost:3000](http://localhost:3000) and configure Redis Data Source. You can add as many data sources as you want to support multiple Redis databases. ![Datasource](https://raw.githubusercontent.com/RedisTimeSeries/grafana-redis-datasource/master/src/img/datasource.png) There are certain settings that can be configured based on your own setup: - Grafana port -- Datasource URL +- Data Source URL #### Configure Grafana port in `docker-compose.yml` @@ -91,7 +91,7 @@ If standard port 3000 is occupied by another application update the port to bind - '3000:3000' ``` -#### Configure Datasource url in `provisioning/datasources/redis.yaml` +#### Configure Data Source URL in `provisioning/datasources/redis.yaml` If Redis is running and listening on localhost:6379 no changes are required @@ -107,7 +107,7 @@ If Redis is running as Docker container on MacOS, please update host to `host.do ### Run using `docker-compose` for development -Datasource have to be built following [BUILD](https://github.com/RedisTimeSeries/grafana-redis-datasource/blob/master/BUILD.md) instructions before starting using `docker-compose-dev.yml` file. +Data Source have to be built following [BUILD](https://github.com/RedisTimeSeries/grafana-redis-datasource/blob/master/BUILD.md) instructions before starting using `docker-compose-dev.yml` file. ```bash docker-compose -f docker-compose-dev.yml up @@ -115,7 +115,7 @@ docker-compose -f docker-compose-dev.yml up ## Supported Commands -Datasource supports many Redis commands using custom components and provide unified interface to query any command. +Data Source supports many Redis commands using custom components and provide unified interface to query any command. ![Query](https://raw.githubusercontent.com/RedisTimeSeries/grafana-redis-datasource/master/src/img/query.png) diff --git a/pkg/datasource.go b/pkg/datasource.go index 6905f4c..aabdf6e 100644 --- a/pkg/datasource.go +++ b/pkg/datasource.go @@ -174,9 +174,14 @@ func newDataSourceInstance(setting backend.DataSourceInstanceSettings) (instance } // Certificate and Key - cert, err := tls.X509KeyPair([]byte(secureData["tlsClientCert"]), []byte(secureData["tlsClientKey"])) - if err == nil { - tlsConfig.Certificates = []tls.Certificate{cert} + if secureData["tlsClientCert"] != "" { + cert, err := tls.X509KeyPair([]byte(secureData["tlsClientCert"]), []byte(secureData["tlsClientKey"])) + if err == nil { + tlsConfig.Certificates = []tls.Certificate{cert} + } else { + log.DefaultLogger.Error("X509KeyPair", "Error", err) + return nil, err + } } // Add TLS Config @@ -200,6 +205,8 @@ func newDataSourceInstance(setting backend.DataSourceInstanceSettings) (instance switch jsonData.Client { case "cluster": client, err = radix.NewCluster(strings.Split(setting.URL, ","), radix.ClusterPoolFunc(poolFunc)) + case "sentinel": + client, err = radix.NewSentinel(jsonData.SentinelName, strings.Split(setting.URL, ","), radix.SentinelPoolFunc(poolFunc)) default: client, err = poolFunc("tcp", setting.URL) } diff --git a/pkg/types.go b/pkg/types.go index 533fc19..f34ad4d 100644 --- a/pkg/types.go +++ b/pkg/types.go @@ -36,6 +36,7 @@ type dataModel struct { TLSAuth bool `json:"tlsAuth"` TLSSkipVerify bool `json:"tlsSkipVerify"` Client string `json:"client"` + SentinelName string `json:"sentinelName"` } /* diff --git a/src/components/ConfigEditor.tsx b/src/components/ConfigEditor.tsx index b4c77ac..ca8e350 100644 --- a/src/components/ConfigEditor.tsx +++ b/src/components/ConfigEditor.tsx @@ -1,7 +1,7 @@ import React, { ChangeEvent, PureComponent } from 'react'; import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { Button, InlineFormLabel, LegacyForms, RadioButtonGroup, TextArea } from '@grafana/ui'; -import { ClientTypeValue, ClientType, RedisDataSourceOptions, RedisSecureJsonData } from '../types'; +import { ClientType, ClientTypeValue, RedisDataSourceOptions, RedisSecureJsonData } from '../types'; /** * Form Field @@ -198,6 +198,21 @@ export class ConfigEditor extends PureComponent { /> + {jsonData.client === ClientTypeValue.SENTINEL && ( +
+ ) => { + onOptionsChange({ ...options, jsonData: { ...options.jsonData, sentinelName: event.target.value } }); + }} + /> +
+ )} +
{ onChange={this.onURLChange} value={url || ''} tooltip="Accepts host:port address or a URI, as defined in https://www.iana.org/assignments/uri-schemes/prov/redis. - For Redis Cluster can contain multiple values with comma." + For Redis Cluster and Sentinel can contain multiple values with comma." placeholder="redis://..." />
@@ -219,7 +234,7 @@ export class ConfigEditor extends PureComponent { placeholder="Database password" labelWidth={10} inputWidth={20} - tooltip="When specified AUTH command will be used to authenticate with the provided password" + tooltip="When specified AUTH command will be used to authenticate with the provided password." onReset={this.onResetPassword} onChange={this.onPasswordChange} /> diff --git a/src/img/datasource.png b/src/img/datasource.png index 69fc129..3b7fe85 100644 Binary files a/src/img/datasource.png and b/src/img/datasource.png differ diff --git a/src/img/redis-dashboard.png b/src/img/redis-dashboard.png index dd36278..4a5e2e8 100644 Binary files a/src/img/redis-dashboard.png and b/src/img/redis-dashboard.png differ diff --git a/src/types.ts b/src/types.ts index b46585c..9257120 100644 --- a/src/types.ts +++ b/src/types.ts @@ -49,9 +49,16 @@ export interface RedisDataSourceOptions extends DataSourceJsonData { /** * Client Type * - * @type {string} + * @type {ClientTypeValue} */ client: ClientTypeValue; + + /** + * Sentinel Master group name + * + * @type {string} + */ + sentinelName: string; } /** @@ -101,6 +108,6 @@ export enum ClientTypeValue { */ export const ClientType = [ { label: 'Redis Cluster', value: ClientTypeValue.CLUSTER }, - // { label: 'Sentinel', value: ClientTypeValue.SENTINEL }, + { label: 'Sentinel', value: ClientTypeValue.SENTINEL }, { label: 'Standalone', value: ClientTypeValue.STANDALONE }, ];