Skip to content

Commit 41f7dda

Browse files
authored
Merge pull request kubernetes-sigs#7917 from ykakarap/label-propagation_clusters-to-objects
✨ Managed Cluster should set labels and annotations on ControlPlane and MDs
2 parents 64c96c3 + 135d4fc commit 41f7dda

File tree

13 files changed

+155
-64
lines changed

13 files changed

+155
-64
lines changed

api/v1beta1/cluster_types.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,10 @@ type Topology struct {
101101

102102
// ControlPlaneTopology specifies the parameters for the control plane nodes in the cluster.
103103
type ControlPlaneTopology struct {
104-
// Metadata is the metadata applied to the machines of the ControlPlane.
104+
// Metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane
105+
// if the ControlPlaneTemplate referenced by the ClusterClass is machine based. If not, it
106+
// is applied only to the ControlPlane.
105107
// At runtime this metadata is merged with the corresponding metadata from the ClusterClass.
106-
//
107-
// This field is supported if and only if the control plane provider template
108-
// referenced in the ClusterClass is Machine based.
109108
// +optional
110109
Metadata ObjectMeta `json:"metadata,omitempty"`
111110

@@ -149,7 +148,7 @@ type WorkersTopology struct {
149148
// MachineDeploymentTopology specifies the different parameters for a set of worker nodes in the topology.
150149
// This set of nodes is managed by a MachineDeployment object whose lifecycle is managed by the Cluster controller.
151150
type MachineDeploymentTopology struct {
152-
// Metadata is the metadata applied to the machines of the MachineDeployment.
151+
// Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment.
153152
// At runtime this metadata is merged with the corresponding metadata from the ClusterClass.
154153
// +optional
155154
Metadata ObjectMeta `json:"metadata,omitempty"`

api/v1beta1/clusterclass_types.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ type ClusterClassSpec struct {
7575

7676
// ControlPlaneClass defines the class for the control plane.
7777
type ControlPlaneClass struct {
78-
// Metadata is the metadata applied to the machines of the ControlPlane.
78+
// Metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane
79+
// if the ControlPlaneTemplate referenced is machine based. If not, it is applied only to the
80+
// ControlPlane.
7981
// At runtime this metadata is merged with the corresponding metadata from the topology.
8082
//
8183
// This field is supported if and only if the control plane provider template
@@ -188,7 +190,7 @@ type MachineDeploymentClass struct {
188190
// MachineDeploymentClassTemplate defines how a MachineDeployment generated from a MachineDeploymentClass
189191
// should look like.
190192
type MachineDeploymentClassTemplate struct {
191-
// Metadata is the metadata applied to the machines of the MachineDeployment.
193+
// Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment.
192194
// At runtime this metadata is merged with the corresponding metadata from the topology.
193195
// +optional
194196
Metadata ObjectMeta `json:"metadata,omitempty"`

api/v1beta1/zz_generated.openapi.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml

Lines changed: 10 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cluster.x-k8s.io_clusters.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/controllers/topology/cluster/desired_state.go

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,29 @@ func (r *Reconciler) computeControlPlane(ctx context.Context, s *scope.Scope, in
179179
cluster := s.Current.Cluster
180180
currentRef := cluster.Spec.ControlPlaneRef
181181

182+
// Compute the labels and annotations to be applied to ControlPlane metadata and ControlPlane machines.
183+
// We merge the labels and annotations from topology and ClusterClass.
184+
// We also add the cluster-name and the topology owned labels, so they are propagated down.
185+
topologyMetadata := s.Blueprint.Topology.ControlPlane.Metadata
186+
clusterClassMetadata := s.Blueprint.ClusterClass.Spec.ControlPlane.Metadata
187+
188+
controlPlaneLabels := mergeMap(topologyMetadata.Labels, clusterClassMetadata.Labels)
189+
if controlPlaneLabels == nil {
190+
controlPlaneLabels = map[string]string{}
191+
}
192+
controlPlaneLabels[clusterv1.ClusterNameLabel] = cluster.Name
193+
controlPlaneLabels[clusterv1.ClusterTopologyOwnedLabel] = ""
194+
195+
controlPlaneAnnotations := mergeMap(topologyMetadata.Annotations, clusterClassMetadata.Annotations)
196+
182197
controlPlane, err := templateToObject(templateToInput{
183198
template: template,
184199
templateClonedFromRef: templateClonedFromRef,
185200
cluster: cluster,
186201
namePrefix: fmt.Sprintf("%s-", cluster.Name),
187202
currentObjectRef: currentRef,
203+
labels: controlPlaneLabels,
204+
annotations: controlPlaneAnnotations,
188205
// Note: It is not possible to add an ownerRef to Cluster at this stage, otherwise the provisioning
189206
// of the ControlPlane starts no matter of the object being actually referenced by the Cluster itself.
190207
})
@@ -224,22 +241,11 @@ func (r *Reconciler) computeControlPlane(ctx context.Context, s *scope.Scope, in
224241
return nil, errors.Wrap(err, "failed to spec.machineTemplate.infrastructureRef in the ControlPlane object")
225242
}
226243

227-
// Compute the labels and annotations to be applied to ControlPlane machines.
228-
// We merge the labels and annotations from topology and ClusterClass.
229-
// We also add the cluster-name and the topology owned labels, so they are propagated down to Machines.
230-
topologyMetadata := s.Blueprint.Topology.ControlPlane.Metadata
231-
clusterClassMetadata := s.Blueprint.ClusterClass.Spec.ControlPlane.Metadata
232-
233-
machineLabels := mergeMap(topologyMetadata.Labels, clusterClassMetadata.Labels)
234-
if machineLabels == nil {
235-
machineLabels = map[string]string{}
236-
}
237-
machineLabels[clusterv1.ClusterNameLabel] = cluster.Name
238-
machineLabels[clusterv1.ClusterTopologyOwnedLabel] = ""
244+
// Apply the ControlPlane labels and annotations to the ControlPlane machines as well.
239245
if err := contract.ControlPlane().MachineTemplate().Metadata().Set(controlPlane,
240246
&clusterv1.ObjectMeta{
241-
Labels: machineLabels,
242-
Annotations: mergeMap(topologyMetadata.Annotations, clusterClassMetadata.Annotations),
247+
Labels: controlPlaneLabels,
248+
Annotations: controlPlaneAnnotations,
243249
}); err != nil {
244250
return nil, errors.Wrap(err, "failed to set spec.machineTemplate.metadata in the ControlPlane object")
245251
}
@@ -659,10 +665,6 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP
659665
MinReadySeconds: minReadySeconds,
660666
Strategy: strategy,
661667
Template: clusterv1.MachineTemplateSpec{
662-
ObjectMeta: clusterv1.ObjectMeta{
663-
Labels: mergeMap(machineDeploymentTopology.Metadata.Labels, machineDeploymentBlueprint.Metadata.Labels),
664-
Annotations: mergeMap(machineDeploymentTopology.Metadata.Annotations, machineDeploymentBlueprint.Metadata.Annotations),
665-
},
666668
Spec: clusterv1.MachineSpec{
667669
ClusterName: s.Current.Cluster.Name,
668670
Version: pointer.String(version),
@@ -683,14 +685,27 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP
683685
desiredMachineDeploymentObj.SetName(currentMachineDeployment.Object.Name)
684686
}
685687

688+
// Apply annotations
689+
machineDeploymentAnnotations := mergeMap(machineDeploymentTopology.Metadata.Annotations, machineDeploymentBlueprint.Metadata.Annotations)
690+
desiredMachineDeploymentObj.SetAnnotations(machineDeploymentAnnotations)
691+
desiredMachineDeploymentObj.Spec.Template.Annotations = machineDeploymentAnnotations
692+
686693
// Apply Labels
687694
// NOTE: On top of all the labels applied to managed objects we are applying the ClusterTopologyMachineDeploymentLabel
688695
// keeping track of the MachineDeployment name from the Topology; this will be used to identify the object in next reconcile loops.
689-
labels := map[string]string{}
690-
labels[clusterv1.ClusterNameLabel] = s.Current.Cluster.Name
691-
labels[clusterv1.ClusterTopologyOwnedLabel] = ""
692-
labels[clusterv1.ClusterTopologyMachineDeploymentNameLabel] = machineDeploymentTopology.Name
693-
desiredMachineDeploymentObj.SetLabels(labels)
696+
machineDeploymentLabels := mergeMap(machineDeploymentTopology.Metadata.Labels, machineDeploymentBlueprint.Metadata.Labels)
697+
if machineDeploymentLabels == nil {
698+
machineDeploymentLabels = map[string]string{}
699+
}
700+
machineDeploymentLabels[clusterv1.ClusterNameLabel] = s.Current.Cluster.Name
701+
machineDeploymentLabels[clusterv1.ClusterTopologyOwnedLabel] = ""
702+
machineDeploymentLabels[clusterv1.ClusterTopologyMachineDeploymentNameLabel] = machineDeploymentTopology.Name
703+
desiredMachineDeploymentObj.SetLabels(machineDeploymentLabels)
704+
705+
// Also set the labels in .spec.template.labels so that they are propagated to
706+
// MachineSet.labels and MachineSet.spec.template.labels and thus to Machine.labels.
707+
// Note: the labels in MachineSet are used to properly cleanup templates when the MachineSet is deleted.
708+
desiredMachineDeploymentObj.Spec.Template.Labels = machineDeploymentLabels
694709

695710
// Set the selector with the subset of labels identifying controlled machines.
696711
// NOTE: this prevents the web hook to add cluster.x-k8s.io/deployment-name label, that is
@@ -700,16 +715,6 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP
700715
desiredMachineDeploymentObj.Spec.Selector.MatchLabels[clusterv1.ClusterTopologyOwnedLabel] = ""
701716
desiredMachineDeploymentObj.Spec.Selector.MatchLabels[clusterv1.ClusterTopologyMachineDeploymentNameLabel] = machineDeploymentTopology.Name
702717

703-
// Also set the labels in .spec.template.labels so that they are propagated to
704-
// MachineSet.labels and MachineSet.spec.template.labels and thus to Machine.labels.
705-
// Note: the labels in MachineSet are used to properly cleanup templates when the MachineSet is deleted.
706-
if desiredMachineDeploymentObj.Spec.Template.Labels == nil {
707-
desiredMachineDeploymentObj.Spec.Template.Labels = map[string]string{}
708-
}
709-
desiredMachineDeploymentObj.Spec.Template.Labels[clusterv1.ClusterNameLabel] = s.Current.Cluster.Name
710-
desiredMachineDeploymentObj.Spec.Template.Labels[clusterv1.ClusterTopologyOwnedLabel] = ""
711-
desiredMachineDeploymentObj.Spec.Template.Labels[clusterv1.ClusterTopologyMachineDeploymentNameLabel] = machineDeploymentTopology.Name
712-
713718
// Set the desired replicas.
714719
desiredMachineDeploymentObj.Spec.Replicas = machineDeploymentTopology.Replicas
715720

@@ -838,6 +843,8 @@ type templateToInput struct {
838843
cluster *clusterv1.Cluster
839844
namePrefix string
840845
currentObjectRef *corev1.ObjectReference
846+
labels map[string]string
847+
annotations map[string]string
841848
// OwnerRef is an optional OwnerReference to attach to the cloned object.
842849
ownerRef *metav1.OwnerReference
843850
}
@@ -849,6 +856,9 @@ func templateToObject(in templateToInput) (*unstructured.Unstructured, error) {
849856
// NOTE: The cluster label is added at creation time so this object could be read by the ClusterTopology
850857
// controller immediately after creation, even before other controllers are going to add the label (if missing).
851858
labels := map[string]string{}
859+
for k, v := range in.labels {
860+
labels[k] = v
861+
}
852862
labels[clusterv1.ClusterNameLabel] = in.cluster.Name
853863
labels[clusterv1.ClusterTopologyOwnedLabel] = ""
854864

@@ -860,6 +870,7 @@ func templateToObject(in templateToInput) (*unstructured.Unstructured, error) {
860870
TemplateRef: in.templateClonedFromRef,
861871
Namespace: in.cluster.Namespace,
862872
Labels: labels,
873+
Annotations: in.annotations,
863874
ClusterName: in.cluster.Name,
864875
OwnerRef: in.ownerRef,
865876
})
@@ -901,6 +912,9 @@ func templateToTemplate(in templateToInput) *unstructured.Unstructured {
901912
if labels == nil {
902913
labels = map[string]string{}
903914
}
915+
for k, v := range in.labels {
916+
labels[k] = v
917+
}
904918
labels[clusterv1.ClusterNameLabel] = in.cluster.Name
905919
labels[clusterv1.ClusterTopologyOwnedLabel] = ""
906920
template.SetLabels(labels)
@@ -911,6 +925,9 @@ func templateToTemplate(in templateToInput) *unstructured.Unstructured {
911925
if annotations == nil {
912926
annotations = map[string]string{}
913927
}
928+
for k, v := range in.annotations {
929+
annotations[k] = v
930+
}
914931
annotations[clusterv1.TemplateClonedFromNameAnnotation] = in.templateClonedFromRef.Name
915932
annotations[clusterv1.TemplateClonedFromGroupKindAnnotation] = in.templateClonedFromRef.GroupVersionKind().GroupKind().String()
916933
delete(annotations, corev1.LastAppliedConfigAnnotation)

0 commit comments

Comments
 (0)