Skip to content

Commit a658119

Browse files
authored
feat: Add custom cert support (#250)
add support for client cert override per cluster via a secret
1 parent e09e016 commit a658119

11 files changed

+417
-29
lines changed

api/v1beta2/ocicluster_types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ type OCIAvailabilityDomain struct {
129129
// ClientOverrides contains information about client host url overrides.
130130
type ClientOverrides struct {
131131

132+
// CertOverride is a secret that contains information about a cert override used by all the OCI SDK clients.
133+
// The secret must contain data with a `cert`property.
134+
//
135+
// +optional
136+
// +nullable
137+
CertOverride *corev1.SecretReference `json:"certOverride,omitempty"`
138+
132139
// ComputeClientUrl allows the default compute SDK client URL to be changed.
133140
//
134141
// +optional

api/v1beta2/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cloud/scope/clients.go

Lines changed: 127 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package scope
1818

1919
import (
20+
"crypto/tls"
21+
"crypto/x509"
2022
"net/http"
2123
"sync"
2224

@@ -60,6 +62,7 @@ type ClientProvider struct {
6062
ociClientsLock *sync.RWMutex
6163
ociAuthConfigProvider common.ConfigurationProvider
6264
ociClientOverrides *v1beta2.ClientOverrides
65+
certOverride *x509.CertPool
6366
}
6467

6568
// ClientProviderParams is the params struct for NewClientProvider
@@ -69,6 +72,9 @@ type ClientProviderParams struct {
6972

7073
// ClientOverrides contains information about client host url overrides.
7174
ClientOverrides *v1beta2.ClientOverrides
75+
76+
// CertOverride a x509 CertPool to use as an override for client TLSClientConfig
77+
CertOverride *x509.CertPool
7278
}
7379

7480
// NewClientProvider builds the ClientProvider with a client for the given region
@@ -81,6 +87,7 @@ func NewClientProvider(params ClientProviderParams) (*ClientProvider, error) {
8187

8288
provider := ClientProvider{
8389
Logger: &log,
90+
certOverride: params.CertOverride,
8491
ociAuthConfigProvider: params.OciAuthConfigProvider,
8592
ociClients: map[string]OCIClients{},
8693
ociClientsLock: new(sync.RWMutex),
@@ -138,7 +145,7 @@ func (c *ClientProvider) createClients(region string) (OCIClients, error) {
138145
if err != nil {
139146
return OCIClients{}, err
140147
}
141-
identityClient, err := c.createIdentityClient(region, c.ociAuthConfigProvider, c.Logger)
148+
identityClt, err := c.createIdentityClient(region, c.ociAuthConfigProvider, c.Logger)
142149
if err != nil {
143150
return OCIClients{}, err
144151
}
@@ -150,7 +157,7 @@ func (c *ClientProvider) createClients(region string) (OCIClients, error) {
150157
if err != nil {
151158
return OCIClients{}, err
152159
}
153-
containerEngineClient, err := c.createContainerEngineClient(region, c.ociAuthConfigProvider, c.Logger)
160+
containerEngineClt, err := c.createContainerEngineClient(region, c.ociAuthConfigProvider, c.Logger)
154161
if err != nil {
155162
return OCIClients{}, err
156163
}
@@ -167,10 +174,10 @@ func (c *ClientProvider) createClients(region string) (OCIClients, error) {
167174
VCNClient: vcnClient,
168175
NetworkLoadBalancerClient: nlbClient,
169176
LoadBalancerClient: lbClient,
170-
IdentityClient: identityClient,
177+
IdentityClient: identityClt,
171178
ComputeClient: computeClient,
172179
ComputeManagementClient: computeManagementClient,
173-
ContainerEngineClient: containerEngineClient,
180+
ContainerEngineClient: containerEngineClt,
174181
BaseClient: baseClient,
175182
}, err
176183
}
@@ -182,6 +189,20 @@ func (c *ClientProvider) createVncClient(region string, ociAuthConfigProvider co
182189
return nil, err
183190
}
184191
vcnClient.SetRegion(region)
192+
193+
if c.certOverride != nil {
194+
if client, ok := vcnClient.HTTPClient.(*http.Client); ok {
195+
err = c.setCerts(client)
196+
if err != nil {
197+
logger.Error(err, "unable to create OCI VCN Client")
198+
return nil, err
199+
}
200+
} else {
201+
return nil, errors.New("The VCN Client dispatcher is not of http.Client type. Can not patch the tls config.")
202+
}
203+
204+
}
205+
185206
if c.ociClientOverrides != nil && c.ociClientOverrides.VCNClientUrl != nil {
186207
vcnClient.Host = *c.ociClientOverrides.VCNClientUrl
187208
}
@@ -197,6 +218,19 @@ func (c *ClientProvider) createNLbClient(region string, ociAuthConfigProvider co
197218
return nil, err
198219
}
199220
nlbClient.SetRegion(region)
221+
222+
if c.certOverride != nil {
223+
if client, ok := nlbClient.HTTPClient.(*http.Client); ok {
224+
err = c.setCerts(client)
225+
if err != nil {
226+
logger.Error(err, "unable to create OCI NetworkLoadBalancer Client")
227+
return nil, err
228+
}
229+
} else {
230+
return nil, errors.New("The Network Loadbalancer Client dispatcher is not of http.Client type. Can not patch the tls config.")
231+
}
232+
}
233+
200234
if c.ociClientOverrides != nil && c.ociClientOverrides.NetworkLoadBalancerClientUrl != nil {
201235
nlbClient.Host = *c.ociClientOverrides.NetworkLoadBalancerClientUrl
202236
}
@@ -212,6 +246,19 @@ func (c *ClientProvider) createLBClient(region string, ociAuthConfigProvider com
212246
return nil, err
213247
}
214248
lbClient.SetRegion(region)
249+
250+
if c.certOverride != nil {
251+
if client, ok := lbClient.HTTPClient.(*http.Client); ok {
252+
err = c.setCerts(client)
253+
if err != nil {
254+
logger.Error(err, "unable to create OCI Loadbalancer Client")
255+
return nil, err
256+
}
257+
} else {
258+
return nil, errors.New("The Loadbalancer Client dispatcher is not of http.Client type. Can not patch the tls config.")
259+
}
260+
}
261+
215262
if c.ociClientOverrides != nil && c.ociClientOverrides.LoadBalancerClientUrl != nil {
216263
lbClient.Host = *c.ociClientOverrides.LoadBalancerClientUrl
217264
}
@@ -221,19 +268,31 @@ func (c *ClientProvider) createLBClient(region string, ociAuthConfigProvider com
221268
}
222269

223270
func (c *ClientProvider) createIdentityClient(region string, ociAuthConfigProvider common.ConfigurationProvider, logger *logr.Logger) (*identity.IdentityClient, error) {
224-
identityClient, err := identity.NewIdentityClientWithConfigurationProvider(ociAuthConfigProvider)
271+
identityClt, err := identity.NewIdentityClientWithConfigurationProvider(ociAuthConfigProvider)
225272
if err != nil {
226273
logger.Error(err, "unable to create OCI Identity Client")
227274
return nil, err
228275
}
229-
identityClient.SetRegion(region)
276+
identityClt.SetRegion(region)
277+
278+
if c.certOverride != nil {
279+
if client, ok := identityClt.HTTPClient.(*http.Client); ok {
280+
err = c.setCerts(client)
281+
if err != nil {
282+
logger.Error(err, "unable to create OCI Identity Client")
283+
return nil, err
284+
}
285+
} else {
286+
return nil, errors.New("The Identity Client dispatcher is not of http.Client type. Can not patch the tls config.")
287+
}
288+
}
230289

231290
if c.ociClientOverrides != nil && c.ociClientOverrides.IdentityClientUrl != nil {
232-
identityClient.Host = *c.ociClientOverrides.IdentityClientUrl
291+
identityClt.Host = *c.ociClientOverrides.IdentityClientUrl
233292
}
234-
identityClient.Interceptor = setVersionHeader()
293+
identityClt.Interceptor = setVersionHeader()
235294

236-
return &identityClient, nil
295+
return &identityClt, nil
237296
}
238297

239298
func (c *ClientProvider) createComputeClient(region string, ociAuthConfigProvider common.ConfigurationProvider, logger *logr.Logger) (*core.ComputeClient, error) {
@@ -243,6 +302,19 @@ func (c *ClientProvider) createComputeClient(region string, ociAuthConfigProvide
243302
return nil, err
244303
}
245304
computeClient.SetRegion(region)
305+
306+
if c.certOverride != nil {
307+
if client, ok := computeClient.HTTPClient.(*http.Client); ok {
308+
err = c.setCerts(client)
309+
if err != nil {
310+
logger.Error(err, "unable to create OCI Compute Client")
311+
return nil, err
312+
}
313+
} else {
314+
return nil, errors.New("The Compute Client dispatcher is not of http.Client type. Can not patch the tls config.")
315+
}
316+
}
317+
246318
if c.ociClientOverrides != nil && c.ociClientOverrides.ComputeClientUrl != nil {
247319
computeClient.Host = *c.ociClientOverrides.ComputeClientUrl
248320
}
@@ -258,6 +330,19 @@ func (c *ClientProvider) createComputeManagementClient(region string, ociAuthCon
258330
return nil, err
259331
}
260332
computeManagementClient.SetRegion(region)
333+
334+
if c.certOverride != nil {
335+
if client, ok := computeManagementClient.HTTPClient.(*http.Client); ok {
336+
err = c.setCerts(client)
337+
if err != nil {
338+
logger.Error(err, "unable to create OCI Compute Management Client")
339+
return nil, err
340+
}
341+
} else {
342+
return nil, errors.New("The Compute Management Client dispatcher is not of http.Client type. Can not patch the tls config.")
343+
}
344+
}
345+
261346
if c.ociClientOverrides != nil && c.ociClientOverrides.ComputeManagementClientUrl != nil {
262347
computeManagementClient.Host = *c.ociClientOverrides.ComputeManagementClientUrl
263348
}
@@ -267,18 +352,31 @@ func (c *ClientProvider) createComputeManagementClient(region string, ociAuthCon
267352
}
268353

269354
func (c *ClientProvider) createContainerEngineClient(region string, ociAuthConfigProvider common.ConfigurationProvider, logger *logr.Logger) (*containerengine.ContainerEngineClient, error) {
270-
containerEngineClient, err := containerengine.NewContainerEngineClientWithConfigurationProvider(ociAuthConfigProvider)
355+
containerEngineClt, err := containerengine.NewContainerEngineClientWithConfigurationProvider(ociAuthConfigProvider)
271356
if err != nil {
272357
logger.Error(err, "unable to create OCI Container Engine Client")
273358
return nil, err
274359
}
275-
containerEngineClient.SetRegion(region)
360+
containerEngineClt.SetRegion(region)
361+
362+
if c.certOverride != nil {
363+
if client, ok := containerEngineClt.HTTPClient.(*http.Client); ok {
364+
err = c.setCerts(client)
365+
if err != nil {
366+
logger.Error(err, "unable to create OCI Container Engine Client")
367+
return nil, err
368+
}
369+
} else {
370+
return nil, errors.New("The Container Engine Client dispatcher is not of http.Client type. Can not patch the tls config.")
371+
}
372+
}
373+
276374
if c.ociClientOverrides != nil && c.ociClientOverrides.ContainerEngineClientUrl != nil {
277-
containerEngineClient.Host = *c.ociClientOverrides.ContainerEngineClientUrl
375+
containerEngineClt.Host = *c.ociClientOverrides.ContainerEngineClientUrl
278376
}
279-
containerEngineClient.Interceptor = setVersionHeader()
377+
containerEngineClt.Interceptor = setVersionHeader()
280378

281-
return &containerEngineClient, nil
379+
return &containerEngineClt, nil
282380
}
283381

284382
func (c *ClientProvider) createBaseClient(region string, ociAuthConfigProvider common.ConfigurationProvider, logger *logr.Logger) (base.BaseClient, error) {
@@ -296,3 +394,18 @@ func setVersionHeader() func(request *http.Request) error {
296394
return nil
297395
}
298396
}
397+
398+
// setCerts updates the client TLSClientConfig with the ClientProvider certOverride
399+
func (c *ClientProvider) setCerts(client *http.Client) error {
400+
tr := client.Transport.(*http.Transport).Clone()
401+
if tr.TLSClientConfig != nil {
402+
tr.TLSClientConfig.RootCAs = c.certOverride
403+
} else {
404+
tr.TLSClientConfig = &tls.Config{
405+
RootCAs: c.certOverride,
406+
}
407+
}
408+
client.Transport = tr
409+
410+
return nil
411+
}

cloud/scope/clients_test.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ func TestClients_NewClientProvider(t *testing.T) {
4040
}
4141

4242
clientProvider, err := NewClientProvider(ClientProviderParams{
43-
ociAuthConfigProvider,
44-
nil})
43+
OciAuthConfigProvider: ociAuthConfigProvider})
4544
if err != nil {
4645
t.Errorf("Expected %v to equal nil", err)
4746
}
@@ -73,8 +72,8 @@ func TestClients_NewClientProviderWithClientOverrides(t *testing.T) {
7372
}
7473

7574
clientProvider, err := NewClientProvider(ClientProviderParams{
76-
ociAuthConfigProvider,
77-
clientOverrides})
75+
OciAuthConfigProvider: ociAuthConfigProvider,
76+
ClientOverrides: clientOverrides})
7877
if err != nil {
7978
t.Errorf("Expected error:%v to not equal nil", err)
8079
}
@@ -113,8 +112,8 @@ func TestClients_NewClientProviderWithMissingOverrides(t *testing.T) {
113112
}
114113

115114
clientProvider, err := NewClientProvider(ClientProviderParams{
116-
ociAuthConfigProvider,
117-
clientOverrides})
115+
OciAuthConfigProvider: ociAuthConfigProvider,
116+
ClientOverrides: clientOverrides})
118117
if err != nil {
119118
t.Errorf("Expected error:%v to not equal nil", err)
120119
}
@@ -129,7 +128,7 @@ func TestClients_NewClientProviderWithMissingOverrides(t *testing.T) {
129128
}
130129

131130
func TestClients_NewClientProviderWithBadAuthConfig(t *testing.T) {
132-
clientProvider, err := NewClientProvider(ClientProviderParams{nil, nil})
131+
clientProvider, err := NewClientProvider(ClientProviderParams{})
133132
if err == nil {
134133
t.Errorf("Expected error:%v to not equal nil", err)
135134
}
@@ -211,8 +210,7 @@ func TestClients_GetAuthProvider(t *testing.T) {
211210
}
212211

213212
clientProvider, err := NewClientProvider(ClientProviderParams{
214-
ociAuthConfigProvider,
215-
nil})
213+
OciAuthConfigProvider: ociAuthConfigProvider})
216214
if err != nil {
217215
t.Errorf("Expected %v to equal nil", err)
218216
}

0 commit comments

Comments
 (0)