Skip to content

Commit 8ec8817

Browse files
committed
feat: make firewallID mutable, propagate it from lmt->lm
1 parent a857b88 commit 8ec8817

File tree

6 files changed

+63
-21
lines changed

6 files changed

+63
-21
lines changed

api/v1alpha2/linodemachine_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ type LinodeMachineSpec struct {
6767
PrivateIP *bool `json:"privateIP,omitempty"`
6868
// Tags is a list of tags to apply to the Linode instance.
6969
Tags []string `json:"tags,omitempty"`
70-
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
70+
// FirewallID is the id of the cloud firewall to apply to the Linode Instance
7171
FirewallID int `json:"firewallID,omitempty"`
7272
// OSDisk is configuration for the root disk that includes the OS,
7373
// if not specified this defaults to whatever space is not taken up by the DataDisks

api/v1alpha2/linodemachinetemplate_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ type LinodeMachineTemplateStatus struct {
3333
// +optional
3434
Tags []string `json:"tags,omitempty"`
3535

36+
// Firewall ID that is currently applied to the LinodeMachineTemplate.
37+
// +optional
38+
FirewallID int `json:"firewallID,omitempty"`
39+
3640
// Conditions represent the latest available observations of a LinodeMachineTemplate's current state.
3741
// +optional
3842
Conditions []metav1.Condition `json:"conditions,omitempty"`

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,9 @@ spec:
164164
- message: Value is immutable
165165
rule: self == oldSelf
166166
firewallID:
167+
description: FirewallID is the id of the cloud firewall to apply to
168+
the Linode Instance
167169
type: integer
168-
x-kubernetes-validations:
169-
- message: Value is immutable
170-
rule: self == oldSelf
171170
firewallRef:
172171
description: FirewallRef is a reference to a firewall object. This
173172
makes the linode use the specified firewall.

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,9 @@ spec:
154154
- message: Value is immutable
155155
rule: self == oldSelf
156156
firewallID:
157+
description: FirewallID is the id of the cloud firewall to
158+
apply to the Linode Instance
157159
type: integer
158-
x-kubernetes-validations:
159-
- message: Value is immutable
160-
rule: self == oldSelf
161160
firewallRef:
162161
description: FirewallRef is a reference to a firewall object.
163162
This makes the linode use the specified firewall.
@@ -541,6 +540,9 @@ spec:
541540
- type
542541
type: object
543542
type: array
543+
firewallID:
544+
description: Firewall ID that is currently applied to the LinodeMachineTemplate.
545+
type: integer
544546
tags:
545547
description: tags that are currently applied to the LinodeMachineTemplate.
546548
items:

docs/src/reference/out.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ _Appears in:_
629629
| `backupsEnabled` _boolean_ | | | |
630630
| `privateIP` _boolean_ | | | |
631631
| `tags` _string array_ | Tags is a list of tags to apply to the Linode instance. | | |
632-
| `firewallID` _integer_ | | | |
632+
| `firewallID` _integer_ | FirewallID is the id of the cloud firewall to apply to the Linode Instance | | |
633633
| `osDisk` _[InstanceDisk](#instancedisk)_ | OSDisk is configuration for the root disk that includes the OS,<br />if not specified this defaults to whatever space is not taken up by the DataDisks | | |
634634
| `dataDisks` _object (keys:string, values:[InstanceDisk](#instancedisk))_ | DataDisks is a map of any additional disks to add to an instance,<br />The sum of these disks + the OSDisk must not be more than allowed on a linodes plan | | |
635635
| `diskEncryption` _string_ | DiskEncryption determines if the disks of the instance should be encrypted. The default is disabled. | | Enum: [enabled disabled] <br /> |
@@ -755,6 +755,7 @@ _Appears in:_
755755
| Field | Description | Default | Validation |
756756
| --- | --- | --- | --- |
757757
| `tags` _string array_ | tags that are currently applied to the LinodeMachineTemplate. | | |
758+
| `firewallID` _integer_ | Firewall ID that is currently applied to the LinodeMachineTemplate. | | |
758759
| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#condition-v1-meta) array_ | Conditions represent the latest available observations of a LinodeMachineTemplate's current state. | | |
759760

760761

internal/controller/linodemachinetemplate_controller.go

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,36 @@ func (lmtr *LinodeMachineTemplateReconciler) reconcile(ctx context.Context, lmtS
126126
}
127127

128128
machinesFoundForTemplate = true
129-
if !slices.Equal(lmtScope.LinodeMachineTemplate.Spec.Template.Spec.Tags, lmtScope.LinodeMachineTemplate.Status.Tags) {
130-
err := lmtr.reconcileTags(ctx, lmtScope.LinodeMachineTemplate, &machine)
131-
if err != nil {
132-
lmtr.Logger.Error(err, "Failed to add tags to LinodeMachine", "template", lmtScope.LinodeMachineTemplate.Name, "machine", machine.Name)
133-
outErr = errors.Join(outErr, err)
134129

135-
failureReason = "FailedToPatchLinodeMachine"
130+
// Define reconciliation tasks
131+
reconciliationTasks := []struct {
132+
shouldReconcile bool
133+
fieldType string
134+
failureReason string
135+
logMessage string
136+
}{
137+
{
138+
shouldReconcile: !slices.Equal(lmtScope.LinodeMachineTemplate.Spec.Template.Spec.Tags, lmtScope.LinodeMachineTemplate.Status.Tags),
139+
fieldType: "tags",
140+
failureReason: "FailedToPatchLinodeMachineWithTags",
141+
logMessage: "Failed to update tags on LinodeMachine",
142+
},
143+
{
144+
shouldReconcile: lmtScope.LinodeMachineTemplate.Spec.Template.Spec.FirewallID != lmtScope.LinodeMachineTemplate.Status.FirewallID,
145+
fieldType: "firewallID",
146+
failureReason: "FailedToPatchLinodeMachineWithFirewallID",
147+
logMessage: "Failed to update firewall ID on LinodeMachine",
148+
},
149+
}
150+
151+
// Execute reconciliation tasks
152+
for _, task := range reconciliationTasks {
153+
if task.shouldReconcile {
154+
if err := lmtr.reconcileField(ctx, lmtScope.LinodeMachineTemplate, &machine, task.fieldType); err != nil {
155+
lmtr.Logger.Error(err, task.logMessage, "template", lmtScope.LinodeMachineTemplate.Name, "machine", machine.Name)
156+
outErr = errors.Join(outErr, err)
157+
failureReason = task.failureReason
158+
}
136159
}
137160
}
138161
}
@@ -142,28 +165,41 @@ func (lmtr *LinodeMachineTemplateReconciler) reconcile(ctx context.Context, lmtS
142165
return ctrl.Result{}, nil
143166
}
144167

145-
// update the LMT status.tags if all the linodeMachines spec.tags is successfully updated.
168+
// update the LMT status if all the linodeMachines are successfully updated.
146169
if outErr == nil {
147170
lmtScope.LinodeMachineTemplate.Status.Tags = slices.Clone(lmtScope.LinodeMachineTemplate.Spec.Template.Spec.Tags)
171+
lmtScope.LinodeMachineTemplate.Status.FirewallID = lmtScope.LinodeMachineTemplate.Spec.Template.Spec.FirewallID
148172
lmtr.Logger.Info("Successfully reconciled LinodeMachineTemplate", "name", lmtScope.LinodeMachineTemplate.Name)
149173
} else {
150174
lmtr.Logger.Error(outErr, "Error in reconciling LinodeMachineTemplate, retrying..", "name", lmtScope.LinodeMachineTemplate.Name)
151175
}
152176
return ctrl.Result{}, outErr
153177
}
154178

155-
func (lmtr *LinodeMachineTemplateReconciler) reconcileTags(ctx context.Context, lmt *infrav1alpha2.LinodeMachineTemplate, machine *infrav1alpha2.LinodeMachine) error {
179+
// reconcileField updates a specific field on a LinodeMachine based on the field type
180+
func (lmtr *LinodeMachineTemplateReconciler) reconcileField(ctx context.Context, lmt *infrav1alpha2.LinodeMachineTemplate, machine *infrav1alpha2.LinodeMachine, fieldType string) error {
156181
helper, err := patch.NewHelper(machine, lmtr.Client)
157182
if err != nil {
158183
return fmt.Errorf("failed to init patch helper: %w", err)
159184
}
160185

161-
machine.Spec.Tags = lmt.Spec.Template.Spec.Tags
162-
163-
if err := helper.Patch(ctx, machine); err != nil {
164-
return fmt.Errorf("failed to patch LinodeMachine %s with new tags: %w", machine.Name, err)
186+
switch fieldType {
187+
case "tags":
188+
machine.Spec.Tags = lmt.Spec.Template.Spec.Tags
189+
if err := helper.Patch(ctx, machine); err != nil {
190+
return fmt.Errorf("failed to patch LinodeMachine %s with new %s: %w", machine.Name, fieldType, err)
191+
}
192+
lmtr.Logger.Info("Patched LinodeMachine with new tags", "machine", machine.Name, "tags", lmt.Spec.Template.Spec.Tags)
193+
case "firewallID":
194+
machine.Spec.FirewallID = lmt.Spec.Template.Spec.FirewallID
195+
if err := helper.Patch(ctx, machine); err != nil {
196+
return fmt.Errorf("failed to patch LinodeMachine %s with new %s: %w", machine.Name, fieldType, err)
197+
}
198+
lmtr.Logger.Info("Patched LinodeMachine with new firewall ID", "machine", machine.Name, "firewallID", lmt.Spec.Template.Spec.FirewallID)
199+
default:
200+
return fmt.Errorf("unsupported field type: %s", fieldType)
165201
}
166-
lmtr.Logger.Info("Patched LinodeMachine with new tags", "machine", machine.Name, "tags", lmt.Spec.Template.Spec.Tags)
202+
167203
return nil
168204
}
169205

0 commit comments

Comments
 (0)