Skip to content

Commit

Permalink
cleanup HPAs and VPAs created by tortoise
Browse files Browse the repository at this point in the history
  • Loading branch information
sanposhiho committed Aug 10, 2023
1 parent d1fbbdf commit 334ee35
Show file tree
Hide file tree
Showing 11 changed files with 502 additions and 30 deletions.
16 changes: 16 additions & 0 deletions api/v1alpha1/tortoise_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ type TortoiseSpec struct {
// FeatureGates allows to list the alpha feature names.
// +optional
FeatureGates []string `json:"featureGates,omitempty" protobuf:"bytes,4,opt,name=featureGates"`
// DeletionPolicy is the policy how the controller deletes associated HPA and VPAs when tortoise is removed.
// If "DeleteAll", tortoise deletes all associated HPA and VPAs, created by tortoise. If the associated HPA is not created by tortoise,
// which is associated by spec.targetRefs.horizontalPodAutoscalerName, tortoise never delete the HPA.
// If "NoDelete", tortoise doesn't delete any associated HPA and VPAs.
//
// "DeleteAll" is the default value.
// +optional
DeletionPolicy DeletionPolicy `json:"deletionPolicy,omitempty" protobuf:"bytes,5,opt,name=deletionPolicy"`
}

type ContainerResourcePolicy struct {
Expand All @@ -82,6 +90,14 @@ type ContainerResourcePolicy struct {
AutoscalingPolicy map[v1.ResourceName]AutoscalingType `json:"autoscalingPolicy,omitempty" protobuf:"bytes,3,opt,name=autoscalingPolicy"`
}

// +kubebuilder:validation:Enum=DeleteAll;NoDelete
type DeletionPolicy string

const (
DeletionPolicyDeleteAll DeletionPolicy = "DeleteAll"
DeletionPolicyNoDelete DeletionPolicy = "NoDelete"
)

// +kubebuilder:validation:Enum=Off;Auto;Emergency
type UpdateMode string

Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha1/tortoise_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ func (r *Tortoise) Default() {
if r.Spec.UpdateMode == "" {
r.Spec.UpdateMode = UpdateModeOff
}
if r.Spec.DeletionPolicy == "" {
r.Spec.DeletionPolicy = DeletionPolicyDeleteAll
}

d, err := ClientService.GetDeploymentOnTortoise(context.Background(), r)
if err != nil {
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/autoscaling.mercari.com_tortoises.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ spec:
spec:
description: TortoiseSpec defines the desired state of Tortoise
properties:
deletionPolicy:
description: "DeletionPolicy is the policy how the controller deletes
associated HPA and VPAs when tortoise is removed. If \"DeleteAll\",
tortoise deletes all associated HPA and VPAs, created by tortoise.
If the associated HPA is not created by tortoise, which is associated
by spec.targetRefs.horizontalPodAutoscalerName, tortoise never delete
the HPA. If \"NoDelete\", tortoise doesn't delete any associated
HPA and VPAs. \n \"DeleteAll\" is the default value."
enum:
- DeleteAll
- NoDelete
type: string
featureGates:
description: FeatureGates allows to list the alpha feature names.
items:
Expand Down
52 changes: 47 additions & 5 deletions controllers/tortoise_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,32 @@ func (r *TortoiseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
tortoise, err := r.TortoiseService.GetTortoise(ctx, req.NamespacedName)
if err != nil {
if apierrors.IsNotFound(err) {
// Probably deleted.
// Probably deleted already and finalizer is already removed.
logger.V(4).Info("tortoise is not found", "tortoise", req.NamespacedName)
// TODO: delete VPA and HPA created by the Tortoise?
return ctrl.Result{}, nil
}

logger.Error(err, "failed to get tortoise", "tortoise", req.NamespacedName)
return ctrl.Result{}, err
}

if !tortoise.ObjectMeta.DeletionTimestamp.IsZero() {
// Tortoise is deleted by user and waiting for finalizer.
logger.Info("tortoise is deleted", "tortoise", req.NamespacedName)
if err := r.deleteVPAAndHPA(ctx, tortoise, now); err != nil {
return ctrl.Result{}, fmt.Errorf("delete VPAs and HPA: %w", err)
}
if err := r.TortoiseService.RemoveFinalizer(ctx, tortoise); err != nil {
return ctrl.Result{}, fmt.Errorf("remove finalizer: %w", err)
}
return ctrl.Result{}, nil
}

// tortoise is not deleted. Make sure finalizer is added to tortoise.
if err := r.TortoiseService.AddFinalizer(ctx, tortoise); err != nil {
return ctrl.Result{}, fmt.Errorf("add finalizer: %w", err)
}

reconcileNow, requeueAfter := r.TortoiseService.ShouldReconcileTortoiseNow(tortoise, now)
if !reconcileNow {
return ctrl.Result{RequeueAfter: requeueAfter}, nil
Expand Down Expand Up @@ -169,6 +185,32 @@ func (r *TortoiseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
return ctrl.Result{}, nil
}

func (r *TortoiseReconciler) deleteVPAAndHPA(ctx context.Context, tortoise *autoscalingv1alpha1.Tortoise, now time.Time) error {
if tortoise.Spec.DeletionPolicy == autoscalingv1alpha1.DeletionPolicyNoDelete {
// don't delete anything.
return nil
}

var err error
if tortoise.Spec.TargetRefs.HorizontalPodAutoscalerName == nil {
// delete HPA created by tortoise
err = r.HpaService.DeleteHPACreatedByTortoise(ctx, tortoise)
if err != nil {
return fmt.Errorf("delete HPA created by tortoise: %w", err)
}
}

err = r.VpaService.DeleteTortoiseMonitorVPA(ctx, tortoise)
if err != nil {
return fmt.Errorf("delete monitor VPA created by tortoise: %w", err)
}
err = r.VpaService.DeleteTortoiseUpdaterVPA(ctx, tortoise)
if err != nil {
return fmt.Errorf("delete updater VPA created by tortoise: %w", err)
}
return nil
}

func (r *TortoiseReconciler) initializeVPAAndHPA(ctx context.Context, tortoise *autoscalingv1alpha1.Tortoise, dm *v1.Deployment, now time.Time) error {
// need to initialize HPA and VPA.
tortoise, err := r.HpaService.InitializeHPA(ctx, tortoise, dm)
Expand All @@ -178,15 +220,15 @@ func (r *TortoiseReconciler) initializeVPAAndHPA(ctx context.Context, tortoise *

_, tortoise, err = r.VpaService.CreateTortoiseMonitorVPA(ctx, tortoise)
if err != nil {
return err
return fmt.Errorf("create tortoise monitor VPA: %w", err)
}
_, tortoise, err = r.VpaService.CreateTortoiseUpdaterVPA(ctx, tortoise)
if err != nil {
return err
return fmt.Errorf("create tortoise updater VPA: %w", err)
}
_, err = r.TortoiseService.UpdateTortoiseStatus(ctx, tortoise, now)
if err != nil {
return err
return fmt.Errorf("update Tortoise status: %w", err)
}
return nil
}
Expand Down
Loading

0 comments on commit 334ee35

Please sign in to comment.