Skip to content

Commit 4ea52c8

Browse files
Fix review comments 2
1 parent ddaf62c commit 4ea52c8

File tree

5 files changed

+72
-18
lines changed

5 files changed

+72
-18
lines changed

api/v1beta2/awsmachinetemplate_types.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ const (
3333
ArchitectureArm64 Architecture = "arm64"
3434
)
3535

36+
// OperatingSystem represents the operating system of the node.
37+
// Its underlying type is a string and its value can be any of linux, windows.
38+
type OperatingSystem string
39+
3640
// Operating system constants.
3741
const (
3842
// OperatingSystemLinux represents the Linux operating system.
39-
OperatingSystemLinux = "linux"
43+
OperatingSystemLinux OperatingSystem = "linux"
4044
// OperatingSystemWindows represents the Windows operating system.
41-
OperatingSystemWindows = "windows"
45+
OperatingSystemWindows OperatingSystem = "windows"
4246
)
4347

4448
// NodeInfo contains information about the node's architecture and operating system.
@@ -48,11 +52,11 @@ type NodeInfo struct {
4852
// +kubebuilder:validation:Enum=amd64;arm64
4953
// +optional
5054
Architecture Architecture `json:"architecture,omitempty"`
51-
// OperatingSystem is a string representing the operating system of the node.
52-
// This may be a string like 'linux' or 'windows'.
55+
// OperatingSystem is the operating system of the node.
56+
// Its underlying type is a string and its value can be any of linux, windows.
5357
// +kubebuilder:validation:Enum=linux;windows
5458
// +optional
55-
OperatingSystem string `json:"operatingSystem,omitempty"`
59+
OperatingSystem OperatingSystem `json:"operatingSystem,omitempty"`
5660
}
5761

5862
// AWSMachineTemplateStatus defines a status for an AWSMachineTemplate.

config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,8 +1172,8 @@ spec:
11721172
type: string
11731173
operatingSystem:
11741174
description: |-
1175-
OperatingSystem is a string representing the operating system of the node.
1176-
This may be a string like 'linux' or 'windows'.
1175+
OperatingSystem is the operating system of the node.
1176+
Its underlying type is a string and its value can be any of linux, windows.
11771177
enum:
11781178
- linux
11791179
- windows

controllers/awsmachinetemplate_controller.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"sigs.k8s.io/controller-runtime/pkg/controller"
3333

3434
infrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
35+
ekscontrolplanev1 "sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/eks/api/v1beta2"
3536
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/scope"
3637
ec2service "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/services/ec2"
3738
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/logger"
@@ -90,6 +91,13 @@ func (r *AWSMachineTemplateReconciler) Reconcile(ctx context.Context, req ctrl.R
9091
return ctrl.Result{}, nil
9192
}
9293

94+
// Check if capacity and nodeInfo are already populated
95+
// This avoids unnecessary AWS API calls when the status is already populated
96+
if len(awsMachineTemplate.Status.Capacity) > 0 &&
97+
awsMachineTemplate.Status.NodeInfo != nil && awsMachineTemplate.Status.NodeInfo.OperatingSystem != "" && awsMachineTemplate.Status.NodeInfo.Architecture != "" {
98+
return ctrl.Result{}, nil
99+
}
100+
93101
// Find the region by checking ownerReferences
94102
region, err := r.getRegion(ctx, awsMachineTemplate)
95103
if err != nil {
@@ -169,6 +177,21 @@ func (r *AWSMachineTemplateReconciler) getRegion(ctx context.Context, template *
169177
}
170178
}
171179

180+
// Get region from AWSManagedControlPlane (EKS cluster)
181+
if cluster.Spec.ControlPlaneRef != nil && cluster.Spec.ControlPlaneRef.Kind == "AWSManagedControlPlane" {
182+
awsManagedCP := &ekscontrolplanev1.AWSManagedControlPlane{}
183+
if err := r.Get(ctx, client.ObjectKey{
184+
Namespace: cluster.Namespace,
185+
Name: cluster.Spec.ControlPlaneRef.Name,
186+
}, awsManagedCP); err != nil {
187+
if !apierrors.IsNotFound(err) {
188+
return "", errors.Wrapf(err, "failed to get AWSManagedControlPlane %s/%s", cluster.Namespace, cluster.Spec.ControlPlaneRef.Name)
189+
}
190+
} else if awsManagedCP.Spec.Region != "" {
191+
return awsManagedCP.Spec.Region, nil
192+
}
193+
}
194+
172195
return "", nil
173196
}
174197

@@ -288,7 +311,7 @@ func (r *AWSMachineTemplateReconciler) getNodeInfo(ctx context.Context, ec2Clien
288311
}
289312

290313
// getNodeInfoFromAMI queries the AMI to determine architecture and operating system.
291-
func (r *AWSMachineTemplateReconciler) getNodeInfoFromAMI(ctx context.Context, ec2Client *ec2.Client, amiID string) (infrav1.Architecture, string, error) {
314+
func (r *AWSMachineTemplateReconciler) getNodeInfoFromAMI(ctx context.Context, ec2Client *ec2.Client, amiID string) (infrav1.Architecture, infrav1.OperatingSystem, error) {
292315
input := &ec2.DescribeImagesInput{
293316
ImageIds: []string{amiID},
294317
}
@@ -325,7 +348,7 @@ func (r *AWSMachineTemplateReconciler) getNodeInfoFromAMI(ctx context.Context, e
325348
// 2. Check PlatformDetails field for Windows indication
326349
if os != infrav1.OperatingSystemWindows && image.PlatformDetails != nil {
327350
platformDetails := strings.ToLower(*image.PlatformDetails)
328-
if strings.Contains(platformDetails, infrav1.OperatingSystemWindows) {
351+
if strings.Contains(platformDetails, string(infrav1.OperatingSystemWindows)) {
329352
os = infrav1.OperatingSystemWindows
330353
}
331354
}

controllers/awsmachinetemplate_controller_unit_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,32 @@ func TestAWSMachineTemplateReconciler(t *testing.T) {
192192
// integration tests.
193193

194194
t.Run("Reconcile", func(t *testing.T) {
195+
t.Run("should skip reconcile when capacity and nodeInfo are already populated", func(t *testing.T) {
196+
g := NewWithT(t)
197+
template := newAWSMachineTemplate("test-template")
198+
template.Status.Capacity = corev1.ResourceList{
199+
corev1.ResourceCPU: *resource.NewQuantity(2, resource.DecimalSI),
200+
corev1.ResourceMemory: resource.MustParse("4Gi"),
201+
}
202+
template.Status.NodeInfo = &infrav1.NodeInfo{
203+
Architecture: infrav1.ArchitectureAmd64,
204+
OperatingSystem: infrav1.OperatingSystemLinux,
205+
}
206+
207+
reconciler := &AWSMachineTemplateReconciler{
208+
Client: newFakeClient(template),
209+
}
210+
211+
// Should skip reconcile and return early without calling AWS APIs
212+
// No need to set up owner cluster or region since the early return happens before that
213+
result, err := reconciler.Reconcile(context.Background(), ctrl.Request{
214+
NamespacedName: client.ObjectKeyFromObject(template),
215+
})
216+
217+
g.Expect(err).To(BeNil())
218+
g.Expect(result.Requeue).To(BeFalse())
219+
})
220+
195221
t.Run("should reconcile when capacity set but nodeInfo is not", func(t *testing.T) {
196222
g := NewWithT(t)
197223
template := newAWSMachineTemplate("test-template")

main.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,19 @@ func setupReconcilersAndWebhooks(ctx context.Context, mgr ctrl.Manager,
360360
setupLog.Error(err, "unable to create controller", "controller", "AWSCluster")
361361
os.Exit(1)
362362
}
363+
364+
setupLog.Info("enabling AWSMachineTemplate controller")
365+
if err := (&controllers.AWSMachineTemplateReconciler{
366+
Client: mgr.GetClient(),
367+
WatchFilterValue: watchFilterValue,
368+
}).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: awsClusterConcurrency, RecoverPanic: ptr.To[bool](true)}); err != nil {
369+
setupLog.Error(err, "unable to create controller", "controller", "AWSMachineTemplate")
370+
os.Exit(1)
371+
}
363372
} else {
364373
setupLog.Info("controller disabled", "controller", "AWSMachine", "controller-group", controllers.Unmanaged)
365374
setupLog.Info("controller disabled", "controller", "AWSCluster", "controller-group", controllers.Unmanaged)
375+
setupLog.Info("controller disabled", "controller", "AWSMachineTemplate", "controller-group", controllers.Unmanaged)
366376
}
367377

368378
if feature.Gates.Enabled(feature.MachinePool) {
@@ -407,15 +417,6 @@ func setupReconcilersAndWebhooks(ctx context.Context, mgr ctrl.Manager,
407417
}
408418
}
409419

410-
setupLog.Debug("enabling AWSMachineTemplate controller")
411-
if err := (&controllers.AWSMachineTemplateReconciler{
412-
Client: mgr.GetClient(),
413-
WatchFilterValue: watchFilterValue,
414-
}).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: awsClusterConcurrency, RecoverPanic: ptr.To[bool](true)}); err != nil {
415-
setupLog.Error(err, "unable to create controller", "controller", "AWSMachineTemplate")
416-
os.Exit(1)
417-
}
418-
419420
if err := (&infrav1.AWSMachineTemplate{}).SetupWebhookWithManager(mgr); err != nil {
420421
setupLog.Error(err, "unable to create webhook", "webhook", "AWSMachineTemplate")
421422
os.Exit(1)

0 commit comments

Comments
 (0)