Skip to content
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

Detect Vault 1.11+ import in secondary datacenters and update default issuer #15661

Merged
merged 9 commits into from
Dec 5, 2022

Conversation

rboyer
Copy link
Member

@rboyer rboyer commented Dec 2, 2022

Description

The fix outlined and merged in #15253 fixed the issue as it occurs in the primary DC. There is a similar issue that arises when vault is used as the Connect CA in a secondary datacenter that is fixed by this PR.

Additionally: this PR adds support to run the existing suite of vault related integration tests against the last 4 versions of vault (1.9, 1.10, 1.11, 1.12)

@rboyer rboyer added the theme/consul-vault Relating to Consul & Vault interactions label Dec 2, 2022
@rboyer rboyer self-assigned this Dec 2, 2022
@github-actions github-actions bot added theme/connect Anything related to Consul Connect, Service Mesh, Side Car Proxies type/ci Relating to continuous integration (CI) tooling for testing or releases labels Dec 2, 2022
//
// The second return value is an opaque string meant to be passed back to
// the subsequent call to SetIntermediate.
GenerateIntermediateCSR() (string, string, error)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the vault provider we needed a way to pass extra data from the GenerateIntermediateCSR step to the SetIntermediate step so an extra output/input pair was setup to thread an opaque string through.

The vault provider will pass a keyId.

@@ -924,6 +924,76 @@ func TestVaultCAProvider_GenerateIntermediate(t *testing.T) {
require.NotEqual(t, orig, new)
}

func TestVaultCAProvider_GenerateIntermediate_inSecondary(t *testing.T) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mirror of the test added in #15253 to validate the primary side of the bug.

buf.WriteString(lib.EnsureTrailingNewline(rootPEM))
buf.WriteString(lib.EnsureTrailingNewline(cert))
if !strings.Contains(strings.TrimSpace(cert), strings.TrimSpace(rootPEM)) {
// Vault < v1.11 included the root in the output of sign-intermediate.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: this needed to be done to get the tests that depend on this to properly pass on vault 1.11+

@@ -1052,7 +1052,7 @@ func (c *CAManager) primaryRenewIntermediate(provider ca.Provider, newActiveRoot
// provider.
// Should only be called while the state lock is held by setting the state to non-ready.
func (c *CAManager) secondaryRequestNewSigningCert(provider ca.Provider, newActiveRoot *structs.CARoot) error {
csr, err := provider.GenerateIntermediateCSR()
csr, opaque, err := provider.GenerateIntermediateCSR()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we see the actual data ferrying from one to the other.

"certificate": intermediatePEM,
})
if err != nil {
return err
}

// Vault 1.11+ will return a non-nil response from intermediate/set-signed
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is lifted verbatim from the former fix.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we wrap this shared bit of code in a common for DRYness?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That already is in setDefaultIntermediateIssuer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah when I was refactoring setDefaultIntermediateIssuer I thought about bringing the nil check inside the function. I concluded that it's more useful to be explicitly loud about some behavioural assumptions than to call setDefaultIntermediateIssuer for all versions but secretly have it be a no-op for some versions.

# run integration tests for the connect ca providers
test-connect-ca-providers:
# run integration tests for the connect ca providers with vault
vault-integration-test:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new name is more right than the former name given what the make target does:

test-connect-ca-providers:
ifeq ("$(CIRCLECI)","true")
# Run in CI
	gotestsum --format=short-verbose --junitfile "$(TEST_RESULTS_DIR)/gotestsum-report.xml" -- -cover -coverprofile=coverage.txt ./agent/connect/ca
# Run leader tests that require Vault
	gotestsum --format=short-verbose --junitfile "$(TEST_RESULTS_DIR)/gotestsum-report-leader.xml" -- -cover -coverprofile=coverage-leader.txt -run Vault ./agent/consul
# Run agent tests that require Vault
	gotestsum --format=short-verbose --junitfile "$(TEST_RESULTS_DIR)/gotestsum-report-agent.xml" -- -cover -coverprofile=coverage-agent.txt -run Vault ./agent
else
# Run locally
	@echo "Running /agent/connect/ca tests in verbose mode"
	@go test -v ./agent/connect/ca
	@go test -v ./agent/consul -run Vault
	@go test -v ./agent -run Vault
endif

@rboyer rboyer marked this pull request as ready for review December 2, 2022 21:37
@@ -1067,7 +1077,6 @@ workflows:
name: "lint-32bit"
go-arch: "386"
<<: *filter-ignore-non-go-branches
- test-connect-ca-providers: *filter-ignore-non-go-branches
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it to live with the other integrations.

@@ -75,6 +75,8 @@ type AWSProvider struct {
logger hclog.Logger
}

var _ Provider = (*AWSProvider)(nil)
Copy link
Contributor

@jkirschner-hashicorp jkirschner-hashicorp Dec 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this change was added to all 3 providers. What is the consequence of this change? (Why initialize a nil pointer to a Provider?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a compile-time no-op type assertion so a failure to make the provider match the Provider interface fails in the definition of the struct not when you try to use it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah - that's really cool!

Copy link
Contributor

@kisunji kisunji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope the Vault CI changes backport well 🤞

agent/connect/ca/provider_vault_test.go Show resolved Hide resolved
agent/connect/ca/provider_vault_test.go Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr/no-metrics-test theme/connect Anything related to Consul Connect, Service Mesh, Side Car Proxies theme/consul-vault Relating to Consul & Vault interactions type/ci Relating to continuous integration (CI) tooling for testing or releases
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants