mirror of https://github.com/docker/docs.git
213 lines
6.4 KiB
Go
213 lines
6.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/docker/notary"
|
|
"github.com/docker/notary/signer"
|
|
"github.com/docker/notary/signer/keydbstore"
|
|
"github.com/docker/notary/tuf/data"
|
|
"github.com/docker/notary/utils"
|
|
"github.com/jinzhu/gorm"
|
|
_ "github.com/mattn/go-sqlite3"
|
|
"github.com/spf13/viper"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const (
|
|
Cert = "../../fixtures/notary-signer.crt"
|
|
Key = "../../fixtures/notary-signer.key"
|
|
Root = "../../fixtures/root-ca.crt"
|
|
)
|
|
|
|
// initializes a viper object with test configuration
|
|
func configure(jsonConfig string) *viper.Viper {
|
|
config := viper.New()
|
|
config.SetConfigType("json")
|
|
config.ReadConfig(bytes.NewBuffer([]byte(jsonConfig)))
|
|
return config
|
|
}
|
|
|
|
// If the TLS configuration is invalid, an error is returned. This doesn't test
|
|
// all the cases of the TLS configuration being invalid, since it's just
|
|
// calling configuration.ParseTLSConfig - this test just makes sure the
|
|
// error is propagated.
|
|
func TestGetAddrAndTLSConfigInvalidTLS(t *testing.T) {
|
|
invalids := []string{
|
|
`{"server": {"http_addr": ":1234", "grpc_addr": ":2345"}}`,
|
|
`{"server": {
|
|
"http_addr": ":1234",
|
|
"grpc_addr": ":2345",
|
|
"tls_cert_file": "nope",
|
|
"tls_key_file": "nope"
|
|
}}`,
|
|
}
|
|
for _, configJSON := range invalids {
|
|
_, _, _, err := getAddrAndTLSConfig(configure(configJSON))
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "unable to set up TLS")
|
|
}
|
|
}
|
|
|
|
// If a GRPC address is not provided, an error is returned.
|
|
func TestGetAddrAndTLSConfigNoGRPCAddr(t *testing.T) {
|
|
_, _, _, err := getAddrAndTLSConfig(configure(fmt.Sprintf(`{
|
|
"server": {
|
|
"http_addr": ":1234",
|
|
"tls_cert_file": "%s",
|
|
"tls_key_file": "%s"
|
|
}
|
|
}`, Cert, Key)))
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "grpc listen address required for server")
|
|
}
|
|
|
|
// If an HTTP address is not provided, an error is returned.
|
|
func TestGetAddrAndTLSConfigNoHTTPAddr(t *testing.T) {
|
|
_, _, _, err := getAddrAndTLSConfig(configure(fmt.Sprintf(`{
|
|
"server": {
|
|
"grpc_addr": ":1234",
|
|
"tls_cert_file": "%s",
|
|
"tls_key_file": "%s"
|
|
}
|
|
}`, Cert, Key)))
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "http listen address required for server")
|
|
}
|
|
|
|
// Success parsing a valid TLS config, HTTP address, and GRPC address.
|
|
func TestGetAddrAndTLSConfigSuccess(t *testing.T) {
|
|
httpAddr, grpcAddr, tlsConf, err := getAddrAndTLSConfig(configure(fmt.Sprintf(`{
|
|
"server": {
|
|
"http_addr": ":2345",
|
|
"grpc_addr": ":1234",
|
|
"tls_cert_file": "%s",
|
|
"tls_key_file": "%s"
|
|
}
|
|
}`, Cert, Key)))
|
|
require.NoError(t, err)
|
|
require.Equal(t, ":2345", httpAddr)
|
|
require.Equal(t, ":1234", grpcAddr)
|
|
require.NotNil(t, tlsConf)
|
|
}
|
|
|
|
// If a default alias is not provided to a DB backend, an error is returned.
|
|
func TestSetupCryptoServicesDBStoreNoDefaultAlias(t *testing.T) {
|
|
tmpFile, err := ioutil.TempFile("/tmp", "sqlite3")
|
|
require.NoError(t, err)
|
|
tmpFile.Close()
|
|
defer os.Remove(tmpFile.Name())
|
|
|
|
_, err = setUpCryptoservices(
|
|
configure(fmt.Sprintf(
|
|
`{"storage": {"backend": "%s", "db_url": "%s"}}`,
|
|
notary.SqliteBackend, tmpFile.Name())),
|
|
[]string{notary.SqliteBackend})
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "must provide a default alias for the key DB")
|
|
}
|
|
|
|
// If a default alias *is* provided to a valid DB backend, a valid
|
|
// CryptoService is returned. (This depends on ParseStorage, which is tested
|
|
// separately, so this doesn't test all the possible cases of storage
|
|
// success/failure).
|
|
func TestSetupCryptoServicesDBStoreSuccess(t *testing.T) {
|
|
tmpFile, err := ioutil.TempFile("/tmp", "sqlite3")
|
|
require.NoError(t, err)
|
|
tmpFile.Close()
|
|
defer os.Remove(tmpFile.Name())
|
|
|
|
// Ensure that the private_key table exists
|
|
db, err := gorm.Open("sqlite3", tmpFile.Name())
|
|
require.NoError(t, err)
|
|
var (
|
|
gormKey = keydbstore.GormPrivateKey{}
|
|
count int
|
|
)
|
|
db.CreateTable(&gormKey)
|
|
db.Model(&gormKey).Count(&count)
|
|
require.Equal(t, 0, count)
|
|
|
|
cryptoServices, err := setUpCryptoservices(
|
|
configure(fmt.Sprintf(
|
|
`{"storage": {"backend": "%s", "db_url": "%s"},
|
|
"default_alias": "timestamp"}`,
|
|
notary.SqliteBackend, tmpFile.Name())),
|
|
[]string{notary.SqliteBackend})
|
|
require.NoError(t, err)
|
|
require.Len(t, cryptoServices, 2)
|
|
|
|
edService, ok := cryptoServices[data.ED25519Key]
|
|
require.True(t, ok)
|
|
|
|
ecService, ok := cryptoServices[data.ECDSAKey]
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, edService, ecService)
|
|
|
|
// since the keystores are not exposed by CryptoService, try creating
|
|
// a key and seeing if it is in the sqlite DB.
|
|
os.Setenv("NOTARY_SIGNER_TIMESTAMP", "password")
|
|
defer os.Unsetenv("NOTARY_SIGNER_TIMESTAMP")
|
|
|
|
_, err = ecService.Create("timestamp", "", data.ECDSAKey)
|
|
require.NoError(t, err)
|
|
db.Model(&gormKey).Count(&count)
|
|
require.Equal(t, 1, count)
|
|
}
|
|
|
|
// If a memory backend is specified, then a default alias is not needed, and
|
|
// a valid CryptoService is returned.
|
|
func TestSetupCryptoServicesMemoryStore(t *testing.T) {
|
|
config := configure(fmt.Sprintf(`{"storage": {"backend": "%s"}}`,
|
|
notary.MemoryBackend))
|
|
cryptoServices, err := setUpCryptoservices(config,
|
|
[]string{notary.SqliteBackend, notary.MemoryBackend})
|
|
require.NoError(t, err)
|
|
require.Len(t, cryptoServices, 2)
|
|
|
|
edService, ok := cryptoServices[data.ED25519Key]
|
|
require.True(t, ok)
|
|
|
|
ecService, ok := cryptoServices[data.ECDSAKey]
|
|
require.True(t, ok)
|
|
|
|
require.Equal(t, edService, ecService)
|
|
|
|
// since the keystores are not exposed by CryptoService, try creating
|
|
// and getting the key
|
|
pubKey, err := ecService.Create("", "", data.ECDSAKey)
|
|
require.NoError(t, err)
|
|
privKey, _, err := ecService.GetPrivateKey(pubKey.ID())
|
|
require.NoError(t, err)
|
|
require.NotNil(t, privKey)
|
|
}
|
|
|
|
func TestSetupHTTPServer(t *testing.T) {
|
|
httpServer := setupHTTPServer(":4443", nil, make(signer.CryptoServiceIndex))
|
|
require.Equal(t, ":4443", httpServer.Addr)
|
|
require.Nil(t, httpServer.TLSConfig)
|
|
}
|
|
|
|
func TestSetupGRPCServerInvalidAddress(t *testing.T) {
|
|
_, _, err := setupGRPCServer("nope", nil, make(signer.CryptoServiceIndex))
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "grpc server failed to listen on nope")
|
|
}
|
|
|
|
func TestSetupGRPCServerSuccess(t *testing.T) {
|
|
tlsConf := tls.Config{InsecureSkipVerify: true}
|
|
grpcServer, lis, err := setupGRPCServer(":7899", &tlsConf,
|
|
make(signer.CryptoServiceIndex))
|
|
defer lis.Close()
|
|
require.NoError(t, err)
|
|
require.Equal(t, "[::]:7899", lis.Addr().String())
|
|
require.Equal(t, "tcp", lis.Addr().Network())
|
|
require.NotNil(t, grpcServer)
|
|
}
|