Skip to content

Commit aece891

Browse files
committed
Factor helpers out of checker
1 parent bd13c66 commit aece891

File tree

5 files changed

+98
-73
lines changed

5 files changed

+98
-73
lines changed

pkg/webhook/preflight/nutanix/checker.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,20 @@ package nutanix
55

66
import (
77
"context"
8-
"sync"
98

109
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1110
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
1211

13-
prismv4 "github.com/nutanix-cloud-native/prism-go-client/v4"
14-
15-
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/variables"
1612
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/webhook/preflight"
13+
preflightutil "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/webhook/preflight/util"
1714
)
1815

1916
type Checker struct {
2017
client ctrlclient.Client
2118
cluster *clusterv1.Cluster
2219

23-
nutanixClient *prismv4.Client
24-
25-
workerConfigGetterByMachineDeploymentName map[string]func() (*variables.WorkerNodeConfigSpec, error)
26-
workerConfigGetterByMachineDeploymentNameMutex sync.Mutex
20+
clientGetter *ClientGetter
21+
variablesGetter *preflightutil.VariablesGetter
2722
}
2823

2924
func (n *Checker) Init(
@@ -33,10 +28,10 @@ func (n *Checker) Init(
3328
) []preflight.Check {
3429
n.client = client
3530
n.cluster = cluster
31+
n.clientGetter = &ClientGetter{client: client, cluster: cluster}
32+
n.variablesGetter = preflightutil.NewVariablesGetter(cluster)
3633

37-
checks := []preflight.Check{
34+
return []preflight.Check{
3835
n.VMImageCheck,
3936
}
40-
41-
return checks
4237
}

pkg/webhook/preflight/nutanix/client.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77

88
corev1 "k8s.io/api/core/v1"
99
"k8s.io/apimachinery/pkg/types"
10+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
11+
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
1012

1113
prism "github.com/nutanix-cloud-native/prism-go-client"
1214
prismcredentials "github.com/nutanix-cloud-native/prism-go-client/environment/credentials"
@@ -15,12 +17,18 @@ import (
1517
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/variables"
1618
)
1719

18-
// clientV4 creates a new Prism V4 client for the Nutanix cluster.
19-
// It retrieves the Prism Central credentials from the provided client and
20-
// uses them to create the client. The client is cached for future use.
21-
// The function returns an error if the credentials cannot be retrieved or
22-
// if the Prism Central endpoint cannot be parsed.
23-
func (n *Checker) clientV4(ctx context.Context, clusterConfig *variables.ClusterConfigSpec) (*prismv4.Client, error) {
20+
// ClientGetter provides methods to create Prism Central clients.
21+
// These methods are thread-safe and cache the results for efficiency.
22+
type ClientGetter struct {
23+
client ctrlclient.Client
24+
cluster *clusterv1.Cluster
25+
nutanixClient *prismv4.Client
26+
}
27+
28+
// V4 creates a new Prism V4 client for the Nutanix cluster using Prism Central credentials
29+
// referenced in the clusterConfig. The client is cached for future use. The function returns an
30+
// error if the credentials cannot be retrieved or if the Prism Central endpoint cannot be parsed.
31+
func (g *ClientGetter) V4(ctx context.Context, clusterConfig *variables.ClusterConfigSpec) (*prismv4.Client, error) {
2432
return sync.OnceValues(func() (*prismv4.Client, error) {
2533
if clusterConfig == nil || clusterConfig.Nutanix == nil {
2634
return nil, fmt.Errorf("clusterConfig variable is nil or does not contain Nutanix config")
@@ -31,10 +39,10 @@ func (n *Checker) clientV4(ctx context.Context, clusterConfig *variables.Cluster
3139
}
3240

3341
credentialsSecret := &corev1.Secret{}
34-
if err := n.client.Get(
42+
if err := g.client.Get(
3543
ctx,
3644
types.NamespacedName{
37-
Namespace: n.cluster.Namespace,
45+
Namespace: g.cluster.Namespace,
3846
Name: clusterConfig.Nutanix.PrismCentralEndpoint.Credentials.SecretRef.Name,
3947
},
4048
credentialsSecret,
@@ -62,7 +70,7 @@ func (n *Checker) clientV4(ctx context.Context, clusterConfig *variables.Cluster
6270
if err != nil {
6371
return nil, fmt.Errorf("failed to create Prism V4 client: %w", err)
6472
}
65-
n.nutanixClient = nutanixClient
66-
return n.nutanixClient, nil
73+
g.nutanixClient = nutanixClient
74+
return g.nutanixClient, nil
6775
})()
6876
}

pkg/webhook/preflight/nutanix/image.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func (n *Checker) VMImageCheck(ctx context.Context) preflight.CheckResult {
2121
}
2222

2323
// Check control plane VM image.
24-
clusterConfig, err := n.getClusterConfig()
24+
clusterConfig, err := n.variablesGetter.ClusterConfig()
2525
if err != nil {
2626
result.Error = true
2727
result.Causes = append(result.Causes, metav1.StatusCause{
@@ -47,7 +47,7 @@ func (n *Checker) VMImageCheck(ctx context.Context) preflight.CheckResult {
4747

4848
// Check worker VM images.
4949
for _, md := range n.cluster.Spec.Topology.Workers.MachineDeployments {
50-
workerConfig, err := n.getWorkerConfigForMachineDeployment(md)
50+
workerConfig, err := n.variablesGetter.WorkerConfigForMachineDeployment(md)
5151
if err != nil {
5252
result.Error = true
5353
result.Causes = append(result.Causes, metav1.StatusCause{
@@ -95,7 +95,7 @@ func (n *Checker) vmImageCheckForMachineDetails(
9595
}
9696

9797
if details.Image != nil {
98-
client, err := n.clientV4(ctx, clusterConfig)
98+
client, err := n.clientGetter.V4(ctx, clusterConfig)
9999
if err != nil {
100100
result.Allowed = false
101101
result.Error = true

pkg/webhook/preflight/nutanix/variables.go

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package nutanix
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
7+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
8+
9+
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/variables"
10+
)
11+
12+
// VariablesGetter provides methods to retrieve variables from a Cluster object.
13+
// These methods are thread-safe and cache the results for efficiency.
14+
type VariablesGetter struct {
15+
cluster *clusterv1.Cluster
16+
workerConfigGetterByMachineDeploymentName map[string]func() (*variables.WorkerNodeConfigSpec, error)
17+
workerConfigGetterByMachineDeploymentNameMutex sync.Mutex
18+
}
19+
20+
func NewVariablesGetter(cluster *clusterv1.Cluster) *VariablesGetter {
21+
return &VariablesGetter{
22+
cluster: cluster,
23+
workerConfigGetterByMachineDeploymentName: make(
24+
map[string]func() (*variables.WorkerNodeConfigSpec, error),
25+
),
26+
workerConfigGetterByMachineDeploymentNameMutex: sync.Mutex{},
27+
}
28+
}
29+
30+
// ClusterConfig retrieves the cluster configuration variables from the Cluster object.
31+
// This method is thread-safe, and caches the result.
32+
func (g *VariablesGetter) ClusterConfig() (*variables.ClusterConfigSpec, error) {
33+
return sync.OnceValues(func() (*variables.ClusterConfigSpec, error) {
34+
if g.cluster.Spec.Topology.Variables == nil {
35+
return nil, nil
36+
}
37+
38+
clusterConfig, err := variables.UnmarshalClusterConfigVariable(g.cluster.Spec.Topology.Variables)
39+
if err != nil {
40+
return nil, fmt.Errorf("failed to unmarshal .variables[.name=clusterConfig]: %w", err)
41+
}
42+
43+
return clusterConfig, nil
44+
})()
45+
}
46+
47+
// WorkerConfigForMachineDeployment retrieves the worker configuration variables for the given MachineDeployment.
48+
// This method is thread-safe, and caches the result.
49+
func (g *VariablesGetter) WorkerConfigForMachineDeployment(
50+
md clusterv1.MachineDeploymentTopology,
51+
) (*variables.WorkerNodeConfigSpec, error) {
52+
g.workerConfigGetterByMachineDeploymentNameMutex.Lock()
53+
defer g.workerConfigGetterByMachineDeploymentNameMutex.Unlock()
54+
55+
fn, ok := g.workerConfigGetterByMachineDeploymentName[md.Name]
56+
if !ok {
57+
fn = sync.OnceValues(func() (*variables.WorkerNodeConfigSpec, error) {
58+
if md.Variables == nil {
59+
return nil, nil
60+
}
61+
62+
workerConfig, err := variables.UnmarshalWorkerConfigVariable(md.Variables.Overrides)
63+
if err != nil {
64+
return nil, fmt.Errorf("failed to unmarshal .variables.overrides[.name=workerConfig]: %w", err)
65+
}
66+
67+
return workerConfig, nil
68+
})
69+
}
70+
return fn()
71+
}

0 commit comments

Comments
 (0)