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

refactor(lifecycle-operator): eventing and telemetry #1844

Merged
merged 5 commits into from
Aug 7, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: refactoring eventing and telemetry
Signed-off-by: Giovanni Liva <giovanni.liva@dynatrace.com>
thisthat committed Aug 6, 2023

Verified

This commit was signed with the committer’s verified signature.
thisthat Giovanni Liva
commit e0faf35f350218984437973f014297b5f133e243
5 changes: 0 additions & 5 deletions lifecycle-operator/apis/options/v1alpha1/keptnconfig_types.go
Original file line number Diff line number Diff line change
@@ -31,16 +31,11 @@ type KeptnConfigSpec struct {
// OTelCollectorUrl can be used to set the Open Telemetry collector that the lifecycle operator should use
// +optional
OTelCollectorUrl string `json:"OTelCollectorUrl,omitempty"`

// KeptnAppCreationRequestTimeoutSeconds is used to set the interval in which automatic app discovery
// searches for workload to put into the same auto-generated KeptnApp
// +kubebuilder:default:=30
// +optional
KeptnAppCreationRequestTimeoutSeconds uint `json:"keptnAppCreationRequestTimeoutSeconds,omitempty"`

// CloudEventsEndpoint can be used to set the endpoint where Cloud Events should be posted by the lifecycle operator
// +optional
CloudEventsEndpoint string `json:"cloudEventsEndpoint,omitempty"`
}

// +kubebuilder:object:root=true
11 changes: 0 additions & 11 deletions lifecycle-operator/controllers/common/config/config.go
Original file line number Diff line number Diff line change
@@ -11,13 +11,10 @@ const defaultKeptnAppCreationRequestTimeout = 30 * time.Second
type IConfig interface {
SetCreationRequestTimeout(value time.Duration)
GetCreationRequestTimeout() time.Duration
SetCloudEventsEndpoint(endpoint string)
GetCloudEventsEndpoint() string
}

type ControllerConfig struct {
keptnAppCreationRequestTimeout time.Duration
cloudEventsEndpoint string
}

var instance *ControllerConfig
@@ -37,11 +34,3 @@ func (o *ControllerConfig) SetCreationRequestTimeout(value time.Duration) {
func (o *ControllerConfig) GetCreationRequestTimeout() time.Duration {
return o.keptnAppCreationRequestTimeout
}

func (o *ControllerConfig) SetCloudEventsEndpoint(endpoint string) {
o.cloudEventsEndpoint = endpoint
}

func (o *ControllerConfig) GetCloudEventsEndpoint() string {
return o.cloudEventsEndpoint
}
11 changes: 6 additions & 5 deletions lifecycle-operator/controllers/common/evaluationhandler.go
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import (
"github.com/go-logr/logr"
klcv1alpha3 "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha3"
apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha3/common"
"github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/telemetry"
controllererrors "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/errors"
"github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/lifecycle/interfaces"
"go.opentelemetry.io/otel/codes"
@@ -21,11 +22,11 @@ import (

type EvaluationHandler struct {
client.Client
EventSender EventSender
EventSender IEvent
Log logr.Logger
Tracer trace.Tracer
Scheme *runtime.Scheme
SpanHandler ISpanHandler
SpanHandler telemetry.ISpanHandler
}

type CreateEvaluationAttributes struct {
@@ -55,7 +56,7 @@ func (r EvaluationHandler) ReconcileEvaluations(ctx context.Context, phaseCtx co
evaluationExists := false

if oldstatus != evaluationStatus.Status {
r.EventSender.SendK8sEvent(apicommon.PhaseReconcileEvaluation, "Normal", reconcileObject, apicommon.PhaseStateStatusChanged, fmt.Sprintf("evaluation status changed from %s to %s", oldstatus, evaluationStatus.Status), piWrapper.GetVersion())
r.EventSender.SendEvent(apicommon.PhaseReconcileEvaluation, "Normal", reconcileObject, apicommon.PhaseStateStatusChanged, fmt.Sprintf("evaluation status changed from %s to %s", oldstatus, evaluationStatus.Status), piWrapper.GetVersion())
}

// Check if evaluation has already succeeded or failed
@@ -126,7 +127,7 @@ func (r EvaluationHandler) CreateKeptnEvaluation(ctx context.Context, namespace
err = r.Client.Create(ctx, &newEvaluation)
if err != nil {
r.Log.Error(err, "could not create KeptnEvaluation")
r.EventSender.SendK8sEvent(phase, "Warning", reconcileObject, apicommon.PhaseStateFailed, "could not create KeptnEvaluation", piWrapper.GetVersion())
r.EventSender.SendEvent(phase, "Warning", reconcileObject, apicommon.PhaseStateFailed, "could not create KeptnEvaluation", piWrapper.GetVersion())
return "", err
}

@@ -142,7 +143,7 @@ func (r EvaluationHandler) emitEvaluationFailureEvents(evaluation *klcv1alpha3.K
k8sEventMessage = fmt.Sprintf("%s\n%s", k8sEventMessage, msg)
}
}
r.EventSender.SendK8sEvent(apicommon.PhaseReconcileEvaluation, "Warning", evaluation, apicommon.PhaseStateFailed, k8sEventMessage, piWrapper.GetVersion())
r.EventSender.SendEvent(apicommon.PhaseReconcileEvaluation, "Warning", evaluation, apicommon.PhaseStateFailed, k8sEventMessage, piWrapper.GetVersion())
}

func (r EvaluationHandler) setupEvaluations(evaluationCreateAttributes CreateEvaluationAttributes, piWrapper *interfaces.PhaseItemWrapper) ([]string, []klcv1alpha3.ItemStatus) {
31 changes: 23 additions & 8 deletions lifecycle-operator/controllers/common/eventsender.go
Original file line number Diff line number Diff line change
@@ -2,25 +2,40 @@ package common

import (
"fmt"

apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha3/common"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type EventSender struct {
//go:generate moq -pkg fake -skip-ensure -out ./fake/event_mock.go . IEvent:MockEvent
type IEvent interface {
SendEvent(phase apicommon.KeptnPhaseType, eventType string, reconcileObject client.Object, status string, message string, version string)
thisthat marked this conversation as resolved.
Show resolved Hide resolved
}

// ===== Main =====

func NewEventSender(recorder record.EventRecorder) IEvent {
return newK8sSender(recorder)
}

// ===== Cloud Event Sender =====
// TODO: implement Cloud Event logic

// ===== K8s Event Sender =====

type k8sEvent struct {
recorder record.EventRecorder
}

func NewEventSender(recorder record.EventRecorder) EventSender {
return EventSender{
func newK8sSender(recorder record.EventRecorder) IEvent {
return &k8sEvent{
recorder: recorder,
}
}

// SendK8sEvent creates k8s Event and adds it to Eventqueue
func (s *EventSender) SendK8sEvent(phase apicommon.KeptnPhaseType, eventType string, reconcileObject client.Object, shortReason string, longReason string, version string) {
msg := setEventMessage(phase, reconcileObject, longReason, version)
// SendEvent creates k8s Event and adds it to Eventqueue
func (s *k8sEvent) SendEvent(phase apicommon.KeptnPhaseType, eventType string, reconcileObject client.Object, status string, message string, version string) {
msg := setEventMessage(phase, reconcileObject, message, version)
annotations := setAnnotations(reconcileObject, phase)
s.recorder.AnnotatedEventf(reconcileObject, annotations, eventType, fmt.Sprintf("%s%s", phase.ShortName, shortReason), msg)
s.recorder.AnnotatedEventf(reconcileObject, annotations, eventType, fmt.Sprintf("%s%s", phase.ShortName, status), msg)
}
4 changes: 2 additions & 2 deletions lifecycle-operator/controllers/common/eventsender_test.go
Original file line number Diff line number Diff line change
@@ -13,9 +13,9 @@ import (

func TestEventSender_SendK8sEvent(t *testing.T) {
fakeRecorder := record.NewFakeRecorder(100)
eventSender := NewEventSender(fakeRecorder)
eventSender := newK8sSender(fakeRecorder)

eventSender.SendK8sEvent(common.PhaseAppDeployment, "pre-event", &v1alpha3.KeptnAppVersion{
eventSender.SendEvent(common.PhaseAppDeployment, "pre-event", &v1alpha3.KeptnAppVersion{
ObjectMeta: v1.ObjectMeta{
Name: "app",
Namespace: "ns",
13 changes: 7 additions & 6 deletions lifecycle-operator/controllers/common/phasehandler.go
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import (

"github.com/go-logr/logr"
apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha3/common"
"github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/telemetry"
controllererrors "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/errors"
"github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/lifecycle/interfaces"
"go.opentelemetry.io/otel/codes"
@@ -16,9 +17,9 @@ import (

type PhaseHandler struct {
client.Client
EventSender EventSender
EventSender IEvent
Log logr.Logger
SpanHandler ISpanHandler
SpanHandler telemetry.ISpanHandler
}

type PhaseResult struct {
@@ -39,7 +40,7 @@ func (r PhaseHandler) HandlePhase(ctx context.Context, ctxTrace context.Context,
return &PhaseResult{Continue: false, Result: ctrl.Result{}}, nil
}
if oldPhase != phase.ShortName {
r.EventSender.SendK8sEvent(phase, "Normal", reconcileObject, apicommon.PhaseStateStarted, "has started", piWrapper.GetVersion())
r.EventSender.SendEvent(phase, "Normal", reconcileObject, apicommon.PhaseStateStarted, "has started", piWrapper.GetVersion())
piWrapper.SetCurrentPhase(phase.ShortName)
}

@@ -51,7 +52,7 @@ func (r PhaseHandler) HandlePhase(ctx context.Context, ctxTrace context.Context,
state, err := reconcilePhase(spanPhaseCtx)
if err != nil {
spanPhaseTrace.AddEvent(phase.LongName + " could not get reconciled")
r.EventSender.SendK8sEvent(phase, "Warning", reconcileObject, apicommon.PhaseStateReconcileError, "could not get reconciled", piWrapper.GetVersion())
r.EventSender.SendEvent(phase, "Warning", reconcileObject, apicommon.PhaseStateReconcileError, "could not get reconciled", piWrapper.GetVersion())
span.SetStatus(codes.Error, err.Error())
return &PhaseResult{Continue: false, Result: requeueResult}, err
}
@@ -88,7 +89,7 @@ func (r PhaseHandler) handleCompletedPhase(state apicommon.KeptnState, piWrapper
if err := r.SpanHandler.UnbindSpan(reconcileObject, phase.ShortName); err != nil {
r.Log.Error(err, controllererrors.ErrCouldNotUnbindSpan, reconcileObject.GetName())
}
r.EventSender.SendK8sEvent(phase, "Warning", reconcileObject, apicommon.PhaseStateFailed, "has failed", piWrapper.GetVersion())
r.EventSender.SendEvent(phase, "Warning", reconcileObject, apicommon.PhaseStateFailed, "has failed", piWrapper.GetVersion())
piWrapper.DeprecateRemainingPhases(phase)
return &PhaseResult{Continue: false, Result: ctrl.Result{}}, nil
}
@@ -100,7 +101,7 @@ func (r PhaseHandler) handleCompletedPhase(state apicommon.KeptnState, piWrapper
if err := r.SpanHandler.UnbindSpan(reconcileObject, phase.ShortName); err != nil {
r.Log.Error(err, controllererrors.ErrCouldNotUnbindSpan, reconcileObject.GetName())
}
r.EventSender.SendK8sEvent(phase, "Normal", reconcileObject, apicommon.PhaseStateFinished, "has finished", piWrapper.GetVersion())
r.EventSender.SendEvent(phase, "Normal", reconcileObject, apicommon.PhaseStateFinished, "has finished", piWrapper.GetVersion())

return &PhaseResult{Continue: true, Result: ctrl.Result{Requeue: true, RequeueAfter: 5 * time.Second}}, nil
}
15 changes: 8 additions & 7 deletions lifecycle-operator/controllers/common/phasehandler_test.go
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import (

"github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha3"
apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha3/common"
"github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/telemetry"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/trace"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -33,7 +34,7 @@ func TestPhaseHandler(t *testing.T) {
{
name: "deprecated",
handler: PhaseHandler{
SpanHandler: &SpanHandler{},
SpanHandler: &telemetry.SpanHandler{},
},
object: &v1alpha3.KeptnAppVersion{
Status: v1alpha3.KeptnAppVersionStatus{
@@ -51,7 +52,7 @@ func TestPhaseHandler(t *testing.T) {
{
name: "reconcilePhase error",
handler: PhaseHandler{
SpanHandler: &SpanHandler{},
SpanHandler: &telemetry.SpanHandler{},
Log: ctrl.Log.WithName("controller"),
EventSender: NewEventSender(record.NewFakeRecorder(100)),
Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).Build(),
@@ -78,7 +79,7 @@ func TestPhaseHandler(t *testing.T) {
{
name: "reconcilePhase pending state",
handler: PhaseHandler{
SpanHandler: &SpanHandler{},
SpanHandler: &telemetry.SpanHandler{},
Log: ctrl.Log.WithName("controller"),
EventSender: NewEventSender(record.NewFakeRecorder(100)),
Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).Build(),
@@ -105,7 +106,7 @@ func TestPhaseHandler(t *testing.T) {
{
name: "reconcilePhase progressing state",
handler: PhaseHandler{
SpanHandler: &SpanHandler{},
SpanHandler: &telemetry.SpanHandler{},
Log: ctrl.Log.WithName("controller"),
EventSender: NewEventSender(record.NewFakeRecorder(100)),
Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).Build(),
@@ -132,7 +133,7 @@ func TestPhaseHandler(t *testing.T) {
{
name: "reconcilePhase succeeded state",
handler: PhaseHandler{
SpanHandler: &SpanHandler{},
SpanHandler: &telemetry.SpanHandler{},
Log: ctrl.Log.WithName("controller"),
EventSender: NewEventSender(record.NewFakeRecorder(100)),
Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).Build(),
@@ -159,7 +160,7 @@ func TestPhaseHandler(t *testing.T) {
{
name: "reconcilePhase failed state",
handler: PhaseHandler{
SpanHandler: &SpanHandler{},
SpanHandler: &telemetry.SpanHandler{},
Log: ctrl.Log.WithName("controller"),
EventSender: NewEventSender(record.NewFakeRecorder(100)),
Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).Build(),
@@ -187,7 +188,7 @@ func TestPhaseHandler(t *testing.T) {
{
name: "reconcilePhase unknown state",
handler: PhaseHandler{
SpanHandler: &SpanHandler{},
SpanHandler: &telemetry.SpanHandler{},
Log: ctrl.Log.WithName("controller"),
EventSender: NewEventSender(record.NewFakeRecorder(100)),
Client: fake.NewClientBuilder().WithScheme(scheme.Scheme).Build(),
9 changes: 5 additions & 4 deletions lifecycle-operator/controllers/common/taskhandler.go
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import (
"github.com/go-logr/logr"
klcv1alpha3 "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha3"
apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha3/common"
"github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/telemetry"
controllererrors "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/errors"
"github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/lifecycle/interfaces"
"go.opentelemetry.io/otel/codes"
@@ -21,11 +22,11 @@ import (

type TaskHandler struct {
client.Client
EventSender EventSender
EventSender IEvent
Log logr.Logger
Tracer trace.Tracer
Scheme *runtime.Scheme
SpanHandler ISpanHandler
SpanHandler telemetry.ISpanHandler
}

type CreateTaskAttributes struct {
@@ -57,7 +58,7 @@ func (r TaskHandler) ReconcileTasks(ctx context.Context, phaseCtx context.Contex
taskExists := false

if oldstatus != taskStatus.Status {
r.EventSender.SendK8sEvent(phase, "Normal", reconcileObject, apicommon.PhaseStateStatusChanged, fmt.Sprintf("task status changed from %s to %s", oldstatus, taskStatus.Status), piWrapper.GetVersion())
r.EventSender.SendEvent(phase, "Normal", reconcileObject, apicommon.PhaseStateStatusChanged, fmt.Sprintf("task status changed from %s to %s", oldstatus, taskStatus.Status), piWrapper.GetVersion())
}

// Check if task has already succeeded or failed
@@ -130,7 +131,7 @@ func (r TaskHandler) CreateKeptnTask(ctx context.Context, namespace string, reco
err = r.Client.Create(ctx, &newTask)
if err != nil {
r.Log.Error(err, "could not create KeptnTask")
r.EventSender.SendK8sEvent(phase, "Warning", reconcileObject, apicommon.PhaseStateFailed, "could not create KeptnTask", piWrapper.GetVersion())
r.EventSender.SendEvent(phase, "Warning", reconcileObject, apicommon.PhaseStateFailed, "could not create KeptnTask", piWrapper.GetVersion())
return "", err
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package common
package telemetry

import (
"context"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package common
package telemetry

import (
"context"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package common
package telemetry

import (
"context"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package common
package telemetry

import (
"net"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package common
package telemetry

import (
"context"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package common
package telemetry

import (
"context"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package common
package telemetry

import "go.opentelemetry.io/otel/trace"

Loading