Skip to content

Commit 18fc46c

Browse files
committed
fix: add registry client TLS connection idle timeout
1 parent 4513fe1 commit 18fc46c

File tree

1 file changed

+57
-11
lines changed

1 file changed

+57
-11
lines changed

internal/helm_client.go

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ package internal
1818

1919
import (
2020
"context"
21+
"crypto/tls"
22+
"crypto/x509"
2123
"fmt"
24+
"net/http"
2225
"net/url"
2326
"os"
2427
"path"
28+
"time"
2529

2630
"github.com/google/go-cmp/cmp"
2731
"github.com/pkg/errors"
@@ -255,21 +259,63 @@ func (c *HelmClient) InstallHelmRelease(ctx context.Context, restConfig *rest.Co
255259

256260
// newDefaultRegistryClient creates registry client object with default config which can be used to install/upgrade helm charts.
257261
func newDefaultRegistryClient(credentialsPath string, enableCache bool, caFilePath string, insecureSkipTLSVerify bool) (*registry.Client, error) {
258-
if caFilePath == "" && !insecureSkipTLSVerify {
259-
opts := []registry.ClientOption{
260-
registry.ClientOptDebug(true),
261-
registry.ClientOptEnableCache(enableCache),
262-
registry.ClientOptWriter(os.Stderr),
263-
}
264-
if credentialsPath != "" {
265-
// Create a new registry client with credentials
266-
opts = append(opts, registry.ClientOptCredentialsFile(credentialsPath))
262+
opts := []registry.ClientOption{
263+
registry.ClientOptDebug(true),
264+
registry.ClientOptEnableCache(enableCache),
265+
registry.ClientOptWriter(os.Stderr),
266+
}
267+
if credentialsPath != "" {
268+
// Create a new registry client with credentials
269+
opts = append(opts, registry.ClientOptCredentialsFile(credentialsPath))
270+
}
271+
272+
if caFilePath != "" || insecureSkipTLSVerify {
273+
tlsConf, err := newClientTLS(caFilePath, insecureSkipTLSVerify)
274+
if err != nil {
275+
return nil, fmt.Errorf("can't create TLS config for client: %s", err)
267276
}
277+
opts = append(opts, registry.ClientOptHTTPClient(&http.Client{
278+
Transport: &http.Transport{
279+
TLSClientConfig: tlsConf,
280+
Proxy: http.ProxyFromEnvironment,
281+
// This registry client is not reused and is discarded after a single reconciliation
282+
// loop. Limit how long can be the idle connection open. Otherwise its possible that
283+
// a registry server that keeps the connection open for a long time could result in
284+
// connections being openend in the controller for a long time.
285+
IdleConnTimeout: 1 * time.Second,
286+
},
287+
}),
288+
)
289+
}
290+
return registry.NewClient(opts...)
291+
}
268292

269-
return registry.NewClient(opts...)
293+
func newClientTLS(caFile string, insecureSkipTLSverify bool) (*tls.Config, error) {
294+
config := tls.Config{
295+
InsecureSkipVerify: insecureSkipTLSverify,
270296
}
271297

272-
return registry.NewRegistryClientWithTLS(os.Stderr, "", "", caFilePath, insecureSkipTLSVerify, credentialsPath, true)
298+
if caFile != "" {
299+
cp, err := certPoolFromFile(caFile)
300+
if err != nil {
301+
return nil, err
302+
}
303+
config.RootCAs = cp
304+
}
305+
306+
return &config, nil
307+
}
308+
309+
func certPoolFromFile(filename string) (*x509.CertPool, error) {
310+
b, err := os.ReadFile(filename)
311+
if err != nil {
312+
return nil, errors.Errorf("can't read CA file: %v", filename)
313+
}
314+
cp := x509.NewCertPool()
315+
if !cp.AppendCertsFromPEM(b) {
316+
return nil, errors.Errorf("failed to append certificates from file: %s", filename)
317+
}
318+
return cp, nil
273319
}
274320

275321
// getHelmChartAndRepoName returns chartName, repoURL as per the format requirred in helm install/upgrade config.

0 commit comments

Comments
 (0)