Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions config/http_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1476,18 +1476,15 @@ func (t *tlsRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
rt := t.rt
t.mtx.RUnlock()
if equal {
// The CA cert hasn't changed, use the existing RoundTripper.
// The TLS materials (CA, cert, key) haven't changed, use the existing RoundTripper.
return rt.RoundTrip(req)
}

// Create a new RoundTripper.
// The cert and key files are read separately by the client
// using GetClientCertificate.
tlsConfig := t.tlsConfig.Clone()
if !updateRootCA(tlsConfig, caData) {
if t.settings.CA == nil {
return nil, errors.New("unable to use specified CA cert: none configured")
}
if t.settings.CA != nil && !updateRootCA(tlsConfig, caData) {
return nil, fmt.Errorf("unable to use specified CA cert %s", t.settings.CA.Description())
}
rt, err = t.newRT(tlsConfig)
Expand Down
24 changes: 15 additions & 9 deletions config/http_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2064,11 +2064,13 @@ func TestModifyTLSCertificates(t *testing.T) {
}
}

// TestTLSRoundTripper_NoCAConfigured verifies that client cert rotation works
// when no ca_file is configured. Regression test for prometheus/prometheus#16622.
func TestTLSRoundTripper_NoCAConfigured(t *testing.T) {
bs := getCertificateBlobs(t)

tmpDir, err := os.MkdirTemp("", "tlspanic")
require.NoErrorf(t, err, "Failed to create tmp dir")
tmpDir, err := os.MkdirTemp("", "tlsnocacert")
require.NoError(t, err)
defer os.RemoveAll(tmpDir)
cert, key := filepath.Join(tmpDir, "cert"), filepath.Join(tmpDir, "key")

Expand All @@ -2090,20 +2092,24 @@ func TestTLSRoundTripper_NoCAConfigured(t *testing.T) {
writeCertificate(bs, ClientCertificatePath, cert)
writeCertificate(bs, ClientKeyNoPassPath, key)
c, err := NewClientFromConfig(cfg, "test")
require.NoErrorf(t, err, "Error creating HTTP Client: %v", err)
require.NoError(t, err)

req, err := http.NewRequest(http.MethodGet, testServer.URL, nil)
require.NoErrorf(t, err, "Error creating HTTP request: %v", err)
require.NoError(t, err)

r, err := c.Do(req)
require.NoErrorf(t, err, "Can't connect to the test server")
require.NoErrorf(t, err, "request should succeed before cert rotation")
r.Body.Close()

err = os.WriteFile(cert, []byte("-----BEGIN GARBAGE-----\nabc\n-----END GARBAGE-----\n"), 0o664)
require.NoError(t, err)
// Rotate the cert/key files to different (but still valid) certs.
// Tthe next RoundTrip should rebuild the transport.
writeCertificate(bs, ServerCertificatePath, cert)
writeCertificate(bs, ServerKeyPath, key)

_, err = c.Do(req)
require.ErrorContainsf(t, err, "unable to use specified CA cert: none configured", "Expected error to mention missing CA cert")
// The request still succeeds after cert rotation.
r, err = c.Do(req)
require.NoErrorf(t, err, "request should succeed after cert rotation without ca_file")
r.Body.Close()
}

// loadHTTPConfigJSON parses the JSON input s into a HTTPClientConfig.
Expand Down
Loading