Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/lazy-planes-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'grafana-github-datasource': minor
---

Add support PDC for github datasource
34 changes: 24 additions & 10 deletions pkg/github/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
googlegithub "github.com/google/go-github/v72/github"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
"github.com/influxdata/tdigest"
"github.com/shurcooL/githubv4"
"golang.org/x/oauth2"
Expand Down Expand Up @@ -53,28 +54,28 @@ var runnerPerMinuteRate = map[string]float64{
}

// New instantiates a new GitHub API client.
func New(ctx context.Context, settings models.Settings) (*Client, error) {
func New(ctx context.Context, settings models.Settings, opts httpclient.Options) (*Client, error) {
if settings.SelectedAuthType == models.AuthTypeGithubApp {
return createAppClient(settings)
return createAppClient(settings, opts)
}
if settings.SelectedAuthType == models.AuthTypePAT {
return createAccessTokenClient(ctx, settings)
return createAccessTokenClient(ctx, settings, opts)
}
return nil, backend.DownstreamError(errors.New("access token or app token are required"))
}

func createAppClient(settings models.Settings) (*Client, error) {
transport, err := httpclient.GetDefaultTransport()
func createAppClient(settings models.Settings, opts httpclient.Options) (*Client, error) {
httpClient, err := httpclient.New(opts)
if err != nil {
return nil, backend.DownstreamError(errors.New("error: http.DefaultTransport is not of type *http.Transport"))
return nil, backend.DownstreamErrorf("error creating http client: %w", err)
}
itr, err := ghinstallation.New(transport, settings.AppIdInt64, settings.InstallationIdInt64, []byte(settings.PrivateKey))

itr, err := ghinstallation.New(httpClient.Transport, settings.AppIdInt64, settings.InstallationIdInt64, []byte(settings.PrivateKey))
if err != nil {
return nil, backend.DownstreamError(errors.New("error creating token source"))
}

httpClient := &http.Client{Transport: itr}

httpClient.Transport = itr
if settings.GitHubURL == "" {
return &Client{
restClient: googlegithub.NewClient(httpClient),
Expand All @@ -87,13 +88,26 @@ func createAppClient(settings models.Settings) (*Client, error) {
return useGitHubEnterprise(httpClient, settings)
}

func createAccessTokenClient(ctx context.Context, settings models.Settings) (*Client, error) {
func createAccessTokenClient(ctx context.Context, settings models.Settings, opts httpclient.Options) (*Client, error) {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: settings.AccessToken},
)

httpClient := oauth2.NewClient(ctx, src)

cli := proxy.New(opts.ProxyOptions)
if cli.SecureSocksProxyEnabled() {
// only override the Transport if Secure Proxy is enabled.
transport, err := httpclient.GetTransport(opts)
if err != nil {
return nil, backend.DownstreamErrorf("error getting the transport: %w", err)
}

httpClient.Transport = &oauth2.Transport{
Base: transport,
Source: oauth2.ReuseTokenSource(nil, src),
}
}
if settings.GitHubURL == "" {
return &Client{
restClient: googlegithub.NewClient(httpClient),
Expand Down
5 changes: 3 additions & 2 deletions pkg/github/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"

"github.com/grafana/github-datasource/pkg/dfutil"
githubclient "github.com/grafana/github-datasource/pkg/github/client"
Expand Down Expand Up @@ -244,8 +245,8 @@ func (d *Datasource) QueryData(ctx context.Context, req *backend.QueryDataReques
}

// NewDatasource creates a new datasource for handling queries
func NewDatasource(ctx context.Context, settings models.Settings) (*Datasource, error) {
client, err := githubclient.New(ctx, settings)
func NewDatasource(ctx context.Context, settings models.Settings, opts httpclient.Options) (*Datasource, error) {
client, err := githubclient.New(ctx, settings, opts)
if err != nil {
return nil, err
}
Expand Down
16 changes: 11 additions & 5 deletions pkg/plugin/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import (
"fmt"

"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"

"github.com/grafana/github-datasource/pkg/github"
"github.com/grafana/github-datasource/pkg/models"
)

// NewGitHubInstance creates a new GitHubInstance using the settings to determine if things like the Caching Wrapper should be enabled
func NewGitHubInstance(ctx context.Context, settings models.Settings) (instancemgmt.Instance, error) {
gh, err := github.NewDatasource(ctx, settings)
func NewGitHubInstance(ctx context.Context, settings models.Settings, opts httpclient.Options) (instancemgmt.Instance, error) {
gh, err := github.NewDatasource(ctx, settings, opts)
if err != nil {
return nil, err
}
Expand All @@ -28,15 +29,20 @@ func NewGitHubInstance(ctx context.Context, settings models.Settings) (instancem
}

// NewDataSourceInstance creates a new instance
func NewDataSourceInstance(_ context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
datasourceSettings, err := models.LoadSettings(settings)
func NewDataSourceInstance(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
opts, err := settings.HTTPClientOptions(ctx)
if err != nil {
return nil, err
}

datasourceSettings, err := models.LoadSettings(settings)
if err != nil {
return nil, err
}

datasourceSettings.CachingEnabled = true

instance, err := NewGitHubInstance(context.Background(), datasourceSettings)
instance, err := NewGitHubInstance(ctx, datasourceSettings, opts)
if err != nil {
return instance, fmt.Errorf("instantiating github instance: %w", err)
}
Expand Down
24 changes: 19 additions & 5 deletions src/views/ConfigEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import React, { ChangeEvent, useCallback, useEffect, useState } from 'react';
import { css } from '@emotion/css';
import { Collapse, Field, Input, Label, RadioButtonGroup, SecretInput, SecretTextArea, useStyles2 } from '@grafana/ui';
import { ConfigSection, DataSourceDescription } from '@grafana/plugin-ui';
import { Divider } from 'components/Divider';
import { components as selectors } from '../components/selectors';
import {
FeatureToggles,
onUpdateDatasourceJsonDataOption,
onUpdateDatasourceSecureJsonDataOption,
type DataSourcePluginOptionsEditorProps,
type GrafanaTheme2,
type SelectableValue,
} from '@grafana/data';
import { ConfigSection, DataSourceDescription } from '@grafana/plugin-ui';
import { config } from '@grafana/runtime';
import {
Collapse,
Field,
Input,
Label,
RadioButtonGroup,
SecretInput,
SecretTextArea,
SecureSocksProxySettings,
useStyles2,
} from '@grafana/ui';
import { Divider } from 'components/Divider';
import type { GitHubAuthType, GitHubLicenseType, GitHubDataSourceOptions, GitHubSecureJsonData } from 'types/config';
import { components as selectors } from '../components/selectors';

export type ConfigEditorProps = DataSourcePluginOptionsEditorProps<GitHubDataSourceOptions, GitHubSecureJsonData>;

Expand Down Expand Up @@ -196,7 +208,9 @@ const ConfigEditor = (props: ConfigEditorProps) => {
</>
)}
</ConfigSection>

{config.featureToggles['secureSocksDSProxyEnabled' as keyof FeatureToggles] && (
<SecureSocksProxySettings options={options} onOptionsChange={onOptionsChange} />
)}
<Divider />

<ConfigSection title="Connection" isCollapsible>
Expand Down
Loading