Skip to content

Commit

Permalink
Scale from and to 0 support for autoscaler for VPC cluster (#1523)
Browse files Browse the repository at this point in the history
* Added support VPC autoscaler

* Update controllers/ibmvpcmachinetemplate_controller_test.go

Co-authored-by: Prajyot Parab <prajyot.parab2@ibm.com>

* Removed duplicate and updated error message

---------

Co-authored-by: Prajyot Parab <prajyot.parab2@ibm.com>
  • Loading branch information
KeerthanaAP and Prajyot-Parab committed Feb 9, 2024
1 parent ea18e5b commit 7150fb8
Show file tree
Hide file tree
Showing 14 changed files with 514 additions and 2 deletions.
4 changes: 4 additions & 0 deletions api/v1beta1/ibmvpc_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ func Convert_v1beta2_IBMVPCMachineSpec_To_v1beta1_IBMVPCMachineSpec(in *infrav1b
return autoConvert_v1beta2_IBMVPCMachineSpec_To_v1beta1_IBMVPCMachineSpec(in, out, s)
}

func Convert_v1beta2_IBMVPCMachineTemplateStatus_To_v1beta1_IBMVPCMachineTemplateStatus(in *infrav1beta2.IBMVPCMachineTemplateStatus, out *IBMVPCMachineTemplateStatus, s apiconversion.Scope) error {
return autoConvert_v1beta2_IBMVPCMachineTemplateStatus_To_v1beta1_IBMVPCMachineTemplateStatus(in, out, s)
}

func Convert_Slice_Pointer_string_To_Slice_Pointer_v1beta2_IBMVPCResourceReference(in *[]*string, out *[]*infrav1beta2.IBMVPCResourceReference, _ apiconversion.Scope) error {
for _, sshKey := range *in {
*out = append(*out, &infrav1beta2.IBMVPCResourceReference{
Expand Down
9 changes: 8 additions & 1 deletion api/v1beta1/ibmvpcmachinetemplate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ type IBMVPCMachineTemplateResource struct {
Spec IBMVPCMachineSpec `json:"spec"`
}

// IBMVPCMachineTemplateStatus defines the observed state of IBMVPCMachineTemplate.
type IBMVPCMachineTemplateStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:path=ibmvpcmachinetemplates,scope=Namespaced,categories=cluster-api

Expand All @@ -39,7 +45,8 @@ type IBMVPCMachineTemplate struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec IBMVPCMachineTemplateSpec `json:"spec,omitempty"`
Spec IBMVPCMachineTemplateSpec `json:"spec,omitempty"`
Status IBMVPCMachineTemplateStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down
30 changes: 30 additions & 0 deletions api/v1beta1/zz_generated.conversion.go

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

16 changes: 16 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

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

14 changes: 13 additions & 1 deletion api/v1beta2/ibmvpcmachinetemplate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1beta2

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand All @@ -31,6 +32,16 @@ type IBMVPCMachineTemplateResource struct {
Spec IBMVPCMachineSpec `json:"spec"`
}

// IBMVPCMachineTemplateStatus defines the observed state of IBMVPCMachineTemplate.
type IBMVPCMachineTemplateStatus struct {
// Capacity defines the resource capacity for this machine.
// This value is used for autoscaling from zero operations as defined in:
// https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md
// +optional
Capacity corev1.ResourceList `json:"capacity,omitempty"`
}

//+kubebuilder:subresource:status
// +kubebuilder:object:root=true
// +kubebuilder:resource:path=ibmvpcmachinetemplates,scope=Namespaced,categories=cluster-api
// +kubebuilder:storageversion
Expand All @@ -40,7 +51,8 @@ type IBMVPCMachineTemplate struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec IBMVPCMachineTemplateSpec `json:"spec,omitempty"`
Spec IBMVPCMachineTemplateSpec `json:"spec,omitempty"`
Status IBMVPCMachineTemplateStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down
23 changes: 23 additions & 0 deletions api/v1beta2/zz_generated.deepcopy.go

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
Expand Up @@ -147,6 +147,10 @@ spec:
required:
- template
type: object
status:
description: IBMVPCMachineTemplateStatus defines the observed state of
IBMVPCMachineTemplate.
type: object
type: object
served: true
storage: false
Expand Down Expand Up @@ -296,6 +300,24 @@ spec:
required:
- template
type: object
status:
description: IBMVPCMachineTemplateStatus defines the observed state of
IBMVPCMachineTemplate.
properties:
capacity:
additionalProperties:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
description: 'Capacity defines the resource capacity for this machine.
This value is used for autoscaling from zero operations as defined
in: https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md'
type: object
type: object
type: object
served: true
storage: true
subresources:
status: {}
16 changes: 16 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,19 @@ rules:
- get
- patch
- update
- apiGroups:
- infrastructure.cluster.x-k8s.io
resources:
- ibmvpcmachinetemplates
verbs:
- get
- list
- watch
- apiGroups:
- infrastructure.cluster.x-k8s.io
resources:
- ibmvpcmachinetemplates/status
verbs:
- get
- patch
- update
118 changes: 118 additions & 0 deletions controllers/ibmvpcmachinetemplate_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package controllers

import (
"context"
"fmt"
"reflect"

"github.com/IBM/vpc-go-sdk/vpcv1"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/runtime"

ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

"sigs.k8s.io/cluster-api/util/patch"

infrav1beta2 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1beta2"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/cloud/services/vpc"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg/endpoints"
)

// IBMVPCMachineTemplateReconciler reconciles a IBMVPCMachineTemplate object.
type IBMVPCMachineTemplateReconciler struct {
client.Client
Scheme *runtime.Scheme
ServiceEndpoint []endpoints.ServiceEndpoint
}

func (r *IBMVPCMachineTemplateReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&infrav1beta2.IBMVPCMachineTemplate{}).
Complete(r)
}

// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=ibmvpcmachinetemplates,verbs=get;list;watch
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=ibmvpcmachinetemplates/status,verbs=get;update;patch

func (r *IBMVPCMachineTemplateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := ctrl.LoggerFrom(ctx)
log.Info("Reconciling IBMVPCMachineTemplate")

var machineTemplate infrav1beta2.IBMVPCMachineTemplate
if err := r.Get(ctx, req.NamespacedName, &machineTemplate); err != nil {
log.Error(err, "Unable to fetch ibmvpcmachinetemplate")
return ctrl.Result{}, client.IgnoreNotFound(err)
}

region := endpoints.CostructRegionFromZone(machineTemplate.Spec.Template.Spec.Zone)

// Fetch the service endpoint.
svcEndpoint := endpoints.FetchVPCEndpoint(region, r.ServiceEndpoint)

vpcClient, err := vpc.NewService(svcEndpoint)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to create IBM VPC client: %w", err)
}

return r.reconcileNormal(ctx, vpcClient, machineTemplate)
}

func (r *IBMVPCMachineTemplateReconciler) reconcileNormal(ctx context.Context, vpcClient vpc.Vpc, machineTemplate infrav1beta2.IBMVPCMachineTemplate) (ctrl.Result, error) {
log := ctrl.LoggerFrom(ctx)
helper, err := patch.NewHelper(&machineTemplate, r.Client)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to init patch helper: %w", err)
}

options := &vpcv1.GetInstanceProfileOptions{}
options.SetName(machineTemplate.Spec.Template.Spec.Profile)
profileDetails, _, err := vpcClient.GetInstanceProfile(options)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to fetch profile Details: %w", err)
}

if profileDetails == nil {
return ctrl.Result{}, fmt.Errorf("failed to find profileDetails")
}

log.V(3).Info("Profile Details:", "profileDetails", profileDetails)

capacity := make(corev1.ResourceList)
memory := fmt.Sprintf("%vG", *profileDetails.Memory.(*vpcv1.InstanceProfileMemory).Value)
cpu := fmt.Sprintf("%v", *profileDetails.VcpuCount.(*vpcv1.InstanceProfileVcpu).Value)
capacity[corev1.ResourceCPU] = resource.MustParse(cpu)
capacity[corev1.ResourceMemory] = resource.MustParse(memory)

log.V(3).Info("Calculated capacity for machine template", "capacity", capacity)
if !reflect.DeepEqual(machineTemplate.Status.Capacity, capacity) {
machineTemplate.Status.Capacity = capacity
if err := helper.Patch(ctx, &machineTemplate); err != nil {
if !apierrors.IsNotFound(err) {
log.Error(err, "Failed to patch machineTemplate")
return ctrl.Result{}, err
}
}
}
log.V(3).Info("Machine template status", "status", machineTemplate.Status)
return ctrl.Result{}, nil
}
Loading

0 comments on commit 7150fb8

Please sign in to comment.