Skip to content

Commit

Permalink
managed Cluster should set labels and annotations on ControlPlane and…
Browse files Browse the repository at this point in the history
… MDs
  • Loading branch information
Yuvaraj Kakaraparthi committed Jan 18, 2023
1 parent 62cd2b6 commit 135d4fc
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 64 deletions.
9 changes: 4 additions & 5 deletions api/v1beta1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,10 @@ type Topology struct {

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

Expand Down Expand Up @@ -149,7 +148,7 @@ type WorkersTopology struct {
// MachineDeploymentTopology specifies the different parameters for a set of worker nodes in the topology.
// This set of nodes is managed by a MachineDeployment object whose lifecycle is managed by the Cluster controller.
type MachineDeploymentTopology struct {
// Metadata is the metadata applied to the machines of the MachineDeployment.
// Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment.
// At runtime this metadata is merged with the corresponding metadata from the ClusterClass.
// +optional
Metadata ObjectMeta `json:"metadata,omitempty"`
Expand Down
6 changes: 4 additions & 2 deletions api/v1beta1/clusterclass_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ type ClusterClassSpec struct {

// ControlPlaneClass defines the class for the control plane.
type ControlPlaneClass struct {
// Metadata is the metadata applied to the machines of the ControlPlane.
// Metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane
// if the ControlPlaneTemplate referenced is machine based. If not, it is applied only to the
// ControlPlane.
// At runtime this metadata is merged with the corresponding metadata from the topology.
//
// This field is supported if and only if the control plane provider template
Expand Down Expand Up @@ -188,7 +190,7 @@ type MachineDeploymentClass struct {
// MachineDeploymentClassTemplate defines how a MachineDeployment generated from a MachineDeploymentClass
// should look like.
type MachineDeploymentClassTemplate struct {
// Metadata is the metadata applied to the machines of the MachineDeployment.
// Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment.
// At runtime this metadata is merged with the corresponding metadata from the topology.
// +optional
Metadata ObjectMeta `json:"metadata,omitempty"`
Expand Down
8 changes: 4 additions & 4 deletions api/v1beta1/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 10 additions & 8 deletions config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions config/crd/bases/cluster.x-k8s.io_clusters.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 50 additions & 33 deletions internal/controllers/topology/cluster/desired_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,29 @@ 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 ControlPlane metadata and 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.
topologyMetadata := s.Blueprint.Topology.ControlPlane.Metadata
clusterClassMetadata := s.Blueprint.ClusterClass.Spec.ControlPlane.Metadata

controlPlaneLabels := mergeMap(topologyMetadata.Labels, clusterClassMetadata.Labels)
if controlPlaneLabels == nil {
controlPlaneLabels = map[string]string{}
}
controlPlaneLabels[clusterv1.ClusterNameLabel] = cluster.Name
controlPlaneLabels[clusterv1.ClusterTopologyOwnedLabel] = ""

controlPlaneAnnotations := mergeMap(topologyMetadata.Annotations, clusterClassMetadata.Annotations)

controlPlane, err := templateToObject(templateToInput{
template: template,
templateClonedFromRef: templateClonedFromRef,
cluster: cluster,
namePrefix: fmt.Sprintf("%s-", cluster.Name),
currentObjectRef: currentRef,
labels: controlPlaneLabels,
annotations: controlPlaneAnnotations,
// 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.
})
Expand Down Expand Up @@ -224,22 +241,11 @@ 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.ClusterNameLabel] = cluster.Name
machineLabels[clusterv1.ClusterTopologyOwnedLabel] = ""
// Apply the ControlPlane labels and annotations to the ControlPlane machines as well.
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")
}
Expand Down Expand Up @@ -659,10 +665,6 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP
MinReadySeconds: minReadySeconds,
Strategy: strategy,
Template: clusterv1.MachineTemplateSpec{
ObjectMeta: clusterv1.ObjectMeta{
Labels: mergeMap(machineDeploymentTopology.Metadata.Labels, machineDeploymentBlueprint.Metadata.Labels),
Annotations: mergeMap(machineDeploymentTopology.Metadata.Annotations, machineDeploymentBlueprint.Metadata.Annotations),
},
Spec: clusterv1.MachineSpec{
ClusterName: s.Current.Cluster.Name,
Version: pointer.String(version),
Expand All @@ -683,14 +685,27 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP
desiredMachineDeploymentObj.SetName(currentMachineDeployment.Object.Name)
}

// Apply annotations
machineDeploymentAnnotations := mergeMap(machineDeploymentTopology.Metadata.Annotations, machineDeploymentBlueprint.Metadata.Annotations)
desiredMachineDeploymentObj.SetAnnotations(machineDeploymentAnnotations)
desiredMachineDeploymentObj.Spec.Template.Annotations = machineDeploymentAnnotations

// Apply Labels
// NOTE: On top of all the labels applied to managed objects we are applying the ClusterTopologyMachineDeploymentLabel
// keeping track of the MachineDeployment name from the Topology; this will be used to identify the object in next reconcile loops.
labels := map[string]string{}
labels[clusterv1.ClusterNameLabel] = s.Current.Cluster.Name
labels[clusterv1.ClusterTopologyOwnedLabel] = ""
labels[clusterv1.ClusterTopologyMachineDeploymentNameLabel] = machineDeploymentTopology.Name
desiredMachineDeploymentObj.SetLabels(labels)
machineDeploymentLabels := mergeMap(machineDeploymentTopology.Metadata.Labels, machineDeploymentBlueprint.Metadata.Labels)
if machineDeploymentLabels == nil {
machineDeploymentLabels = map[string]string{}
}
machineDeploymentLabels[clusterv1.ClusterNameLabel] = s.Current.Cluster.Name
machineDeploymentLabels[clusterv1.ClusterTopologyOwnedLabel] = ""
machineDeploymentLabels[clusterv1.ClusterTopologyMachineDeploymentNameLabel] = machineDeploymentTopology.Name
desiredMachineDeploymentObj.SetLabels(machineDeploymentLabels)

// Also set the labels in .spec.template.labels so that they are propagated to
// MachineSet.labels and MachineSet.spec.template.labels and thus to Machine.labels.
// Note: the labels in MachineSet are used to properly cleanup templates when the MachineSet is deleted.
desiredMachineDeploymentObj.Spec.Template.Labels = machineDeploymentLabels

// 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
Expand All @@ -700,16 +715,6 @@ func computeMachineDeployment(_ context.Context, s *scope.Scope, desiredControlP
desiredMachineDeploymentObj.Spec.Selector.MatchLabels[clusterv1.ClusterTopologyOwnedLabel] = ""
desiredMachineDeploymentObj.Spec.Selector.MatchLabels[clusterv1.ClusterTopologyMachineDeploymentNameLabel] = machineDeploymentTopology.Name

// Also set the labels in .spec.template.labels so that they are propagated to
// MachineSet.labels and MachineSet.spec.template.labels and thus to Machine.labels.
// Note: the labels in MachineSet are used to properly cleanup templates when the MachineSet is deleted.
if desiredMachineDeploymentObj.Spec.Template.Labels == nil {
desiredMachineDeploymentObj.Spec.Template.Labels = map[string]string{}
}
desiredMachineDeploymentObj.Spec.Template.Labels[clusterv1.ClusterNameLabel] = s.Current.Cluster.Name
desiredMachineDeploymentObj.Spec.Template.Labels[clusterv1.ClusterTopologyOwnedLabel] = ""
desiredMachineDeploymentObj.Spec.Template.Labels[clusterv1.ClusterTopologyMachineDeploymentNameLabel] = machineDeploymentTopology.Name

// Set the desired replicas.
desiredMachineDeploymentObj.Spec.Replicas = machineDeploymentTopology.Replicas

Expand Down Expand Up @@ -838,6 +843,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
}
Expand All @@ -849,6 +856,9 @@ 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{}
for k, v := range in.labels {
labels[k] = v
}
labels[clusterv1.ClusterNameLabel] = in.cluster.Name
labels[clusterv1.ClusterTopologyOwnedLabel] = ""

Expand All @@ -860,6 +870,7 @@ func templateToObject(in templateToInput) (*unstructured.Unstructured, error) {
TemplateRef: in.templateClonedFromRef,
Namespace: in.cluster.Namespace,
Labels: labels,
Annotations: in.annotations,
ClusterName: in.cluster.Name,
OwnerRef: in.ownerRef,
})
Expand Down Expand Up @@ -901,6 +912,9 @@ func templateToTemplate(in templateToInput) *unstructured.Unstructured {
if labels == nil {
labels = map[string]string{}
}
for k, v := range in.labels {
labels[k] = v
}
labels[clusterv1.ClusterNameLabel] = in.cluster.Name
labels[clusterv1.ClusterTopologyOwnedLabel] = ""
template.SetLabels(labels)
Expand All @@ -911,6 +925,9 @@ func templateToTemplate(in templateToInput) *unstructured.Unstructured {
if annotations == nil {
annotations = map[string]string{}
}
for k, v := range in.annotations {
annotations[k] = v
}
annotations[clusterv1.TemplateClonedFromNameAnnotation] = in.templateClonedFromRef.Name
annotations[clusterv1.TemplateClonedFromGroupKindAnnotation] = in.templateClonedFromRef.GroupVersionKind().GroupKind().String()
delete(annotations, corev1.LastAppliedConfigAnnotation)
Expand Down
Loading

0 comments on commit 135d4fc

Please sign in to comment.