Skip to content

Commit c9e9960

Browse files
Store certpool inside the client object (#38)
* Store certpool inside the client object This allows us to use multiple certificates using the `WithCertificate` option. * Update CHANGELOG.md Update the changelog file with details on what's changed. * Use hashicorp/go-cleanhttp for creating http client Use cleanhttp to create a unique Default client instead of mutating http.DefaultCient. * Add error checks if transport type is unexpected Error out if Transport is not of type http.Transport * Update CHANGELOG.md Update the changelog with info about cleanhttp.
1 parent 588e385 commit c9e9960

File tree

4 files changed

+30
-10
lines changed

4 files changed

+30
-10
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
### Changed
1313
- Add license header to generated file and add a makefile target for generate
1414
- `NUTANIX_INSECURE` and `NUTANIX_ADDITIONAL_TRUST_BUNDLE` environment variables are used to hydrate environment/local provider
15+
- Store the certpool in the client to allow injecting multiple certificates using the `WithCertificate` option
16+
- Use `hashicorp/go-cleanhttp` as the underlying http client constructor
1517

1618
## [0.3.0] - 2022-09-27
1719
### Added

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/go-logr/logr v1.2.3
88
github.com/go-logr/zapr v1.2.3
99
github.com/google/go-cmp v0.5.8 // indirect
10+
github.com/hashicorp/go-cleanhttp v0.5.2
1011
github.com/keploy/go-sdk v0.4.3
1112
github.com/onsi/ginkgo v1.16.5 // indirect
1213
github.com/onsi/ginkgo/v2 v2.1.4

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
243243
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
244244
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
245245
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
246+
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
247+
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
246248
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
247249
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
248250
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=

internal/client.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/PaesslerAG/jsonpath"
1919
"github.com/go-logr/logr"
2020
"github.com/go-logr/zapr"
21+
"github.com/hashicorp/go-cleanhttp"
2122
"go.uber.org/zap"
2223

2324
"github.com/nutanix-cloud-native/prism-go-client"
@@ -62,7 +63,8 @@ type Client struct {
6263
// error message, incase httpClient is in error state
6364
ErrorMsg string
6465

65-
logger *logr.Logger
66+
logger *logr.Logger
67+
certpool *x509.CertPool
6668
}
6769

6870
type ClientOption func(*Client) error
@@ -80,15 +82,23 @@ func WithCredentials(credentials *prismgoclient.Credentials) ClientOption {
8082
return func(c *Client) error {
8183
c.credentials = credentials
8284
if c.credentials.Insecure {
83-
c.httpClient.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify = true
85+
transport, ok := c.httpClient.Transport.(*http.Transport)
86+
if !ok {
87+
return fmt.Errorf("transport is not of type http.Transport: %T", c.httpClient.Transport)
88+
}
89+
transport.TLSClientConfig.InsecureSkipVerify = true
8490
}
8591
if c.credentials.ProxyURL != "" {
8692
c.logger.V(1).Info("Using proxy:", "proxy", c.credentials.ProxyURL)
8793
proxy, err := url.Parse(c.credentials.ProxyURL)
8894
if err != nil {
8995
return fmt.Errorf("error parsing proxy url: %s", err)
9096
}
91-
c.httpClient.Transport.(*http.Transport).Proxy = http.ProxyURL(proxy)
97+
transport, ok := c.httpClient.Transport.(*http.Transport)
98+
if !ok {
99+
return fmt.Errorf("transport is not of type http.Transport: %T", c.httpClient.Transport)
100+
}
101+
transport.Proxy = http.ProxyURL(proxy)
92102
}
93103
return nil
94104
}
@@ -143,13 +153,10 @@ func WithAbsolutePath(absolutePath string) ClientOption {
143153
// WithCertificate adds the certificate to the certificate pool in tls config
144154
func WithCertificate(cert *x509.Certificate) ClientOption {
145155
return func(c *Client) error {
146-
certPool, err := x509.SystemCertPool()
147-
if err != nil {
148-
return fmt.Errorf("failed to get system cert pool: %s", err)
156+
if cert == nil {
157+
return fmt.Errorf("certificate is nil")
149158
}
150-
151-
certPool.AddCert(cert)
152-
c.httpClient.Transport.(*http.Transport).TLSClientConfig.RootCAs = certPool
159+
c.certpool.AddCert(cert)
153160
return nil
154161
}
155162
}
@@ -167,10 +174,18 @@ func WithRoundTripper(transport http.RoundTripper) ClientOption {
167174
// NewClient returns a wrapper around http/https (as per isHTTP flag) httpClient with additions of proxy & session_auth if given
168175
func NewClient(opts ...ClientOption) (*Client, error) {
169176
c := &Client{
170-
httpClient: http.DefaultClient,
177+
httpClient: cleanhttp.DefaultClient(),
171178
}
179+
180+
certPool, err := x509.SystemCertPool()
181+
if err != nil {
182+
return nil, fmt.Errorf("failed to get system cert pool: %s", err)
183+
}
184+
c.certpool = certPool
185+
172186
c.httpClient.Transport = http.DefaultTransport
173187
c.httpClient.Transport.(*http.Transport).TLSClientConfig = &tls.Config{}
188+
c.httpClient.Transport.(*http.Transport).TLSClientConfig.RootCAs = c.certpool
174189

175190
// If the user does not specify a logger, then we'll use zap for a default one
176191
// If the user specified a logger, then we'll use that logger

0 commit comments

Comments
 (0)