Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: annotate K8s Events #589

Merged
merged 14 commits into from
Jan 17, 2023
16 changes: 15 additions & 1 deletion operator/apis/lifecycle/v1alpha2/common/phases.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ var phases = []KeptnPhaseType{
PhaseAppPreEvaluation,
PhaseAppPostEvaluation,
PhaseAppDeployment,
PhaseReconcileEvaluation,
PhaseReconcileTask,
PhaseCreateEvaluation,
PhaseCreateTask,
PhaseCreateApp,
PhaseCreateWorkload,
PhaseCreateWorklodInstance,
PhaseCreateAppVersion,
PhaseCompleted,
PhaseDeprecated,
thisthat marked this conversation as resolved.
Show resolved Hide resolved
}
Expand Down Expand Up @@ -80,7 +88,13 @@ var (
PhaseAppPostEvaluation = KeptnPhaseType{LongName: "App Post-Deployment Evaluations", ShortName: "AppPostDeployEvaluations"}
PhaseAppDeployment = KeptnPhaseType{LongName: "App Deployment", ShortName: "AppDeploy"}
PhaseReconcileEvaluation = KeptnPhaseType{LongName: "Reconcile Evaluation", ShortName: "ReconcileEvaluation"}
PhaseCreateEvaluation = KeptnPhaseType{LongName: "Create Evaluation", ShortName: "Create Evaluation"}
PhaseReconcileTask = KeptnPhaseType{LongName: "Reconcile Task", ShortName: "ReconcileTask"}
PhaseCreateEvaluation = KeptnPhaseType{LongName: "Create Evaluation", ShortName: "CreateEvaluation"}
PhaseCreateTask = KeptnPhaseType{LongName: "Create Task", ShortName: "CreateTask"}
PhaseCreateApp = KeptnPhaseType{LongName: "Create App", ShortName: "CreateApp"}
PhaseCreateWorkload = KeptnPhaseType{LongName: "Create Workload", ShortName: "CreateWorkload"}
PhaseCreateWorklodInstance = KeptnPhaseType{LongName: "Create WorkloadInstance", ShortName: "CreateWorkloadInstance"}
PhaseCreateAppVersion = KeptnPhaseType{LongName: "Create AppVersion", ShortName: "CreateAppVersion"}
PhaseCompleted = KeptnPhaseType{LongName: "Completed", ShortName: "Completed"}
PhaseDeprecated = KeptnPhaseType{LongName: "Deprecated", ShortName: "Deprecated"}
)
Expand Down
6 changes: 6 additions & 0 deletions operator/apis/lifecycle/v1alpha2/keptnapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,10 @@ func TestKeptnApp(t *testing.T) {
common.AppName.String("app"),
common.AppVersion.String("version"),
}, app.GetSpanAttributes())

require.Equal(t, map[string]string{
"appName": "app",
"appVersion": "version",
"appRevision": "1",
}, app.GetEventAnnotations())
}
9 changes: 9 additions & 0 deletions operator/apis/lifecycle/v1alpha2/keptnapp_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package v1alpha2

import (
"fmt"
"strconv"
"strings"

"github.com/keptn/lifecycle-toolkit/operator/apis/lifecycle/v1alpha2/common"
Expand Down Expand Up @@ -106,3 +107,11 @@ func (a KeptnApp) GetSpanAttributes() []attribute.KeyValue {
common.AppVersion.String(a.Spec.Version),
}
}

func (a KeptnApp) GetEventAnnotations() map[string]string {
return map[string]string{
"appName": a.Name,
"appVersion": a.Spec.Version,
"appRevision": strconv.FormatInt(a.Generation, 10),
}
}
6 changes: 6 additions & 0 deletions operator/apis/lifecycle/v1alpha2/keptnappversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@ func TestKeptnAppVersion(t *testing.T) {
common.AppVersion.String("version"),
common.AppNamespace.String("namespace"),
}, app.GetSpanAttributes())

require.Equal(t, map[string]string{
"appName": "appname",
"appVersion": "version",
"appVersionName": "app",
}, app.GetEventAnnotations())
}

func TestKeptnAppVersion_GetWorkloadNameOfApp(t *testing.T) {
Expand Down
8 changes: 8 additions & 0 deletions operator/apis/lifecycle/v1alpha2/keptnappversion_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,11 @@ func (a *KeptnAppVersion) SetPhaseTraceID(phase string, carrier propagation.MapC
}
a.Status.PhaseTraceIDs[common.GetShortPhaseName(phase)] = carrier
}

func (a KeptnAppVersion) GetEventAnnotations() map[string]string {
return map[string]string{
"appName": a.Spec.AppName,
"appVersion": a.Spec.Version,
"appVersionName": a.Name,
}
}
22 changes: 16 additions & 6 deletions operator/apis/lifecycle/v1alpha2/keptnevaluation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ func TestKeptnEvaluation(t *testing.T) {
Name: "evaluation",
},
Spec: KeptnEvaluationSpec{
AppName: "app",
AppVersion: "appversion",
Type: common.PostDeploymentCheckType,
AppName: "app",
odubajDT marked this conversation as resolved.
Show resolved Hide resolved
AppVersion: "appversion",
Type: common.PostDeploymentCheckType,
EvaluationDefinition: "def",
},
Status: KeptnEvaluationStatus{
OverallStatus: common.StateFailed,
Expand All @@ -30,9 +31,10 @@ func TestKeptnEvaluation(t *testing.T) {
Name: "evaluation",
},
Spec: KeptnEvaluationSpec{
AppName: "app",
AppVersion: "appversion",
Type: common.PostDeploymentCheckType,
AppName: "app",
AppVersion: "appversion",
Type: common.PostDeploymentCheckType,
EvaluationDefinition: "def",
},
Status: KeptnEvaluationStatus{
OverallStatus: common.StateFailed,
Expand Down Expand Up @@ -84,6 +86,14 @@ func TestKeptnEvaluation(t *testing.T) {
common.EvaluationType.String(string(common.PostDeploymentCheckType)),
}, evaluation.GetSpanAttributes())

require.Equal(t, map[string]string{
"appName": "app",
"appVersion": "appversion",
"workloadName": "",
"workloadVersion": "",
"evaluationName": "evaluation",
"evaluationDefinitionName": "def",
}, evaluation.GetEventAnnotations())
}

func TestKeptnEvaluationList(t *testing.T) {
Expand Down
11 changes: 11 additions & 0 deletions operator/apis/lifecycle/v1alpha2/keptnevaluation_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,14 @@ func (e KeptnEvaluation) GetSpanKey(phase string) string {
func (e KeptnEvaluation) GetSpanName(phase string) string {
return e.Name
}

func (e KeptnEvaluation) GetEventAnnotations() map[string]string {
return map[string]string{
"appName": e.Spec.AppName,
"appVersion": e.Spec.AppVersion,
"workloadName": e.Spec.Workload,
"workloadVersion": e.Spec.WorkloadVersion,
"evaluationName": e.Name,
"evaluationDefinitionName": e.Spec.EvaluationDefinition,
}
}
23 changes: 17 additions & 6 deletions operator/apis/lifecycle/v1alpha2/keptntask_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ func TestKeptnTask(t *testing.T) {
Name: "task",
},
Spec: KeptnTaskSpec{
AppName: "app",
AppVersion: "appversion",
Type: common.PostDeploymentCheckType,
AppName: "app",
AppVersion: "appversion",
Type: common.PostDeploymentCheckType,
TaskDefinition: "def",
},
Status: KeptnTaskStatus{
Status: common.StateFailed,
Expand All @@ -30,9 +31,10 @@ func TestKeptnTask(t *testing.T) {
Name: "task",
},
Spec: KeptnTaskSpec{
AppName: "app",
AppVersion: "appversion",
Type: common.PostDeploymentCheckType,
AppName: "app",
AppVersion: "appversion",
Type: common.PostDeploymentCheckType,
TaskDefinition: "def",
},
Status: KeptnTaskStatus{
Status: common.StateFailed,
Expand Down Expand Up @@ -95,6 +97,15 @@ func TestKeptnTask(t *testing.T) {
common.TaskType.String(string(common.PostDeploymentCheckType)),
}, task.GetSpanAttributes())

require.Equal(t, map[string]string{
"appName": "app",
"appVersion": "appversion",
"workloadName": "workload",
"workloadVersion": "workloadversion",
"taskName": "task",
"taskDefinitionName": "def",
}, task.GetEventAnnotations())

}

func TestKeptnTaskList(t *testing.T) {
Expand Down
11 changes: 11 additions & 0 deletions operator/apis/lifecycle/v1alpha2/keptntask_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,14 @@ func (t KeptnTask) GetSpanKey(phase string) string {
func (t KeptnTask) GetSpanName(phase string) string {
return t.Name
}

func (t KeptnTask) GetEventAnnotations() map[string]string {
return map[string]string{
"appName": t.Spec.AppName,
"appVersion": t.Spec.AppVersion,
"workloadName": t.Spec.Workload,
"workloadVersion": t.Spec.WorkloadVersion,
"taskName": t.Name,
"taskDefinitionName": t.Spec.TaskDefinition,
}
}
6 changes: 6 additions & 0 deletions operator/apis/lifecycle/v1alpha2/keptnworkload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,10 @@ func TestKeptnWorkload(t *testing.T) {
common.WorkloadName.String("workload"),
common.WorkloadVersion.String("version"),
}, workload.GetSpanAttributes())

require.Equal(t, map[string]string{
"appName": "app",
"workloadName": "workload",
"workloadVersion": "version",
}, workload.GetEventAnnotations())
}
16 changes: 12 additions & 4 deletions operator/apis/lifecycle/v1alpha2/keptnworkload_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,18 @@ func (w KeptnWorkload) GenerateWorkloadInstance(previousVersion string, traceCon
}
}

func (i KeptnWorkload) GetSpanAttributes() []attribute.KeyValue {
func (w KeptnWorkload) GetSpanAttributes() []attribute.KeyValue {
return []attribute.KeyValue{
common.AppName.String(i.Spec.AppName),
common.WorkloadName.String(i.Name),
common.WorkloadVersion.String(i.Spec.Version),
common.AppName.String(w.Spec.AppName),
odubajDT marked this conversation as resolved.
Show resolved Hide resolved
common.WorkloadName.String(w.Name),
common.WorkloadVersion.String(w.Spec.Version),
}
}

func (w KeptnWorkload) GetEventAnnotations() map[string]string {
return map[string]string{
odubajDT marked this conversation as resolved.
Show resolved Hide resolved
"appName": w.Spec.AppName,
"workloadName": w.Name,
"workloadVersion": w.Spec.Version,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@ func TestKeptnWorkloadInstance(t *testing.T) {
common.WorkloadVersion.String("version"),
common.WorkloadNamespace.String("namespace"),
}, workload.GetSpanAttributes())

require.Equal(t, map[string]string{
"appName": "appname",
"workloadName": "workloadname",
"workloadVersion": "version",
"workloadInstanceName": "workload",
}, workload.GetEventAnnotations())
}

//nolint:dupl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,3 +427,12 @@ func (w *KeptnWorkloadInstance) SetPhaseTraceID(phase string, carrier propagatio
}
w.Status.PhaseTraceIDs[common.GetShortPhaseName(phase)] = carrier
}

func (w KeptnWorkloadInstance) GetEventAnnotations() map[string]string {
return map[string]string{
"appName": w.Spec.AppName,
"workloadName": w.Spec.WorkloadName,
odubajDT marked this conversation as resolved.
Show resolved Hide resolved
"workloadVersion": w.Spec.Version,
"workloadInstanceName": w.Name,
}
}
43 changes: 43 additions & 0 deletions operator/controllers/common/helperfunctions.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package common

import (
"fmt"

klcv1alpha2 "github.com/keptn/lifecycle-toolkit/operator/apis/lifecycle/v1alpha2"
apicommon "github.com/keptn/lifecycle-toolkit/operator/apis/lifecycle/v1alpha2/common"
"github.com/keptn/lifecycle-toolkit/operator/controllers/lifecycle/interfaces"
"golang.org/x/exp/maps"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type CreateAttributes struct {
Expand Down Expand Up @@ -41,3 +47,40 @@ func GetOldStatus(name string, statuses []klcv1alpha2.ItemStatus) apicommon.Kept

return oldstatus
}

// RecordEvent creates k8s Event and adds it to Eventqueue
func RecordEvent(recorder record.EventRecorder, phase apicommon.KeptnPhaseType, eventType string, reconcileObject client.Object, shortReason string, longReason string, version string) {
msg := setEventMessage(phase, reconcileObject, longReason, version)
annotations := setAnnotations(reconcileObject, phase)
recorder.AnnotatedEventf(reconcileObject, annotations, eventType, fmt.Sprintf("%s%s", phase.ShortName, shortReason), msg)
}

func setEventMessage(phase apicommon.KeptnPhaseType, reconcileObject client.Object, longReason string, version string) string {
if version == "" {
return fmt.Sprintf("%s: %s / Namespace: %s, Name: %s", phase.LongName, longReason, reconcileObject.GetNamespace(), reconcileObject.GetName())
}
return fmt.Sprintf("%s: %s / Namespace: %s, Name: %s, Version: %s", phase.LongName, longReason, reconcileObject.GetNamespace(), reconcileObject.GetName(), version)
odubajDT marked this conversation as resolved.
Show resolved Hide resolved
}

func setAnnotations(reconcileObject client.Object, phase apicommon.KeptnPhaseType) map[string]string {
if reconcileObject == nil || reconcileObject.GetName() == "" || reconcileObject.GetNamespace() == "" {
return nil
}
annotations := map[string]string{
"namespace": reconcileObject.GetNamespace(),
"name": reconcileObject.GetName(),
"phase": phase.ShortName,
}

piWrapper, err := interfaces.NewEventObjectWrapperFromClientObject(reconcileObject)
if err == nil {
maps.Copy(annotations, piWrapper.GetEventAnnotations())
}

annotationsObject := reconcileObject.GetAnnotations()
if val, ok := annotationsObject["traceparent"]; ok {
annotations["traceparent"] = val
}
odubajDT marked this conversation as resolved.
Show resolved Hide resolved

return annotations
}
Loading