ca: fix mockCAServerDelegate to work with the new interface
raftApply was removed so ApplyCARequest needs to handle all the possible operations Also set the providerShim to use the mock provider. other changes are small test improvements that were necessary to debug the failures.
This commit is contained in:
parent
6d4b0ce194
commit
68d5f7769a
|
@ -113,23 +113,15 @@ func (c *ConsulProvider) Configure(cfg ProviderConfig) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the provider state to the state store.
|
|
||||||
newState := structs.CAConsulProviderState{
|
|
||||||
ID: c.id,
|
|
||||||
}
|
|
||||||
|
|
||||||
args := &structs.CARequest{
|
args := &structs.CARequest{
|
||||||
Op: structs.CAOpSetProviderState,
|
Op: structs.CAOpSetProviderState,
|
||||||
ProviderState: &newState,
|
ProviderState: &structs.CAConsulProviderState{ID: c.id},
|
||||||
}
|
}
|
||||||
if _, err := c.Delegate.ApplyCARequest(args); err != nil {
|
if _, err := c.Delegate.ApplyCARequest(args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Debug("consul CA provider configured",
|
c.Logger.Debug("consul CA provider configured", "id", c.id, "is_primary", c.isPrimary)
|
||||||
"id", c.id,
|
|
||||||
"is_primary", c.isPrimary,
|
|
||||||
)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,10 @@ type caState string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
caStateUninitialized caState = "UNINITIALIZED"
|
caStateUninitialized caState = "UNINITIALIZED"
|
||||||
caStateInitializing = "INITIALIZING"
|
caStateInitializing caState = "INITIALIZING"
|
||||||
caStateInitialized = "INITIALIZED"
|
caStateInitialized caState = "INITIALIZED"
|
||||||
caStateRenewIntermediate = "RENEWING"
|
caStateRenewIntermediate caState = "RENEWING"
|
||||||
caStateReconfig = "RECONFIGURING"
|
caStateReconfig caState = "RECONFIGURING"
|
||||||
)
|
)
|
||||||
|
|
||||||
// caServerDelegate is an interface for server operations for facilitating
|
// caServerDelegate is an interface for server operations for facilitating
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/serf/serf"
|
"github.com/hashicorp/serf/serf"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/connect"
|
"github.com/hashicorp/consul/agent/connect"
|
||||||
|
@ -61,15 +62,57 @@ func (m *mockCAServerDelegate) CheckServers(datacenter string, fn func(*metadata
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApplyCARequest mirrors FSM.applyConnectCAOperation because that functionality
|
||||||
|
// is not exported.
|
||||||
func (m *mockCAServerDelegate) ApplyCARequest(req *structs.CARequest) (interface{}, error) {
|
func (m *mockCAServerDelegate) ApplyCARequest(req *structs.CARequest) (interface{}, error) {
|
||||||
return ca.ApplyCARequestToStore(m.store, req)
|
idx, _, err := m.store.CAConfig(nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockCAServerDelegate) createCAProvider(conf *structs.CAConfiguration) (ca.Provider, error) {
|
m.callbackCh <- fmt.Sprintf("raftApply/ConnectCA")
|
||||||
return &mockCAProvider{
|
|
||||||
callbackCh: m.callbackCh,
|
switch req.Op {
|
||||||
rootPEM: m.primaryRoot.RootCert,
|
case structs.CAOpSetConfig:
|
||||||
}, nil
|
if req.Config.ModifyIndex != 0 {
|
||||||
|
act, err := m.store.CACheckAndSetConfig(idx+1, req.Config.ModifyIndex, req.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return act, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, m.store.CASetConfig(idx+1, req.Config)
|
||||||
|
case structs.CAOpSetRootsAndConfig:
|
||||||
|
act, err := m.store.CARootSetCAS(idx, req.Index, req.Roots)
|
||||||
|
if err != nil || !act {
|
||||||
|
return act, err
|
||||||
|
}
|
||||||
|
|
||||||
|
act, err = m.store.CACheckAndSetConfig(idx+1, req.Config.ModifyIndex, req.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return act, nil
|
||||||
|
case structs.CAOpSetProviderState:
|
||||||
|
_, err := m.store.CASetProviderState(idx+1, req.ProviderState)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
case structs.CAOpDeleteProviderState:
|
||||||
|
if err := m.store.CADeleteProviderState(idx+1, req.ProviderState.ID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
case structs.CAOpIncrementProviderSerialNumber:
|
||||||
|
return uint64(2), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Invalid CA operation '%s'", req.Op)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockCAServerDelegate) forwardDC(method, dc string, args interface{}, reply interface{}) error {
|
func (m *mockCAServerDelegate) forwardDC(method, dc string, args interface{}, reply interface{}) error {
|
||||||
|
@ -98,23 +141,6 @@ func (m *mockCAServerDelegate) generateCASignRequest(csr string) *structs.CASign
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockCAServerDelegate) raftApply(t structs.MessageType, msg interface{}) (interface{}, error) {
|
|
||||||
if t == structs.ConnectCARequestType {
|
|
||||||
req := msg.(*structs.CARequest)
|
|
||||||
act, err := m.store.CARootSetCAS(1, req.Index, req.Roots)
|
|
||||||
require.NoError(m.t, err)
|
|
||||||
require.True(m.t, act)
|
|
||||||
|
|
||||||
act, err = m.store.CACheckAndSetConfig(1, req.Config.ModifyIndex, req.Config)
|
|
||||||
require.NoError(m.t, err)
|
|
||||||
require.True(m.t, act)
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("got invalid MessageType %v", t)
|
|
||||||
}
|
|
||||||
m.callbackCh <- fmt.Sprintf("raftApply/%s", t)
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// mockCAProvider mocks an empty provider implementation with a channel in order to coordinate
|
// mockCAProvider mocks an empty provider implementation with a channel in order to coordinate
|
||||||
// waiting for certain methods to be called.
|
// waiting for certain methods to be called.
|
||||||
type mockCAProvider struct {
|
type mockCAProvider struct {
|
||||||
|
@ -147,6 +173,7 @@ func (m *mockCAProvider) SupportsCrossSigning() (bool, error)
|
||||||
func (m *mockCAProvider) Cleanup(_ bool, _ map[string]interface{}) error { return nil }
|
func (m *mockCAProvider) Cleanup(_ bool, _ map[string]interface{}) error { return nil }
|
||||||
|
|
||||||
func waitForCh(t *testing.T, ch chan string, expected string) {
|
func waitForCh(t *testing.T, ch chan string, expected string) {
|
||||||
|
t.Helper()
|
||||||
select {
|
select {
|
||||||
case op := <-ch:
|
case op := <-ch:
|
||||||
if op != expected {
|
if op != expected {
|
||||||
|
@ -179,6 +206,7 @@ func testCAConfig() *structs.CAConfiguration {
|
||||||
// initTestManager initializes a CAManager with a mockCAServerDelegate, consuming
|
// initTestManager initializes a CAManager with a mockCAServerDelegate, consuming
|
||||||
// the ops that come through the channels and returning when initialization has finished.
|
// the ops that come through the channels and returning when initialization has finished.
|
||||||
func initTestManager(t *testing.T, manager *CAManager, delegate *mockCAServerDelegate) {
|
func initTestManager(t *testing.T, manager *CAManager, delegate *mockCAServerDelegate) {
|
||||||
|
t.Helper()
|
||||||
initCh := make(chan struct{})
|
initCh := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
require.NoError(t, manager.InitializeCA())
|
require.NoError(t, manager.InitializeCA())
|
||||||
|
@ -209,13 +237,19 @@ func TestCAManager_Initialize(t *testing.T) {
|
||||||
conf.Datacenter = "dc2"
|
conf.Datacenter = "dc2"
|
||||||
delegate := NewMockCAServerDelegate(t, conf)
|
delegate := NewMockCAServerDelegate(t, conf)
|
||||||
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
|
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
|
||||||
|
manager.providerShim = &mockCAProvider{
|
||||||
|
callbackCh: delegate.callbackCh,
|
||||||
|
rootPEM: delegate.primaryRoot.RootCert,
|
||||||
|
}
|
||||||
|
|
||||||
// Call InitializeCA and then confirm the RPCs and provider calls
|
// Call InitializeCA and then confirm the RPCs and provider calls
|
||||||
// happen in the expected order.
|
// happen in the expected order.
|
||||||
require.EqualValues(t, caStateUninitialized, manager.state)
|
require.Equal(t, caStateUninitialized, manager.state)
|
||||||
errCh := make(chan error)
|
errCh := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
errCh <- manager.InitializeCA()
|
err := manager.InitializeCA()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
errCh <- err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
waitForCh(t, delegate.callbackCh, "forwardDC/ConnectCA.Roots")
|
waitForCh(t, delegate.callbackCh, "forwardDC/ConnectCA.Roots")
|
||||||
|
@ -234,7 +268,7 @@ func TestCAManager_Initialize(t *testing.T) {
|
||||||
t.Fatal("never got result from errCh")
|
t.Fatal("never got result from errCh")
|
||||||
}
|
}
|
||||||
|
|
||||||
require.EqualValues(t, caStateInitialized, manager.state)
|
require.Equal(t, caStateInitialized, manager.state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCAManager_UpdateConfigWhileRenewIntermediate(t *testing.T) {
|
func TestCAManager_UpdateConfigWhileRenewIntermediate(t *testing.T) {
|
||||||
|
@ -259,6 +293,10 @@ func TestCAManager_UpdateConfigWhileRenewIntermediate(t *testing.T) {
|
||||||
conf.Datacenter = "dc2"
|
conf.Datacenter = "dc2"
|
||||||
delegate := NewMockCAServerDelegate(t, conf)
|
delegate := NewMockCAServerDelegate(t, conf)
|
||||||
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
|
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
|
||||||
|
manager.providerShim = &mockCAProvider{
|
||||||
|
callbackCh: delegate.callbackCh,
|
||||||
|
rootPEM: delegate.primaryRoot.RootCert,
|
||||||
|
}
|
||||||
initTestManager(t, manager, delegate)
|
initTestManager(t, manager, delegate)
|
||||||
|
|
||||||
// Wait half the TTL for the cert to need renewing.
|
// Wait half the TTL for the cert to need renewing.
|
||||||
|
|
Loading…
Reference in New Issue