@@ -18,10 +18,14 @@ package internal
18
18
19
19
import (
20
20
"context"
21
+ "crypto/tls"
22
+ "crypto/x509"
21
23
"fmt"
24
+ "net/http"
22
25
"net/url"
23
26
"os"
24
27
"path"
28
+ "time"
25
29
26
30
"github.com/google/go-cmp/cmp"
27
31
"github.com/pkg/errors"
@@ -255,21 +259,68 @@ func (c *HelmClient) InstallHelmRelease(ctx context.Context, restConfig *rest.Co
255
259
256
260
// newDefaultRegistryClient creates registry client object with default config which can be used to install/upgrade helm charts.
257
261
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 ),
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: %w" , err )
263
276
}
264
- if credentialsPath != "" {
265
- // Create a new registry client with credentials
266
- opts = append (opts , registry .ClientOptCredentialsFile (credentialsPath ))
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
+
291
+ return registry .NewClient (opts ... )
292
+ }
293
+
294
+ // newClientTLS creates a new TLS config for the registry client based on the provided
295
+ // CA file and insecureSkipTLSverify flag.
296
+ func newClientTLS (caFile string , insecureSkipTLSverify bool ) (* tls.Config , error ) {
297
+ config := tls.Config {
298
+ InsecureSkipVerify : insecureSkipTLSverify ,
299
+ }
300
+
301
+ if caFile != "" {
302
+ cp , err := certPoolFromFile (caFile )
303
+ if err != nil {
304
+ return nil , err
267
305
}
306
+ config .RootCAs = cp
307
+ }
268
308
269
- return registry .NewClient (opts ... )
309
+ return & config , nil
310
+ }
311
+
312
+ // certPoolFromFile creates a new CertPool and appends the certificates from the given file.
313
+ func certPoolFromFile (filename string ) (* x509.CertPool , error ) {
314
+ b , err := os .ReadFile (filename )
315
+ if err != nil {
316
+ return nil , errors .Wrapf (err , "can't read CA file: %s" , filename )
317
+ }
318
+ cp := x509 .NewCertPool ()
319
+ if ! cp .AppendCertsFromPEM (b ) {
320
+ return nil , errors .Errorf ("failed to append certificates from file: %s" , filename )
270
321
}
271
322
272
- return registry . NewRegistryClientWithTLS ( os . Stderr , "" , "" , caFilePath , insecureSkipTLSVerify , credentialsPath , true )
323
+ return cp , nil
273
324
}
274
325
275
326
// getHelmChartAndRepoName returns chartName, repoURL as per the format requirred in helm install/upgrade config.
0 commit comments