-
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
Setup intermediate_pki_path on secondary #8001
Merged
hanshasselberg
merged 1 commit into
master
from
connect_secondary_vault_setupintermediate
Jun 5, 2020
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,11 +21,12 @@ var ErrBackendNotMounted = fmt.Errorf("backend not mounted") | |
var ErrBackendNotInitialized = fmt.Errorf("backend not initialized") | ||
|
||
type VaultProvider struct { | ||
config *structs.VaultCAProviderConfig | ||
client *vaultapi.Client | ||
isPrimary bool | ||
clusterID string | ||
spiffeID *connect.SpiffeIDSigning | ||
config *structs.VaultCAProviderConfig | ||
client *vaultapi.Client | ||
isPrimary bool | ||
clusterID string | ||
spiffeID *connect.SpiffeIDSigning | ||
setupIntermediatePKIPathDone bool | ||
} | ||
|
||
func vaultTLSConfig(config *structs.VaultCAProviderConfig) *vaultapi.TLSConfig { | ||
|
@@ -137,10 +138,13 @@ func (v *VaultProvider) GenerateIntermediateCSR() (string, error) { | |
return v.generateIntermediateCSR() | ||
} | ||
|
||
func (v *VaultProvider) generateIntermediateCSR() (string, error) { | ||
func (v *VaultProvider) setupIntermediatePKIPath() error { | ||
if v.setupIntermediatePKIPathDone { | ||
return nil | ||
} | ||
mounts, err := v.client.Sys().ListMounts() | ||
if err != nil { | ||
return "", err | ||
return err | ||
} | ||
|
||
// Mount the backend if it isn't mounted already. | ||
|
@@ -154,15 +158,15 @@ func (v *VaultProvider) generateIntermediateCSR() (string, error) { | |
}) | ||
|
||
if err != nil { | ||
return "", err | ||
return err | ||
} | ||
} | ||
|
||
// Create the role for issuing leaf certs if it doesn't exist yet | ||
rolePath := v.config.IntermediatePKIPath + "roles/" + VaultCALeafCertRole | ||
role, err := v.client.Logical().Read(rolePath) | ||
if err != nil { | ||
return "", err | ||
return err | ||
} | ||
if role == nil { | ||
_, err := v.client.Logical().Write(rolePath, map[string]interface{}{ | ||
|
@@ -174,9 +178,18 @@ func (v *VaultProvider) generateIntermediateCSR() (string, error) { | |
"require_cn": false, | ||
}) | ||
if err != nil { | ||
return "", err | ||
return err | ||
} | ||
} | ||
v.setupIntermediatePKIPathDone = true | ||
return nil | ||
} | ||
|
||
func (v *VaultProvider) generateIntermediateCSR() (string, error) { | ||
err := v.setupIntermediatePKIPath() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
// Generate a new intermediate CSR for the root to sign. | ||
uid, err := connect.CompactUID() | ||
|
@@ -231,7 +244,22 @@ func (v *VaultProvider) SetIntermediate(intermediatePEM, rootPEM string) error { | |
|
||
// ActiveIntermediate returns the current intermediate certificate. | ||
func (v *VaultProvider) ActiveIntermediate() (string, error) { | ||
return v.getCA(v.config.IntermediatePKIPath) | ||
if err := v.setupIntermediatePKIPath(); err != nil { | ||
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. Not sure it is the best way to make sure everything is setup in here, but I didn't find a better place. Using |
||
return "", err | ||
} | ||
|
||
cert, err := v.getCA(v.config.IntermediatePKIPath) | ||
|
||
// This error is expected when calling initializeSecondaryCA for the | ||
// first time. It means that the backend is mounted and ready, but | ||
// there is no intermediate. | ||
// This error is swallowed because there is nothing the caller can do | ||
// about it. The caller needs to handle the empty cert though and | ||
// create an intermediate CA. | ||
if err == ErrBackendNotInitialized { | ||
return "", nil | ||
} | ||
return cert, err | ||
} | ||
|
||
// getCA returns the raw CA cert for the given endpoint if there is one. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Does this need a mutex or is it only accessed by a single goroutine?
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.
There are two different flows.
The leader in the primary dc calls this the first time in
initializeRootCA
while holdingcaProviderReconfigurationLock
:consul/agent/consul/leader_connect.go
Lines 262 to 266 in ad7fb3a
The leader in a secondary dc calls this the first time in
initializeSecondaryCA
while holdingcaProviderReconfigurationLock
:consul/agent/consul/leader_connect.go
Lines 346 to 349 in ad7fb3a
An error will prevent the initialization to move on and and it will be retried later. I think this is safe to do. However I considered using
atomic
just to make sure we don't shoot our foot in case the other code changes.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.
Sounds good.