diff --git a/operator/api/v1alpha1/keptntask_types.go b/operator/api/v1alpha1/keptntask_types.go index 70625f1b8d3..9faa590f413 100644 --- a/operator/api/v1alpha1/keptntask_types.go +++ b/operator/api/v1alpha1/keptntask_types.go @@ -49,8 +49,8 @@ type SecureParameters struct { type KeptnTaskStatus struct { JobName string `json:"jobName,omitempty"` Status common.KeptnState `json:"status,omitempty"` - StartTime time.Time `json:"startTime,omitempty"` - EndTime time.Time `json:"endTime,omitempty"` + StartTime metav1.Time `json:"startTime,omitempty"` + EndTime metav1.Time `json:"endTime,omitempty"` // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // Important: Run "make" to regenerate code after modifying this file } @@ -87,12 +87,12 @@ func init() { func (i KeptnTask) SetStartTime() { if i.Status.StartTime.IsZero() { - i.Status.StartTime = time.Now().UTC() + i.Status.StartTime = metav1.NewTime(time.Now().UTC()) } } func (i KeptnTask) SetEndTime() { if i.Status.EndTime.IsZero() { - i.Status.EndTime = time.Now().UTC() + i.Status.EndTime = metav1.NewTime(time.Now().UTC()) } } diff --git a/operator/api/v1alpha1/keptnworkloadinstance_types.go b/operator/api/v1alpha1/keptnworkloadinstance_types.go index fbbbe987959..537f76838fe 100644 --- a/operator/api/v1alpha1/keptnworkloadinstance_types.go +++ b/operator/api/v1alpha1/keptnworkloadinstance_types.go @@ -42,16 +42,16 @@ type KeptnWorkloadInstanceStatus struct { PostDeploymentStatus common.KeptnState `json:"postDeploymentStatus,omitempty"` PreDeploymentTaskStatus []WorkloadTaskStatus `json:"preDeploymentTaskStatus,omitempty"` PostDeploymentTaskStatus []WorkloadTaskStatus `json:"postDeploymentTaskStatus,omitempty"` - StartTime time.Time `json:"startTime,omitempty"` - EndTime time.Time `json:"endTime,omitempty"` + StartTime metav1.Time `json:"startTime,omitempty"` + EndTime metav1.Time `json:"endTime,omitempty"` } type WorkloadTaskStatus struct { TaskDefinitionName string `json:"TaskDefinitionName,omitempty"` Status common.KeptnState `json:"status,omitempty"` TaskName string `json:"taskName,omitempty"` - StartTime time.Time `json:"startTime,omitempty"` - EndTime time.Time `json:"endTime,omitempty"` + StartTime metav1.Time `json:"startTime,omitempty"` + EndTime metav1.Time `json:"endTime,omitempty"` } //+kubebuilder:object:root=true @@ -97,26 +97,26 @@ func (i KeptnWorkloadInstance) IsDeploymentCompleted() bool { return i.Status.DeploymentStatus.IsCompleted() } -func (i KeptnWorkloadInstance) SetStartTime() { +func (i *KeptnWorkloadInstance) SetStartTime() { if i.Status.StartTime.IsZero() { - i.Status.StartTime = time.Now().UTC() + i.Status.StartTime = metav1.NewTime(time.Now().UTC()) } } -func (i KeptnWorkloadInstance) SetEndTime() { +func (i *KeptnWorkloadInstance) SetEndTime() { if i.Status.EndTime.IsZero() { - i.Status.EndTime = time.Now().UTC() + i.Status.EndTime = metav1.NewTime(time.Now().UTC()) } } -func (i WorkloadTaskStatus) SetStartTime() { +func (i *WorkloadTaskStatus) SetStartTime() { if i.StartTime.IsZero() { - i.StartTime = time.Now().UTC() + i.StartTime = metav1.NewTime(time.Now().UTC()) } } -func (i WorkloadTaskStatus) SetEndTime() { +func (i *WorkloadTaskStatus) SetEndTime() { if i.EndTime.IsZero() { - i.EndTime = time.Now().UTC() + i.EndTime = metav1.NewTime(time.Now().UTC()) } } diff --git a/operator/api/v1alpha1/zz_generated.deepcopy.go b/operator/api/v1alpha1/zz_generated.deepcopy.go index 4fdfcd1e4da..59a913d41b7 100644 --- a/operator/api/v1alpha1/zz_generated.deepcopy.go +++ b/operator/api/v1alpha1/zz_generated.deepcopy.go @@ -248,7 +248,7 @@ func (in *KeptnTask) DeepCopyInto(out *KeptnTask) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeptnTask. @@ -412,6 +412,8 @@ func (in *KeptnTaskSpec) DeepCopy() *KeptnTaskSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KeptnTaskStatus) DeepCopyInto(out *KeptnTaskStatus) { *out = *in + in.StartTime.DeepCopyInto(&out.StartTime) + in.EndTime.DeepCopyInto(&out.EndTime) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeptnTaskStatus. @@ -532,13 +534,19 @@ func (in *KeptnWorkloadInstanceStatus) DeepCopyInto(out *KeptnWorkloadInstanceSt if in.PreDeploymentTaskStatus != nil { in, out := &in.PreDeploymentTaskStatus, &out.PreDeploymentTaskStatus *out = make([]WorkloadTaskStatus, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } if in.PostDeploymentTaskStatus != nil { in, out := &in.PostDeploymentTaskStatus, &out.PostDeploymentTaskStatus *out = make([]WorkloadTaskStatus, len(*in)) - copy(*out, *in) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } + in.StartTime.DeepCopyInto(&out.StartTime) + in.EndTime.DeepCopyInto(&out.EndTime) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeptnWorkloadInstanceStatus. @@ -689,6 +697,8 @@ func (in *TaskParameters) DeepCopy() *TaskParameters { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WorkloadTaskStatus) DeepCopyInto(out *WorkloadTaskStatus) { *out = *in + in.StartTime.DeepCopyInto(&out.StartTime) + in.EndTime.DeepCopyInto(&out.EndTime) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadTaskStatus. diff --git a/operator/config/crd/bases/lifecycle.keptn.sh_keptntasks.yaml b/operator/config/crd/bases/lifecycle.keptn.sh_keptntasks.yaml index f63a5513bb1..7a3f19aa5e9 100644 --- a/operator/config/crd/bases/lifecycle.keptn.sh_keptntasks.yaml +++ b/operator/config/crd/bases/lifecycle.keptn.sh_keptntasks.yaml @@ -82,8 +82,14 @@ spec: status: description: KeptnTaskStatus defines the observed state of KeptnTask properties: + endTime: + format: date-time + type: string jobName: type: string + startTime: + format: date-time + type: string status: type: string type: object diff --git a/operator/config/crd/bases/lifecycle.keptn.sh_keptnworkloadinstances.yaml b/operator/config/crd/bases/lifecycle.keptn.sh_keptnworkloadinstances.yaml index fcbe171485a..7c71dbe0c8e 100644 --- a/operator/config/crd/bases/lifecycle.keptn.sh_keptnworkloadinstances.yaml +++ b/operator/config/crd/bases/lifecycle.keptn.sh_keptnworkloadinstances.yaml @@ -104,6 +104,9 @@ spec: deploymentStatus: default: Pending type: string + endTime: + format: date-time + type: string postDeploymentStatus: default: Pending type: string @@ -112,6 +115,12 @@ spec: properties: TaskDefinitionName: type: string + endTime: + format: date-time + type: string + startTime: + format: date-time + type: string status: type: string taskName: @@ -126,12 +135,21 @@ spec: properties: TaskDefinitionName: type: string + endTime: + format: date-time + type: string + startTime: + format: date-time + type: string status: type: string taskName: type: string type: object type: array + startTime: + format: date-time + type: string type: object type: object served: true diff --git a/operator/config/manager/kustomization.yaml b/operator/config/manager/kustomization.yaml index 2fe7962a878..28242f57e95 100644 --- a/operator/config/manager/kustomization.yaml +++ b/operator/config/manager/kustomization.yaml @@ -11,4 +11,4 @@ kind: Kustomization images: - name: controller newName: docker.io/odubajdt/keptn-lifecycle-operator - newTag: metrics + newTag: metrics4 diff --git a/operator/controllers/keptnworkloadinstance/controller.go b/operator/controllers/keptnworkloadinstance/controller.go index a7322cc0f2c..f0a6e2c38d0 100644 --- a/operator/controllers/keptnworkloadinstance/controller.go +++ b/operator/controllers/keptnworkloadinstance/controller.go @@ -29,8 +29,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/tools/record" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/keptn-sandbox/lifecycle-controller/operator/api/v1alpha1" @@ -123,8 +125,15 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr return ctrl.Result{Requeue: true, RequeueAfter: 5 * time.Second}, nil } + // WorkloadInstance is completed at this place + workloadInstance.SetEndTime() + err = r.Client.Status().Update(ctx, workloadInstance) + if err != nil { + return ctrl.Result{Requeue: true}, err + } + attrs := []attribute.KeyValue{ attribute.Key("KeptnApp").String(workloadInstance.Spec.AppName), attribute.Key("KeptnWorkload").String(workloadInstance.Spec.WorkloadName), @@ -133,11 +142,13 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr attribute.Key("Status").String(string(workloadInstance.Status.PostDeploymentStatus)), } + r.Log.Info("Increasing deployment count") + // metrics: increment deployment counter r.Meters.DeploymentCount.Add(ctx, 1, attrs...) // metrics: add deployment duration - duration := workloadInstance.Status.EndTime.Sub(workloadInstance.Status.StartTime) + duration := workloadInstance.Status.EndTime.Time.Sub(workloadInstance.Status.StartTime.Time) r.Meters.DeploymentDuration.Record(ctx, duration.Seconds(), attrs...) return ctrl.Result{}, nil @@ -146,7 +157,8 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr // SetupWithManager sets up the controller with the Manager. func (r *KeptnWorkloadInstanceReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). - For(&klcv1alpha1.KeptnWorkloadInstance{}). + // predicate disabling the auto reconciliation after updating the object status + For(&klcv1alpha1.KeptnWorkloadInstance{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})). Complete(r) }