From 4a59d4bd2d46c125e7315140fb79753eaf68f1e2 Mon Sep 17 00:00:00 2001 From: ermisw Date: Mon, 13 Nov 2023 15:25:46 +0100 Subject: [PATCH] first commit --- argo/carts.tgz | Bin 0 -> 3184 bytes argo/carts/Chart.yaml | 4 + argo/carts/templates/NOTES.txt | 19 ++ argo/carts/templates/_helpers.tpl | 32 +++ argo/carts/templates/carts-db-deployment.yaml | 47 +++++ argo/carts/templates/carts-db-service.yaml | 12 ++ argo/carts/templates/keptn-hook.yaml | 28 +++ argo/carts/templates/rollout.yaml | 75 +++++++ argo/carts/templates/service.yaml | 41 ++++ argo/carts/values.yaml | 28 +++ carts-db.tgz | Bin 0 -> 919 bytes carts-db/Chart.yaml | 4 + carts-db/templates/carts-db-deployment.yaml | 53 +++++ carts-db/templates/carts-db-service.yaml | 12 ++ carts-db/values.yaml | 6 + carts.tgz | Bin 0 -> 1189 bytes carts/Chart.yaml | 4 + carts/templates/deployment.yaml | 77 +++++++ carts/templates/service.yaml | 14 ++ carts/values.yaml | 2 + dynatrace/dynatrace.conf.yaml | 2 + jmeter/basiccheck.jmx | 177 ++++++++++++++++ jmeter/load.jmx | 191 ++++++++++++++++++ lighthouse-source-dynatrace.yaml | 7 + lighthouse-source-prometheus.yaml | 7 + manifests/manifest-carts-db.yaml | 58 ++++++ manifests/manifest-carts.yaml | 88 ++++++++ remediation.yaml | 18 ++ remediation_feature_toggle.yaml | 20 ++ shipyard-argo.yaml | 18 ++ shipyard-quality-gates.yaml | 7 + shipyard.yaml | 96 +++++++++ sli-config-argo-prometheus.yaml | 6 + sli-config-dynatrace-no-deployment-tag.yaml | 8 + sli-config-dynatrace.yaml | 8 + sli-config-prometheus.yaml | 6 + slo-quality-gates.yaml | 23 +++ slo-self-healing-dynatrace.yaml | 30 +++ slo-self-healing-prometheus.yaml | 23 +++ 39 files changed, 1251 insertions(+) create mode 100644 argo/carts.tgz create mode 100644 argo/carts/Chart.yaml create mode 100644 argo/carts/templates/NOTES.txt create mode 100644 argo/carts/templates/_helpers.tpl create mode 100644 argo/carts/templates/carts-db-deployment.yaml create mode 100644 argo/carts/templates/carts-db-service.yaml create mode 100644 argo/carts/templates/keptn-hook.yaml create mode 100644 argo/carts/templates/rollout.yaml create mode 100644 argo/carts/templates/service.yaml create mode 100644 argo/carts/values.yaml create mode 100644 carts-db.tgz create mode 100644 carts-db/Chart.yaml create mode 100644 carts-db/templates/carts-db-deployment.yaml create mode 100644 carts-db/templates/carts-db-service.yaml create mode 100644 carts-db/values.yaml create mode 100644 carts.tgz create mode 100644 carts/Chart.yaml create mode 100644 carts/templates/deployment.yaml create mode 100644 carts/templates/service.yaml create mode 100644 carts/values.yaml create mode 100644 dynatrace/dynatrace.conf.yaml create mode 100644 jmeter/basiccheck.jmx create mode 100644 jmeter/load.jmx create mode 100644 lighthouse-source-dynatrace.yaml create mode 100644 lighthouse-source-prometheus.yaml create mode 100644 manifests/manifest-carts-db.yaml create mode 100644 manifests/manifest-carts.yaml create mode 100644 remediation.yaml create mode 100644 remediation_feature_toggle.yaml create mode 100644 shipyard-argo.yaml create mode 100644 shipyard-quality-gates.yaml create mode 100644 shipyard.yaml create mode 100644 sli-config-argo-prometheus.yaml create mode 100644 sli-config-dynatrace-no-deployment-tag.yaml create mode 100644 sli-config-dynatrace.yaml create mode 100644 sli-config-prometheus.yaml create mode 100644 slo-quality-gates.yaml create mode 100644 slo-self-healing-dynatrace.yaml create mode 100644 slo-self-healing-prometheus.yaml diff --git a/argo/carts.tgz b/argo/carts.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5cd9d3d5a043deb261e1c010e51e12ee08e14174 GIT binary patch literal 3184 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 WVGV0o!y4A`Jn&z$WOLB~Pyhg%@-jOB literal 0 HcmV?d00001 diff --git a/argo/carts/Chart.yaml b/argo/carts/Chart.yaml new file mode 100644 index 0000000..cfb84b9 --- /dev/null +++ b/argo/carts/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for service carts +name: carts +version: 0.1.0 diff --git a/argo/carts/templates/NOTES.txt b/argo/carts/templates/NOTES.txt new file mode 100644 index 0000000..96ff70e --- /dev/null +++ b/argo/carts/templates/NOTES.txt @@ -0,0 +1,19 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "carts.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ template "carts.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "carts.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "carts.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/argo/carts/templates/_helpers.tpl b/argo/carts/templates/_helpers.tpl new file mode 100644 index 0000000..8dd6d17 --- /dev/null +++ b/argo/carts/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "carts.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "carts.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "carts.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/argo/carts/templates/carts-db-deployment.yaml b/argo/carts/templates/carts-db-deployment.yaml new file mode 100644 index 0000000..3f72721 --- /dev/null +++ b/argo/carts/templates/carts-db-deployment.yaml @@ -0,0 +1,47 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: carts-db-mongodata +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi +status: {} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: carts-db + labels: + app: carts-db +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: carts-db + template: + metadata: + labels: + app: carts-db + deployment: carts-db + spec: + containers: + - name: carts-db + image: mongo + imagePullPolicy: IfNotPresent + ports: + - containerPort: 27017 + resources: {} + volumeMounts: + - mountPath: /data/db + name: carts-db-mongodata + restartPolicy: Always + volumes: + - name: carts-db-mongodata + persistentVolumeClaim: + claimName: carts-db-mongodata diff --git a/argo/carts/templates/carts-db-service.yaml b/argo/carts/templates/carts-db-service.yaml new file mode 100644 index 0000000..48a21ae --- /dev/null +++ b/argo/carts/templates/carts-db-service.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: carts-db +spec: + ports: + - name: carts-db + port: 27017 + targetPort: 27017 + selector: + app: carts-db \ No newline at end of file diff --git a/argo/carts/templates/keptn-hook.yaml b/argo/carts/templates/keptn-hook.yaml new file mode 100644 index 0000000..d0563a2 --- /dev/null +++ b/argo/carts/templates/keptn-hook.yaml @@ -0,0 +1,28 @@ +apiVersion: batch/v1 +kind: Job +metadata: + generateName: app-keptn-notification- + annotations: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: HookSucceeded +spec: + template: + spec: + containers: + - name: keptn-notification + image: agrimmer/alpine-curl-uuid-kubectl:latest + command: ["/bin/sh","-c"] + args: ['while [[ $(kubectl get rollout {{ .Values.keptn.service }}-{{ .Values.keptn.stage }} -n {{ .Values.keptn.project }}-{{ .Values.keptn.stage }} -o "jsonpath={..status.conditions[?(@.type==\"Progressing\")].reason}") == "ReplicaSetUpdated" ]]; do echo "waiting for rollout" && sleep 1; done; UUID=$(uuidgen); now=$(TZ=UTC date "+%FT%T.00Z"); curl -X POST -H "Content-Type: application/cloudevents+json" -H "x-token: ${KEPTN_API_TOKEN}" --insecure -d "{\"contenttype\": \"application/json\", \"data\": { \"project\": \"{{ .Values.keptn.project }}\", \"service\": \"{{ .Values.keptn.service }}\", \"stage\": \"{{ .Values.keptn.stage }}\", \"deploymentURILocal\": \"http://{{ .Values.keptn.service }}-canary.{{ .Values.keptn.project }}-{{ .Values.keptn.stage }}\", \"deploymentstrategy\": \"blue_green_service\", \"teststrategy\": \"performance\"}, \"id\": \"${UUID}\", \"source\": \"argo\", \"specversion\": \"0.2\", \"time\": \"${now}\", \"type\": \"sh.keptn.events.deployment-finished\", \"shkeptncontext\": \"${UUID}\"}" ${KEPTN_API_URL}/v1/event'] + env: + - name: KEPTN_API_URL + valueFrom: + secretKeyRef: + name: argo + key: KEPTN_API_URL + - name: KEPTN_API_TOKEN + valueFrom: + secretKeyRef: + name: argo + key: KEPTN_API_TOKEN + restartPolicy: Never + backoffLimit: 2 \ No newline at end of file diff --git a/argo/carts/templates/rollout.yaml b/argo/carts/templates/rollout.yaml new file mode 100644 index 0000000..340c8e9 --- /dev/null +++ b/argo/carts/templates/rollout.yaml @@ -0,0 +1,75 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: {{ template "carts.fullname" . }} + labels: + app: {{ template "carts.name" . }} + chart: {{ template "carts.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: {{ .Values.replicaCount }} + revisionHistoryLimit: 3 + selector: + matchLabels: + app: {{ template "carts.name" . }} + release: {{ .Release.Name }} + strategy: + blueGreen: + autoPromotionEnabled: false + activeService: {{ template "carts.name" . }}-primary + previewService: {{ template "carts.name" . }}-canary + template: + metadata: + labels: + app: {{ template "carts.name" . }} + release: {{ .Release.Name }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + env: + - name: DT_CUSTOM_PROP + value: "keptn_project={{ .Values.keptn.project }} keptn_service={{ .Values.keptn.service }} keptn_stage={{ .Values.keptn.stage }}" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: "metadata.name" + - name: DEPLOYMENT_NAME + valueFrom: + fieldRef: + fieldPath: "metadata.labels['deployment']" + - name: CONTAINER_IMAGE + value: "{{ .Values.image }}" + - name: KEPTN_PROJECT + value: "{{ .Values.keptn.project }}" + - name: KEPTN_STAGE + value: "{{ .Values.keptn.stage }}" + - name: KEPTN_SERVICE + value: "{{ .Values.keptn.service }}" + livenessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 15 + readinessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 15 + resources: + limits: + cpu: 1000m + memory: 2048Mi + requests: + cpu: 500m + memory: 1024Mi diff --git a/argo/carts/templates/service.yaml b/argo/carts/templates/service.yaml new file mode 100644 index 0000000..8c0d093 --- /dev/null +++ b/argo/carts/templates/service.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "carts.name" . }}-primary + labels: + app: {{ template "carts.name" . }} + chart: {{ template "carts.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 8080 + protocol: TCP + name: http + selector: + app: {{ template "carts.name" . }} + release: {{ .Release.Name }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "carts.name" . }}-canary + labels: + app: {{ template "carts.name" . }} + chart: {{ template "carts.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 8080 + protocol: TCP + name: http + selector: + app: {{ template "carts.name" . }} + release: {{ .Release.Name }} + \ No newline at end of file diff --git a/argo/carts/values.yaml b/argo/carts/values.yaml new file mode 100644 index 0000000..4e9e8de --- /dev/null +++ b/argo/carts/values.yaml @@ -0,0 +1,28 @@ +replicaCount: 1 + +image: + repository: docker.io/keptnexamples/carts + tag: 0.13.1 + pullPolicy: Always + +service: + type: LoadBalancer + port: 80 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + path: / + hosts: + - chart-example.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +keptn: + project: sockshop + stage: production + service: carts \ No newline at end of file diff --git a/carts-db.tgz b/carts-db.tgz new file mode 100644 index 0000000000000000000000000000000000000000..6247f4cb877f82699f469cdca292466a85d95646 GIT binary patch literal 919 zcmV;I18DpoiwFP!000001MOH#Z<|06_8E!)u=1%rfB}Ooaf?!^t=gnkDy7G2jn@v% z!cul|Yqk0Bo#l-mSXCS+YWGtPVP zV^_`pb6{`&E0VDw31ypz#E;qwN9Modxzld`9ow-yHUG~6!!UGhdkNf!@xn(lN#X*M zf6HhVkxPohNY^4F@B$0$>l#Ac@oz*dUNOnkHJ*?l7r{Y5IKN`BS@LHC-4ML^l7@nO ziUT4^Dd8+jgHk{~f6oXP)gwY&uoSPrlKnOW)dGu*`{>t$uI>1blZ20&Al}p!-0Qid zP)I+mY=W9Lw~i(SePMv5^&hQkO{y*9tv=r`nLi8BiPd<=^r z_72m_dW)9aM=W zEEVlKGa6TB!19qZwd`rbZyG#r+KRl+=gO6Ao36GWkV-tdZ97(M*PcGW?=`$nPPb}5jQ>w}7(d(0n1|Nbxg^N}Bg$G-o@)2;iTW4WH% z|7StZ{{LJg|H$5~2U0T=s*Y++nyQc_qaHX(J}UM|k)HwvD5i3j)Y6cq6%n&TXTo^r z%+`wSEW_u1?=J5~DhbwsF$p<%Ri%}@

aJqbi!BcG_?4S%V)zR{s)QpHm6P zxC#D!|JPMRYx@6dpnCoe_*`sU@LudXc&7jBr^asoA8P%k|Gx^l-7e|0i?;yv{je8Z z1y9U#OmdN@L#OS6qz;wT?6e6fHUH2DJEjIG&TJZ*oY<$2%X*LrNpWrC;wnx~7cN2ab!W2}5pte3=$iVw1qZmLf>iT`KM6 z6&@)MbA#wxzGbwN=6t4*c}FsFUe?~#&uPlj>Hz`|uzVCIdP!so{y%{)Jtez5lK|{f zW*#P_XQP3W0~Wd!-nML!eR608Te!aPP%t`cc1Y4kPrG7Kw-rASe`2(sTg#;$eFUfb zurbM}Nb!(xK0)AWzl4}FlAM?)`NGUaQ@<*6jr>gTGrPqX6vfpkeF(^RfXZgV`7lo<3HIhh4P^@3x-5`%<%y(amIbemNOW=a<*#AFBI!wjeS?pT^c~5@p`+8O7deU0r*_?OqzjLy_m`vEAjHk0M)7WPH9o)n7^`9s@1|FE+ELk? zz23@;DrTvq&#nXO9`@gYSh5w}a7BRkLSNO-u33>Az+YHH`-~X}Y-ws=k8B-h{;SUaX#;-2Z$Zy}{~2h5 zo%#P1pUwRL8mP|y+tL3v$%Mk(PwEH%n4C=IBaQ)u;4&UTl0hiuR%f8B$kVs#EQIIs z2(ml^0aU1L+?hN7zpgM1R8K zkr}>Hybka(h?B!q6-`sHEfoL9Coph1HMKaPI@cM2)T04M+e D6|hcE literal 0 HcmV?d00001 diff --git a/carts/Chart.yaml b/carts/Chart.yaml new file mode 100644 index 0000000..cfb84b9 --- /dev/null +++ b/carts/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for service carts +name: carts +version: 0.1.0 diff --git a/carts/templates/deployment.yaml b/carts/templates/deployment.yaml new file mode 100644 index 0000000..52dc329 --- /dev/null +++ b/carts/templates/deployment.yaml @@ -0,0 +1,77 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: carts +spec: + replicas: {{ .Values.replicaCount }} + strategy: + rollingUpdate: + maxUnavailable: 0 + type: RollingUpdate + selector: + matchLabels: + app: carts + template: + metadata: + labels: + app: carts + app.kubernetes.io/name: {{ .Values.keptn.service }} + app.kubernetes.io/instance: "{{ .Values.keptn.service }}-{{ .Values.keptn.deployment }}" + app.kubernetes.io/component: api + app.kubernetes.io/part-of: "{{ .Values.keptn.project }}" + app.kubernetes.io/managed-by: Keptn + app.kubernetes.io/version: {{ (split ":" .Values.image)._1 | default "latest" }} + spec: + containers: + - name: carts + image: "{{ .Values.image }}" + imagePullPolicy: IfNotPresent + ports: + - name: http + protocol: TCP + containerPort: 8080 + env: + - name: DT_CUSTOM_PROP + value: "version={{ .Chart.Version }} revision={{ .Release.Revision }} releasename={{ .Release.Name }} keptn_project={{ .Values.keptn.project }} keptn_service={{ .Values.keptn.service }} keptn_stage={{ .Values.keptn.stage }} keptn_deployment={{ .Values.keptn.deployment }}" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: "metadata.name" + - name: DEPLOYMENT_NAME + valueFrom: + fieldRef: + fieldPath: "metadata.labels['deployment']" + - name: CONTAINER_IMAGE + value: "{{ .Values.image }}" + - name: KEPTN_PROJECT + value: "{{ .Chart.Name }}" + - name: KEPTN_STAGE + valueFrom: + fieldRef: + fieldPath: "metadata.namespace" + - name: KEPTN_SERVICE + value: "carts" + - name: UNLEASH_SERVER_URL + value: "http://unleash.unleash-dev/api" + livenessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 15 + readinessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 15 + resources: + limits: + cpu: 1000m + memory: 2048Mi + requests: + cpu: 500m + memory: 1024Mi diff --git a/carts/templates/service.yaml b/carts/templates/service.yaml new file mode 100644 index 0000000..daea781 --- /dev/null +++ b/carts/templates/service.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: carts +spec: + type: ClusterIP + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8080 + selector: + app: carts diff --git a/carts/values.yaml b/carts/values.yaml new file mode 100644 index 0000000..559ee01 --- /dev/null +++ b/carts/values.yaml @@ -0,0 +1,2 @@ +image: docker.io/keptnexamples/carts:0.13.1 +replicaCount: 1 \ No newline at end of file diff --git a/dynatrace/dynatrace.conf.yaml b/dynatrace/dynatrace.conf.yaml new file mode 100644 index 0000000..8fece01 --- /dev/null +++ b/dynatrace/dynatrace.conf.yaml @@ -0,0 +1,2 @@ +spec_version: '0.1.0' +dtCreds: dynatrace \ No newline at end of file diff --git a/jmeter/basiccheck.jmx b/jmeter/basiccheck.jmx new file mode 100644 index 0000000..e83cd87 --- /dev/null +++ b/jmeter/basiccheck.jmx @@ -0,0 +1,177 @@ + + + + + + false + false + + + + SERVER_URL + carts.sockshop-staging.public.demo.keptn.sh + = + + + CHECK_PATH + / + = + + + DT_LTN + Default + = + + + DefaultThinkTime + 250 + = + + + SERVER_PORT + 80 + = + + + PROTOCOL + http + = + + + VUCount + 1 + = + + + LoopCount + 1 + = + + + + + + + + continue + + false + ${__P(LoopCount,${VUCount})} + + ${__P(VUCount,${VUCount})} + 1 + 1444323045000 + 1444323045000 + false + + + + + + + false + + + + + + + + true + + + import org.apache.jmeter.util.JMeterUtils; +import org.apache.jmeter.protocol.http.control.HeaderManager; +import java.io; +import java.util; + +// ------------------------------------------------------------------------------------- +// Generate the x-dynatrace-test header based on this best practic +// -> https://www.dynatrace.com/support/help/integrations/test-automation-frameworks/how-do-i-integrate-dynatrace-into-my-load-testing-process/ +// ------------------------------------------------------------------------------------- +String LTN=JMeterUtils.getProperty("DT_LTN"); +if((LTN == null) || (LTN.length() == 0)) { + if(vars != null) { + LTN = vars.get("DT_LTN"); + } +} +if(LTN == null) LTN = "NoTestName"; + +String LSN = (bsh.args.length > 0) ? bsh.args[0] : "Test Scenario"; +String TSN = sampler.getName(); +String VU = ctx.getThreadGroup().getName() + ctx.getThreadNum(); +String headerValue = "LSN="+ LSN + ";TSN=" + TSN + ";LTN=" + LTN + ";VU=" + VU + ";"; + +// ------------------------------------------- +// Set header +// ------------------------------------------- +HeaderManager hm = sampler.getHeaderManager(); +hm.removeHeaderNamed("x-dynatrace-test"); +hm.add(new org.apache.jmeter.protocol.http.control.Header("x-dynatrace-test", headerValue)); + + + + + + + ${__P(SERVER_URL,${SERVER_URL})} + ${__P(SERVER_PORT,${SERVER_PORT})} + ${__P(PROTOCOL,${PROTOCOL})} + + ${__P(CHECK_PATH,${CHECK_PATH})} + GET + true + false + true + false + + + + + + + + + + + + {__P(ThinkTime,${DefaultThinkTime})} + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + false + false + false + false + false + 0 + true + true + + + + + + + + diff --git a/jmeter/load.jmx b/jmeter/load.jmx new file mode 100644 index 0000000..235227a --- /dev/null +++ b/jmeter/load.jmx @@ -0,0 +1,191 @@ + + + + + + false + false + + + + SERVER_URL + carts.sockshop-staging.public.demo.keptn.sh + = + + + DefaultThinkTime + 250 + = + + + DT_LTN + Default + = + + + SERVER_PORT + 80 + = + + + PROTOCOL + http + = + + + VUCount + 1 + = + + + LoopCount + 1 + = + + + + + + + + continue + + false + ${__P(LoopCount,${LoopCount})} + + ${__P(VUCount,${VUCount})} + 1 + 1536064517000 + 1536064517000 + false + + + + + + + false + + + + + + Cache-Control + no-cache + + + Content-Type + application/json + + + json + true + + + + + + + + false + import org.apache.jmeter.util.JMeterUtils; +import org.apache.jmeter.protocol.http.control.HeaderManager; +import java.io; +import java.util; + +// ------------------------------------------------------------------------------------- +// Generate the x-dynatrace-test header based on this best practic +// -> https://www.dynatrace.com/support/help/integrations/test-automation-frameworks/how-do-i-integrate-dynatrace-into-my-load-testing-process/ +// ------------------------------------------------------------------------------------- +String LTN=JMeterUtils.getProperty("DT_LTN"); +if((LTN == null) || (LTN.length() == 0)) { + if(vars != null) { + LTN = vars.get("DT_LTN"); + } +} +if(LTN == null) LTN = "NoTestName"; + +String LSN = (bsh.args.length > 0) ? bsh.args[0] : "Test Scenario"; +String TSN = sampler.getName(); +String VU = ctx.getThreadGroup().getName() + ctx.getThreadNum(); +String headerValue = "LSN="+ LSN + ";TSN=" + TSN + ";LTN=" + LTN + ";VU=" + VU + ";"; + +// ------------------------------------------- +// Set header +// ------------------------------------------- +HeaderManager hm = sampler.getHeaderManager(); +hm.removeHeaderNamed("x-dynatrace-test"); +hm.add(new org.apache.jmeter.protocol.http.control.Header("x-dynatrace-test", headerValue)); + + + + true + + + + false + { + "itemId":"03fef6ac-1896-4ce8-bd69-b798f85c6e0b", + "unitPrice":"99.99" + } + = + + + + ${__P(SERVER_URL,${SERVER_URL})} + ${__P(SERVER_PORT,${SERVER_PORT})} + ${__P(PROTOCOL,${PROTOCOL})} + + /carts/1/items + POST + true + false + true + false + true + + + + + + + {__P(ThinkTime,${DefaultThinkTime})} + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + false + false + false + false + false + 0 + true + true + + + + + + + + diff --git a/lighthouse-source-dynatrace.yaml b/lighthouse-source-dynatrace.yaml new file mode 100644 index 0000000..2fc0e52 --- /dev/null +++ b/lighthouse-source-dynatrace.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +data: + sli-provider: dynatrace +kind: ConfigMap +metadata: + name: lighthouse-config-sockshop + namespace: keptn diff --git a/lighthouse-source-prometheus.yaml b/lighthouse-source-prometheus.yaml new file mode 100644 index 0000000..357112b --- /dev/null +++ b/lighthouse-source-prometheus.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +data: + sli-provider: prometheus +kind: ConfigMap +metadata: + name: lighthouse-config-sockshop + namespace: keptn diff --git a/manifests/manifest-carts-db.yaml b/manifests/manifest-carts-db.yaml new file mode 100644 index 0000000..24f4663 --- /dev/null +++ b/manifests/manifest-carts-db.yaml @@ -0,0 +1,58 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: carts-db-mongodata + namespace: sockshop-hardening +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi +status: {} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: carts-db + namespace: sockshop-hardening +spec: + replicas: 1 + selector: + matchLabels: + app: carts-db + strategy: + type: Recreate + template: + metadata: + labels: + app: carts-db + spec: + containers: + - image: mongo + name: carts-db + ports: + - containerPort: 27017 + resources: {} + volumeMounts: + - mountPath: /data/db + name: carts-db-mongodata + restartPolicy: Always + volumes: + - name: carts-db-mongodata + persistentVolumeClaim: + claimName: carts-db-mongodata +--- +apiVersion: v1 +kind: Service +metadata: + name: carts-db + namespace: sockshop-hardening +spec: + ports: + - name: "27017" + port: 27017 + targetPort: 27017 + selector: + app: carts-db diff --git a/manifests/manifest-carts.yaml b/manifests/manifest-carts.yaml new file mode 100644 index 0000000..0d242ca --- /dev/null +++ b/manifests/manifest-carts.yaml @@ -0,0 +1,88 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: carts + namespace: sockshop-hardening +spec: + replicas: 1 + selector: + matchLabels: + app: carts + template: + metadata: + labels: + app: carts + version: v1 + deployment: carts + spec: + containers: + - name: carts + image: docker.io/keptnexamples/carts:0.13.1 + env: + - name: JAVA_OPTS + value: -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseG1GC -Djava.security.egd=file:/dev/urandom + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: "metadata.name" + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: "metadata.namespace" + - name: DEPLOYMENT_NAME + valueFrom: + fieldRef: + fieldPath: "metadata.labels['deployment']" + - name: CONTAINER_IMAGE + value: docker.io/keptnexamples/carts:0.13.1 + - name: DT_CUSTOM_PROP + value: "keptn_stage=hardening keptn_project=sockshop keptn_service=carts" + resources: + limits: + cpu: 500m + memory: 1024Mi + requests: + cpu: 400m + memory: 768Mi + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /tmp + name: tmp-volume + livenessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 15 + readinessProbe: + httpGet: + path: /health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 15 + volumes: + - name: tmp-volume + emptyDir: + medium: Memory + nodeSelector: + beta.kubernetes.io/os: linux +--- +apiVersion: v1 +kind: Service +metadata: + name: carts + labels: + app: carts + namespace: sockshop-hardening +spec: + ports: + - name: http + port: 80 + targetPort: 8080 + selector: + app: carts + type: LoadBalancer diff --git a/remediation.yaml b/remediation.yaml new file mode 100644 index 0000000..22cfc56 --- /dev/null +++ b/remediation.yaml @@ -0,0 +1,18 @@ +apiVersion: spec.keptn.sh/0.1.4 +kind: Remediation +metadata: + name: carts-remediation +spec: + remediations: + - problemType: Response time degradation + actionsOnOpen: + - action: scaling + name: scaling + description: Scale up + value: "1" + - problemType: response_time_p90 + actionsOnOpen: + - action: scaling + name: scaling + description: Scale up + value: "1" diff --git a/remediation_feature_toggle.yaml b/remediation_feature_toggle.yaml new file mode 100644 index 0000000..343152f --- /dev/null +++ b/remediation_feature_toggle.yaml @@ -0,0 +1,20 @@ +apiVersion: spec.keptn.sh/0.1.4 +kind: Remediation +metadata: + name: carts-remediation +spec: + remediations: + - problemType: Response time degradation + actionsOnOpen: + - action: toggle-feature + name: Toogle feature flag + description: Toogle feature flag EnableItemCache to ON + value: + EnableItemCache: "on" + - problemType: Failure rate increase + actionsOnOpen: + - action: toggle-feature + name: Toogle feature flag + description: Toogle feature flag EnablePromotion to OFF + value: + EnablePromotion: "off" diff --git a/shipyard-argo.yaml b/shipyard-argo.yaml new file mode 100644 index 0000000..a2770e3 --- /dev/null +++ b/shipyard-argo.yaml @@ -0,0 +1,18 @@ +apiVersion: "spec.keptn.sh/0.2.2" +kind: "Shipyard" +metadata: + name: "shipyard-sockshop" +spec: + stages: + - name: "production" + sequences: + - name: "artifact-delivery" + tasks: + - name: "deployment" + properties: + deploymentstrategy: "blue_green_service" + - name: "test" + properties: + teststrategy: "performance" + - name: "evaluation" + - name: "release" diff --git a/shipyard-quality-gates.yaml b/shipyard-quality-gates.yaml new file mode 100644 index 0000000..641c5b9 --- /dev/null +++ b/shipyard-quality-gates.yaml @@ -0,0 +1,7 @@ +apiVersion: "spec.keptn.sh/0.2.2" +kind: "Shipyard" +metadata: + name: "shipyard-quality-gates" +spec: + stages: + - name: "hardening" diff --git a/shipyard.yaml b/shipyard.yaml new file mode 100644 index 0000000..1ec6727 --- /dev/null +++ b/shipyard.yaml @@ -0,0 +1,96 @@ +apiVersion: "spec.keptn.sh/0.2.2" +kind: "Shipyard" +metadata: + name: "shipyard-sockshop" +spec: + stages: + - name: "dev" + sequences: + - name: "delivery" + tasks: + - name: "deployment" + properties: + deploymentstrategy: "direct" + - name: "test" + properties: + teststrategy: "functional" + - name: "evaluation" + - name: "release" + - name: "delivery-direct" + tasks: + - name: "deployment" + properties: + deploymentstrategy: "direct" + - name: "release" + + - name: "staging" + sequences: + - name: "delivery" + triggeredOn: + - event: "dev.delivery.finished" + tasks: + - name: "deployment" + properties: + deploymentstrategy: "blue_green_service" + - name: "test" + properties: + teststrategy: "performance" + - name: "evaluation" + - name: "release" + - name: "rollback" + triggeredOn: + - event: "staging.delivery.finished" + selector: + match: + result: "fail" + tasks: + - name: "rollback" + - name: "delivery-direct" + triggeredOn: + - event: "dev.delivery-direct.finished" + tasks: + - name: "deployment" + properties: + deploymentstrategy: "direct" + - name: "release" + + - name: "production" + sequences: + - name: "delivery" + triggeredOn: + - event: "staging.delivery.finished" + tasks: + - name: "deployment" + properties: + deploymentstrategy: "blue_green_service" + - name: "release" + - name: "rollback" + triggeredOn: + - event: "production.delivery.finished" + selector: + match: + result: "fail" + tasks: + - name: "rollback" + - name: "delivery-direct" + triggeredOn: + - event: "staging.delivery-direct.finished" + tasks: + - name: "deployment" + properties: + deploymentstrategy: "direct" + - name: "release" + + - name: "remediation" + triggeredOn: + - event: "production.remediation.finished" + selector: + match: + evaluation.result: "fail" + tasks: + - name: "get-action" + - name: "action" + - name: "evaluation" + triggeredAfter: "15m" + properties: + timeframe: "15m" diff --git a/sli-config-argo-prometheus.yaml b/sli-config-argo-prometheus.yaml new file mode 100644 index 0000000..af25f11 --- /dev/null +++ b/sli-config-argo-prometheus.yaml @@ -0,0 +1,6 @@ +--- +spec_version: '1.0' +indicators: + response_time_p50: histogram_quantile(0.5, sum by(le) (rate(http_response_time_milliseconds_bucket{handler="ItemsController.addToCart",job="$SERVICE-$PROJECT-$STAGE-canary"}[$DURATION_SECONDS]))) + response_time_p90: histogram_quantile(0.9, sum by(le) (rate(http_response_time_milliseconds_bucket{handler="ItemsController.addToCart",job="$SERVICE-$PROJECT-$STAGE-canary"}[$DURATION_SECONDS]))) + response_time_p95: histogram_quantile(0.95, sum by(le) (rate(http_response_time_milliseconds_bucket{handler="ItemsController.addToCart",job="$SERVICE-$PROJECT-$STAGE-canary"}[$DURATION_SECONDS]))) \ No newline at end of file diff --git a/sli-config-dynatrace-no-deployment-tag.yaml b/sli-config-dynatrace-no-deployment-tag.yaml new file mode 100644 index 0000000..59a6756 --- /dev/null +++ b/sli-config-dynatrace-no-deployment-tag.yaml @@ -0,0 +1,8 @@ +--- +spec_version: '1.0' +indicators: + throughput: "metricSelector=builtin:service.requestCount.total:merge(\"dt.entity.service\"):sum&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE)" + error_rate: "metricSelector=builtin:service.errors.total.count:merge(\"dt.entity.service\"):avg&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE)" + response_time_p50: "metricSelector=builtin:service.response.time:merge(\"dt.entity.service\"):percentile(50)&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE)" + response_time_p90: "metricSelector=builtin:service.response.time:merge(\"dt.entity.service\"):percentile(90)&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE)" + response_time_p95: "metricSelector=builtin:service.response.time:merge(\"dt.entity.service\"):percentile(95)&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE)" \ No newline at end of file diff --git a/sli-config-dynatrace.yaml b/sli-config-dynatrace.yaml new file mode 100644 index 0000000..26089df --- /dev/null +++ b/sli-config-dynatrace.yaml @@ -0,0 +1,8 @@ +--- +spec_version: '1.0' +indicators: + throughput: "metricSelector=builtin:service.requestCount.total:merge(\"dt.entity.service\"):sum&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + error_rate: "metricSelector=builtin:service.errors.total.count:merge(\"dt.entity.service\"):avg&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + response_time_p50: "metricSelector=builtin:service.response.time:merge(\"dt.entity.service\"):percentile(50)&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + response_time_p90: "metricSelector=builtin:service.response.time:merge(\"dt.entity.service\"):percentile(90)&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + response_time_p95: "metricSelector=builtin:service.response.time:merge(\"dt.entity.service\"):percentile(95)&entitySelector=type(SERVICE),tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" \ No newline at end of file diff --git a/sli-config-prometheus.yaml b/sli-config-prometheus.yaml new file mode 100644 index 0000000..e4cb42f --- /dev/null +++ b/sli-config-prometheus.yaml @@ -0,0 +1,6 @@ +--- +spec_version: '1.0' +indicators: + response_time_p50: histogram_quantile(0.5, sum by(le) (rate(http_response_time_milliseconds_bucket{handler="ItemsController.addToCart",job="$SERVICE-$PROJECT-$STAGE-$DEPLOYMENT"}[$DURATION_SECONDS]))) + response_time_p90: histogram_quantile(0.9, sum by(le) (rate(http_response_time_milliseconds_bucket{handler="ItemsController.addToCart",job="$SERVICE-$PROJECT-$STAGE-$DEPLOYMENT"}[$DURATION_SECONDS]))) + response_time_p95: histogram_quantile(0.95, sum by(le) (rate(http_response_time_milliseconds_bucket{handler="ItemsController.addToCart",job="$SERVICE-$PROJECT-$STAGE-$DEPLOYMENT"}[$DURATION_SECONDS]))) \ No newline at end of file diff --git a/slo-quality-gates.yaml b/slo-quality-gates.yaml new file mode 100644 index 0000000..1fa9d13 --- /dev/null +++ b/slo-quality-gates.yaml @@ -0,0 +1,23 @@ +--- +spec_version: "1.0" +comparison: + aggregate_function: "avg" + compare_with: "single_result" + include_result_with_score: "pass" + number_of_comparison_results: 1 +filter: +objectives: + - sli: "response_time_p95" + displayName: "Response time P95" + key_sli: false + pass: # pass if (relative change <= 10% AND absolute value is < 600ms) + - criteria: + - "<=+10%" # relative values require a prefixed sign (plus or minus) + - "<600" # absolute values only require a logical operator + warning: # if the response time is below 800ms, the result should be a warning + - criteria: + - "<=800" + weight: 1 +total_score: + pass: "90%" + warning: "75%" \ No newline at end of file diff --git a/slo-self-healing-dynatrace.yaml b/slo-self-healing-dynatrace.yaml new file mode 100644 index 0000000..9101c6e --- /dev/null +++ b/slo-self-healing-dynatrace.yaml @@ -0,0 +1,30 @@ +--- +spec_version: "1.0" +comparison: + aggregate_function: "avg" + compare_with: "single_result" + include_result_with_score: "pass" + number_of_comparison_results: 1 +filter: +objectives: + - sli: "response_time_p90" + displayName: "Response time P90" + key_sli: false + pass: # pass if (relative change <= 10% AND absolute value is < 1000) + - criteria: + - "<=+10%" # relative values require a prefixed sign (plus or minus) + - "<1000" # absolute values only require a logical operator + warning: # if the response time is below 1200ms, the result should be a warning + - criteria: + - "<=1200" + weight: 1 + - sli: "problem_open" + displayName: "Problem open" + key_sli: true + pass: + - criteria: + - "=0" + weight: 1 +total_score: + pass: "90%" + warning: "40%" diff --git a/slo-self-healing-prometheus.yaml b/slo-self-healing-prometheus.yaml new file mode 100644 index 0000000..3291113 --- /dev/null +++ b/slo-self-healing-prometheus.yaml @@ -0,0 +1,23 @@ +--- +spec_version: "1.0" +comparison: + aggregate_function: "avg" + compare_with: "single_result" + include_result_with_score: "pass" + number_of_comparison_results: 1 +filter: +objectives: + - sli: "response_time_p90" + displayName: "Response time P90" + key_sli: false + pass: # pass if (relative change <= 10% AND absolute value is < 1000) + - criteria: + - "<=+10%" # relative values require a prefixed sign (plus or minus) + - "<1000" # absolute values only require a logical operator + warning: # if the response time is below 1200ms, the result should be a warning + - criteria: + - "<=1200" + weight: 1 +total_score: + pass: "90%" + warning: "40%"