Skip to content

Commit 21b8cf2

Browse files
authored
[fix] create scope with default credentials for all resources (#507)
* updating scope for controllers * not mandating adding credential ref in Spec for LinodeMachine templates * adding testcases in vpc scope testing * adding testcases in pg scope testing * adding testcases for the new scope method for all resources * updating machine scope and added testcases * handling cyclomatic complexity * handling cyclomatic complexity for all controllers * making sure the update token is places right
1 parent 17568b5 commit 21b8cf2

20 files changed

+870
-466
lines changed

clients/clients.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type LinodeClient interface {
1919
LinodeDNSClient
2020
LinodePlacementGroupClient
2121
LinodeFirewallClient
22+
LinodeTokenClient
2223
}
2324

2425
type AkamClient interface {
@@ -118,3 +119,7 @@ type LinodeFirewallClient interface {
118119
type K8sClient interface {
119120
client.Client
120121
}
122+
123+
type LinodeTokenClient interface {
124+
SetToken(token string) *linodego.Client
125+
}

cloud/scope/cluster.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,6 @@ func NewClusterScope(ctx context.Context, linodeClientConfig, dnsClientConfig Cl
5656
return nil, err
5757
}
5858

59-
// Override the controller credentials with ones from the Cluster's Secret reference (if supplied).
60-
if params.LinodeCluster.Spec.CredentialsRef != nil {
61-
// TODO: This key is hard-coded (for now) to match the externally-managed `manager-credentials` Secret.
62-
apiToken, err := getCredentialDataFromRef(ctx, params.Client, *params.LinodeCluster.Spec.CredentialsRef, params.LinodeCluster.GetNamespace(), "apiToken")
63-
if err != nil {
64-
return nil, fmt.Errorf("credentials from secret ref: %w", err)
65-
}
66-
linodeClientConfig.Token = string(apiToken)
67-
dnsToken, err := getCredentialDataFromRef(ctx, params.Client, *params.LinodeCluster.Spec.CredentialsRef, params.LinodeCluster.GetNamespace(), "dnsToken")
68-
if err != nil || len(dnsToken) == 0 {
69-
dnsToken = apiToken
70-
}
71-
dnsClientConfig.Token = string(dnsToken)
72-
}
7359
linodeClient, err := CreateLinodeClient(linodeClientConfig)
7460
if err != nil {
7561
return nil, fmt.Errorf("failed to create linode client: %w", err)
@@ -152,3 +138,20 @@ func (s *ClusterScope) RemoveCredentialsRefFinalizer(ctx context.Context) error
152138
*s.LinodeCluster.Spec.CredentialsRef, s.LinodeCluster.GetNamespace(),
153139
toFinalizer(s.LinodeCluster))
154140
}
141+
142+
func (s *ClusterScope) SetCredentialRefTokenForLinodeClients(ctx context.Context) error {
143+
if s.LinodeCluster.Spec.CredentialsRef != nil {
144+
apiToken, err := getCredentialDataFromRef(ctx, s.Client, *s.LinodeCluster.Spec.CredentialsRef, s.LinodeCluster.GetNamespace(), "apiToken")
145+
if err != nil {
146+
return fmt.Errorf("credentials from secret ref: %w", err)
147+
}
148+
s.LinodeClient = s.LinodeClient.SetToken(string(apiToken))
149+
dnsToken, err := getCredentialDataFromRef(ctx, s.Client, *s.LinodeCluster.Spec.CredentialsRef, s.LinodeCluster.GetNamespace(), "dnsToken")
150+
if err != nil || len(dnsToken) == 0 {
151+
dnsToken = apiToken
152+
}
153+
s.LinodeDomainsClient = s.LinodeDomainsClient.SetToken(string(dnsToken))
154+
return nil
155+
}
156+
return nil
157+
}

cloud/scope/cluster_test.go

Lines changed: 115 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -214,51 +214,6 @@ func TestNewClusterScope(t *testing.T) {
214214
})
215215
},
216216
},
217-
{
218-
name: "Success - Validate getCredentialDataFromRef() returns some apiKey data and we create a valid ClusterScope",
219-
args: args{
220-
apiKey: "test-key",
221-
dnsApiKey: "test-key",
222-
params: ClusterScopeParams{
223-
Client: nil,
224-
Cluster: &clusterv1.Cluster{},
225-
LinodeCluster: &infrav1alpha2.LinodeCluster{
226-
Spec: infrav1alpha2.LinodeClusterSpec{
227-
CredentialsRef: &corev1.SecretReference{
228-
Name: "example",
229-
Namespace: "test",
230-
},
231-
},
232-
},
233-
},
234-
},
235-
expectedError: nil,
236-
expects: func(mock *mock.MockK8sClient) {
237-
mock.EXPECT().Scheme().DoAndReturn(func() *runtime.Scheme {
238-
s := runtime.NewScheme()
239-
infrav1alpha2.AddToScheme(s)
240-
return s
241-
}).AnyTimes()
242-
mock.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, key types.NamespacedName, obj *corev1.Secret, opts ...client.GetOption) error {
243-
cred := corev1.Secret{
244-
Data: map[string][]byte{
245-
"apiToken": []byte("example"),
246-
},
247-
}
248-
*obj = cred
249-
return nil
250-
})
251-
mock.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, key types.NamespacedName, obj *corev1.Secret, opts ...client.GetOption) error {
252-
cred := corev1.Secret{
253-
Data: map[string][]byte{
254-
"dnsToken": []byte("example"),
255-
},
256-
}
257-
*obj = cred
258-
return nil
259-
})
260-
},
261-
},
262217
{
263218
name: "Error - ValidateClusterScopeParams triggers error because ClusterScopeParams is empty",
264219
args: args{
@@ -283,29 +238,6 @@ func TestNewClusterScope(t *testing.T) {
283238
mock.EXPECT().Scheme().Return(runtime.NewScheme())
284239
},
285240
},
286-
{
287-
name: "Error - Using getCredentialDataFromRef(), func returns an error. Unable to create a valid ClusterScope",
288-
args: args{
289-
apiKey: "test-key",
290-
dnsApiKey: "test-key",
291-
params: ClusterScopeParams{
292-
Client: nil,
293-
Cluster: &clusterv1.Cluster{},
294-
LinodeCluster: &infrav1alpha2.LinodeCluster{
295-
Spec: infrav1alpha2.LinodeClusterSpec{
296-
CredentialsRef: &corev1.SecretReference{
297-
Name: "example",
298-
Namespace: "test",
299-
},
300-
},
301-
},
302-
},
303-
},
304-
expectedError: fmt.Errorf("credentials from secret ref: get credentials secret test/example: failed to get secret"),
305-
expects: func(mock *mock.MockK8sClient) {
306-
mock.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("failed to get secret"))
307-
},
308-
},
309241
{
310242
name: "Error - createLinodeCluster throws an error for passing empty apiKey. Unable to create a valid ClusterScope",
311243
args: args{
@@ -451,3 +383,118 @@ func TestRemoveCredentialsRefFinalizer(t *testing.T) {
451383
})
452384
}
453385
}
386+
387+
func TestClusterSetCredentialRefTokenForLinodeClients(t *testing.T) {
388+
t.Parallel()
389+
type fields struct {
390+
Cluster *clusterv1.Cluster
391+
LinodeCluster *infrav1alpha2.LinodeCluster
392+
LinodeMachineList infrav1alpha2.LinodeMachineList
393+
}
394+
395+
tests := []struct {
396+
name string
397+
fields fields
398+
expects func(mock *mock.MockK8sClient)
399+
expectedError error
400+
}{
401+
{
402+
name: "Success - Validate getCredentialDataFromRef() returns some apiKey data",
403+
fields: fields{
404+
Cluster: &clusterv1.Cluster{},
405+
LinodeMachineList: infrav1alpha2.LinodeMachineList{},
406+
LinodeCluster: &infrav1alpha2.LinodeCluster{
407+
ObjectMeta: metav1.ObjectMeta{
408+
Name: "test-cluster",
409+
},
410+
Spec: infrav1alpha2.LinodeClusterSpec{
411+
CredentialsRef: &corev1.SecretReference{
412+
Name: "example",
413+
Namespace: "test",
414+
},
415+
},
416+
},
417+
},
418+
expectedError: nil,
419+
expects: func(mock *mock.MockK8sClient) {
420+
mock.EXPECT().Scheme().DoAndReturn(func() *runtime.Scheme {
421+
s := runtime.NewScheme()
422+
infrav1alpha2.AddToScheme(s)
423+
return s
424+
})
425+
mock.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, key types.NamespacedName, obj *corev1.Secret, opts ...client.GetOption) error {
426+
cred := corev1.Secret{
427+
ObjectMeta: metav1.ObjectMeta{
428+
Name: "example",
429+
Namespace: "test",
430+
},
431+
Data: map[string][]byte{
432+
"apiToken": []byte("example"),
433+
},
434+
}
435+
*obj = cred
436+
437+
return nil
438+
}).AnyTimes()
439+
},
440+
},
441+
{
442+
name: "Error - error when getting the credentials secret",
443+
fields: fields{
444+
Cluster: &clusterv1.Cluster{},
445+
LinodeMachineList: infrav1alpha2.LinodeMachineList{},
446+
LinodeCluster: &infrav1alpha2.LinodeCluster{
447+
ObjectMeta: metav1.ObjectMeta{
448+
Name: "test-cluster",
449+
},
450+
Spec: infrav1alpha2.LinodeClusterSpec{
451+
CredentialsRef: &corev1.SecretReference{
452+
Name: "example",
453+
Namespace: "test",
454+
},
455+
},
456+
},
457+
},
458+
expectedError: fmt.Errorf("credentials from secret ref: get credentials secret test/example: test error"),
459+
expects: func(mock *mock.MockK8sClient) {
460+
mock.EXPECT().Scheme().DoAndReturn(func() *runtime.Scheme {
461+
s := runtime.NewScheme()
462+
infrav1alpha2.AddToScheme(s)
463+
return s
464+
})
465+
mock.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("test error"))
466+
},
467+
},
468+
}
469+
for _, tt := range tests {
470+
testcase := tt
471+
t.Run(testcase.name, func(t *testing.T) {
472+
t.Parallel()
473+
474+
ctrl := gomock.NewController(t)
475+
defer ctrl.Finish()
476+
477+
mockK8sClient := mock.NewMockK8sClient(ctrl)
478+
479+
testcase.expects(mockK8sClient)
480+
481+
cScope, err := NewClusterScope(
482+
context.Background(),
483+
ClientConfig{Token: "test-key"},
484+
ClientConfig{Token: "test-key"},
485+
ClusterScopeParams{
486+
Cluster: testcase.fields.Cluster,
487+
LinodeCluster: testcase.fields.LinodeCluster,
488+
LinodeMachineList: testcase.fields.LinodeMachineList,
489+
Client: mockK8sClient,
490+
})
491+
if err != nil {
492+
t.Errorf("NewClusterScope() error = %v", err)
493+
}
494+
495+
if err := cScope.SetCredentialRefTokenForLinodeClients(context.Background()); err != nil {
496+
assert.ErrorContains(t, err, testcase.expectedError.Error())
497+
}
498+
})
499+
}
500+
}

cloud/scope/firewall.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,6 @@ func NewFirewallScope(ctx context.Context, linodeClientConfig ClientConfig, para
5757
if err := validateFirewallScopeParams(params); err != nil {
5858
return nil, err
5959
}
60-
61-
// Override the controller credentials with ones from the Firewall's Secret reference (if supplied).
62-
if params.LinodeFirewall.Spec.CredentialsRef != nil {
63-
// TODO: This key is hard-coded (for now) to match the externally-managed `manager-credentials` Secret.
64-
apiToken, err := getCredentialDataFromRef(ctx, params.Client, *params.LinodeFirewall.Spec.CredentialsRef, params.LinodeFirewall.GetNamespace(), "apiToken")
65-
if err != nil {
66-
return nil, fmt.Errorf("credentials from secret ref: %w", err)
67-
}
68-
linodeClientConfig.Token = string(apiToken)
69-
}
7060
linodeClient, err := CreateLinodeClient(linodeClientConfig,
7161
WithRetryCount(0),
7262
)
@@ -126,3 +116,16 @@ func (s *FirewallScope) RemoveCredentialsRefFinalizer(ctx context.Context) error
126116
*s.LinodeFirewall.Spec.CredentialsRef, s.LinodeFirewall.GetNamespace(),
127117
toFinalizer(s.LinodeFirewall))
128118
}
119+
120+
func (s *FirewallScope) SetCredentialRefTokenForLinodeClients(ctx context.Context) error {
121+
if s.LinodeFirewall.Spec.CredentialsRef != nil {
122+
// TODO: This key is hard-coded (for now) to match the externally-managed `manager-credentials` Secret.
123+
apiToken, err := getCredentialDataFromRef(ctx, s.Client, *s.LinodeFirewall.Spec.CredentialsRef, s.LinodeFirewall.GetNamespace(), "apiToken")
124+
if err != nil {
125+
return fmt.Errorf("credentials from secret ref: %w", err)
126+
}
127+
s.LinodeClient = s.LinodeClient.SetToken(string(apiToken))
128+
return nil
129+
}
130+
return nil
131+
}

0 commit comments

Comments
 (0)