Skip to content

Commit

Permalink
feat: respect externally managed annotation on unmanaged MachinePools
Browse files Browse the repository at this point in the history
  • Loading branch information
mweibel committed Aug 23, 2022
1 parent bbb0e9e commit 46e860c
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 12 deletions.
4 changes: 4 additions & 0 deletions azure/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@ const (
// See https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
// for annotation formatting rules.
RGTagsLastAppliedAnnotation = "sigs.k8s.io/cluster-api-provider-azure-last-applied-tags-rg"

// ReplicasManagedByAutoscalerAnnotation is set to true in the corresponding capi machine pool
// when an external autoscaler manages the node count of the associated machine pool.
ReplicasManagedByAutoscalerAnnotation = "cluster.x-k8s.io/replicas-managed-by-autoscaler"
)
71 changes: 60 additions & 11 deletions azure/scope/machinepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ type (
// MachinePoolScope defines a scope defined around a machine pool and its cluster.
MachinePoolScope struct {
azure.ClusterScoper
AzureMachinePool *infrav1exp.AzureMachinePool
MachinePool *expv1.MachinePool
client client.Client
patchHelper *patch.Helper
vmssState *azure.VMSS
AzureMachinePool *infrav1exp.AzureMachinePool
MachinePool *expv1.MachinePool
client client.Client
patchHelper *patch.Helper
capiMachinePoolPatchHelper *patch.Helper
vmssState *azure.VMSS
}

// NodeStatus represents the status of a Kubernetes node.
Expand Down Expand Up @@ -98,12 +99,18 @@ func NewMachinePoolScope(params MachinePoolScopeParams) (*MachinePoolScope, erro
return nil, errors.Wrap(err, "failed to init patch helper")
}

capiMachinePoolPatchHelper, err := patch.NewHelper(params.MachinePool, params.Client)
if err != nil {
return nil, errors.Wrap(err, "failed to init capi patch helper")
}

return &MachinePoolScope{
client: params.Client,
MachinePool: params.MachinePool,
AzureMachinePool: params.AzureMachinePool,
patchHelper: helper,
ClusterScoper: params.ClusterScope,
client: params.Client,
MachinePool: params.MachinePool,
AzureMachinePool: params.AzureMachinePool,
patchHelper: helper,
capiMachinePoolPatchHelper: capiMachinePoolPatchHelper,
ClusterScoper: params.ClusterScope,
}, nil
}

Expand Down Expand Up @@ -522,7 +529,13 @@ func (m *MachinePoolScope) Close(ctx context.Context) error {
}
}

return m.PatchObject(ctx)
if err := m.PatchObject(ctx); err != nil {
return errors.Wrap(err, "unable to patch AzureMachinePool")
}
if err := m.PatchCAPIMachinePoolObject(ctx); err != nil {
return errors.Wrap(err, "unable to patch CAPI MachinePool")
}
return nil
}

// GetBootstrapData returns the bootstrap data from the secret in the MachinePool's bootstrap.dataSecretName.
Expand Down Expand Up @@ -688,3 +701,39 @@ func (m *MachinePoolScope) UpdatePatchStatus(condition clusterv1.ConditionType,
conditions.MarkFalse(m.AzureMachinePool, condition, infrav1.FailedReason, clusterv1.ConditionSeverityError, "%s failed to update. err: %s", service, err.Error())
}
}

// PatchCAPIMachinePoolObject persists the capi machinepool configuration and status.
func (m *MachinePoolScope) PatchCAPIMachinePoolObject(ctx context.Context) error {
return m.capiMachinePoolPatchHelper.Patch(
ctx,
m.MachinePool,
)
}

// UpdateCAPIMachinePoolReplicas updates the associated MachinePool replica count.
func (m *MachinePoolScope) UpdateCAPIMachinePoolReplicas(ctx context.Context, replicas *int32) {
m.MachinePool.Spec.Replicas = replicas
}

// HasReplicasExternallyManaged returns true if the externally managed annotation is set on the CAPI MachinePool resource.
func (m *MachinePoolScope) HasReplicasExternallyManaged(ctx context.Context) bool {
return m.MachinePool.Annotations[azure.ReplicasManagedByAutoscalerAnnotation] == "true"
}

// ReconcileReplicas ensures MachinePool replicas match VMSS capacity if replicas are externally managed by an autoscaler.
func (m *MachinePoolScope) ReconcileReplicas(ctx context.Context, vmss *azure.VMSS) error {
if !m.HasReplicasExternallyManaged(ctx) {
return nil
}

var replicas int32 = 0
if m.MachinePool.Spec.Replicas != nil {
replicas = *m.MachinePool.Spec.Replicas
}
capacity := int32(vmss.Capacity)
if capacity != replicas {
m.UpdateCAPIMachinePoolReplicas(ctx, &capacity)
}

return nil
}
14 changes: 14 additions & 0 deletions azure/services/scalesets/mock_scalesets/scalesets_mock.go

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

5 changes: 5 additions & 0 deletions azure/services/scalesets/scalesets.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type (
SetAnnotation(string, string)
SetProviderID(string)
SetVMSSState(*azure.VMSS)
ReconcileReplicas(context.Context, *azure.VMSS) error
}

// Service provides operations on Azure resources.
Expand Down Expand Up @@ -250,6 +251,10 @@ func (s *Service) patchVMSSIfNeeded(ctx context.Context, infraVMSS *azure.VMSS)
ctx, log, done := tele.StartSpanWithLogger(ctx, "scalesets.Service.patchVMSSIfNeeded")
defer done()

if err := s.Scope.ReconcileReplicas(ctx, infraVMSS); err != nil {
return nil, errors.Wrap(err, "unable to reconcile replicas")
}

spec := s.Scope.ScaleSetSpec()

vmss, err := s.buildVMSSFromSpec(ctx, spec)
Expand Down
1 change: 1 addition & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ rules:
verbs:
- get
- list
- patch
- watch
- apiGroups:
- cluster.x-k8s.io
Expand Down
2 changes: 1 addition & 1 deletion exp/controllers/azuremachinepool_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (ampr *AzureMachinePoolReconciler) SetupWithManager(ctx context.Context, mg
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=azuremachinepools/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=azuremachinepoolmachines,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=azuremachinepoolmachines/status,verbs=get
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machinepools;machinepools/status,verbs=get;list;watch
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machinepools;machinepools/status,verbs=get;list;watch;patch
// +kubebuilder:rbac:groups="",resources=events,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups="",resources=secrets;,verbs=get;list;watch
// +kubebuilder:rbac:groups=core,resources=nodes,verbs=get;list;watch
Expand Down

0 comments on commit 46e860c

Please sign in to comment.