Skip to content

Commit 2d5238d

Browse files
authored
Merge pull request #12691 from sbueringer/pr-fix-engine-1.11
[release-1.11] 🐛 Ensure holder field path in GeneratePatchRequest is set based on contract
2 parents 5893b38 + a5fabc2 commit 2d5238d

File tree

4 files changed

+183
-116
lines changed

4 files changed

+183
-116
lines changed

exp/topology/desiredstate/desired_state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func NewGenerator(client client.Client, clusterCache clustercache.ClusterCache,
6868
Client: client,
6969
ClusterCache: clusterCache,
7070
RuntimeClient: runtimeClient,
71-
patchEngine: patches.NewEngine(runtimeClient),
71+
patchEngine: patches.NewEngine(client, runtimeClient),
7272
}
7373
}
7474

internal/controllers/topology/cluster/patches/engine.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
kerrors "k8s.io/apimachinery/pkg/util/errors"
3030
"k8s.io/klog/v2"
3131
ctrl "sigs.k8s.io/controller-runtime"
32+
"sigs.k8s.io/controller-runtime/pkg/client"
3233

3334
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
3435
runtimehooksv1 "sigs.k8s.io/cluster-api/api/runtime/hooks/v1alpha1"
@@ -48,14 +49,16 @@ type Engine interface {
4849
}
4950

5051
// NewEngine creates a new patch engine.
51-
func NewEngine(runtimeClient runtimeclient.Client) Engine {
52+
func NewEngine(c client.Client, runtimeClient runtimeclient.Client) Engine {
5253
return &engine{
54+
client: c,
5355
runtimeClient: runtimeClient,
5456
}
5557
}
5658

5759
// engine implements the Engine interface.
5860
type engine struct {
61+
client client.Client
5962
runtimeClient runtimeclient.Client
6063
}
6164

@@ -73,8 +76,14 @@ func (e *engine) Apply(ctx context.Context, blueprint *scope.ClusterBlueprint, d
7376

7477
log := ctrl.LoggerFrom(ctx)
7578

79+
// Determine contract version used by the ControlPlane.
80+
controlPlaneContractVersion, err := contract.GetContractVersionForVersion(ctx, e.client, desired.ControlPlane.Object.GroupVersionKind().GroupKind(), desired.ControlPlane.Object.GroupVersionKind().Version)
81+
if err != nil {
82+
return errors.Wrapf(err, "failed to generate patch request: failed to get contract version for the ControlPlane object")
83+
}
84+
7685
// Create a patch generation request.
77-
req, err := createRequest(blueprint, desired)
86+
req, err := createRequest(blueprint, desired, controlPlaneContractVersion)
7887
if err != nil {
7988
return errors.Wrapf(err, "failed to generate patch request")
8089
}
@@ -91,7 +100,7 @@ func (e *engine) Apply(ctx context.Context, blueprint *scope.ClusterBlueprint, d
91100
if clusterClassPatch.External == nil {
92101
definitionFrom = clusterv1.VariableDefinitionFromInline
93102
}
94-
if err := addVariablesForPatch(blueprint, desired, req, definitionFrom); err != nil {
103+
if err := addVariablesForPatch(blueprint, desired, req, definitionFrom, controlPlaneContractVersion); err != nil {
95104
return errors.Wrapf(err, "failed to calculate variables for patch %q", clusterClassPatch.Name)
96105
}
97106
log.V(5).Info("Applying patch to templates")
@@ -144,15 +153,15 @@ func (e *engine) Apply(ctx context.Context, blueprint *scope.ClusterBlueprint, d
144153

145154
// Use patched templates to update the desired state objects.
146155
log.V(5).Info("Applying patched templates to desired state")
147-
if err := updateDesiredState(ctx, req, blueprint, desired); err != nil {
156+
if err := updateDesiredState(ctx, req, blueprint, desired, controlPlaneContractVersion); err != nil {
148157
return errors.Wrapf(err, "failed to apply patches to desired state")
149158
}
150159

151160
return nil
152161
}
153162

154163
// addVariablesForPatch adds variables for a given ClusterClassPatch to the items in the PatchRequest.
155-
func addVariablesForPatch(blueprint *scope.ClusterBlueprint, desired *scope.ClusterState, req *runtimehooksv1.GeneratePatchesRequest, definitionFrom string) error {
164+
func addVariablesForPatch(blueprint *scope.ClusterBlueprint, desired *scope.ClusterState, req *runtimehooksv1.GeneratePatchesRequest, definitionFrom, controlPlaneContractVersion string) error {
156165
// If there is no definitionFrom return an error.
157166
if definitionFrom == "" {
158167
return errors.New("failed to calculate variables: no patch name provided")
@@ -187,7 +196,7 @@ func addVariablesForPatch(blueprint *scope.ClusterBlueprint, desired *scope.Clus
187196
}
188197
// If the item holder reference is a Control Plane machine add the Control Plane variables.
189198
if blueprint.HasControlPlaneInfrastructureMachine() &&
190-
item.HolderReference.FieldPath == strings.Join(contract.ControlPlane().MachineTemplate().InfrastructureRef().Path(), ".") {
199+
item.HolderReference.FieldPath == getControlPlaneHolderFieldPath(controlPlaneContractVersion) {
191200
item.Variables = controlPlaneVariables
192201
}
193202
// If the item holder reference is a MachineDeployment calculate the variables for each MachineDeploymentTopology
@@ -261,7 +270,7 @@ func getMPTopologyFromMP(blueprint *scope.ClusterBlueprint, mp *clusterv1.Machin
261270
// replicas of a MachineDeployment.
262271
// NOTE: A single GeneratePatchesRequest object is used to carry templates state across subsequent Generate calls.
263272
// NOTE: This function does not add variables to items for the request, as the variables depend on the specific patch.
264-
func createRequest(blueprint *scope.ClusterBlueprint, desired *scope.ClusterState) (*runtimehooksv1.GeneratePatchesRequest, error) {
273+
func createRequest(blueprint *scope.ClusterBlueprint, desired *scope.ClusterState, controlPlaneContractVersion string) (*runtimehooksv1.GeneratePatchesRequest, error) {
265274
req := &runtimehooksv1.GeneratePatchesRequest{}
266275

267276
// Add the InfrastructureClusterTemplate.
@@ -288,7 +297,7 @@ func createRequest(blueprint *scope.ClusterBlueprint, desired *scope.ClusterStat
288297
// add the InfrastructureMachineTemplate for control plane machines.
289298
if blueprint.HasControlPlaneInfrastructureMachine() {
290299
t, err := newRequestItemBuilder(blueprint.ControlPlane.InfrastructureMachineTemplate).
291-
WithHolder(desired.ControlPlane.Object, desired.ControlPlane.Object.GroupVersionKind(), strings.Join(contract.ControlPlane().MachineTemplate().InfrastructureRef().Path(), ".")).
300+
WithHolder(desired.ControlPlane.Object, desired.ControlPlane.Object.GroupVersionKind(), getControlPlaneHolderFieldPath(controlPlaneContractVersion)).
292301
Build()
293302
if err != nil {
294303
return nil, errors.Wrapf(err, "failed to prepare ControlPlane's %s %s for patching",
@@ -523,7 +532,7 @@ func convertToValidationRequest(generateRequest *runtimehooksv1.GeneratePatchesR
523532

524533
// updateDesiredState uses the patched templates of a GeneratePatchesRequest to update the desired state.
525534
// NOTE: This func should be called after all the patches have been applied to the GeneratePatchesRequest.
526-
func updateDesiredState(ctx context.Context, req *runtimehooksv1.GeneratePatchesRequest, blueprint *scope.ClusterBlueprint, desired *scope.ClusterState) error {
535+
func updateDesiredState(ctx context.Context, req *runtimehooksv1.GeneratePatchesRequest, blueprint *scope.ClusterBlueprint, desired *scope.ClusterState, controlPlaneContractVersion string) error {
527536
var err error
528537

529538
// Update the InfrastructureCluster.
@@ -563,7 +572,7 @@ func updateDesiredState(ctx context.Context, req *runtimehooksv1.GeneratePatches
563572
// If the ClusterClass mandates the ControlPlane has InfrastructureMachines,
564573
// update the InfrastructureMachineTemplate for ControlPlane machines.
565574
if blueprint.HasControlPlaneInfrastructureMachine() {
566-
infrastructureMachineTemplate, err := getTemplateAsUnstructured(req, desired.ControlPlane.Object.GetKind(), strings.Join(contract.ControlPlane().MachineTemplate().InfrastructureRef().Path(), "."), requestTopologyName{})
575+
infrastructureMachineTemplate, err := getTemplateAsUnstructured(req, desired.ControlPlane.Object.GetKind(), getControlPlaneHolderFieldPath(controlPlaneContractVersion), requestTopologyName{})
567576
if err != nil {
568577
return err
569578
}
@@ -631,3 +640,10 @@ func definitionsForPatch(blueprint *scope.ClusterBlueprint, definitionFrom strin
631640
}
632641
return variableDefinitionsForPatch
633642
}
643+
644+
func getControlPlaneHolderFieldPath(contractVersion string) string {
645+
if contractVersion == "v1beta1" {
646+
return strings.Join(contract.ControlPlane().MachineTemplate().InfrastructureV1Beta1Ref().Path(), ".")
647+
}
648+
return strings.Join(contract.ControlPlane().MachineTemplate().InfrastructureRef().Path(), ".")
649+
}

0 commit comments

Comments
 (0)