-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
connect: persist intermediate CAs on leader change #4379
Changes from 1 commit
1d3f4b5
462ace4
4e5fb6b
f95c680
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ import ( | |
"github.com/hashicorp/consul/testutil/retry" | ||
"github.com/hashicorp/net-rpc-msgpackrpc" | ||
"github.com/hashicorp/serf/serf" | ||
"github.com/pascaldekloe/goe/verify" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
|
@@ -1064,3 +1065,81 @@ func TestLeader_CARootPruning(t *testing.T) { | |
require.True(roots[0].Active) | ||
require.NotEqual(roots[0].ID, oldRoot.ID) | ||
} | ||
|
||
func TestLeader_PersistIntermediateCAs(t *testing.T) { | ||
t.Parallel() | ||
|
||
require := require.New(t) | ||
dir1, s1 := testServer(t) | ||
defer os.RemoveAll(dir1) | ||
defer s1.Shutdown() | ||
codec := rpcClient(t, s1) | ||
defer codec.Close() | ||
|
||
dir2, s2 := testServerDCBootstrap(t, "dc1", false) | ||
defer os.RemoveAll(dir2) | ||
defer s2.Shutdown() | ||
|
||
dir3, s3 := testServerDCBootstrap(t, "dc1", false) | ||
defer os.RemoveAll(dir3) | ||
defer s3.Shutdown() | ||
|
||
joinLAN(t, s2, s1) | ||
joinLAN(t, s3, s1) | ||
|
||
testrpc.WaitForLeader(t, s1.RPC, "dc1") | ||
|
||
// Get the current root | ||
rootReq := &structs.DCSpecificRequest{ | ||
Datacenter: "dc1", | ||
} | ||
var rootList structs.IndexedCARoots | ||
require.Nil(msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", rootReq, &rootList)) | ||
require.Len(rootList.Roots, 1) | ||
|
||
// Update the provider config to use a new private key, which should | ||
// cause a rotation. | ||
_, newKey, err := connect.GeneratePrivateKey() | ||
require.NoError(err) | ||
newConfig := &structs.CAConfiguration{ | ||
Provider: "consul", | ||
Config: map[string]interface{}{ | ||
"PrivateKey": newKey, | ||
"RootCert": "", | ||
"RotationPeriod": 90 * 24 * time.Hour, | ||
}, | ||
} | ||
{ | ||
args := &structs.CARequest{ | ||
Datacenter: "dc1", | ||
Config: newConfig, | ||
} | ||
var reply interface{} | ||
|
||
require.NoError(msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationSet", args, &reply)) | ||
} | ||
|
||
// Get the active root before leader change. | ||
_, root := s1.getCAProvider() | ||
require.Len(root.IntermediateCerts, 1) | ||
|
||
// Force a leader change and make sure the root CA values are preserved. | ||
s1.Leave() | ||
s1.Shutdown() | ||
|
||
retry.Run(t, func(r *retry.R) { | ||
var leader *Server | ||
for _, s := range []*Server{s2, s3} { | ||
if s.IsLeader() { | ||
leader = s | ||
break | ||
} | ||
} | ||
if leader == nil { | ||
r.Fatal("no leader") | ||
} | ||
|
||
_, newLeaderRoot := leader.getCAProvider() | ||
verify.Values(r, "", root, newLeaderRoot) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this somehow better than Regardless of what we choose, we should decide on which testing helper framework to use and stick with it. I had been encouraged to use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. retry.R doesn't quite satisfy the TestingT interface there - i'll just change this to reflect.DeepEqual instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See discussion on #4379 (comment) |
||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is now misleading - we don't just exit if the CA is already bootstrapped, we still importantly need to load the intermediates into the CA instance.