[v10.4.x] Plugins: Pass PDC file contents in requests (#85144)
* Plugins: Pass PDC file contents in requests (#84783)
* Plugins: Pass PDC file contents in requests
* go mod tidy
* undo go.mod changes
* fix linter
* fix tests
* undo unnecessary changes
* update dep
* join with comma
* update naming
* bump SDK
(cherry picked from commit b765c21d4c)
* set env + req config
* fix linter
This commit is contained in:
@@ -63,7 +63,7 @@ require (
|
||||
github.com/grafana/cuetsy v0.1.11 // @grafana/grafana-as-code
|
||||
github.com/grafana/grafana-aws-sdk v0.23.1 // @grafana/aws-datasources
|
||||
github.com/grafana/grafana-azure-sdk-go v1.12.0 // @grafana/partner-datasources
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.215.0 // @grafana/plugins-platform-backend
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.217.0 // @grafana/plugins-platform-backend
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // @grafana/backend-platform
|
||||
github.com/hashicorp/go-hclog v1.6.2 // @grafana/plugins-platform-backend
|
||||
github.com/hashicorp/go-plugin v1.6.0 // @grafana/plugins-platform-backend
|
||||
@@ -105,9 +105,9 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.10.0 // @grafana/backend-platform
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 // @grafana/backend-platform
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // @grafana/backend-platform
|
||||
golang.org/x/crypto v0.19.0 // @grafana/backend-platform
|
||||
golang.org/x/crypto v0.21.0 // @grafana/backend-platform
|
||||
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb // @grafana/alerting-squad-backend
|
||||
golang.org/x/net v0.21.0 // @grafana/oss-big-tent @grafana/partner-datasources
|
||||
golang.org/x/net v0.22.0 // @grafana/oss-big-tent @grafana/partner-datasources
|
||||
golang.org/x/oauth2 v0.16.0 // @grafana/grafana-authnz-team
|
||||
golang.org/x/sync v0.6.0 // @grafana/alerting-squad-backend
|
||||
golang.org/x/time v0.5.0 // @grafana/backend-platform
|
||||
@@ -115,7 +115,7 @@ require (
|
||||
gonum.org/v1/gonum v0.12.0 // @grafana/observability-metrics
|
||||
google.golang.org/api v0.155.0 // @grafana/backend-platform
|
||||
google.golang.org/grpc v1.62.1 // @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.32.0 // @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.33.0 // @grafana/plugins-platform-backend
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // @grafana/alerting-squad-backend
|
||||
gopkg.in/mail.v2 v2.3.1 // @grafana/backend-platform
|
||||
@@ -214,7 +214,7 @@ require (
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // @grafana/alerting-squad-backend
|
||||
go.uber.org/goleak v1.3.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // @grafana/backend-platform
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
@@ -403,7 +403,7 @@ require (
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
golang.org/x/term v0.17.0 // indirect
|
||||
golang.org/x/term v0.18.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
|
||||
|
||||
@@ -2535,8 +2535,8 @@ github.com/grafana/grafana-google-sdk-go v0.1.0/go.mod h1:Vo2TKWfDVmNTELBUM+3lkr
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 h1:r+mU5bGMzcXCRVAuOrTn54S80qbfVkvTdUJZfSfTNbs=
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79/go.mod h1:wc6Hbh3K2TgCUSfBC/BOzabItujtHMESZeFk5ZhdxhQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.114.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.215.0 h1:02gwVsqYi1I+U48/MQR61eOMxiXE7KNKC8QsiMJ//qA=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.215.0/go.mod h1:nBsh3jRItKQUXDF2BQkiQCPxqrsSQeb+7hiFyJTO1RE=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.217.0 h1:oQjq5KRrVrhweXHxFtEMgjv1KW7hujGiRPIYrsPZ9PE=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.217.0/go.mod h1:FdvSvOliqpVLnytM7e89zCFyYPDE6VOn9SIjVQRvVxM=
|
||||
github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482 h1:1YNoeIhii4UIIQpCPU+EXidnqf449d0C3ZntAEt4KSo=
|
||||
github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482/go.mod h1:GNcfpy5+SY6RVbNGQW264gC0r336Dm+0zgQ5vt6+M8Y=
|
||||
github.com/grafana/prometheus-alertmanager v0.25.1-0.20240208102907-e82436ce63e6 h1:CBm0rwLCPDyarg9/bHJ50rBLYmyMDoyCWpgRMITZhdA=
|
||||
@@ -3893,8 +3893,9 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf
|
||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -4080,8 +4081,8 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -4319,8 +4320,9 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -4341,8 +4343,9 @@ golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -4930,8 +4933,9 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
|
||||
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.27.0/go.mod h1:Sp1lku8WJMvNV0kjDI4Ni/T7J/U3BO5ct5kEaoVU8+I=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
|
||||
@@ -152,7 +152,7 @@ func (s *Service) GetConfigMap(ctx context.Context, pluginID string, _ *auth.Ext
|
||||
m[proxy.PluginSecureSocksProxyEnabled] = "true"
|
||||
m[proxy.PluginSecureSocksProxyClientCert] = s.cfg.ProxySettings.ClientCert
|
||||
m[proxy.PluginSecureSocksProxyClientKey] = s.cfg.ProxySettings.ClientKey
|
||||
m[proxy.PluginSecureSocksProxyRootCACert] = s.cfg.ProxySettings.RootCA
|
||||
m[proxy.PluginSecureSocksProxyRootCAs] = strings.Join(s.cfg.ProxySettings.RootCAs, " ")
|
||||
m[proxy.PluginSecureSocksProxyProxyAddress] = s.cfg.ProxySettings.ProxyAddress
|
||||
m[proxy.PluginSecureSocksProxyServerName] = s.cfg.ProxySettings.ServerName
|
||||
m[proxy.PluginSecureSocksProxyAllowInsecure] = strconv.FormatBool(s.cfg.ProxySettings.AllowInsecure)
|
||||
@@ -287,13 +287,20 @@ func (s *Service) awsEnvVars() []string {
|
||||
func (s *Service) secureSocksProxyEnvVars() []string {
|
||||
if s.cfg.ProxySettings.Enabled {
|
||||
return []string{
|
||||
proxy.PluginSecureSocksProxyClientCert + "=" + s.cfg.ProxySettings.ClientCert,
|
||||
proxy.PluginSecureSocksProxyClientKey + "=" + s.cfg.ProxySettings.ClientKey,
|
||||
proxy.PluginSecureSocksProxyRootCACert + "=" + s.cfg.ProxySettings.RootCA,
|
||||
proxy.PluginSecureSocksProxyProxyAddress + "=" + s.cfg.ProxySettings.ProxyAddress,
|
||||
proxy.PluginSecureSocksProxyServerName + "=" + s.cfg.ProxySettings.ServerName,
|
||||
proxy.PluginSecureSocksProxyEnabled + "=" + strconv.FormatBool(s.cfg.ProxySettings.Enabled),
|
||||
proxy.PluginSecureSocksProxyAllowInsecure + "=" + strconv.FormatBool(s.cfg.ProxySettings.AllowInsecure),
|
||||
// nolint:staticcheck
|
||||
proxy.PluginSecureSocksProxyClientCertFilePathEnvVarName + "=" + s.cfg.ProxySettings.ClientCertFilePath,
|
||||
// nolint:staticcheck
|
||||
proxy.PluginSecureSocksProxyClientKeyFilePathEnvVarName + "=" + s.cfg.ProxySettings.ClientKeyFilePath,
|
||||
// nolint:staticcheck
|
||||
proxy.PluginSecureSocksProxyRootCACertFilePathsEnvVarName + "=" + strings.Join(s.cfg.ProxySettings.RootCAFilePaths, " "),
|
||||
// nolint:staticcheck
|
||||
proxy.PluginSecureSocksProxyAddressEnvVarName + "=" + s.cfg.ProxySettings.ProxyAddress,
|
||||
// nolint:staticcheck
|
||||
proxy.PluginSecureSocksProxyServerNameEnvVarName + "=" + s.cfg.ProxySettings.ServerName,
|
||||
// nolint:staticcheck
|
||||
proxy.PluginSecureSocksProxyEnabledEnvVarName + "=" + strconv.FormatBool(s.cfg.ProxySettings.Enabled),
|
||||
// nolint:staticcheck
|
||||
proxy.PluginSecureSocksProxyAllowInsecureEnvVarName + "=" + strconv.FormatBool(s.cfg.ProxySettings.AllowInsecure),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -686,7 +686,7 @@ func TestService_GetConfigMap(t *testing.T) {
|
||||
ShowUI: true,
|
||||
ClientCert: "c3rt",
|
||||
ClientKey: "k3y",
|
||||
RootCA: "ca",
|
||||
RootCAs: []string{"ca"},
|
||||
ProxyAddress: "https://proxy.grafana.com",
|
||||
ServerName: "secureProxy",
|
||||
AllowInsecure: true,
|
||||
@@ -712,7 +712,7 @@ func TestService_GetConfigMap(t *testing.T) {
|
||||
ShowUI: true,
|
||||
ClientCert: "c3rt",
|
||||
ClientKey: "k3y",
|
||||
RootCA: "ca",
|
||||
RootCAs: []string{"ca"},
|
||||
ProxyAddress: "https://proxy.grafana.com",
|
||||
ServerName: "secureProxy",
|
||||
},
|
||||
@@ -730,7 +730,7 @@ func TestService_GetConfigMap(t *testing.T) {
|
||||
ShowUI: true,
|
||||
ClientCert: "c3rt",
|
||||
ClientKey: "k3y",
|
||||
RootCA: "ca",
|
||||
RootCAs: []string{"ca"},
|
||||
ProxyAddress: "https://proxy.grafana.com",
|
||||
ServerName: "secureProxy",
|
||||
},
|
||||
|
||||
@@ -534,7 +534,7 @@ func (s *Service) httpClientOptions(ctx context.Context, ds *datasources.DataSou
|
||||
ClientCfg: &sdkproxy.ClientCfg{
|
||||
ClientCert: s.cfg.SecureSocksDSProxy.ClientCert,
|
||||
ClientKey: s.cfg.SecureSocksDSProxy.ClientKey,
|
||||
RootCA: s.cfg.SecureSocksDSProxy.RootCA,
|
||||
RootCAs: s.cfg.SecureSocksDSProxy.RootCAs,
|
||||
ProxyAddress: s.cfg.SecureSocksDSProxy.ProxyAddress,
|
||||
ServerName: s.cfg.SecureSocksDSProxy.ServerName,
|
||||
AllowInsecure: s.cfg.SecureSocksDSProxy.AllowInsecure,
|
||||
|
||||
@@ -1,33 +1,41 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
type SecureSocksDSProxySettings struct {
|
||||
Enabled bool
|
||||
ShowUI bool
|
||||
AllowInsecure bool
|
||||
ClientCert string
|
||||
ClientKey string
|
||||
RootCA string
|
||||
ProxyAddress string
|
||||
ServerName string
|
||||
Enabled bool
|
||||
ShowUI bool
|
||||
AllowInsecure bool
|
||||
ClientCert string
|
||||
ClientCertFilePath string
|
||||
ClientKey string
|
||||
ClientKeyFilePath string
|
||||
RootCAs []string
|
||||
RootCAFilePaths []string
|
||||
ProxyAddress string
|
||||
ServerName string
|
||||
}
|
||||
|
||||
func readSecureSocksDSProxySettings(iniFile *ini.File) (SecureSocksDSProxySettings, error) {
|
||||
s := SecureSocksDSProxySettings{}
|
||||
s := SecureSocksDSProxySettings{
|
||||
RootCAs: []string{},
|
||||
RootCAFilePaths: []string{},
|
||||
}
|
||||
secureSocksProxySection := iniFile.Section("secure_socks_datasource_proxy")
|
||||
s.Enabled = secureSocksProxySection.Key("enabled").MustBool(false)
|
||||
s.ClientCert = secureSocksProxySection.Key("client_cert").MustString("")
|
||||
s.ClientKey = secureSocksProxySection.Key("client_key").MustString("")
|
||||
s.RootCA = secureSocksProxySection.Key("root_ca_cert").MustString("")
|
||||
s.ProxyAddress = secureSocksProxySection.Key("proxy_address").MustString("")
|
||||
s.ServerName = secureSocksProxySection.Key("server_name").MustString("")
|
||||
s.ShowUI = secureSocksProxySection.Key("show_ui").MustBool(true)
|
||||
s.AllowInsecure = secureSocksProxySection.Key("allow_insecure").MustBool(false)
|
||||
s.ClientCertFilePath = secureSocksProxySection.Key("client_cert").MustString("")
|
||||
s.ClientKeyFilePath = secureSocksProxySection.Key("client_key").MustString("")
|
||||
s.RootCAFilePaths = secureSocksProxySection.Key("root_ca_cert").Strings(" ")
|
||||
|
||||
if !s.Enabled {
|
||||
return s, nil
|
||||
@@ -40,14 +48,50 @@ func readSecureSocksDSProxySettings(iniFile *ini.File) (SecureSocksDSProxySettin
|
||||
// If the proxy is going to use TLS.
|
||||
if !s.AllowInsecure {
|
||||
// all fields must be specified to use the proxy
|
||||
if s.RootCA == "" {
|
||||
return s, errors.New("rootCA required")
|
||||
} else if s.ClientCert == "" || s.ClientKey == "" {
|
||||
if len(s.RootCAFilePaths) == 0 {
|
||||
return s, errors.New("one or more rootCA required")
|
||||
} else if s.ClientCertFilePath == "" || s.ClientKeyFilePath == "" {
|
||||
return s, errors.New("client key pair required")
|
||||
} else if s.ServerName == "" {
|
||||
return s, errors.New("server name required")
|
||||
}
|
||||
} else {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
if s.ClientCertFilePath != "" {
|
||||
certPEMBlock, err := os.ReadFile(s.ClientCertFilePath)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
s.ClientCert = string(certPEMBlock)
|
||||
}
|
||||
|
||||
if s.ClientKeyFilePath != "" {
|
||||
keyPEMBlock, err := os.ReadFile(s.ClientKeyFilePath)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
s.ClientKey = string(keyPEMBlock)
|
||||
}
|
||||
|
||||
var rootCAs []string
|
||||
for _, rootCAFile := range s.RootCAFilePaths {
|
||||
// nolint:gosec
|
||||
// The gosec G304 warning can be ignored because `rootCAFile` comes from config ini, and we check below if
|
||||
// it's the right file type.
|
||||
pemBytes, err := os.ReadFile(rootCAFile)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
pemDecoded, _ := pem.Decode(pemBytes)
|
||||
if pemDecoded == nil || pemDecoded.Type != "CERTIFICATE" {
|
||||
return s, errors.New("root ca is invalid")
|
||||
}
|
||||
rootCAs = append(rootCAs, string(pemBytes))
|
||||
}
|
||||
s.RootCAs = rootCAs
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -1,25 +1,46 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
func mustNewIniFile(fileContents string) *ini.File {
|
||||
file, err := ini.Load([]byte(fileContents))
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("creating ini file for test: %s", err))
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
func TestReadSecureSocksDSProxySettings(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tempDir := t.TempDir()
|
||||
testFilePath := filepath.Join(tempDir, "test")
|
||||
testFileData := "foobar"
|
||||
err := os.WriteFile(testFilePath, []byte(testFileData), 0600)
|
||||
require.NoError(t, err)
|
||||
|
||||
rootCACertFilePath := filepath.Join(tempDir, "ca.cert")
|
||||
// nolint:gosec
|
||||
caCertFile, err := os.Create(rootCACertFilePath)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err = caCertFile.Close()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
rootCaFileData := createTestRootCAFile(t, rootCACertFilePath)
|
||||
require.NoError(t, err)
|
||||
|
||||
cases := []struct {
|
||||
description string
|
||||
iniFile *ini.File
|
||||
@@ -32,24 +53,27 @@ func TestReadSecureSocksDSProxySettings(t *testing.T) {
|
||||
[secure_socks_datasource_proxy]
|
||||
`),
|
||||
expectedSettings: SecureSocksDSProxySettings{
|
||||
Enabled: false,
|
||||
ClientCert: "",
|
||||
ClientKey: "",
|
||||
RootCA: "",
|
||||
ProxyAddress: "",
|
||||
ServerName: "",
|
||||
ShowUI: true,
|
||||
AllowInsecure: false,
|
||||
Enabled: false,
|
||||
ShowUI: true,
|
||||
AllowInsecure: false,
|
||||
ClientCertFilePath: "",
|
||||
ClientCert: "",
|
||||
ClientKey: "",
|
||||
ClientKeyFilePath: "",
|
||||
RootCAs: []string{},
|
||||
RootCAFilePaths: []string{},
|
||||
ProxyAddress: "",
|
||||
ServerName: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "root ca is required",
|
||||
description: "one or more root ca is required",
|
||||
iniFile: mustNewIniFile(`
|
||||
[secure_socks_datasource_proxy]
|
||||
enabled = true
|
||||
proxy_address = address
|
||||
`),
|
||||
expectedErr: errors.New("rootCA required"),
|
||||
expectedErr: errors.New("one or more rootCA required"),
|
||||
},
|
||||
{
|
||||
description: "client cert is required",
|
||||
@@ -106,35 +130,40 @@ server_name = name
|
||||
allow_insecure = true
|
||||
`),
|
||||
expectedSettings: SecureSocksDSProxySettings{
|
||||
Enabled: true,
|
||||
ProxyAddress: "address",
|
||||
ServerName: "name",
|
||||
ShowUI: true,
|
||||
AllowInsecure: true,
|
||||
Enabled: true,
|
||||
ProxyAddress: "address",
|
||||
ServerName: "name",
|
||||
ShowUI: true,
|
||||
AllowInsecure: true,
|
||||
RootCAFilePaths: []string{},
|
||||
RootCAs: []string{},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "custom values",
|
||||
iniFile: mustNewIniFile(`
|
||||
iniFile: mustNewIniFile(fmt.Sprintf(`
|
||||
[secure_socks_datasource_proxy]
|
||||
enabled = true
|
||||
client_cert = cert
|
||||
client_key = key
|
||||
root_ca_cert = root_ca
|
||||
client_cert = %s
|
||||
client_key = %s
|
||||
root_ca_cert = %s
|
||||
proxy_address = proxy_address
|
||||
server_name = server_name
|
||||
show_ui = false
|
||||
allow_insecure = true
|
||||
`),
|
||||
allow_insecure = false
|
||||
`, testFilePath, testFilePath, rootCACertFilePath)),
|
||||
expectedSettings: SecureSocksDSProxySettings{
|
||||
Enabled: true,
|
||||
ClientCert: "cert",
|
||||
ClientKey: "key",
|
||||
RootCA: "root_ca",
|
||||
ProxyAddress: "proxy_address",
|
||||
ServerName: "server_name",
|
||||
ShowUI: false,
|
||||
AllowInsecure: true,
|
||||
Enabled: true,
|
||||
ShowUI: false,
|
||||
AllowInsecure: false,
|
||||
ClientCert: testFileData,
|
||||
ClientCertFilePath: testFilePath,
|
||||
ClientKey: testFileData,
|
||||
ClientKeyFilePath: testFilePath,
|
||||
RootCAs: []string{rootCaFileData},
|
||||
RootCAFilePaths: []string{rootCACertFilePath},
|
||||
ProxyAddress: "proxy_address",
|
||||
ServerName: "server_name",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -146,9 +175,56 @@ allow_insecure = true
|
||||
if tt.expectedErr != nil {
|
||||
assert.Equal(t, tt.expectedErr, err)
|
||||
} else {
|
||||
assert.Equal(t, tt.expectedSettings, settings)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.expectedSettings, settings)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func createTestRootCAFile(t *testing.T, path string) string {
|
||||
t.Helper()
|
||||
|
||||
ca := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(2019),
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"Grafana Labs"},
|
||||
CommonName: "Grafana",
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().AddDate(10, 0, 0),
|
||||
IsCA: true,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
||||
require.NoError(t, err)
|
||||
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
// nolint:gosec
|
||||
caCertFile, err := os.Create(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
block := &pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: caBytes,
|
||||
}
|
||||
err = pem.Encode(caCertFile, block)
|
||||
require.NoError(t, err)
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
err = pem.Encode(buf, block)
|
||||
require.NoError(t, err)
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func mustNewIniFile(fileContents string) *ini.File {
|
||||
file, err := ini.Load([]byte(fileContents))
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("creating ini file for test: %s", err))
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user