Skip to content

Commit

Permalink
change Schedule scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
kmdrn7 committed Sep 12, 2021
1 parent af52377 commit f7a9eb8
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 34 deletions.
20 changes: 16 additions & 4 deletions api/v1alpha1/scheduledscaler_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,34 @@ const (
PhaseDone = "DONE"
)

type Schedule struct {
// Start time for scheduling
Start string `json:"start,omitempty"`
// End time for scheduling
End string `json:"end,omitempty"`
}

// ScheduledScalerSpec defines the desired state of ScheduledScaler
type ScheduledScalerSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Foo is an example field of ScheduledScaler. Edit scheduledscaler_types.go to remove/update
Schedule string `json:"schedule,omitempty"`
DeploymentName string `json:"deploymentName,omitempty"`
ReplicaCount int32 `json:"replicaCount,omitempty"`
// Schedule defines the time between scaling up and down
Schedule Schedule `json:"schedule,omitempty"`
// DeploymentName defines target of deployment
DeploymentName string `json:"deploymentName,omitempty"`
// ReplicaCount defines how many replicas deployment will scale into
ReplicaCount int32 `json:"replicaCount,omitempty"`
}

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

// StoredReplicaCount store information original replicas
StoredReplicaCount int32 `json:"storedReplicaCount,omitempty"`
// Phase store information about phase of this resource
Phase string `json:"phase,omitempty"`
}

Expand Down
16 changes: 16 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

20 changes: 14 additions & 6 deletions config/crd/bases/scaler.andikahmadr.io_scheduledscalers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,32 @@ spec:
description: ScheduledScalerSpec defines the desired state of ScheduledScaler
properties:
deploymentName:
description: DeploymentName defines target of deployment
type: string
replicaCount:
description: ReplicaCount defines how many replicas deployment will
scale into
format: int32
type: integer
schedule:
description: Foo is an example field of ScheduledScaler. Edit scheduledscaler_types.go
to remove/update
type: string
description: Schedule defines the time between scaling up and down
properties:
end:
description: End time for scheduling
type: string
start:
description: Start time for scheduling
type: string
type: object
type: object
status:
description: ScheduledScalerStatus defines the observed state of ScheduledScaler
properties:
phase:
description: Phase store information about phase of this resource
type: string
storedReplicaCount:
description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
of cluster Important: Run "make" to regenerate code after modifying
this file'
description: StoredReplicaCount store information original replicas
format: int32
type: integer
type: object
Expand Down
4 changes: 2 additions & 2 deletions config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: controller
newName: controller
newTag: latest
newName: kmdr7/scheduled-scaler-operator
newTag: "1.0"
2 changes: 1 addition & 1 deletion config/samples/deployment2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ spec:
selector:
matchLabels:
app: web-2
replicas: 1
replicas: 2
template:
metadata:
labels:
Expand Down
4 changes: 3 additions & 1 deletion config/samples/scaler_v1alpha1_scheduledscaler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ metadata:
name: scheduledscaler-sample
namespace: web
spec:
schedule: "2021-09-09T14:54:00Z,2021-09-09T14:55:00Z"
schedule:
start: "2021-09-11T14:54:00Z"
end: "2021-09-11T14:55:00Z"
deploymentName: "web-2"
replicaCount: 5
32 changes: 12 additions & 20 deletions controllers/scheduledscaler_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import (
"fmt"
"github.com/go-logr/logr"
scalerv1alpha1 "github.com/kmdrn7/scheduled-scaler-operator/api/v1alpha1"
timeUtils "github.com/kmdrn7/scheduled-scaler-operator/pkg/time"
appsv1 "k8s.io/api/apps/v1"
"os"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"strconv"
"strings"
"time"

"k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -85,24 +85,16 @@ func (r *ScheduledScalerReconciler) Reconcile(ctx context.Context, req ctrl.Requ
instance.Status.StoredReplicaCount = -1
}

timeLayout := "2006-01-02T15:04:05Z"
timeZone, err := time.LoadLocation("Asia/Jakarta")
if err != nil {
fmt.Println("Error set timezone")
}

now := time.Now().UTC().In(timeZone)
schedule := instance.Spec.Schedule
scheduleSplit := strings.Split(schedule, ",")
scheduleStart := scheduleSplit[0]
scheduleEnd := scheduleSplit[1]
now := timeUtils.Now()
scheduleStart := instance.Spec.Schedule.Start
scheduleEnd := instance.Spec.Schedule.End

timeStart, err := time.ParseInLocation(timeLayout, scheduleStart, timeZone)
timeStart, err := timeUtils.Parse(scheduleStart)
if err != nil {
fmt.Println("Error parsing start time")
}

timeEnd, err := time.ParseInLocation(timeLayout, scheduleEnd, timeZone)
timeEnd, err := timeUtils.Parse(scheduleEnd)
if err != nil {
fmt.Println("Error parsing end time")
}
Expand All @@ -111,7 +103,7 @@ func (r *ScheduledScalerReconciler) Reconcile(ctx context.Context, req ctrl.Requ
switch instance.Status.Phase {
case scalerv1alpha1.PhasePending:
log.Info(req.NamespacedName.String() + " still in pending phase")
log.Info(req.NamespacedName.String()+" detail", "now", now.String(), "time start", timeStart.String(), "stored replica count", strconv.Itoa(int(instance.Status.StoredReplicaCount)))
log.Info(req.NamespacedName.String() + " detail", "now", now.String(), "time start", timeStart.String(), "stored replica count", strconv.Itoa(int(instance.Status.StoredReplicaCount)))

if now.Before(timeStart) {
reconcileAfter := timeStart.Sub(now)
Expand All @@ -124,9 +116,9 @@ func (r *ScheduledScalerReconciler) Reconcile(ctx context.Context, req ctrl.Requ

case scalerv1alpha1.PhaseRunning:
log.Info(req.NamespacedName.String() + " is in running phase")
log.Info(req.NamespacedName.String()+" detail", "now", now.String(), "time start", timeStart.String(), "stored replica count", strconv.Itoa(int(instance.Status.StoredReplicaCount)))
log.Info(req.NamespacedName.String() + " detail", "now", now.String(), "time start", timeStart.String(), "stored replica count", strconv.Itoa(int(instance.Status.StoredReplicaCount)))

//get deployment
// get deployment
deployment := &appsv1.Deployment{}
err := cl.Get(ctx, client.ObjectKey{
Namespace: instance.Namespace,
Expand Down Expand Up @@ -155,7 +147,7 @@ func (r *ScheduledScalerReconciler) Reconcile(ctx context.Context, req ctrl.Requ
deployment.Spec.Replicas = &instance.Spec.ReplicaCount
err := cl.Update(ctx, deployment)
if err != nil {
log.Error(err, "Error updating deployment "+deployment.Name)
log.Error(err, "Error updating deployment " + deployment.Name)
return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
}
log.Info("Successfully scaling " + deployment.Name + " with " + strconv.Itoa(int(instance.Spec.ReplicaCount)) + " replicas")
Expand All @@ -171,9 +163,9 @@ func (r *ScheduledScalerReconciler) Reconcile(ctx context.Context, req ctrl.Requ

case scalerv1alpha1.PhaseDone:
log.Info(req.NamespacedName.String() + " is in done phase")
log.Info(req.NamespacedName.String()+" detail", "now", now.String(), "time start", timeStart.String(), "stored replica count", strconv.Itoa(int(instance.Status.StoredReplicaCount)))
log.Info(req.NamespacedName.String() + " detail", "now", now.String(), "time start", timeStart.String(), "stored replica count", strconv.Itoa(int(instance.Status.StoredReplicaCount)))

//get deployment
// get deployment
deployment := &appsv1.Deployment{}
err := cl.Get(ctx, client.ObjectKey{
Namespace: instance.Namespace,
Expand Down
30 changes: 30 additions & 0 deletions pkg/time/time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package time

import (
"fmt"
"time"
)

var (
timeLayout = "2006-01-02T15:04:05Z"
timeZone, err = time.LoadLocation("Asia/Jakarta")
)

func init() {
if err != nil {
fmt.Println("Error configuring timezone")
panic(err)
}
}

func Now() time.Time {
return time.Now().UTC().In(timeZone)
}

func Parse(timeString string) (time.Time, error) {
parsedTime, err := time.ParseInLocation(timeLayout, timeString, timeZone)
if err != nil {
return time.Time{}, err
}
return parsedTime, nil
}

0 comments on commit f7a9eb8

Please sign in to comment.