Skip to content

Commit 7b190bc

Browse files
laserninjanineinchnick
authored andcommitted
Add Client tags to the Trino Grafana plugin
1 parent e91e00d commit 7b190bc

File tree

7 files changed

+49
-4
lines changed

7 files changed

+49
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ docker run -d -p 3000:3000 \
2626
* OAuth
2727
* Raw SQL editor only, no query builder yet
2828
* Macros
29+
* Client tags support, used to identify resource groups.
2930

3031
## Macros support
3132

pkg/trino/datasource-context.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ import (
1212
)
1313

1414
const (
15-
accessTokenKey = "accessToken"
16-
trinoUserHeader = "X-Trino-User"
17-
bearerPrefix = "Bearer "
15+
accessTokenKey = "accessToken"
16+
trinoUserHeader = "X-Trino-User"
17+
trinoClientTagsKey = "X-Trino-Client-Tags"
18+
bearerPrefix = "Bearer "
1819
)
1920

2021
type SQLDatasourceWithTrinoUserContext struct {
@@ -40,6 +41,10 @@ func (ds *SQLDatasourceWithTrinoUserContext) QueryData(ctx context.Context, req
4041
ctx = context.WithValue(ctx, trinoUserHeader, user)
4142
}
4243

44+
if settings.ClientTags != "" {
45+
ctx = context.WithValue(ctx, trinoClientTagsKey, settings.ClientTags)
46+
}
47+
4348
return ds.SQLDatasource.QueryData(ctx, req)
4449
}
4550

pkg/trino/datasource.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ func (s *TrinoDatasource) SetQueryArgs(ctx context.Context, headers http.Header)
8383

8484
user := ctx.Value(trinoUserHeader)
8585
accessToken := ctx.Value(accessTokenKey)
86+
clientTags := ctx.Value(trinoClientTagsKey)
8687

8788
if user != nil {
8889
args = append(args, sql.Named(trinoUserHeader, string(user.(*backend.User).Login)))
@@ -92,6 +93,10 @@ func (s *TrinoDatasource) SetQueryArgs(ctx context.Context, headers http.Header)
9293
args = append(args, sql.Named(accessTokenKey, accessToken.(string)))
9394
}
9495

96+
if clientTags != nil {
97+
args = append(args, sql.Named(trinoClientTagsKey, clientTags.(string)))
98+
}
99+
95100
return args
96101
}
97102

pkg/trino/models/settings.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type TrinoDatasourceSettings struct {
2020
ClientId string `json:"clientId"`
2121
ClientSecret string `json:"clientSecret"`
2222
ImpersonationUser string `json:"impersonationUser"`
23+
ClientTags string `json:"clientTags"`
2324
}
2425

2526
func (s *TrinoDatasourceSettings) Load(config backend.DataSourceInstanceSettings) error {

src/ConfigEditor.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ export class ConfigEditor extends PureComponent<Props, State> {
3434
const onImpersonationUserChange = (event: ChangeEvent<HTMLInputElement>) => {
3535
onOptionsChange({...options, jsonData: {...options.jsonData, impersonationUser: event.target.value}})
3636
};
37+
const onClientTagsChange = (event: ChangeEvent<HTMLInputElement>) => {
38+
onOptionsChange({...options, jsonData: {...options.jsonData, clientTags: event.target.value}})
39+
};
3740
return (
3841
<div className="gf-form-group">
3942
<DataSourceHttpSettings
@@ -72,6 +75,20 @@ export class ConfigEditor extends PureComponent<Props, State> {
7275
/>
7376
</InlineField>
7477
</div>
78+
<div className="gf-form-inline">
79+
<InlineField
80+
label="Client Tags"
81+
tooltip="A comma-separated list of strings, used to identify Trino resource groups."
82+
labelWidth={26}
83+
>
84+
<Input
85+
value={options.jsonData?.clientTags ?? ''}
86+
onChange={onClientTagsChange}
87+
width={60}
88+
placeholder="tag1,tag2,tag3"
89+
/>
90+
</InlineField>
91+
</div>
7592
</div>
7693

7794
<h3 className="page-heading">OAuth Trino Authentication</h3>

src/e2e.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ async function setupDataSourceWithClientCredentials(page: Page, clientId: string
3535
await page.getByTestId('data-testid Data source settings page Save and Test button').click();
3636
}
3737

38+
async function setupDataSourceWithClientTags(page: Page, clientTags: string) {
39+
await page.getByTestId('data-testid Datasource HTTP settings url').fill('http://trino:8080');
40+
await page.locator('div').filter({hasText: /^Impersonate logged in user$/}).getByLabel('Toggle switch').click();
41+
await page.locator('div').filter({hasText: /^Access token$/}).locator('input[type="password"]').fill('aaa');
42+
await page.locator('div').filter({hasText: /^Client Tags$/}).locator('input').fill(clientTags);
43+
await page.getByTestId('data-testid Data source settings page Save and Test button').click();
44+
}
45+
3846
async function runQueryAndCheckResults(page: Page) {
3947
await page.getByLabel(EXPORT_DATA).click();
4048
await page.getByTestId('data-testid TimePicker Open Button').click();
@@ -76,3 +84,10 @@ test('test client credentials flow with configured access token', async ({ page
7684
await setupDataSourceWithClientCredentials(page, GRAFANA_CLIENT);
7785
await expect(page.getByLabel(EXPORT_DATA)).toHaveCount(0);
7886
});
87+
88+
test('test with client tags', async ({ page }) => {
89+
await login(page);
90+
await goToTrinoSettings(page);
91+
await setupDataSourceWithClientTags(page, 'tag1,tag2,tag3');
92+
await runQueryAndCheckResults(page);
93+
});

src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ export interface TrinoDataSourceOptions extends DataSourceJsonData {
5555
enableImpersonation?: boolean;
5656
tokenUrl?: string;
5757
clientId?: string;
58-
impersonationUser?: string
58+
impersonationUser?: string;
59+
clientTags?: string;
5960
}
6061
/**
6162
* Value that is used in the backend, but never sent over HTTP to the frontend

0 commit comments

Comments
 (0)