-
Notifications
You must be signed in to change notification settings - Fork 1.4k
✨ Propagate labels and annotations from ClusterClass and Cluster topology to KCP and MD #7088
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -112,11 +112,16 @@ func computeInfrastructureCluster(_ context.Context, s *scope.Scope) (*unstructu | |
| cluster := s.Current.Cluster | ||
| currentRef := cluster.Spec.InfrastructureRef | ||
|
|
||
| labels := map[string]string{} | ||
| labels[clusterv1.ClusterLabelName] = cluster.Name | ||
| labels[clusterv1.ClusterTopologyOwnedLabel] = "" | ||
|
|
||
| infrastructureCluster, err := templateToObject(templateToInput{ | ||
| template: template, | ||
| templateClonedFromRef: templateClonedFromRef, | ||
| cluster: cluster, | ||
| namePrefix: fmt.Sprintf("%s-", cluster.Name), | ||
| labels: labels, | ||
| currentObjectRef: currentRef, | ||
| // Note: It is not possible to add an ownerRef to Cluster at this stage, otherwise the provisioning | ||
| // of the infrastructure cluster starts no matter of the object being actually referenced by the Cluster itself. | ||
|
|
@@ -176,11 +181,28 @@ func (r *Reconciler) computeControlPlane(ctx context.Context, s *scope.Scope, in | |
| cluster := s.Current.Cluster | ||
| currentRef := cluster.Spec.ControlPlaneRef | ||
|
|
||
| // Compute the labels and annotations to be applied to KubeadmControlPlane and Machines. | ||
| // We merge the labels and annotations from topology and ClusterClass. | ||
| topologyMetadata := s.Blueprint.Topology.ControlPlane.Metadata | ||
| clusterClassMetadata := s.Blueprint.ClusterClass.Spec.ControlPlane.Metadata | ||
|
|
||
| controlPlaneLabels := mergeMap(topologyMetadata.Labels, clusterClassMetadata.Labels) | ||
| controlPlaneAnnotations := mergeMap(topologyMetadata.Annotations, clusterClassMetadata.Annotations) | ||
|
|
||
| // Add the cluster-name and the topology owned labels, so they are propagated down to Machines. | ||
| if controlPlaneLabels == nil { | ||
| controlPlaneLabels = map[string]string{} | ||
| } | ||
| controlPlaneLabels[clusterv1.ClusterLabelName] = cluster.Name | ||
| controlPlaneLabels[clusterv1.ClusterTopologyOwnedLabel] = "" | ||
|
|
||
| controlPlane, err := templateToObject(templateToInput{ | ||
| template: template, | ||
| templateClonedFromRef: templateClonedFromRef, | ||
| cluster: cluster, | ||
| namePrefix: fmt.Sprintf("%s-", cluster.Name), | ||
| labels: controlPlaneLabels, | ||
| annotations: controlPlaneAnnotations, | ||
| currentObjectRef: currentRef, | ||
| // Note: It is not possible to add an ownerRef to Cluster at this stage, otherwise the provisioning | ||
| // of the ControlPlane starts no matter of the object being actually referenced by the Cluster itself. | ||
|
|
@@ -205,22 +227,10 @@ func (r *Reconciler) computeControlPlane(ctx context.Context, s *scope.Scope, in | |
| return nil, errors.Wrap(err, "failed to spec.machineTemplate.infrastructureRef in the ControlPlane object") | ||
| } | ||
|
|
||
| // Compute the labels and annotations to be applied to ControlPlane machines. | ||
| // We merge the labels and annotations from topology and ClusterClass. | ||
| // We also add the cluster-name and the topology owned labels, so they are propagated down to Machines. | ||
| topologyMetadata := s.Blueprint.Topology.ControlPlane.Metadata | ||
| clusterClassMetadata := s.Blueprint.ClusterClass.Spec.ControlPlane.Metadata | ||
|
|
||
| machineLabels := mergeMap(topologyMetadata.Labels, clusterClassMetadata.Labels) | ||
| if machineLabels == nil { | ||
| machineLabels = map[string]string{} | ||
| } | ||
| machineLabels[clusterv1.ClusterLabelName] = cluster.Name | ||
| machineLabels[clusterv1.ClusterTopologyOwnedLabel] = "" | ||
| if err := contract.ControlPlane().MachineTemplate().Metadata().Set(controlPlane, | ||
| &clusterv1.ObjectMeta{ | ||
| Labels: machineLabels, | ||
| Annotations: mergeMap(topologyMetadata.Annotations, clusterClassMetadata.Annotations), | ||
| Labels: controlPlaneLabels, | ||
| Annotations: controlPlaneAnnotations, | ||
| }); err != nil { | ||
| return nil, errors.Wrap(err, "failed to set spec.machineTemplate.metadata in the ControlPlane object") | ||
| } | ||
|
|
@@ -512,6 +522,10 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP | |
| return nil, errors.Wrapf(err, "failed to compute version for %s", machineDeploymentTopology.Name) | ||
| } | ||
|
|
||
| // Compute labels for MachineDeployment and Machines | ||
| machineDeploymentLabels := mergeMap(machineDeploymentTopology.Metadata.Labels, machineDeploymentBlueprint.Metadata.Labels) | ||
| machineDeploymentAnnotations := mergeMap(machineDeploymentTopology.Metadata.Annotations, machineDeploymentBlueprint.Metadata.Annotations) | ||
|
|
||
| // Compute the MachineDeployment object. | ||
| gv := clusterv1.GroupVersion | ||
| desiredMachineDeploymentObj := &clusterv1.MachineDeployment{ | ||
|
|
@@ -527,8 +541,8 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP | |
| ClusterName: s.Current.Cluster.Name, | ||
| Template: clusterv1.MachineTemplateSpec{ | ||
| ObjectMeta: clusterv1.ObjectMeta{ | ||
| Labels: mergeMap(machineDeploymentTopology.Metadata.Labels, machineDeploymentBlueprint.Metadata.Labels), | ||
| Annotations: mergeMap(machineDeploymentTopology.Metadata.Annotations, machineDeploymentBlueprint.Metadata.Annotations), | ||
| Labels: machineDeploymentLabels, | ||
| Annotations: machineDeploymentAnnotations, | ||
| }, | ||
| Spec: clusterv1.MachineSpec{ | ||
| ClusterName: s.Current.Cluster.Name, | ||
|
|
@@ -562,7 +576,10 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP | |
| labels[clusterv1.ClusterLabelName] = s.Current.Cluster.Name | ||
| labels[clusterv1.ClusterTopologyOwnedLabel] = "" | ||
| labels[clusterv1.ClusterTopologyMachineDeploymentLabelName] = machineDeploymentTopology.Name | ||
| desiredMachineDeploymentObj.SetLabels(labels) | ||
| desiredMachineDeploymentObj.SetLabels(mergeMap(labels, machineDeploymentLabels)) | ||
|
|
||
| // Apply Annotations | ||
| desiredMachineDeploymentObj.SetAnnotations(machineDeploymentAnnotations) | ||
|
|
||
| // Set the selector with the subset of labels identifying controlled machines. | ||
| // NOTE: this prevents the web hook to add cluster.x-k8s.io/deployment-name label, that is | ||
|
|
@@ -710,6 +727,8 @@ type templateToInput struct { | |
| cluster *clusterv1.Cluster | ||
| namePrefix string | ||
| currentObjectRef *corev1.ObjectReference | ||
| labels map[string]string | ||
| annotations map[string]string | ||
| // OwnerRef is an optional OwnerReference to attach to the cloned object. | ||
| ownerRef *metav1.OwnerReference | ||
| } | ||
|
|
@@ -718,20 +737,15 @@ type templateToInput struct { | |
| // of adding required labels (cluster, topology), annotations (clonedFrom) | ||
| // and assigning a meaningful name (or reusing current reference name). | ||
| func templateToObject(in templateToInput) (*unstructured.Unstructured, error) { | ||
| // NOTE: The cluster label is added at creation time so this object could be read by the ClusterTopology | ||
| // controller immediately after creation, even before other controllers are going to add the label (if missing). | ||
| labels := map[string]string{} | ||
| labels[clusterv1.ClusterLabelName] = in.cluster.Name | ||
| labels[clusterv1.ClusterTopologyOwnedLabel] = "" | ||
|
|
||
|
Comment on lines
-723
to
-726
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about keeping this and doing a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Hi @ykakarap! I would be grateful if you take this on. Unfortunately i don't have free time right now to continue with it :( |
||
| // Generate the object from the template. | ||
| // NOTE: OwnerRef can't be set at this stage; other controllers are going to add OwnerReferences when | ||
| // the object is actually created. | ||
| object, err := external.GenerateTemplate(&external.GenerateTemplateInput{ | ||
| Template: in.template, | ||
| TemplateRef: in.templateClonedFromRef, | ||
| Namespace: in.cluster.Namespace, | ||
| Labels: labels, | ||
| Labels: in.labels, | ||
| Annotations: in.annotations, | ||
| ClusterName: in.cluster.Name, | ||
| OwnerRef: in.ownerRef, | ||
| }) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still mulling about this, but if we are going to propagate labels/annotations to objects down the chain I think we should propagate labels/annotations to bootstrap and infrastructure template as well; this implies also keeping such labels and annotations in sync (TBD how given that this should work no matter is using a cluster class or not)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you consider it a part of this PR, or is it better to create a separate issue\PR to track this activity?