mirror of
https://github.com/kemko/nomad.git
synced 2026-01-04 01:15:43 +03:00
Merge pull request #4046 from hashicorp/tls-same-file-reload
Check file contents when determining if agent should reload TLS confi…
This commit is contained in:
@@ -784,7 +784,11 @@ func (a *Agent) ShouldReload(newConfig *Config) (agent, http, rpc bool) {
|
||||
a.configLock.Lock()
|
||||
defer a.configLock.Unlock()
|
||||
|
||||
if !a.config.TLSConfig.CertificateInfoIsEqual(newConfig.TLSConfig) {
|
||||
isEqual, err := a.config.TLSConfig.CertificateInfoIsEqual(newConfig.TLSConfig)
|
||||
if err != nil {
|
||||
a.logger.Printf("[INFO] agent: error when parsing TLS certificate %v", err)
|
||||
return false, false, false
|
||||
} else if !isEqual {
|
||||
return true, true, true
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -743,19 +744,6 @@ func TestServer_ShouldReload_ReturnFalseForNoChanges(t *testing.T) {
|
||||
dir := tmpDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
logger := log.New(ioutil.Discard, "", 0)
|
||||
|
||||
agentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
},
|
||||
}
|
||||
|
||||
sameAgentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
@@ -767,10 +755,17 @@ func TestServer_ShouldReload_ReturnFalseForNoChanges(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
agent := &Agent{
|
||||
logger: logger,
|
||||
config: agentConfig,
|
||||
}
|
||||
agent := NewTestAgent(t, t.Name(), func(c *Config) {
|
||||
c.TLSConfig = &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
})
|
||||
defer agent.Shutdown()
|
||||
|
||||
shouldReloadAgent, shouldReloadHTTP, shouldReloadRPC := agent.ShouldReload(sameAgentConfig)
|
||||
assert.False(shouldReloadAgent)
|
||||
@@ -790,9 +785,7 @@ func TestServer_ShouldReload_ReturnTrueForOnlyHTTPChanges(t *testing.T) {
|
||||
dir := tmpDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
logger := log.New(ioutil.Discard, "", 0)
|
||||
|
||||
agentConfig := &Config{
|
||||
sameAgentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
EnableHTTP: false,
|
||||
EnableRPC: true,
|
||||
@@ -803,21 +796,17 @@ func TestServer_ShouldReload_ReturnTrueForOnlyHTTPChanges(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
sameAgentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
agent := NewTestAgent(t, t.Name(), func(c *Config) {
|
||||
c.TLSConfig = &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
},
|
||||
}
|
||||
|
||||
agent := &Agent{
|
||||
logger: logger,
|
||||
config: agentConfig,
|
||||
}
|
||||
}
|
||||
})
|
||||
defer agent.Shutdown()
|
||||
|
||||
shouldReloadAgent, shouldReloadHTTP, shouldReloadRPC := agent.ShouldReload(sameAgentConfig)
|
||||
require.True(shouldReloadAgent)
|
||||
@@ -837,19 +826,6 @@ func TestServer_ShouldReload_ReturnTrueForOnlyRPCChanges(t *testing.T) {
|
||||
dir := tmpDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
logger := log.New(ioutil.Discard, "", 0)
|
||||
|
||||
agentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: false,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
},
|
||||
}
|
||||
|
||||
sameAgentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
@@ -861,10 +837,17 @@ func TestServer_ShouldReload_ReturnTrueForOnlyRPCChanges(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
agent := &Agent{
|
||||
logger: logger,
|
||||
config: agentConfig,
|
||||
}
|
||||
agent := NewTestAgent(t, t.Name(), func(c *Config) {
|
||||
c.TLSConfig = &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: false,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
})
|
||||
defer agent.Shutdown()
|
||||
|
||||
shouldReloadAgent, shouldReloadHTTP, shouldReloadRPC := agent.ShouldReload(sameAgentConfig)
|
||||
assert.True(shouldReloadAgent)
|
||||
@@ -880,24 +863,23 @@ func TestServer_ShouldReload_ReturnTrueForConfigChanges(t *testing.T) {
|
||||
cafile = "../../helper/tlsutil/testdata/ca.pem"
|
||||
foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
|
||||
fookey = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
|
||||
foocert2 = "any_cert_path"
|
||||
fookey2 = "any_key_path"
|
||||
foocert2 = "../../helper/tlsutil/testdata/nomad-bad.pem"
|
||||
fookey2 = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
|
||||
)
|
||||
dir := tmpDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
logger := log.New(ioutil.Discard, "", 0)
|
||||
|
||||
agentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
agent := NewTestAgent(t, t.Name(), func(c *Config) {
|
||||
c.TLSConfig = &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
defer agent.Shutdown()
|
||||
|
||||
newConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
@@ -910,13 +892,168 @@ func TestServer_ShouldReload_ReturnTrueForConfigChanges(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
agent := &Agent{
|
||||
logger: logger,
|
||||
config: agentConfig,
|
||||
}
|
||||
|
||||
shouldReloadAgent, shouldReloadHTTP, shouldReloadRPC := agent.ShouldReload(newConfig)
|
||||
assert.True(shouldReloadAgent)
|
||||
assert.True(shouldReloadHTTP)
|
||||
assert.True(shouldReloadRPC)
|
||||
}
|
||||
|
||||
func TestServer_ShouldReload_ReturnTrueForFileChanges(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
|
||||
oldCertificate := `
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICrzCCAlagAwIBAgIUN+4rYZ6wqQCIBzYYd0sfX2e8hDowCgYIKoZIzj0EAwIw
|
||||
eDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
|
||||
biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx
|
||||
GDAWBgNVBAMTD25vbWFkLmhhc2hpY29ycDAgFw0xNjExMTAxOTU2MDBaGA8yMTE2
|
||||
MTAxNzE5NTYwMFoweDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
|
||||
FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwG
|
||||
A1UECxMFTm9tYWQxGDAWBgNVBAMTD3JlZ2lvbkZvby5ub21hZDBZMBMGByqGSM49
|
||||
AgEGCCqGSM49AwEHA0IABOqGSFNjm+EBlLYlxmIP6SQTdX8U/6hbPWObB0ffkEO/
|
||||
CFweeYIVWb3FKNPqYAlhMqg1K0ileD0FbhEzarP0sL6jgbswgbgwDgYDVR0PAQH/
|
||||
BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8E
|
||||
AjAAMB0GA1UdDgQWBBQnMcjU4yI3k0AoMtapACpO+w9QMTAfBgNVHSMEGDAWgBQ6
|
||||
NWr8F5y2eFwqfoQdQPg0kWb9QDA5BgNVHREEMjAwghZzZXJ2ZXIucmVnaW9uRm9v
|
||||
Lm5vbWFkghZjbGllbnQucmVnaW9uRm9vLm5vbWFkMAoGCCqGSM49BAMCA0cAMEQC
|
||||
ICrvzc5NzqhdT/HkazAx5OOUU8hqoptnmhRmwn6X+0y9AiA8bNvMUxHz3ZLjGBiw
|
||||
PLBDC2UaSDqJqiiYpYegLhbQtw==
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
content := []byte(oldCertificate)
|
||||
dir, err := ioutil.TempDir("", "certificate")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir) // clean up
|
||||
|
||||
tmpfn := filepath.Join(dir, "testcert")
|
||||
err = ioutil.WriteFile(tmpfn, content, 0666)
|
||||
require.Nil(err)
|
||||
|
||||
const (
|
||||
cafile = "../../helper/tlsutil/testdata/ca.pem"
|
||||
key = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
|
||||
)
|
||||
|
||||
logger := log.New(ioutil.Discard, "", 0)
|
||||
|
||||
agentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: tmpfn,
|
||||
KeyFile: key,
|
||||
},
|
||||
}
|
||||
|
||||
agent := &Agent{
|
||||
logger: logger,
|
||||
config: agentConfig,
|
||||
}
|
||||
agent.config.TLSConfig.SetChecksum()
|
||||
|
||||
shouldReloadAgent, shouldReloadHTTP, shouldReloadRPC := agent.ShouldReload(agentConfig)
|
||||
require.False(shouldReloadAgent)
|
||||
require.False(shouldReloadHTTP)
|
||||
require.False(shouldReloadRPC)
|
||||
|
||||
newCertificate := `
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICtTCCAlqgAwIBAgIUQp/L2szbgE4b1ASlPOZMReFE27owCgYIKoZIzj0EAwIw
|
||||
fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
|
||||
biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx
|
||||
HDAaBgNVBAMTE2JhZC5ub21hZC5oYXNoaWNvcnAwIBcNMTYxMTEwMjAxMDAwWhgP
|
||||
MjExNjEwMTcyMDEwMDBaMHgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
|
||||
bmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKEwlIYXNoaUNvcnAx
|
||||
DjAMBgNVBAsTBU5vbWFkMRgwFgYDVQQDEw9yZWdpb25CYWQubm9tYWQwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAAQk6oXJwlxNrKvl6kpeeR4NJc5EYFI2b3y7odjY
|
||||
u55Jp4sI91JVDqnpyatkyGmavdAWa4t0U6HkeaWqKk16/ZcYo4G7MIG4MA4GA1Ud
|
||||
DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T
|
||||
AQH/BAIwADAdBgNVHQ4EFgQUxhzOftFR2L0QAPx8LOuP99WPbpgwHwYDVR0jBBgw
|
||||
FoAUHPDLSgzlHqBEh+c4A7HeT0GWygIwOQYDVR0RBDIwMIIWc2VydmVyLnJlZ2lv
|
||||
bkJhZC5ub21hZIIWY2xpZW50LnJlZ2lvbkJhZC5ub21hZDAKBggqhkjOPQQDAgNJ
|
||||
ADBGAiEAq2rnBeX/St/8i9Cab7Yw0C7pjcaE+mrFYeQByng1Uc0CIQD/o4BrZdkX
|
||||
Nm7QGTRZbUFZTHYZr0ULz08Iaz2aHQ6Mcw==
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
os.Remove(tmpfn)
|
||||
err = ioutil.WriteFile(tmpfn, []byte(newCertificate), 0666)
|
||||
require.Nil(err)
|
||||
|
||||
newAgentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: tmpfn,
|
||||
KeyFile: key,
|
||||
},
|
||||
}
|
||||
|
||||
shouldReloadAgent, shouldReloadHTTP, shouldReloadRPC = agent.ShouldReload(newAgentConfig)
|
||||
require.True(shouldReloadAgent)
|
||||
require.True(shouldReloadHTTP)
|
||||
require.True(shouldReloadRPC)
|
||||
}
|
||||
|
||||
func TestServer_ShouldReload_ShouldHandleMultipleChanges(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
|
||||
const (
|
||||
cafile = "../../helper/tlsutil/testdata/ca.pem"
|
||||
foocert = "../../helper/tlsutil/testdata/nomad-foo.pem"
|
||||
fookey = "../../helper/tlsutil/testdata/nomad-foo-key.pem"
|
||||
foocert2 = "../../helper/tlsutil/testdata/nomad-bad.pem"
|
||||
fookey2 = "../../helper/tlsutil/testdata/nomad-bad-key.pem"
|
||||
)
|
||||
dir := tmpDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
sameAgentConfig := &Config{
|
||||
TLSConfig: &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
},
|
||||
}
|
||||
|
||||
agent := NewTestAgent(t, t.Name(), func(c *Config) {
|
||||
c.TLSConfig = &sconfig.TLSConfig{
|
||||
EnableHTTP: true,
|
||||
EnableRPC: true,
|
||||
VerifyServerHostname: true,
|
||||
CAFile: cafile,
|
||||
CertFile: foocert2,
|
||||
KeyFile: fookey2,
|
||||
}
|
||||
})
|
||||
defer agent.Shutdown()
|
||||
|
||||
{
|
||||
shouldReloadAgent, shouldReloadHTTP, shouldReloadRPC := agent.ShouldReload(sameAgentConfig)
|
||||
require.True(shouldReloadAgent)
|
||||
require.True(shouldReloadHTTP)
|
||||
require.True(shouldReloadRPC)
|
||||
}
|
||||
|
||||
err := agent.Reload(sameAgentConfig)
|
||||
require.Nil(err)
|
||||
|
||||
{
|
||||
shouldReloadAgent, shouldReloadHTTP, shouldReloadRPC := agent.ShouldReload(sameAgentConfig)
|
||||
require.False(shouldReloadAgent)
|
||||
require.False(shouldReloadHTTP)
|
||||
require.False(shouldReloadRPC)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,6 +321,15 @@ func (c *Command) readConfig() *Config {
|
||||
c.Ui.Error("WARNING: Bootstrap mode enabled! Potentially unsafe operation.")
|
||||
}
|
||||
|
||||
// Set up the TLS configuration properly if we have one.
|
||||
// XXX chelseakomlo: set up a TLSConfig New method which would wrap
|
||||
// constructor-type actions like this.
|
||||
if config.TLSConfig != nil && !config.TLSConfig.IsEmpty() {
|
||||
if err := config.TLSConfig.SetChecksum(); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("WARNING: Error when parsing TLS configuration: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
|
||||
@@ -665,7 +665,13 @@ func (s *Server) Reload(newConfig *Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
if !newConfig.TLSConfig.CertificateInfoIsEqual(s.config.TLSConfig) || newConfig.TLSConfig.EnableRPC != s.config.TLSConfig.EnableRPC {
|
||||
tlsInfoEqual, err := newConfig.TLSConfig.CertificateInfoIsEqual(s.config.TLSConfig)
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERR] nomad: error parsing server TLS configuration: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !tlsInfoEqual || newConfig.TLSConfig.EnableRPC != s.config.TLSConfig.EnableRPC {
|
||||
if err := s.reloadTLSConnections(newConfig.TLSConfig); err != nil {
|
||||
s.logger.Printf("[ERR] nomad: error reloading server TLS configuration: %s", err)
|
||||
multierror.Append(&mErr, err)
|
||||
|
||||
@@ -427,6 +427,7 @@ func TestServer_Reload_TLSConnections_PlaintextToTLS_OnlyRPC(t *testing.T) {
|
||||
|
||||
err := s1.reloadTLSConnections(newTLSConfig)
|
||||
assert.Nil(err)
|
||||
assert.True(s1.config.TLSConfig.EnableRPC)
|
||||
assert.True(s1.config.TLSConfig.CertificateInfoIsEqual(newTLSConfig))
|
||||
|
||||
codec := rpcClient(t, s1)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -47,6 +51,10 @@ type TLSConfig struct {
|
||||
|
||||
// Verify connections to the HTTPS API
|
||||
VerifyHTTPSClient bool `mapstructure:"verify_https_client"`
|
||||
|
||||
// Checksum is a MD5 hash of the certificate CA File, Certificate file, and
|
||||
// key file.
|
||||
Checksum string
|
||||
}
|
||||
|
||||
type KeyLoader struct {
|
||||
@@ -138,6 +146,9 @@ func (t *TLSConfig) Copy() *TLSConfig {
|
||||
new.KeyFile = t.KeyFile
|
||||
new.RPCUpgradeMode = t.RPCUpgradeMode
|
||||
new.VerifyHTTPSClient = t.VerifyHTTPSClient
|
||||
|
||||
new.SetChecksum()
|
||||
|
||||
return new
|
||||
}
|
||||
|
||||
@@ -191,12 +202,72 @@ func (t *TLSConfig) Merge(b *TLSConfig) *TLSConfig {
|
||||
// It is possible for either the calling TLSConfig to be nil, or the TLSConfig
|
||||
// that it is being compared against, so we need to handle both places. See
|
||||
// server.go Reload for example.
|
||||
func (t *TLSConfig) CertificateInfoIsEqual(newConfig *TLSConfig) bool {
|
||||
func (t *TLSConfig) CertificateInfoIsEqual(newConfig *TLSConfig) (bool, error) {
|
||||
if t == nil || newConfig == nil {
|
||||
return t == newConfig
|
||||
return t == newConfig, nil
|
||||
}
|
||||
|
||||
return t.CAFile == newConfig.CAFile &&
|
||||
t.CertFile == newConfig.CertFile &&
|
||||
t.KeyFile == newConfig.KeyFile
|
||||
if t.IsEmpty() && newConfig.IsEmpty() {
|
||||
return true, nil
|
||||
} else if t.IsEmpty() || newConfig.IsEmpty() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Set the checksum if it hasn't yet been set (this should happen when the
|
||||
// config is parsed but this provides safety in depth)
|
||||
if newConfig.Checksum == "" {
|
||||
err := newConfig.SetChecksum()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
if t.Checksum == "" {
|
||||
err := t.SetChecksum()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
return t.Checksum == newConfig.Checksum, nil
|
||||
}
|
||||
|
||||
// SetChecksum generates and sets the checksum for a TLS configuration
|
||||
func (t *TLSConfig) SetChecksum() error {
|
||||
newCertChecksum, err := createChecksumOfFiles(t.CAFile, t.CertFile, t.KeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Checksum = newCertChecksum
|
||||
return nil
|
||||
}
|
||||
|
||||
func getFileChecksum(filepath string) (string, error) {
|
||||
f, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
h := md5.New()
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
}
|
||||
|
||||
func createChecksumOfFiles(inputs ...string) (string, error) {
|
||||
h := md5.New()
|
||||
|
||||
for _, input := range inputs {
|
||||
checksum, err := getFileChecksum(input)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
io.WriteString(h, checksum)
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTLSConfig_Merge(t *testing.T) {
|
||||
@@ -27,37 +28,191 @@ func TestTLSConfig_Merge(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTLS_CertificateInfoIsEqual_TrueWhenEmpty(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
a := &TLSConfig{}
|
||||
b := &TLSConfig{}
|
||||
assert.True(a.CertificateInfoIsEqual(b))
|
||||
isEqual, err := a.CertificateInfoIsEqual(b)
|
||||
require.Nil(err)
|
||||
require.True(isEqual)
|
||||
}
|
||||
|
||||
func TestTLS_CertificateInfoIsEqual_FalseWhenUnequal(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
a := &TLSConfig{CAFile: "abc", CertFile: "def", KeyFile: "ghi"}
|
||||
b := &TLSConfig{CAFile: "jkl", CertFile: "def", KeyFile: "ghi"}
|
||||
assert.False(a.CertificateInfoIsEqual(b))
|
||||
require := require.New(t)
|
||||
const (
|
||||
cafile = "../../../helper/tlsutil/testdata/ca.pem"
|
||||
foocert = "../../../helper/tlsutil/testdata/nomad-foo.pem"
|
||||
fookey = "../../../helper/tlsutil/testdata/nomad-foo-key.pem"
|
||||
foocert2 = "../../../helper/tlsutil/testdata/nomad-bad.pem"
|
||||
fookey2 = "../../../helper/tlsutil/testdata/nomad-bad-key.pem"
|
||||
)
|
||||
|
||||
// Assert that both mismatching certificate and key files are considered
|
||||
// unequal
|
||||
{
|
||||
a := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
a.SetChecksum()
|
||||
|
||||
b := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert2,
|
||||
KeyFile: fookey2,
|
||||
}
|
||||
isEqual, err := a.CertificateInfoIsEqual(b)
|
||||
require.Nil(err)
|
||||
require.False(isEqual)
|
||||
}
|
||||
|
||||
// Assert that mismatching certificate are considered unequal
|
||||
{
|
||||
a := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
a.SetChecksum()
|
||||
|
||||
b := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert2,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
isEqual, err := a.CertificateInfoIsEqual(b)
|
||||
require.Nil(err)
|
||||
require.False(isEqual)
|
||||
}
|
||||
|
||||
// Assert that mismatching keys are considered unequal
|
||||
{
|
||||
a := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
a.SetChecksum()
|
||||
|
||||
b := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey2,
|
||||
}
|
||||
isEqual, err := a.CertificateInfoIsEqual(b)
|
||||
require.Nil(err)
|
||||
require.False(isEqual)
|
||||
}
|
||||
|
||||
// Assert that mismatching empty types are considered unequal
|
||||
{
|
||||
a := &TLSConfig{}
|
||||
|
||||
b := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey2,
|
||||
}
|
||||
isEqual, err := a.CertificateInfoIsEqual(b)
|
||||
require.Nil(err)
|
||||
require.False(isEqual)
|
||||
}
|
||||
|
||||
// Assert that invalid files return an error
|
||||
{
|
||||
a := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey2,
|
||||
}
|
||||
|
||||
b := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: "invalid_file",
|
||||
KeyFile: fookey2,
|
||||
}
|
||||
isEqual, err := a.CertificateInfoIsEqual(b)
|
||||
require.NotNil(err)
|
||||
require.False(isEqual)
|
||||
}
|
||||
}
|
||||
|
||||
// Certificate info should be equal when the CA file, certificate file, and key
|
||||
// file all are equal
|
||||
func TestTLS_CertificateInfoIsEqual_TrueWhenEqual(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
a := &TLSConfig{CAFile: "abc", CertFile: "def", KeyFile: "ghi"}
|
||||
b := &TLSConfig{CAFile: "abc", CertFile: "def", KeyFile: "ghi"}
|
||||
assert.True(a.CertificateInfoIsEqual(b))
|
||||
require := require.New(t)
|
||||
const (
|
||||
cafile = "../../../helper/tlsutil/testdata/ca.pem"
|
||||
foocert = "../../../helper/tlsutil/testdata/nomad-foo.pem"
|
||||
fookey = "../../../helper/tlsutil/testdata/nomad-foo-key.pem"
|
||||
)
|
||||
a := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
a.SetChecksum()
|
||||
|
||||
b := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
isEqual, err := a.CertificateInfoIsEqual(b)
|
||||
require.Nil(err)
|
||||
require.True(isEqual)
|
||||
}
|
||||
|
||||
func TestTLS_Copy(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
a := &TLSConfig{CAFile: "abc", CertFile: "def", KeyFile: "ghi"}
|
||||
require := require.New(t)
|
||||
const (
|
||||
cafile = "../../../helper/tlsutil/testdata/ca.pem"
|
||||
foocert = "../../../helper/tlsutil/testdata/nomad-foo.pem"
|
||||
fookey = "../../../helper/tlsutil/testdata/nomad-foo-key.pem"
|
||||
)
|
||||
a := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
a.SetChecksum()
|
||||
|
||||
aCopy := a.Copy()
|
||||
assert.True(a.CertificateInfoIsEqual(aCopy))
|
||||
isEqual, err := a.CertificateInfoIsEqual(aCopy)
|
||||
require.Nil(err)
|
||||
require.True(isEqual)
|
||||
}
|
||||
|
||||
// GetKeyLoader should always return an initialized KeyLoader for a TLSConfig
|
||||
// object
|
||||
func TestTLS_GetKeyloader(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
a := &TLSConfig{}
|
||||
assert.NotNil(a.GetKeyLoader())
|
||||
require.NotNil(a.GetKeyLoader())
|
||||
}
|
||||
|
||||
func TestTLS_SetChecksum(t *testing.T) {
|
||||
require := require.New(t)
|
||||
const (
|
||||
cafile = "../../../helper/tlsutil/testdata/ca.pem"
|
||||
foocert = "../../../helper/tlsutil/testdata/nomad-foo.pem"
|
||||
fookey = "../../../helper/tlsutil/testdata/nomad-foo-key.pem"
|
||||
foocert2 = "../../../helper/tlsutil/testdata/nomad-bad.pem"
|
||||
fookey2 = "../../../helper/tlsutil/testdata/nomad-bad-key.pem"
|
||||
)
|
||||
|
||||
a := &TLSConfig{
|
||||
CAFile: cafile,
|
||||
CertFile: foocert,
|
||||
KeyFile: fookey,
|
||||
}
|
||||
a.SetChecksum()
|
||||
oldChecksum := a.Checksum
|
||||
|
||||
a.CertFile = foocert2
|
||||
a.KeyFile = fookey2
|
||||
|
||||
a.SetChecksum()
|
||||
|
||||
require.NotEqual(oldChecksum, a.Checksum)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user