Skip to content

Commit

Permalink
Merge branch 'main' into firewall-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
AshleyDumaine authored Aug 21, 2024
2 parents be9c6d6 + 3a074f0 commit e837fea
Show file tree
Hide file tree
Showing 23 changed files with 1,166 additions and 1,589 deletions.
1 change: 1 addition & 0 deletions clients/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type LinodeVPCClient interface {
type LinodeNodeBalancerClient interface {
CreateNodeBalancer(ctx context.Context, opts linodego.NodeBalancerCreateOptions) (*linodego.NodeBalancer, error)
GetNodeBalancer(ctx context.Context, nodebalancerID int) (*linodego.NodeBalancer, error)
ListNodeBalancerNodes(ctx context.Context, nodebalancerID int, configID int, opts *linodego.ListOptions) ([]linodego.NodeBalancerNode, error)
GetNodeBalancerConfig(ctx context.Context, nodebalancerID int, configID int) (*linodego.NodeBalancerConfig, error)
CreateNodeBalancerConfig(ctx context.Context, nodebalancerID int, opts linodego.NodeBalancerConfigCreateOptions) (*linodego.NodeBalancerConfig, error)
DeleteNodeBalancerNode(ctx context.Context, nodebalancerID int, configID int, nodeID int) error
Expand Down
49 changes: 35 additions & 14 deletions cloud/scope/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ import (

// ClusterScopeParams defines the input parameters used to create a new Scope.
type ClusterScopeParams struct {
Client K8sClient
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
Client K8sClient
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
LinodeMachineList infrav1alpha2.LinodeMachineList
}

func validateClusterScopeParams(params ClusterScopeParams) error {
Expand All @@ -50,7 +51,7 @@ func validateClusterScopeParams(params ClusterScopeParams) error {

// NewClusterScope creates a new Scope from the supplied parameters.
// This is meant to be called for each reconcile iteration.
func NewClusterScope(ctx context.Context, linodeClientConfig ClientConfig, params ClusterScopeParams) (*ClusterScope, error) {
func NewClusterScope(ctx context.Context, linodeClientConfig, dnsClientConfig ClientConfig, params ClusterScopeParams) (*ClusterScope, error) {
if err := validateClusterScopeParams(params); err != nil {
return nil, err
}
Expand All @@ -63,6 +64,11 @@ func NewClusterScope(ctx context.Context, linodeClientConfig ClientConfig, param
return nil, fmt.Errorf("credentials from secret ref: %w", err)
}
linodeClientConfig.Token = string(apiToken)
dnsToken, err := getCredentialDataFromRef(ctx, params.Client, *params.LinodeCluster.Spec.CredentialsRef, params.LinodeCluster.GetNamespace(), "dnsToken")
if err != nil || len(dnsToken) == 0 {
dnsToken = apiToken
}
dnsClientConfig.Token = string(dnsToken)
}
linodeClient, err := CreateLinodeClient(linodeClientConfig)
if err != nil {
Expand All @@ -74,22 +80,37 @@ func NewClusterScope(ctx context.Context, linodeClientConfig ClientConfig, param
return nil, fmt.Errorf("failed to init patch helper: %w", err)
}

akamDomainsClient, err := setUpEdgeDNSInterface()
if err != nil {
return nil, fmt.Errorf("failed to create akamai dns client: %w", err)
}
linodeDomainsClient, err := CreateLinodeClient(dnsClientConfig, WithRetryCount(0))
if err != nil {
return nil, fmt.Errorf("failed to create linode client: %w", err)
}

return &ClusterScope{
Client: params.Client,
Cluster: params.Cluster,
LinodeClient: linodeClient,
LinodeCluster: params.LinodeCluster,
PatchHelper: helper,
Client: params.Client,
Cluster: params.Cluster,
LinodeClient: linodeClient,
LinodeDomainsClient: linodeDomainsClient,
AkamaiDomainsClient: akamDomainsClient,
LinodeCluster: params.LinodeCluster,
LinodeMachines: params.LinodeMachineList,
PatchHelper: helper,
}, nil
}

// ClusterScope defines the basic context for an actuator to operate upon.
type ClusterScope struct {
Client K8sClient
PatchHelper *patch.Helper
LinodeClient LinodeClient
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
Client K8sClient
PatchHelper *patch.Helper
LinodeClient LinodeClient
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
LinodeMachines infrav1alpha2.LinodeMachineList
AkamaiDomainsClient AkamClient
LinodeDomainsClient LinodeClient
}

// PatchObject persists the cluster configuration and status.
Expand Down
173 changes: 48 additions & 125 deletions cloud/scope/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ func TestValidateClusterScopeParams(t *testing.T) {
func TestClusterScopeMethods(t *testing.T) {
t.Parallel()
type fields struct {
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
LinodeMachineList infrav1alpha2.LinodeMachineList
}

tests := []struct {
Expand Down Expand Up @@ -126,7 +127,8 @@ func TestClusterScopeMethods(t *testing.T) {
{
name: "AddFinalizer error - finalizer should not be added to the Linode Cluster object. Function returns nil since it was already present",
fields: fields{
Cluster: &clusterv1.Cluster{},
Cluster: &clusterv1.Cluster{},
LinodeMachineList: infrav1alpha2.LinodeMachineList{},
LinodeCluster: &infrav1alpha2.LinodeCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster",
Expand Down Expand Up @@ -158,10 +160,12 @@ func TestClusterScopeMethods(t *testing.T) {
cScope, err := NewClusterScope(
context.Background(),
ClientConfig{Token: "test-key"},
ClientConfig{Token: "test-key"},
ClusterScopeParams{
Cluster: testcase.fields.Cluster,
LinodeCluster: testcase.fields.LinodeCluster,
Client: mockK8sClient,
Cluster: testcase.fields.Cluster,
LinodeMachineList: testcase.fields.LinodeMachineList,
LinodeCluster: testcase.fields.LinodeCluster,
Client: mockK8sClient,
})
if err != nil {
t.Errorf("NewClusterScope() error = %v", err)
Expand All @@ -181,8 +185,9 @@ func TestClusterScopeMethods(t *testing.T) {
func TestNewClusterScope(t *testing.T) {
t.Parallel()
type args struct {
apiKey string
params ClusterScopeParams
apiKey string
dnsApiKey string
params ClusterScopeParams
}
tests := []struct {
name string
Expand All @@ -193,7 +198,8 @@ func TestNewClusterScope(t *testing.T) {
{
name: "Success - Pass in valid args and get a valid ClusterScope",
args: args{
apiKey: "test-key",
apiKey: "test-key",
dnsApiKey: "test-key",
params: ClusterScopeParams{
Cluster: &clusterv1.Cluster{},
LinodeCluster: &infrav1alpha2.LinodeCluster{},
Expand All @@ -211,7 +217,8 @@ func TestNewClusterScope(t *testing.T) {
{
name: "Success - Validate getCredentialDataFromRef() returns some apiKey data and we create a valid ClusterScope",
args: args{
apiKey: "test-key",
apiKey: "test-key",
dnsApiKey: "test-key",
params: ClusterScopeParams{
Client: nil,
Cluster: &clusterv1.Cluster{},
Expand All @@ -231,7 +238,7 @@ func TestNewClusterScope(t *testing.T) {
s := runtime.NewScheme()
infrav1alpha2.AddToScheme(s)
return s
})
}).AnyTimes()
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 {
cred := corev1.Secret{
Data: map[string][]byte{
Expand All @@ -241,13 +248,23 @@ func TestNewClusterScope(t *testing.T) {
*obj = cred
return nil
})
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 {
cred := corev1.Secret{
Data: map[string][]byte{
"dnsToken": []byte("example"),
},
}
*obj = cred
return nil
})
},
},
{
name: "Error - ValidateClusterScopeParams triggers error because ClusterScopeParams is empty",
args: args{
apiKey: "test-key",
params: ClusterScopeParams{},
apiKey: "test-key",
dnsApiKey: "test-key",
params: ClusterScopeParams{},
},
expectedError: fmt.Errorf("cluster is required when creating a ClusterScope"),
expects: func(mock *mock.MockK8sClient) {},
Expand All @@ -269,7 +286,8 @@ func TestNewClusterScope(t *testing.T) {
{
name: "Error - Using getCredentialDataFromRef(), func returns an error. Unable to create a valid ClusterScope",
args: args{
apiKey: "test-key",
apiKey: "test-key",
dnsApiKey: "test-key",
params: ClusterScopeParams{
Client: nil,
Cluster: &clusterv1.Cluster{},
Expand All @@ -291,7 +309,8 @@ func TestNewClusterScope(t *testing.T) {
{
name: "Error - createLinodeCluster throws an error for passing empty apiKey. Unable to create a valid ClusterScope",
args: args{
apiKey: "",
apiKey: "",
dnsApiKey: "",
params: ClusterScopeParams{
Cluster: &clusterv1.Cluster{},
LinodeCluster: &infrav1alpha2.LinodeCluster{},
Expand All @@ -316,7 +335,7 @@ func TestNewClusterScope(t *testing.T) {

testcase.args.params.Client = mockK8sClient

got, err := NewClusterScope(context.Background(), ClientConfig{Token: testcase.args.apiKey}, testcase.args.params)
got, err := NewClusterScope(context.Background(), ClientConfig{Token: testcase.args.apiKey}, ClientConfig{Token: testcase.args.dnsApiKey}, testcase.args.params)

if testcase.expectedError != nil {
assert.ErrorContains(t, err, testcase.expectedError.Error())
Expand All @@ -327,112 +346,12 @@ func TestNewClusterScope(t *testing.T) {
}
}

func TestClusterAddCredentialsRefFinalizer(t *testing.T) {
t.Parallel()
type fields struct {
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
}

tests := []struct {
name string
fields fields
expects func(mock *mock.MockK8sClient)
}{
{
name: "Success - finalizer should be added to the Linode Cluster credentials Secret",
fields: fields{
Cluster: &clusterv1.Cluster{},
LinodeCluster: &infrav1alpha2.LinodeCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster",
},
Spec: infrav1alpha2.LinodeClusterSpec{
CredentialsRef: &corev1.SecretReference{
Name: "example",
Namespace: "test",
},
},
},
},
expects: func(mock *mock.MockK8sClient) {
mock.EXPECT().Scheme().DoAndReturn(func() *runtime.Scheme {
s := runtime.NewScheme()
infrav1alpha2.AddToScheme(s)
return s
})
mock.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, key types.NamespacedName, obj *corev1.Secret, opts ...client.GetOption) error {
cred := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "example",
Namespace: "test",
},
Data: map[string][]byte{
"apiToken": []byte("example"),
},
}
*obj = cred

return nil
}).Times(2)
mock.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil)
},
},
{
name: "No-op - no Linode Cluster credentials Secret",
fields: fields{
Cluster: &clusterv1.Cluster{},
LinodeCluster: &infrav1alpha2.LinodeCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster",
},
},
},
expects: func(mock *mock.MockK8sClient) {
mock.EXPECT().Scheme().DoAndReturn(func() *runtime.Scheme {
s := runtime.NewScheme()
infrav1alpha2.AddToScheme(s)
return s
})
},
},
}
for _, tt := range tests {
testcase := tt
t.Run(testcase.name, func(t *testing.T) {
t.Parallel()

ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockK8sClient := mock.NewMockK8sClient(ctrl)

testcase.expects(mockK8sClient)

cScope, err := NewClusterScope(
context.Background(),
ClientConfig{Token: "test-key"},
ClusterScopeParams{
Cluster: testcase.fields.Cluster,
LinodeCluster: testcase.fields.LinodeCluster,
Client: mockK8sClient,
})
if err != nil {
t.Errorf("NewClusterScope() error = %v", err)
}

if err := cScope.AddCredentialsRefFinalizer(context.Background()); err != nil {
t.Errorf("ClusterScope.AddCredentialsRefFinalizer() error = %v", err)
}
})
}
}

func TestRemoveCredentialsRefFinalizer(t *testing.T) {
t.Parallel()
type fields struct {
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
Cluster *clusterv1.Cluster
LinodeCluster *infrav1alpha2.LinodeCluster
LinodeMachineList infrav1alpha2.LinodeMachineList
}

tests := []struct {
Expand All @@ -443,7 +362,8 @@ func TestRemoveCredentialsRefFinalizer(t *testing.T) {
{
name: "Success - finalizer should be removed from the Linode Cluster credentials Secret",
fields: fields{
Cluster: &clusterv1.Cluster{},
Cluster: &clusterv1.Cluster{},
LinodeMachineList: infrav1alpha2.LinodeMachineList{},
LinodeCluster: &infrav1alpha2.LinodeCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster",
Expand Down Expand Up @@ -475,14 +395,15 @@ func TestRemoveCredentialsRefFinalizer(t *testing.T) {
*obj = cred

return nil
}).Times(2)
}).AnyTimes()
mock.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil)
},
},
{
name: "No-op - no Linode Cluster credentials Secret",
fields: fields{
Cluster: &clusterv1.Cluster{},
Cluster: &clusterv1.Cluster{},
LinodeMachineList: infrav1alpha2.LinodeMachineList{},
LinodeCluster: &infrav1alpha2.LinodeCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "test-cluster",
Expand Down Expand Up @@ -513,10 +434,12 @@ func TestRemoveCredentialsRefFinalizer(t *testing.T) {
cScope, err := NewClusterScope(
context.Background(),
ClientConfig{Token: "test-key"},
ClientConfig{Token: "test-key"},
ClusterScopeParams{
Cluster: testcase.fields.Cluster,
LinodeCluster: testcase.fields.LinodeCluster,
Client: mockK8sClient,
Cluster: testcase.fields.Cluster,
LinodeCluster: testcase.fields.LinodeCluster,
LinodeMachineList: testcase.fields.LinodeMachineList,
Client: mockK8sClient,
})
if err != nil {
t.Errorf("NewClusterScope() error = %v", err)
Expand Down
Loading

0 comments on commit e837fea

Please sign in to comment.