Skip to content

Commit

Permalink
feat(lifecycle-operator): propagate metadata from deployment annotati…
Browse files Browse the repository at this point in the history
…ons (keptn#2832)

Signed-off-by: Florian Bacher <[email protected]>
Signed-off-by: check-spelling-bot <[email protected]>
Co-authored-by: Moritz Wiesinger <[email protected]>
  • Loading branch information
bacherfl and mowies authored Jan 22, 2024
1 parent 42b805c commit 6f700ce
Show file tree
Hide file tree
Showing 38 changed files with 353 additions and 9 deletions.
3 changes: 1 addition & 2 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ configmapref
configmapreference
containedctx
containerspec
contextcommon
contextdata
controllercommon
controllererrors
Expand Down Expand Up @@ -294,6 +293,7 @@ keptnappversionstatus
keptnconfig
keptnconfiglist
keptnconfigspec
keptncontext
keptncontroller
keptndemo
keptndemoapp
Expand Down Expand Up @@ -487,7 +487,6 @@ previousversion
printargs
printcolumn
privs
Process
proj
promapi
promhttp
Expand Down
12 changes: 12 additions & 0 deletions .github/scripts/.helm-tests/default/result.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7207,6 +7207,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down Expand Up @@ -7690,6 +7696,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down
12 changes: 12 additions & 0 deletions .github/scripts/.helm-tests/lifecycle-only/result.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7153,6 +7153,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down Expand Up @@ -7636,6 +7642,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down
12 changes: 12 additions & 0 deletions .github/scripts/.helm-tests/lifecycle-with-certs/result.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7187,6 +7187,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down Expand Up @@ -7671,6 +7677,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down
2 changes: 2 additions & 0 deletions docs/docs/reference/api-reference/lifecycle/v1beta1/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,7 @@ _Appears in:_
| `preDeploymentEvaluations` _string array_ | PreDeploymentEvaluations is a list of all evaluations to be performed during the pre-deployment phase of the KeptnWorkload. The items of this list refer to the names of KeptnEvaluationDefinitions located in the same namespace as the KeptnWorkload, or in the Keptn namespace. |||
| `postDeploymentEvaluations` _string array_ | PostDeploymentEvaluations is a list of all evaluations to be performed during the post-deployment phase of the KeptnWorkload. The items of this list refer to the names of KeptnEvaluationDefinitions located in the same namespace as the KeptnWorkload, or in the Keptn namespace. |||
| `resourceReference` _[ResourceReference](#resourcereference)_ | ResourceReference is a reference to the Kubernetes resource (Deployment, DaemonSet, StatefulSet or ReplicaSet) the KeptnWorkload is representing. || x |
| `metadata` _object (keys:string, values:string)_ | Refer to Kubernetes API documentation for fields of `metadata`. |||


#### KeptnWorkloadStatus
Expand Down Expand Up @@ -868,6 +869,7 @@ _Appears in:_
| `preDeploymentEvaluations` _string array_ | PreDeploymentEvaluations is a list of all evaluations to be performed during the pre-deployment phase of the KeptnWorkload. The items of this list refer to the names of KeptnEvaluationDefinitions located in the same namespace as the KeptnWorkload, or in the Keptn namespace. |||
| `postDeploymentEvaluations` _string array_ | PostDeploymentEvaluations is a list of all evaluations to be performed during the post-deployment phase of the KeptnWorkload. The items of this list refer to the names of KeptnEvaluationDefinitions located in the same namespace as the KeptnWorkload, or in the Keptn namespace. |||
| `resourceReference` _[ResourceReference](#resourcereference)_ | ResourceReference is a reference to the Kubernetes resource (Deployment, DaemonSet, StatefulSet or ReplicaSet) the KeptnWorkload is representing. || x |
| `metadata` _object (keys:string, values:string)_ | Refer to Kubernetes API documentation for fields of `metadata`. |||
| `workloadName` _string_ | WorkloadName is the name of the KeptnWorkload. || x |
| `previousVersion` _string_ | PreviousVersion is the version of the KeptnWorkload that has been deployed prior to this version. |||
| `traceId` _object (keys:string, values:string)_ | TraceId contains the OpenTelemetry trace ID. |||
Expand Down
1 change: 1 addition & 0 deletions lifecycle-operator/apis/lifecycle/v1beta1/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const CreateWorkloadEvalSpanName = "create_%s_deployment_evaluation"
const AppTypeAnnotation = "keptn.sh/app-type"
const KeptnGate = "keptn-prechecks-gate"
const ContainerNameAnnotation = "keptn.sh/container"
const MetadataAnnotation = "keptn.sh/metadata"

const MinKeptnNameLen = 80
const MaxK8sObjectLength = 253
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ type KeptnWorkloadSpec struct {
// ResourceReference is a reference to the Kubernetes resource
// (Deployment, DaemonSet, StatefulSet or ReplicaSet) the KeptnWorkload is representing.
ResourceReference ResourceReference `json:"resourceReference"`
// +optional
// Metadata contains additional key-value pairs for contextual information.
Metadata map[string]string `json:"metadata,omitempty"`
}

// KeptnWorkloadStatus defines the observed state of KeptnWorkload
Expand Down
14 changes: 14 additions & 0 deletions lifecycle-operator/apis/lifecycle/v1beta1/zz_generated.deepcopy.go

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

6 changes: 6 additions & 0 deletions lifecycle-operator/chart/templates/keptnworkload-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,12 @@ spec:
app:
description: AppName is the name of the KeptnApp containing the KeptnWorkload.
type: string
metadata:
additionalProperties:
type: string
description: Metadata contains additional key-value pairs for contextual
information.
type: object
postDeploymentEvaluations:
description: |-
PostDeploymentEvaluations is a list of all evaluations to be performed
Expand Down
27 changes: 27 additions & 0 deletions lifecycle-operator/controllers/common/context/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package context

import "context"

type keptnAppContextKeyType string

var keptnAppContextKey = keptnAppContextKeyType("keptnAppContextMeta")

func WithAppMetadata(ctx context.Context, appContextMeta ...map[string]string) context.Context {
mergedMap := map[string]string{}
for _, meta := range appContextMeta {
for key, value := range meta {
mergedMap[key] = value
}
}
return context.WithValue(ctx, keptnAppContextKey, mergedMap)
}

func GetAppMetadataFromContext(ctx context.Context) (map[string]string, bool) {
value := ctx.Value(keptnAppContextKey)

appContextMeta, ok := value.(map[string]string)
if ok {
return appContextMeta, true
}
return map[string]string{}, false
}
25 changes: 25 additions & 0 deletions lifecycle-operator/controllers/common/context/context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package context

import (
"context"
"testing"

"github.com/stretchr/testify/require"
)

func TestContextWithAppMetadata(t *testing.T) {
ctx := context.Background()

metadata := map[string]string{
"foo": "bar",
}

ctx = WithAppMetadata(ctx, metadata)

require.NotNil(t, ctx)

metadata, ok := GetAppMetadataFromContext(ctx)

require.True(t, ok)
require.Equal(t, "bar", metadata["foo"])
}
12 changes: 12 additions & 0 deletions lifecycle-operator/controllers/common/telemetry/spanhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"context"
"sync"

keptncontext "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/context"
"github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/lifecycle/interfaces"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -45,6 +47,16 @@ func (r *Handler) GetSpan(ctx context.Context, tracer ITracer, reconcileObject c
childCtx, span := tracer.Start(ctx, spanName, trace.WithSpanKind(trace.SpanKindConsumer))
piWrapper.SetSpanAttributes(span)

// also get attributes from context
if meta, ok := keptncontext.GetAppMetadataFromContext(ctx); ok {
for key, value := range meta {
span.SetAttributes(attribute.KeyValue{
Key: attribute.Key(key),
Value: attribute.StringValue(value),
})
}
}

if phase != "" {
traceContextCarrier := propagation.MapCarrier{}
otel.GetTextMapPropagator().Inject(childCtx, traceContextCarrier)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (

"github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1"
apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1/common"
keptncontext "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/context"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/trace"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -103,3 +105,35 @@ func TestSpanHandler_GetSpan(t *testing.T) {
require.Equal(t, span, span5)

}

func TestSpanHandler_GetSpanWithAttributes(t *testing.T) {
wi := &v1beta1.KeptnWorkloadVersion{}
wi.Spec.TraceId = make(map[string]string, 1)
wi.Spec.TraceId["traceparent"] = "test-parent"
wi.Spec.AppName = "test"
wi.Spec.WorkloadName = "test"
wi.Spec.Version = "test"

r := Handler{}
phase := apicommon.PhaseAppDeployment.ShortName

tp := trace.NewTracerProvider()

tracer := tp.Tracer("keptn")

ctx := context.TODO()

ctx = keptncontext.WithAppMetadata(ctx, map[string]string{"foo": "bar"})
ctx, span, err := r.GetSpan(ctx, tracer, wi, phase)

require.Nil(t, err)
require.NotNil(t, span)
require.NotNil(t, ctx)

attributes := span.(trace.ReadOnlySpan).Attributes()
require.NotNil(t, attributes)

// the total number of attributes should be 5 (i.e. the workload specific ones + the additional one)
require.Len(t, attributes, 5)
require.Equal(t, "bar", attributes[4].Value.AsString())
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func (r *KeptnWorkloadReconciler) Reconcile(ctx context.Context, req ctrl.Reques
if err != nil {
return reconcile.Result{}, err
}

err = r.Client.Create(ctx, workloadVersion)
if err != nil {
r.Log.Error(err, "could not create WorkloadVersion")
Expand Down Expand Up @@ -142,6 +143,7 @@ func (r *KeptnWorkloadReconciler) createWorkloadVersion(ctx context.Context, wor
}

workloadVersion := generateWorkloadVersion(previousVersion, traceContextCarrier, workload)

err := controllerutil.SetControllerReference(workload, &workloadVersion, r.Scheme)
if err != nil {
r.Log.Error(err, "could not set controller reference for WorkloadVersion: "+workloadVersion.Name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ func TestKeptnWorkload(t *testing.T) {
Spec: klcv1beta1.KeptnWorkloadSpec{
Version: "version",
AppName: "app",
Metadata: map[string]string{
"foo": "bar",
},
},
}

Expand All @@ -31,6 +34,9 @@ func TestKeptnWorkload(t *testing.T) {
KeptnWorkloadSpec: klcv1beta1.KeptnWorkloadSpec{
Version: "version",
AppName: "app",
Metadata: map[string]string{
"foo": "bar",
},
},
WorkloadName: "workload",
PreviousVersion: "prev",
Expand Down
Loading

0 comments on commit 6f700ce

Please sign in to comment.