mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 03:19:30 +08:00
Postgres: Switch the datasource plugin from lib/pq to pgx (#81353)
* postgres: switch from lib/pq to pgx * postgres: improved tls handling
This commit is contained in:
382
pkg/tsdb/grafana-postgresql-datasource/tls/tls_test.go
Normal file
382
pkg/tsdb/grafana-postgresql-datasource/tls/tls_test.go
Normal file
@ -0,0 +1,382 @@
|
||||
package tls
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/tsdb/sqleng"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func noReadFile(path string) ([]byte, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func TestTLSNoMode(t *testing.T) {
|
||||
// for backward-compatibility reason,
|
||||
// when mode is unset, it defaults to `require`
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
ConfigurationMethod: "",
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.True(t, c.InsecureSkipVerify)
|
||||
}
|
||||
|
||||
func TestTLSDisable(t *testing.T) {
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "disable",
|
||||
ConfigurationMethod: "",
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, c)
|
||||
}
|
||||
|
||||
func TestTLSRequire(t *testing.T) {
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "",
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.True(t, c.InsecureSkipVerify)
|
||||
require.Nil(t, c.RootCAs)
|
||||
}
|
||||
|
||||
func TestTLSRequireWithRootCert(t *testing.T) {
|
||||
rootCertBytes, err := CreateRandomRootCertBytes()
|
||||
require.NoError(t, err)
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{
|
||||
"tlsCACert": string(rootCertBytes),
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.True(t, c.InsecureSkipVerify)
|
||||
require.NotNil(t, c.VerifyConnection)
|
||||
require.NotNil(t, c.RootCAs) // TODO: not the best, but nothing better available
|
||||
}
|
||||
|
||||
func TestTLSVerifyCA(t *testing.T) {
|
||||
rootCertBytes, err := CreateRandomRootCertBytes()
|
||||
require.NoError(t, err)
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "verify-ca",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{
|
||||
"tlsCACert": string(rootCertBytes),
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.True(t, c.InsecureSkipVerify)
|
||||
require.NotNil(t, c.VerifyConnection)
|
||||
require.NotNil(t, c.RootCAs) // TODO: not the best, but nothing better available
|
||||
}
|
||||
|
||||
func TestTLSVerifyCAMisingRootCert(t *testing.T) {
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "verify-ca",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{},
|
||||
}
|
||||
_, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.ErrorIs(t, err, errNoRootCert)
|
||||
}
|
||||
|
||||
func TestTLSClientCert(t *testing.T) {
|
||||
clientKey, clientCert, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{
|
||||
"tlsClientCert": string(clientCert),
|
||||
"tlsClientKey": string(clientKey),
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.Len(t, c.Certificates, 1)
|
||||
}
|
||||
|
||||
func TestTLSMethodFileContentClientCertMissingKey(t *testing.T) {
|
||||
_, clientCert, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{
|
||||
"tlsClientCert": string(clientCert),
|
||||
},
|
||||
}
|
||||
_, err = GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.ErrorIs(t, err, errPartialClientCertNoKey)
|
||||
}
|
||||
|
||||
func TestTLSMethodFileContentClientCertMissingCert(t *testing.T) {
|
||||
clientKey, _, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{
|
||||
"tlsClientKey": string(clientKey),
|
||||
},
|
||||
}
|
||||
_, err = GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.ErrorIs(t, err, errPartialClientCertNoCert)
|
||||
}
|
||||
|
||||
func TestTLSMethodFilePathClientCertMissingKey(t *testing.T) {
|
||||
clientKey, _, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
readFile := newMockReadFile(map[string]([]byte){
|
||||
"path1": clientKey,
|
||||
})
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "file-path",
|
||||
CertKeyFile: "path1",
|
||||
},
|
||||
}
|
||||
_, err = GetTLSConfig(dsInfo, readFile, "localhost")
|
||||
require.ErrorIs(t, err, errPartialClientCertNoCert)
|
||||
}
|
||||
|
||||
func TestTLSMethodFilePathClientCertMissingCert(t *testing.T) {
|
||||
_, clientCert, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
readFile := newMockReadFile(map[string]([]byte){
|
||||
"path1": clientCert,
|
||||
})
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "file-path",
|
||||
CertFile: "path1",
|
||||
},
|
||||
}
|
||||
_, err = GetTLSConfig(dsInfo, readFile, "localhost")
|
||||
require.ErrorIs(t, err, errPartialClientCertNoKey)
|
||||
}
|
||||
|
||||
func TestTLSVerifyFull(t *testing.T) {
|
||||
rootCertBytes, err := CreateRandomRootCertBytes()
|
||||
require.NoError(t, err)
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "verify-full",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{
|
||||
"tlsCACert": string(rootCertBytes),
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.False(t, c.InsecureSkipVerify)
|
||||
require.Nil(t, c.VerifyConnection)
|
||||
require.NotNil(t, c.RootCAs) // TODO: not the best, but nothing better available
|
||||
}
|
||||
|
||||
func TestTLSMethodFileContent(t *testing.T) {
|
||||
rootCertBytes, err := CreateRandomRootCertBytes()
|
||||
require.NoError(t, err)
|
||||
|
||||
clientKey, clientCert, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "verify-full",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{
|
||||
"tlsCACert": string(rootCertBytes),
|
||||
"tlsClientCert": string(clientCert),
|
||||
"tlsClientKey": string(clientKey),
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.Len(t, c.Certificates, 1)
|
||||
require.NotNil(t, c.RootCAs) // TODO: not the best, but nothing better available
|
||||
}
|
||||
|
||||
func TestTLSMethodFilePath(t *testing.T) {
|
||||
rootCertBytes, err := CreateRandomRootCertBytes()
|
||||
require.NoError(t, err)
|
||||
|
||||
clientKey, clientCert, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
readFile := newMockReadFile(map[string]([]byte){
|
||||
"root-cert-path": rootCertBytes,
|
||||
"client-key-path": clientKey,
|
||||
"client-cert-path": clientCert,
|
||||
})
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "verify-full",
|
||||
ConfigurationMethod: "file-path",
|
||||
RootCertFile: "root-cert-path",
|
||||
CertKeyFile: "client-key-path",
|
||||
CertFile: "client-cert-path",
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, readFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.Len(t, c.Certificates, 1)
|
||||
require.NotNil(t, c.RootCAs) // TODO: not the best, but nothing better available
|
||||
}
|
||||
|
||||
func TestTLSMethodFilePathRootCertDoesNotExist(t *testing.T) {
|
||||
readFile := newMockReadFile(map[string]([]byte){})
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "verify-full",
|
||||
ConfigurationMethod: "file-path",
|
||||
RootCertFile: "path1",
|
||||
},
|
||||
}
|
||||
_, err := GetTLSConfig(dsInfo, readFile, "localhost")
|
||||
require.ErrorIs(t, err, os.ErrNotExist)
|
||||
}
|
||||
|
||||
func TestTLSMethodFilePathClientCertKeyDoesNotExist(t *testing.T) {
|
||||
_, clientCert, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
readFile := newMockReadFile(map[string]([]byte){
|
||||
"cert-path": clientCert,
|
||||
})
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "file-path",
|
||||
CertKeyFile: "key-path",
|
||||
CertFile: "cert-path",
|
||||
},
|
||||
}
|
||||
_, err = GetTLSConfig(dsInfo, readFile, "localhost")
|
||||
require.ErrorIs(t, err, os.ErrNotExist)
|
||||
}
|
||||
|
||||
func TestTLSMethodFilePathClientCertCertDoesNotExist(t *testing.T) {
|
||||
clientKey, _, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
readFile := newMockReadFile(map[string]([]byte){
|
||||
"key-path": clientKey,
|
||||
})
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "require",
|
||||
ConfigurationMethod: "file-path",
|
||||
CertKeyFile: "key-path",
|
||||
CertFile: "cert-path",
|
||||
},
|
||||
}
|
||||
_, err = GetTLSConfig(dsInfo, readFile, "localhost")
|
||||
require.ErrorIs(t, err, os.ErrNotExist)
|
||||
}
|
||||
|
||||
// method="" equals to method="file-path"
|
||||
func TestTLSMethodEmpty(t *testing.T) {
|
||||
rootCertBytes, err := CreateRandomRootCertBytes()
|
||||
require.NoError(t, err)
|
||||
|
||||
clientKey, clientCert, err := CreateRandomClientCert()
|
||||
require.NoError(t, err)
|
||||
|
||||
readFile := newMockReadFile(map[string]([]byte){
|
||||
"root-cert-path": rootCertBytes,
|
||||
"client-key-path": clientKey,
|
||||
"client-cert-path": clientCert,
|
||||
})
|
||||
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "verify-full",
|
||||
ConfigurationMethod: "",
|
||||
RootCertFile: "root-cert-path",
|
||||
CertKeyFile: "client-key-path",
|
||||
CertFile: "client-cert-path",
|
||||
},
|
||||
}
|
||||
c, err := GetTLSConfig(dsInfo, readFile, "localhost")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, c)
|
||||
require.Len(t, c.Certificates, 1)
|
||||
require.NotNil(t, c.RootCAs) // TODO: not the best, but nothing better available
|
||||
}
|
||||
|
||||
func TestTLSVerifyFullMisingRootCert(t *testing.T) {
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "verify-full",
|
||||
ConfigurationMethod: "file-content",
|
||||
},
|
||||
DecryptedSecureJSONData: map[string]string{},
|
||||
}
|
||||
_, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.ErrorIs(t, err, errNoRootCert)
|
||||
}
|
||||
|
||||
func TestTLSInvalidMode(t *testing.T) {
|
||||
dsInfo := sqleng.DataSourceInfo{
|
||||
JsonData: sqleng.JsonData{
|
||||
Mode: "not-a-valid-mode",
|
||||
},
|
||||
}
|
||||
|
||||
_, err := GetTLSConfig(dsInfo, noReadFile, "localhost")
|
||||
require.Error(t, err)
|
||||
}
|
Reference in New Issue
Block a user