diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index a61b33c640..a15efbeea4 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -22,6 +22,7 @@ jobs: - "multi-apps" - "helm-chart" - "fe-synthetic" + - "cli-upgrade" include: - kube-version: "1.23" kind-image: "kindest/node:v1.23.17@sha256:14d0a9a892b943866d7e6be119a06871291c517d279aedb816a4b4bc0ec0a5b3" diff --git a/cli/cmd/upgrade.go b/cli/cmd/upgrade.go index c39113cd84..0eaf4583c7 100644 --- a/cli/cmd/upgrade.go +++ b/cli/cmd/upgrade.go @@ -42,52 +42,58 @@ and apply any required migrations and adaptations.`, os.Exit(1) } - cm, err := client.CoreV1().ConfigMaps(ns).Get(ctx, resources.OdigosDeploymentConfigMapName, metav1.GetOptions{}) - if err != nil { - fmt.Println("Odigos upgrade failed - unable to read the current Odigos version for migration") - os.Exit(1) - } + var operation string - currOdigosVersion := cm.Data["ODIGOS_VERSION"] - if currOdigosVersion == "" { - fmt.Println("Odigos upgrade failed - unable to read the current Odigos version for migration") - os.Exit(1) - } + if !cmd.Flag("skip-version-check").Changed { - sourceVersion, err := version.NewVersion(currOdigosVersion) - if err != nil { - fmt.Println("Odigos upgrade failed - unable to parse the current Odigos version for migration") - os.Exit(1) - } - if sourceVersion.LessThan(version.Must(version.NewVersion("1.0.0"))) { - fmt.Printf("Unable to upgrade from Odigos version older than 'v1.0.0' current version is %s.\n", currOdigosVersion) - fmt.Printf("To upgrade, please use 'odigos uninstall' and 'odigos install'.\n") - os.Exit(1) - } - targetVersion, err := version.NewVersion(versionFlag) - if err != nil { - fmt.Println("Odigos upgrade failed - unable to parse the target Odigos version for migration") - os.Exit(1) - } + cm, err := client.CoreV1().ConfigMaps(ns).Get(ctx, resources.OdigosDeploymentConfigMapName, metav1.GetOptions{}) + if err != nil { + fmt.Println("Odigos upgrade failed - unable to read the current Odigos version for migration") + os.Exit(1) + } - var operation string - if sourceVersion.Equal(targetVersion) { - fmt.Printf("Odigos version is already '%s', synching installation\n", versionFlag) - operation = "Synching" - } else if sourceVersion.GreaterThan(targetVersion) { - fmt.Printf("About to DOWNGRADE Odigos version from '%s' (current) to '%s' (target)\n", currOdigosVersion, versionFlag) - operation = "Downgrading" - } else { - fmt.Printf("About to upgrade Odigos version from '%s' (current) to '%s' (target)\n", currOdigosVersion, versionFlag) - operation = "Upgrading" - } + currOdigosVersion := cm.Data["ODIGOS_VERSION"] + if currOdigosVersion == "" { + fmt.Println("Odigos upgrade failed - unable to read the current Odigos version for migration") + os.Exit(1) + } - if !cmd.Flag("yes").Changed { - confirmed, err := confirm.Ask("Are you sure?") - if err != nil || !confirmed { - fmt.Println("Aborting upgrade") - return + sourceVersion, err := version.NewVersion(currOdigosVersion) + if err != nil { + fmt.Println("Odigos upgrade failed - unable to parse the current Odigos version for migration") + os.Exit(1) + } + if sourceVersion.LessThan(version.Must(version.NewVersion("1.0.0"))) { + fmt.Printf("Unable to upgrade from Odigos version older than 'v1.0.0' current version is %s.\n", currOdigosVersion) + fmt.Printf("To upgrade, please use 'odigos uninstall' and 'odigos install'.\n") + os.Exit(1) } + targetVersion, err := version.NewVersion(versionFlag) + if err != nil { + fmt.Println("Odigos upgrade failed - unable to parse the target Odigos version for migration") + os.Exit(1) + } + + if sourceVersion.Equal(targetVersion) { + fmt.Printf("Odigos version is already '%s', synching installation\n", versionFlag) + operation = "Synching" + } else if sourceVersion.GreaterThan(targetVersion) { + fmt.Printf("About to DOWNGRADE Odigos version from '%s' (current) to '%s' (target)\n", currOdigosVersion, versionFlag) + operation = "Downgrading" + } else { + fmt.Printf("About to upgrade Odigos version from '%s' (current) to '%s' (target)\n", currOdigosVersion, versionFlag) + operation = "Upgrading" + } + + if !cmd.Flag("yes").Changed { + confirmed, err := confirm.Ask("Are you sure?") + if err != nil || !confirmed { + fmt.Println("Aborting upgrade") + return + } + } + } else { + operation = "Focefully upgrading" } config, err := resources.GetCurrentConfig(ctx, client, ns) @@ -133,5 +139,7 @@ func init() { versionFlag = OdigosVersion } else { upgradeCmd.Flags().StringVar(&versionFlag, "version", OdigosVersion, "for development purposes only") + upgradeCmd.Flags().Bool("skip-version-check", false, "skip the version check and install any version tag provided. used for tests") + updateCmd.Flags().MarkHidden("skip-version-check") } } diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 7a00951d48..bd1508bb33 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -98,4 +98,31 @@ expected: Once you have the file, you can run the test via: ```bash tests/e2e/common/traceql_runner.sh -``` \ No newline at end of file +``` + +## Debugging + +When tests fail, and it's related to some traceql query not succeeding, it can be useful to setup a grafana ui to commit queries and see the traces that are stored in tempo. + +- Install grafana with helm: + +```bash +helm install -n traces grafana grafana/grafana --set adminPassword='odigos' +``` + +- Port forward to the grafana service: + +```bash +kubectl port-forward svc/grafana 3080:80 -n traces +``` + +- Browse to `http://localhost:3080` and login with `admin` and `odigos`. + +- Add tempo as a datasource, by going to `Connections -> Data Sources -> Add data source` and selecting `Tempo` as the type. Set the URL to `http://e2e-tests-tempo:3100` and save. + +- In grafana left side menu, go to `Explore` and select the tempo datasource. You can now write queries, run them, and see the traces that are stored in tempo to troubleshoot your test issues. example query: + +``` +{resource.service.name = "coupon"} +``` + diff --git a/tests/e2e/cli-upgrade/.gitignore b/tests/e2e/cli-upgrade/.gitignore new file mode 100644 index 0000000000..a34d8e643f --- /dev/null +++ b/tests/e2e/cli-upgrade/.gitignore @@ -0,0 +1,3 @@ +# the odigos cli executable downloaded from github for the test to run +odigos +odigos-latest.tar.gz \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/02-install-simple-demo.yaml b/tests/e2e/cli-upgrade/02-install-simple-demo.yaml new file mode 100644 index 0000000000..d12e8abd41 --- /dev/null +++ b/tests/e2e/cli-upgrade/02-install-simple-demo.yaml @@ -0,0 +1,203 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: coupon + namespace: default + labels: + app: coupon +spec: + selector: + matchLabels: + app: coupon + template: + metadata: + labels: + app: coupon + spec: + containers: + - name: coupon + image: keyval/odigos-demo-coupon:v0.1 + imagePullPolicy: IfNotPresent + env: + - name: MEMBERSHIP_SERVICE_HOST + value: "membership:8080" + ports: + - containerPort: 8080 +--- +kind: Service +apiVersion: v1 +metadata: + name: coupon + namespace: default +spec: + selector: + app: coupon + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: frontend + namespace: default + labels: + app: frontend +spec: + selector: + matchLabels: + app: frontend + template: + metadata: + labels: + app: frontend + spec: + containers: + - name: frontend + image: keyval/odigos-demo-frontend:v0.2 + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: 1000 + env: + - name: INVENTORY_SERVICE_HOST + value: inventory:8080 + - name: PRICING_SERVICE_HOST + value: pricing:8080 + - name: COUPON_SERVICE_HOST + value: coupon:8080 + ports: + - containerPort: 8080 + readinessProbe: + httpGet: + path: /actuator/health/readiness + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 +--- +kind: Service +apiVersion: v1 +metadata: + name: frontend + namespace: default +spec: + selector: + app: frontend + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: inventory + namespace: default + labels: + app: inventory +spec: + selector: + matchLabels: + app: inventory + template: + metadata: + labels: + app: inventory + spec: + containers: + - name: inventory + image: keyval/odigos-demo-inventory:v0.1 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8080 +--- +kind: Service +apiVersion: v1 +metadata: + name: inventory + namespace: default +spec: + selector: + app: inventory + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: membership + namespace: default + labels: + app: membership +spec: + selector: + matchLabels: + app: membership + template: + metadata: + labels: + app: membership + spec: + containers: + - name: membership + image: keyval/odigos-demo-membership:v0.1 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8080 +--- +kind: Service +apiVersion: v1 +metadata: + name: membership + namespace: default +spec: + selector: + app: membership + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: pricing + namespace: default + labels: + app: pricing +spec: + selector: + matchLabels: + app: pricing + template: + metadata: + labels: + app: pricing + spec: + containers: + - name: pricing + image: keyval/odigos-demo-pricing:v0.1 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8080 +--- +kind: Service +apiVersion: v1 +metadata: + name: pricing + namespace: default +spec: + selector: + app: pricing + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/03-instrument-ns.yaml b/tests/e2e/cli-upgrade/03-instrument-ns.yaml new file mode 100644 index 0000000000..6814c325fc --- /dev/null +++ b/tests/e2e/cli-upgrade/03-instrument-ns.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: default + labels: + odigos-instrumentation: enabled \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/04-add-destination.yaml b/tests/e2e/cli-upgrade/04-add-destination.yaml new file mode 100644 index 0000000000..92ad6a49f8 --- /dev/null +++ b/tests/e2e/cli-upgrade/04-add-destination.yaml @@ -0,0 +1,12 @@ +apiVersion: odigos.io/v1alpha1 +kind: Destination +metadata: + name: odigos.io.dest.tempo-123123 + namespace: odigos-test-cli-upgrade +spec: + data: + TEMPO_URL: e2e-tests-tempo.traces:4317 + destinationName: e2e-tests + signals: + - TRACES + type: tempo \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/05-generate-traffic.yaml b/tests/e2e/cli-upgrade/05-generate-traffic.yaml new file mode 100644 index 0000000000..fb94d0f538 --- /dev/null +++ b/tests/e2e/cli-upgrade/05-generate-traffic.yaml @@ -0,0 +1,23 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: buybot-job + namespace: default +spec: + template: + metadata: + annotations: + workload: job + labels: + app: buybot + spec: + restartPolicy: Never + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + containers: + - name: curl + image: curlimages/curl:8.4.0 + imagePullPolicy: IfNotPresent + command: [ "curl" ] + args: [ "-s","-X","POST","http://frontend:8080/buy?id=123" ] diff --git a/tests/e2e/cli-upgrade/assert-apps-installed.yaml b/tests/e2e/cli-upgrade/assert-apps-installed.yaml new file mode 100644 index 0000000000..c78756927c --- /dev/null +++ b/tests/e2e/cli-upgrade/assert-apps-installed.yaml @@ -0,0 +1,69 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app: frontend + namespace: default +status: + containerStatuses: + - name: frontend + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app: coupon + namespace: default +status: + containerStatuses: + - name: coupon + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app: inventory + namespace: default +status: + containerStatuses: + - name: inventory + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app: membership + namespace: default +status: + containerStatuses: + - name: membership + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app: pricing + namespace: default +status: + containerStatuses: + - name: pricing + ready: true + restartCount: 0 + started: true + phase: Running \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/assert-instrumented-and-pipeline.yaml b/tests/e2e/cli-upgrade/assert-instrumented-and-pipeline.yaml new file mode 100644 index 0000000000..8f32b4ada3 --- /dev/null +++ b/tests/e2e/cli-upgrade/assert-instrumented-and-pipeline.yaml @@ -0,0 +1,337 @@ +apiVersion: odigos.io/v1alpha1 +kind: CollectorsGroup +metadata: + name: odigos-data-collection + namespace: odigos-test-cli-upgrade +spec: + role: NODE_COLLECTOR +status: + ready: true +--- +apiVersion: odigos.io/v1alpha1 +kind: CollectorsGroup +metadata: + name: odigos-gateway + namespace: odigos-test-cli-upgrade +spec: + role: CLUSTER_GATEWAY +status: + ready: true +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + odigos.io/collector-role: "CLUSTER_GATEWAY" + name: odigos-gateway + namespace: odigos-test-cli-upgrade + ownerReferences: + - apiVersion: odigos.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CollectorsGroup + name: odigos-gateway +spec: + replicas: 1 + selector: + matchLabels: + odigos.io/collector-role: "CLUSTER_GATEWAY" + template: + metadata: + labels: + odigos.io/collector-role: "CLUSTER_GATEWAY" + spec: + containers: + - env: + - name: ODIGOS_VERSION + valueFrom: + configMapKeyRef: + key: ODIGOS_VERSION + name: odigos-deployment + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: GOMEMLIMIT + (value != null): true + name: gateway + resources: + requests: + (memory != null): true + volumeMounts: + - mountPath: /conf + name: collector-conf + volumes: + - configMap: + defaultMode: 420 + items: + - key: collector-conf + path: collector-conf.yaml + name: odigos-gateway + name: collector-conf +status: + availableReplicas: 1 + readyReplicas: 1 + replicas: 1 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: odigos-gateway + namespace: odigos-test-cli-upgrade + ownerReferences: + - apiVersion: odigos.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CollectorsGroup + name: odigos-gateway +(data != null): true +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: odigos-data-collection + namespace: odigos-test-cli-upgrade + ownerReferences: + - apiVersion: odigos.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CollectorsGroup + name: odigos-data-collection +(data != null): true +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + odigos.io/collector-role: "NODE_COLLECTOR" + name: odigos-data-collection + namespace: odigos-test-cli-upgrade + ownerReferences: + - apiVersion: odigos.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: CollectorsGroup + name: odigos-data-collection +spec: + selector: + matchLabels: + odigos.io/collector-role: "NODE_COLLECTOR" + template: + metadata: + labels: + odigos.io/collector-role: "NODE_COLLECTOR" + spec: + containers: + - name: data-collection + securityContext: + privileged: true + volumeMounts: + - mountPath: /conf + name: conf + - mountPath: /var/lib/docker/containers + name: varlibdockercontainers + readOnly: true + - mountPath: /var/log + name: varlog + readOnly: true + - mountPath: /var/lib/kubelet/pod-resources + name: kubeletpodresources + readOnly: true + env: + - name: NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + hostNetwork: true + nodeSelector: + kubernetes.io/os: linux + securityContext: {} + serviceAccount: odigos-data-collection + serviceAccountName: odigos-data-collection + volumes: + - configMap: + defaultMode: 420 + items: + - key: conf + path: conf.yaml + name: odigos-data-collection + name: conf + - hostPath: + path: /var/log + type: "" + name: varlog + - hostPath: + path: /var/lib/docker/containers + type: "" + name: varlibdockercontainers + - hostPath: + path: /var/lib/kubelet/pod-resources + type: "" + name: kubeletpodresources +status: + numberAvailable: 1 + numberReady: 1 +--- +apiVersion: v1 +kind: Pod +metadata: + namespace: default + labels: + app: frontend +spec: + containers: + - name: frontend + resources: + limits: + instrumentation.odigos.io/java-native-community: "1" + requests: + instrumentation.odigos.io/java-native-community: "1" +status: + containerStatuses: + - name: frontend + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + namespace: default + labels: + app: coupon +spec: + containers: + - name: coupon + resources: + limits: + instrumentation.odigos.io/javascript-native-community: "1" + requests: + instrumentation.odigos.io/javascript-native-community: "1" +status: + containerStatuses: + - name: coupon + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + namespace: default + labels: + app: inventory +spec: + containers: + - name: inventory + resources: + limits: + instrumentation.odigos.io/python-native-community: "1" + requests: + instrumentation.odigos.io/python-native-community: "1" +status: + containerStatuses: + - name: inventory + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + namespace: default + labels: + app: membership +spec: + containers: + - name: membership + resources: + limits: + instrumentation.odigos.io/go-ebpf-community: "1" + requests: + instrumentation.odigos.io/go-ebpf-community: "1" +status: + containerStatuses: + - name: membership + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + namespace: default + labels: + app: pricing +spec: + containers: + - name: pricing + resources: + limits: + instrumentation.odigos.io/dotnet-native-community: "1" + requests: + instrumentation.odigos.io/dotnet-native-community: "1" +status: + containerStatuses: + - name: pricing + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: odigos.io/v1alpha1 +kind: InstrumentationInstance +metadata: + namespace: default + labels: + instrumented-app: deployment-coupon +status: + healthy: true + identifyingAttributes: + - key: service.instance.id + (value != null): true + - key: telemetry.sdk.language + value: nodejs + - key: process.runtime.version + (value != null): true + - key: telemetry.distro.version + (value != null): true # This will hold the version before the upgrade + - key: process.pid + (value != null): true +--- +apiVersion: odigos.io/v1alpha1 +kind: InstrumentationInstance +metadata: + namespace: default + labels: + instrumented-app: deployment-inventory +status: + healthy: true + identifyingAttributes: + - key: service.instance.id + (value != null): true + - key: process.pid + (value != null): true + - key: telemetry.sdk.language + value: python +--- +apiVersion: odigos.io/v1alpha1 +kind: InstrumentationInstance +metadata: + namespace: default + labels: + instrumented-app: deployment-membership +status: + healthy: true + reason: LoadedSuccessfully diff --git a/tests/e2e/cli-upgrade/assert-odigos-installed.yaml b/tests/e2e/cli-upgrade/assert-odigos-installed.yaml new file mode 100644 index 0000000000..412a2f4c36 --- /dev/null +++ b/tests/e2e/cli-upgrade/assert-odigos-installed.yaml @@ -0,0 +1,114 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: odigos-test-cli-upgrade + labels: + odigos.io/system-object: "true" +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/name: odigos-autoscaler + namespace: odigos-test-cli-upgrade +status: + containerStatuses: + - name: manager + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/name: odigos-scheduler + namespace: odigos-test-cli-upgrade +status: + containerStatuses: + - name: manager + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/name: odigos-instrumentor + namespace: odigos-test-cli-upgrade +status: + containerStatuses: + - name: manager + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/name: odiglet + namespace: odigos-test-cli-upgrade + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: DaemonSet + name: odiglet +spec: + containers: + - name: odiglet + resources: {} + securityContext: + capabilities: + add: + - SYS_PTRACE + privileged: true + hostNetwork: true + hostPID: true + nodeSelector: + kubernetes.io/os: linux + serviceAccount: odiglet + serviceAccountName: odiglet +status: + containerStatuses: + - name: odiglet + ready: true + restartCount: 0 + started: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + odigos.io/config: "1" + odigos.io/system-object: "true" + name: destinations.odigos.io +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + odigos.io/config: "1" + odigos.io/system-object: "true" + name: instrumentedapplications.odigos.io +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + odigos.io/config: "1" + odigos.io/system-object: "true" + name: odigosconfigurations.odigos.io +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + odigos.io/config: "1" + odigos.io/system-object: "true" + name: processors.odigos.io diff --git a/tests/e2e/cli-upgrade/assert-odigos-upgraded.yaml b/tests/e2e/cli-upgrade/assert-odigos-upgraded.yaml new file mode 100644 index 0000000000..a69cac6acc --- /dev/null +++ b/tests/e2e/cli-upgrade/assert-odigos-upgraded.yaml @@ -0,0 +1,158 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: odigos-test-cli-upgrade + labels: + odigos.io/system-object: "true" +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/name: odigos-autoscaler + namespace: odigos-test-cli-upgrade +spec: + containers: + - name: manager + image: keyval/odigos-autoscaler:e2e-test +status: + containerStatuses: + - name: manager + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/name: odigos-scheduler + namespace: odigos-test-cli-upgrade +spec: + containers: + - name: manager + image: keyval/odigos-scheduler:e2e-test +status: + containerStatuses: + - name: manager + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/name: odigos-instrumentor + namespace: odigos-test-cli-upgrade +spec: + containers: + - name: manager + image: keyval/odigos-instrumentor:e2e-test +status: + containerStatuses: + - name: manager + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + app.kubernetes.io/name: odiglet + namespace: odigos-test-cli-upgrade + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: DaemonSet + name: odiglet +spec: + containers: + - name: odiglet + resources: {} + securityContext: + capabilities: + add: + - SYS_PTRACE + privileged: true + image: keyval/odigos-odiglet:e2e-test + hostNetwork: true + hostPID: true + nodeSelector: + kubernetes.io/os: linux + serviceAccount: odiglet + serviceAccountName: odiglet +status: + containerStatuses: + - name: odiglet + ready: true + restartCount: 0 + started: true +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + odigos.io/collector-role: CLUSTER_GATEWAY + namespace: odigos-test-cli-upgrade +spec: + containers: + - name: gateway + image: keyval/odigos-collector:e2e-test +status: + containerStatuses: + - name: gateway + ready: true + restartCount: 0 + started: true + phase: Running +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: odigos-gateway + namespace: odigos-test-cli-upgrade + labels: + odigos.io/collector-role: CLUSTER_GATEWAY +status: + replicas: 1 + readyReplicas: 1 + updatedReplicas: 1 + availableReplicas: 1 +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + odigos.io/config: "2" + odigos.io/system-object: "true" + name: destinations.odigos.io +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + odigos.io/config: "2" + odigos.io/system-object: "true" + name: instrumentedapplications.odigos.io +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + odigos.io/config: "2" + odigos.io/system-object: "true" + name: odigosconfigurations.odigos.io +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + odigos.io/config: "2" + odigos.io/system-object: "true" + name: processors.odigos.io diff --git a/tests/e2e/cli-upgrade/assert-runtime-detected.yaml b/tests/e2e/cli-upgrade/assert-runtime-detected.yaml new file mode 100644 index 0000000000..f0894f78a4 --- /dev/null +++ b/tests/e2e/cli-upgrade/assert-runtime-detected.yaml @@ -0,0 +1,79 @@ +apiVersion: odigos.io/v1alpha1 +kind: InstrumentedApplication +metadata: + name: deployment-coupon + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: coupon +spec: + runtimeDetails: + - containerName: coupon + language: javascript +--- +apiVersion: odigos.io/v1alpha1 +kind: InstrumentedApplication +metadata: + name: deployment-frontend + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: frontend +spec: + runtimeDetails: + - containerName: frontend + language: java +--- +apiVersion: odigos.io/v1alpha1 +kind: InstrumentedApplication +metadata: + name: deployment-inventory + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: inventory +spec: + runtimeDetails: + - containerName: inventory + language: python +--- +apiVersion: odigos.io/v1alpha1 +kind: InstrumentedApplication +metadata: + name: deployment-membership + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: membership +spec: + runtimeDetails: + - containerName: membership + language: go +--- +apiVersion: odigos.io/v1alpha1 +kind: InstrumentedApplication +metadata: + name: deployment-pricing + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: Deployment + name: pricing +spec: + runtimeDetails: + - containerName: pricing + language: dotnet diff --git a/tests/e2e/cli-upgrade/assert-tempo-running.yaml b/tests/e2e/cli-upgrade/assert-tempo-running.yaml new file mode 100644 index 0000000000..f4653f4a37 --- /dev/null +++ b/tests/e2e/cli-upgrade/assert-tempo-running.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: e2e-tests-tempo-0 + namespace: traces +status: + phase: Running + containerStatuses: + - name: tempo + ready: true + restartCount: 0 \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/chainsaw-test.yaml b/tests/e2e/cli-upgrade/chainsaw-test.yaml new file mode 100644 index 0000000000..9a07dbf3fa --- /dev/null +++ b/tests/e2e/cli-upgrade/chainsaw-test.yaml @@ -0,0 +1,161 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: cli-upgrade +spec: + description: Check successful upgrade from latest version of CLI + skipDelete: true + steps: + - name: Prepare destination + try: + - script: + timeout: 60s + content: | + if helm status e2e-tests -n traces >/dev/null 2>&1; then + echo "e2e-tests helm already installed, probably from previous run. Skipping..." + else + helm repo add grafana https://grafana.github.io/helm-charts + helm repo update + helm install e2e-tests grafana/tempo -n traces --create-namespace --set tempo.storage.trace.block.version=vParquet4 --version 1.10.1 + fi + - assert: + file: assert-tempo-running.yaml + - name: Wait for destination to be ready + try: + - script: + timeout: 60s + content: ../../common/wait_for_dest.sh + - name: Install Odigos latest release from GitHub for pre upgrade setup + try: + - script: + content: | + #!/bin/bash + + # Define variables + REPO_URL="https://api.github.com/repos/odigos-io/odigos/releases/latest" + ARCH=$(uname -m) # Get the system architecture + OS=$(uname | tr '[:upper:]' '[:lower:]') # Get the OS name in lowercase + + # Convert architecture to match GitHub naming conventions if necessary + if [ "$ARCH" = "x86_64" ]; then + ARCH="amd64" + elif [ "$ARCH" = "aarch64" ]; then + ARCH="arm64" + fi + + # Fetch the release assets from GitHub API + ASSETS_JSON=$(curl -s "$REPO_URL") + + # Find the download URL that matches the OS and architecture + DOWNLOAD_URL=$(echo "$ASSETS_JSON" | grep "browser_download_url" | grep "$OS" | grep "$ARCH" | cut -d '"' -f 4) + + # Check if the download URL was found + if [ -z "$DOWNLOAD_URL" ]; then + echo "No matching release found for OS: $OS and Architecture: $ARCH" + exit 1 + fi + + # Download the matched asset + curl -L -o odigos-latest.tar.gz "$DOWNLOAD_URL" + + # Extract the downloaded file + tar -xvzf odigos-latest.tar.gz + + # cleanup any existing installation of odigos the might be left over from previous runs while developing + ./odigos uninstall --yes + # Run the Odigos CLI installation + ./odigos install --namespace odigos-test-cli-upgrade + timeout: 120s # longer timeout since the images are being pulled from dockerhub + - assert: + file: assert-odigos-installed.yaml + - name: Install Demo App + try: + - script: + timeout: 100s + content: | + docker pull keyval/odigos-demo-inventory:v0.1 + docker pull keyval/odigos-demo-membership:v0.1 + docker pull keyval/odigos-demo-coupon:v0.1 + docker pull keyval/odigos-demo-inventory:v0.1 + docker pull keyval/odigos-demo-frontend:v0.2 + kind load docker-image keyval/odigos-demo-inventory:v0.1 + kind load docker-image keyval/odigos-demo-membership:v0.1 + kind load docker-image keyval/odigos-demo-coupon:v0.1 + kind load docker-image keyval/odigos-demo-inventory:v0.1 + kind load docker-image keyval/odigos-demo-frontend:v0.2 + - apply: + file: 02-install-simple-demo.yaml + - assert: + file: assert-apps-installed.yaml + - name: Detect Languages + try: + - apply: + file: 03-instrument-ns.yaml + - assert: + file: assert-runtime-detected.yaml + - name: Add Destination + try: + - apply: + file: 04-add-destination.yaml + - assert: + file: assert-instrumented-and-pipeline.yaml + - name: Upgrade to HEAD version with the current compiled cli + try: + - script: + content: ../../../cli/odigos upgrade --version e2e-test --skip-version-check # since the tag e2e-test is not a valid semantic version, we need to bypass it with --skip-version-check + timeout: 60s + - assert: + file: assert-odigos-upgraded.yaml + - name: Generate Traffic + try: + - script: + timeout: 60s + content: | + while true; do + # Apply the job + kubectl apply -f 05-generate-traffic.yaml + + # Wait for the job to complete + job_name=$(kubectl get -f 05-generate-traffic.yaml -o=jsonpath='{.metadata.name}') + kubectl wait --for=condition=complete job/$job_name + + # Delete the job + kubectl delete -f 05-generate-traffic.yaml + + # Run the wait-for-trace script + ../../common/traceql_runner.sh tracesql/wait-for-trace.yaml + if [ $? -eq 0 ]; then + break + else + sleep 3 + ../../common/flush_traces.sh + fi + done + - name: Verify Trace - Context Propagation + try: + - script: + content: | + ../../common/traceql_runner.sh tracesql/context-propagation.yaml + catch: + - podLogs: + name: odiglet + namespace: odigos-test-cli-upgrade + - name: Verify Trace - Resource Attributes + try: + - script: + content: | + ../../common/traceql_runner.sh tracesql/resource-attributes.yaml + catch: + - podLogs: + name: odiglet + namespace: odigos-test-cli-upgrade + - name: Verify Trace - Span Attributes + try: + - script: + timeout: 60s + content: | + ../../common/traceql_runner.sh tracesql/span-attributes.yaml + catch: + - podLogs: + name: odiglet + namespace: odigos-test-cli-upgrade diff --git a/tests/e2e/cli-upgrade/odigos-ui.pid b/tests/e2e/cli-upgrade/odigos-ui.pid new file mode 100644 index 0000000000..989dc8b874 --- /dev/null +++ b/tests/e2e/cli-upgrade/odigos-ui.pid @@ -0,0 +1 @@ +88480 diff --git a/tests/e2e/cli-upgrade/tracesql/context-propagation.yaml b/tests/e2e/cli-upgrade/tracesql/context-propagation.yaml new file mode 100644 index 0000000000..9c463f9b3f --- /dev/null +++ b/tests/e2e/cli-upgrade/tracesql/context-propagation.yaml @@ -0,0 +1,13 @@ +apiVersion: e2e.tests.odigos.io/v1 +kind: TraceTest +description: This test checks if the context propagation is working correctly between different languages +query: | + { resource.service.name = "frontend" && resource.telemetry.sdk.language = "java" && + span.http.request.method = "POST" && span.http.route = "/buy" && span:kind = server } + >> ( + { resource.service.name = "pricing" && resource.telemetry.sdk.language = "dotnet" } && + { resource.service.name = "inventory" && resource.telemetry.sdk.language = "python" } && + ({ resource.service.name = "coupon" && resource.telemetry.sdk.language = "nodejs" } + >> { resource.service.name = "membership" && resource.telemetry.sdk.language = "go" })) +expected: + count: 1 \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/tracesql/resource-attributes.yaml b/tests/e2e/cli-upgrade/tracesql/resource-attributes.yaml new file mode 100644 index 0000000000..4322a57eaf --- /dev/null +++ b/tests/e2e/cli-upgrade/tracesql/resource-attributes.yaml @@ -0,0 +1,14 @@ +apiVersion: e2e.tests.odigos.io/v1 +kind: TraceTest +description: | + This test check the following resource attributes: + A. odigos.version attribute exists on all spans, since it's an upgrade, we can have version of both the old and new odigos deployments. + B. Kubernetes attributes are correctly set on all spans + At the time of writing this test, TraceQL api does not support not equal to nil so we use regex instead. +query: | + { resource.odigos.version !~ ".*" || + resource.k8s.deployment.name !~ ".*" || + resource.k8s.node.name !~ "kind-control-plane" || + resource.k8s.pod.name !~ ".*" } +expected: + count: 0 \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/tracesql/span-attributes.yaml b/tests/e2e/cli-upgrade/tracesql/span-attributes.yaml new file mode 100644 index 0000000000..60be82c0fb --- /dev/null +++ b/tests/e2e/cli-upgrade/tracesql/span-attributes.yaml @@ -0,0 +1,18 @@ +apiVersion: e2e.tests.odigos.io/v1 +kind: TraceTest +description: | + This test checks the span attributes for a specific trace. + TODO - JS, Python and DotNet SDK are not generating data in latest semconv. add additional checks when they are updated. +query: | + { resource.odigos.version = "e2e-test" && resource.service.name = "frontend" && resource.telemetry.sdk.language = "java" && + span.http.request.method = "POST" && span.http.route = "/buy" && span:kind = server && + span.http.response.status_code = 200 && span.url.query = "id=123" } + >> ( + { resource.odigos.version = "e2e-test" && resource.service.name = "pricing" && resource.telemetry.sdk.language = "dotnet" && span:kind = server } && + { resource.odigos.version = "e2e-test" && resource.service.name = "inventory" && resource.telemetry.sdk.language = "python" && span:kind = server } && + ({ resource.odigos.version = "e2e-test" && resource.service.name = "coupon" && resource.telemetry.sdk.language = "nodejs" && span:kind = server } + >> { resource.odigos.version = "e2e-test" && resource.service.name = "membership" && resource.telemetry.sdk.language = "go" && + span.http.request.method = "GET" && span:kind = server && + span.http.response.status_code = 200 && span.url.path = "/isMember" })) +expected: + count: 1 \ No newline at end of file diff --git a/tests/e2e/cli-upgrade/tracesql/wait-for-trace.yaml b/tests/e2e/cli-upgrade/tracesql/wait-for-trace.yaml new file mode 100644 index 0000000000..a88f58987c --- /dev/null +++ b/tests/e2e/cli-upgrade/tracesql/wait-for-trace.yaml @@ -0,0 +1,11 @@ +apiVersion: e2e.tests.odigos.io/v1 +kind: TraceTest +description: This test waits for a trace that goes from frontend to pricing, inventory, coupon, and membership services +query: | + { resource.service.name = "frontend" } && + { resource.service.name = "pricing" } && + { resource.service.name = "inventory" } && + { resource.service.name = "coupon" } && + { resource.service.name = "membership" } +expected: + count: 1 \ No newline at end of file