Skip to content

Commit 8ba8ae1

Browse files
authored
Merge pull request #99 from questdb/remove-tls-dropdown
Remove `TLS Method` configuration option
2 parents 2882a61 + 6d8212c commit 8ba8ae1

File tree

7 files changed

+67
-133
lines changed

7 files changed

+67
-133
lines changed

README.md

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ example, statements like `UPDATE users SET name='blahblah'`
2121
and `DROP TABLE importantTable;` would be executed.
2222

2323
To configure a readonly user, follow these steps:
24-
* Open Source version
24+
25+
- Open Source version
2526
1. Set the following properties in server.conf file:
2627
- pg.readonly.user.enabled=true
2728
- pg.readonly.user=myuser
2829
- pg.readonly.password=secret
2930
2. Restart QuestDB instance.
30-
* Enterprise version
31+
- Enterprise version
3132
1. Create user:
3233
- CREATE USER grafana_readonly;
33-
2. Grant read permission on selected tables/table columns ;
34+
2. Grant read permission on selected tables/table columns ;
3435
- GRANT SELECT ON table1, ... TO grafana_readonly;
3536

3637
### Manual configuration
@@ -58,7 +59,6 @@ datasources:
5859
port: 8812
5960
username: admin
6061
tlsMode: disable
61-
# tlsConfigurationMethod: file-path | file-content
6262
# tlsCACertFile: <string>
6363
# timeout: <seconds>
6464
# queryTimeout: <seconds>
@@ -88,11 +88,13 @@ interprets timestamp rows without explicit time zone as UTC. Any column except
8888

8989
To create multi-line time series, the query must return at least 3 fields in
9090
the following order:
91-
- field 1: `timestamp` field with an alias of `time`
92-
- field 2: value to group by
91+
92+
- field 1: `timestamp` field with an alias of `time`
93+
- field 2: value to group by
9394
- field 3+: the metric values
9495

9596
For example:
97+
9698
```sql
9799
SELECT pickup_datetime AS time, cab_type, avg(fare_amount) AS avg_fare_amount
98100
FROM trips
@@ -109,24 +111,25 @@ Table visualizations will always be available for any valid QuestDB query.
109111
To simplify syntax and to allow for dynamic parts, like date range filters, the query can contain macros.
110112

111113
Here is an example of a query with a macro that will use Grafana's time filter:
114+
112115
```sql
113116
SELECT desginated_timestamp, data_stuff
114117
FROM test_data
115118
WHERE $__timeFilter(desginated_timestamp)
116119
```
117120

118-
| Macro | Description | Output example |
119-
|----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
120-
| *$__timeFilter(columnName)* | Replaced by a conditional that filters the data (using the provided column) based on the time range of the panel in seconds | `timestamp >= cast(1706263425598000 as timestamp) AND timestamp <= cast(1706285057560000 as timestamp)` |
121-
| *$__fromTime* | Replaced by the starting time of the range of the panel cast to timestamp | `cast(1706263425598000 as timestamp)` |
122-
| *$__toTime* | Replaced by the ending time of the range of the panel cast to timestamp | `cast(1706285057560000 as timestamp)` |
123-
| *$__sampleByInterval* | Replaced by the interval followed by unit: d, h, s or T (millisecond). Example: 1d, 5h, 20s, 1T. | `20s` (20 seconds) , `1T` (1 millisecond) |
124-
| *$__conditionalAll(condition, $templateVar)* | Replaced by the first parameter when the template variable in the second parameter does not select every value. Replaced by the 1=1 when the template variable selects every value. | `condition` or `1=1` |
121+
| Macro | Description | Output example |
122+
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
123+
| _$\_\_timeFilter(columnName)_ | Replaced by a conditional that filters the data (using the provided column) based on the time range of the panel in seconds | `timestamp >= cast(1706263425598000 as timestamp) AND timestamp <= cast(1706285057560000 as timestamp)` |
124+
| _$\_\_fromTime_ | Replaced by the starting time of the range of the panel cast to timestamp | `cast(1706263425598000 as timestamp)` |
125+
| _$\_\_toTime_ | Replaced by the ending time of the range of the panel cast to timestamp | `cast(1706285057560000 as timestamp)` |
126+
| _$\_\_sampleByInterval_ | Replaced by the interval followed by unit: d, h, s or T (millisecond). Example: 1d, 5h, 20s, 1T. | `20s` (20 seconds) , `1T` (1 millisecond) |
127+
| _$\_\_conditionalAll(condition, $templateVar)_ | Replaced by the first parameter when the template variable in the second parameter does not select every value. Replaced by the 1=1 when the template variable selects every value. | `condition` or `1=1` |
125128

126129
The plugin also supports notation using braces {}. Use this notation when queries are needed inside parameters.
127130

128-
Additionally, Grafana has the built-in [`$__interval` macro][query-transform-data-query-options], which calculates an interval in seconds or milliseconds.
129-
It shouldn't be used with SAMPLE BY because of time unit incompatibility, 1ms vs 1T (expected by QuestDB). Use `$__sampleByInterval` instead.
131+
Additionally, Grafana has the built-in [`$__interval` macro][query-transform-data-query-options], which calculates an interval in seconds or milliseconds.
132+
It shouldn't be used with SAMPLE BY because of time unit incompatibility, 1ms vs 1T (expected by QuestDB). Use `$__sampleByInterval` instead.
130133

131134
### Templates and variables
132135

@@ -144,12 +147,12 @@ Ad hoc filters allow you to add key/value filters that are automatically added
144147
to all metric queries that use the specified data source, without being
145148
explicitly used in queries.
146149

147-
By default, Ad Hoc filters will be populated with all Tables and Columns. If
150+
By default, Ad Hoc filters will be populated with all Tables and Columns. If
148151
you have a default database defined in the Datasource settings, all Tables from
149152
that database will be used to populate the filters. As this could be
150153
slow/expensive, you can introduce a second variable to allow limiting the
151154
Ad Hoc filters. It should be a `constant` type named `questdb_adhoc_query`
152-
and can contain: a comma delimited list of tables to show only columns for one or more tables.
155+
and can contain: a comma delimited list of tables to show only columns for one or more tables.
153156

154157
For more information on Ad Hoc filters, check the [Grafana
155158
docs](https://grafana.com/docs/grafana/latest/variables/variable-types/add-ad-hoc-filters/)
@@ -162,7 +165,7 @@ You may choose to hide this variable from view as it serves no further purpose.
162165

163166
## Learn more
164167

165-
* Add [Annotations](https://grafana.com/docs/grafana/latest/dashboards/annotations/).
166-
* Configure and use [Templates and variables](https://grafana.com/docs/grafana/latest/variables/).
167-
* Add [Transformations](https://grafana.com/docs/grafana/latest/panels/transformations/).
168-
* Set up alerting; refer to [Alerts overview](https://grafana.com/docs/grafana/latest/alerting/).
168+
- Add [Annotations](https://grafana.com/docs/grafana/latest/dashboards/annotations/).
169+
- Configure and use [Templates and variables](https://grafana.com/docs/grafana/latest/variables/).
170+
- Add [Transformations](https://grafana.com/docs/grafana/latest/panels/transformations/).
171+
- Set up alerting; refer to [Alerts overview](https://grafana.com/docs/grafana/latest/alerting/).

pkg/plugin/driver_test.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import (
55
"database/sql"
66
"encoding/json"
77
"fmt"
8-
"github.com/docker/docker/api/types/mount"
9-
"github.com/lib/pq"
108
"math"
119
"os"
1210
"path"
@@ -15,6 +13,9 @@ import (
1513
"testing"
1614
"time"
1715

16+
"github.com/docker/docker/api/types/mount"
17+
"github.com/lib/pq"
18+
1819
"github.com/docker/docker/api/types/container"
1920
"github.com/grafana/grafana-plugin-sdk-go/backend"
2021
"github.com/grafana/grafana-plugin-sdk-go/data"
@@ -212,7 +213,6 @@ func TestInsertAndQueryData(t *testing.T) {
212213
" ge8 geohash(8c)," +
213214
" ip ipv4, " +
214215
" uuid_ uuid ," +
215-
" l256 long256," +
216216
" ts timestamp " +
217217
") TIMESTAMP(ts) PARTITION BY YEAR BYPASS WAL")
218218
require.NoError(t, err)
@@ -233,20 +233,18 @@ func TestInsertAndQueryData(t *testing.T) {
233233
require.NoError(t, err)
234234

235235
stmt, err := conn.Prepare("INSERT INTO all_types values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, " +
236-
"cast($13 as geohash(1c)), cast($14 as geohash(2c)) , cast($15 as geohash(4c)), cast($16 as geohash(8c)), $17, $18, cast('' || $19 as long256), $20)")
236+
"cast($13 as geohash(1c)), cast($14 as geohash(2c)) , cast($15 as geohash(4c)), cast($16 as geohash(8c)), $17, $18, $19)")
237237
require.NoError(t, err)
238238
defer stmt.Close()
239239

240240
var data = [][]interface{}{
241-
{bool(false), int16(0), int16(0), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, timestamp},
242-
241+
{bool(false), int16(0), int16(0), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, timestamp},
243242
{bool(true), int16(1), int16(1), mkstring("a"), mkint32(4), mkint64(5), &date, &timestamp, mkfloat32(12.345), mkfloat64(1.0234567890123),
244243
mkstring("string"), mkstring("symbol"), mkstring("r"), mkstring("rj"), mkstring("rjtw"), mkstring("rjtwedd0"), mkstring("1.2.3.4"),
245-
mkstring("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"), mkstring("0x5dd94b8492b4be20632d0236ddb8f47c91efc2568b4d452847b4a645dbe4871a"), &timestamp},
246-
244+
mkstring("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"), &timestamp},
247245
{bool(true), int16(math.MaxInt8), int16(math.MaxInt16), mkstring("z"), mkint32(math.MaxInt32), mkint64(math.MaxInt64), &date, mktimestamp("1970-01-01T00:00:00.000000", t),
248246
mkfloat32(math.MaxFloat32), mkfloat64(math.MaxFloat64), mkstring("XXX"), mkstring(" "), mkstring("e"), mkstring("ee"), mkstring("eeee"), mkstring("eeeeeeee"),
249-
mkstring("255.255.255.255"), mkstring("a0eebc99-ffff-ffff-ffff-ffffffffffff"), mkstring("0x5dd94b8492b4be20632d0236ddb8f47c91efc2568b4d452847b4a645dbefffff"), mktimestamp("2020-03-31T00:00:00.987654", t)}}
247+
mkstring("255.255.255.255"), mkstring("a0eebc99-ffff-ffff-ffff-ffffffffffff"), mktimestamp("2020-03-31T00:00:00.987654", t)}}
250248

251249
for i := 1; i < len(data); i++ {
252250
_, err = stmt.Exec(data[i]...)

provisioning/datasources/questdb_questdb_datasource.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ datasources:
77
port: 8812
88
username: admin
99
tlsMode: disable
10-
# tlsConfigurationMethod: file-path | file-content
1110
# tlsCACertFile: <string>
1211
# timeout: <seconds>
1312
# queryTimeout: <seconds>

src/components/ui/CertificationKey.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ import { Input, Button, TextArea, Field } from '@grafana/ui';
33

44
interface Props {
55
label: string;
6+
tooltip?: string;
67
hasCert: boolean;
78
placeholder: string;
89
onChange: (event: ChangeEvent<HTMLTextAreaElement>) => void;
910
onClick: (event: MouseEvent<HTMLButtonElement>) => void;
1011
}
1112

12-
export const CertificationKey: FC<Props> = ({ hasCert, label, onChange, onClick, placeholder }) => {
13+
export const CertificationKey: FC<Props> = ({ hasCert, label, tooltip, onChange, onClick, placeholder }) => {
1314
return (
14-
<Field label={label}>
15+
<Field label={label} description={tooltip}>
1516
{hasCert ? (
1617
<>
1718
<Input type="text" disabled value="configured" width={24} />

src/selectors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export const Components = {
2424
TLSCACert: {
2525
label: 'TLS/SSL Root Certificate',
2626
placeholder: 'CA Cert. Begins with -----BEGIN CERTIFICATE-----',
27+
tooltip:
28+
"Allows you to configure certificates by specifying its content. The content will be stored encrypted in Grafana's database.",
2729
},
2830
TLSClientCert: {
2931
label: 'TLS/SSL Client Certificate',

src/views/QuestDBConfigEditor.test.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ describe('ConfigEditor', () => {
2222
expect(screen.getByPlaceholderText(Components.ConfigEditor.Username.placeholder)).toBeInTheDocument();
2323
expect(screen.getByPlaceholderText(Components.ConfigEditor.Password.placeholder)).toBeInTheDocument();
2424
expect(screen.getByText(Components.ConfigEditor.TlsMode.placeholder)).toBeInTheDocument();
25-
expect(screen.getByText(Components.ConfigEditor.TlsMethod.label)).toBeInTheDocument();
2625
});
2726
it('with password', async () => {
2827
render(
@@ -63,7 +62,7 @@ describe('ConfigEditor', () => {
6362
expect(screen.queryByPlaceholderText(Components.ConfigEditor.TLSClientCert.placeholder)).not.toBeInTheDocument();
6463
expect(screen.queryByPlaceholderText(Components.ConfigEditor.TLSClientKey.placeholder)).not.toBeInTheDocument();
6564
});
66-
it('with tlsMode and filePath tlsMethod', async () => {
65+
it('with verifyCA tlsMode and fileContent tlsMethod', async () => {
6766
render(
6867
<ConfigEditor
6968
{...mockConfigEditorProps()}
@@ -72,15 +71,14 @@ describe('ConfigEditor', () => {
7271
jsonData: {
7372
...mockConfigEditorProps().options.jsonData,
7473
tlsMode: PostgresTLSModes.verifyCA,
75-
tlsConfigurationMethod: PostgresTLSMethods.filePath,
74+
tlsConfigurationMethod: PostgresTLSMethods.fileContent,
7675
},
7776
}}
7877
/>
7978
);
8079
expect(screen.queryByText(PostgresTLSModes.verifyCA)).toBeInTheDocument();
81-
expect(screen.queryByText(Components.ConfigEditor.TlsMethod.placeholder)).toBeInTheDocument();
82-
expect(screen.queryByPlaceholderText(Components.ConfigEditor.TLSCACertFile.placeholder)).toBeInTheDocument();
83-
expect(screen.queryByPlaceholderText(Components.ConfigEditor.TLSCACert.placeholder)).not.toBeInTheDocument();
80+
expect(screen.queryByPlaceholderText(Components.ConfigEditor.TLSCACertFile.placeholder)).not.toBeInTheDocument();
81+
expect(screen.queryByPlaceholderText(Components.ConfigEditor.TLSCACert.placeholder)).toBeInTheDocument();
8482
});
8583

8684
it('with verifyFull tlsMode and fileContent tlsMethod', async () => {
@@ -98,7 +96,6 @@ describe('ConfigEditor', () => {
9896
/>
9997
);
10098
expect(screen.queryByText(PostgresTLSModes.verifyFull)).toBeInTheDocument();
101-
expect(screen.queryByText(Components.ConfigEditor.TlsMethod.placeholder)).toBeInTheDocument();
10299
expect(screen.queryByPlaceholderText(Components.ConfigEditor.TLSCACertFile.placeholder)).not.toBeInTheDocument();
103100
expect(screen.queryByPlaceholderText(Components.ConfigEditor.TLSCACert.placeholder)).toBeInTheDocument();
104101
});

0 commit comments

Comments
 (0)