Skip to content

Commit

Permalink
Add ArgoRollouts Example
Browse files Browse the repository at this point in the history
  • Loading branch information
techmaharaj committed Oct 1, 2024
1 parent ba03871 commit 456a665
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 0 deletions.
21 changes: 21 additions & 0 deletions ArgoRollouts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Testkube with ArgoRollouts

## Overview

This project integrates Testkube with ArgoRollouts to provide a robust testing and deployment pipeline. Testkube is a cloud-native testing framework, while ArgoRollouts is a Kubernetes controller for managing the deployment of applications using advanced deployment strategies.

## Prerequisites

- Kubernetes cluster
- kubectl configured to interact with your cluster
- Testkube installed
- ArgoRollouts installed
- API key from http://api.weatherapi.com

## Project Structure

- `rollout.yaml`: Configuration file for deploying the application using ArgoRollouts.
- `template.yaml`: Template file containing the Testkube Test Workflow and other configurations.
- `weatherSample-v1`: Files for the v1 of the weather application which shows the weather of Hyderabad.
- `weatherSample-v2`: Files for the v1 of the weather application which shows the weather of New York.

73 changes: 73 additions & 0 deletions ArgoRollouts/argo-rollout/rollout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollout-experiment
spec:
replicas: 2
strategy:
canary:
steps:
- setWeight: 50
- pause: {duration: 10}
# The second step is the experiment which starts a single canary pod
- experiment:
duration: 5m
templates:
- name: canary
specRef: canary
# This experiment performs its own analysis by referencing an AnalysisTemplates
# The success or failure of these runs will progress or abort the rollout respectively.
analyses:
- name: canary-experiment
templateName: testkube-experiment-analysis
- setWeight: 100
- pause: {duration: 10}
revisionHistoryLimit: 2
selector:
matchLabels:
app: rollout-experiment
template:
metadata:
labels:
app: rollout-experiment
spec:
containers:
- name: rollouts-demo
image: docker.io/atulinfracloud/weathersample:v1
imagePullPolicy: Always
ports:
- containerPort: 5000

---
apiVersion: v1
kind: Service
metadata:
name: rollout-weather-svc
spec:
selector:
app: rollout-experiment
ports:
- protocol: "TCP"
port: 80
targetPort: 5000
type: NodePort


---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rollout-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rollout-weather-svc
port:
number: 80
43 changes: 43 additions & 0 deletions ArgoRollouts/argo-rollout/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: testkube-experiment-analysis
spec:
metrics:
- name: run-testkube-workflows
provider:
job:
spec:
template:
spec:
containers:
- name: execute-testkube
image: kubeshop/testkube-cli:2.1.19
env:
- name: API_TOKEN
value: "<your-API-token>"
- name: ENVIRONMENT_ID
value: "<your-environment-ID>"
- name: ORGANIZATION_ID
value: "<your-organization-ID>"
- name: ROOT_DOMAIN
value: "testkube.io"
command:
- /bin/sh
- -c
- |
testkube set context \
--api-key ${API_TOKEN} \
--root-domain ${ROOT_DOMAIN} \
--org-id ${ORGANIZATION_ID} \
--env-id ${ENVIRONMENT_ID}
# Run the desired Testkube workflows during the experiment
testkube run tw basic-k6-workflow -f || exit 1
restartPolicy: Never
backoffLimit: 2
successCondition: "result.exitCode == 0" # Exit code 0 for success
failureCondition: "result.exitCode == 1" # Exit code 1 for failure
interval: 1m
count: 1
10 changes: 10 additions & 0 deletions ArgoRollouts/weatherSample-v1/dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM python:3.7

RUN mkdir /app
WORKDIR /app
ADD . /app/
RUN apt-get update
RUN apt-get install iputils-ping -y
RUN pip install -r requirements.txt

CMD ["python", "main.py"]
37 changes: 37 additions & 0 deletions ArgoRollouts/weatherSample-v1/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from flask import Flask, render_template
import requests, json

app = Flask(__name__)

@app.route(f"/")
def home():
# Hyderabad
# Replace <your-api-key> with your actual api key
api_url="http://api.weatherapi.com/v1/current.json?key=<your-api-key>&q=Hyderabad&aqi=no"
response = requests.get(api_url)
response.raise_for_status()
if response.status_code != 204:
res = json.loads(response.content.decode('utf-8'))
temp = res['current']['temp_c']
wind_speed = res['current']['condition']['text']
weather_code = res['current']['cloud']

if weather_code < 10 and weather_code > 0:
weather="Mainly Clear"
elif weather_code > 40 and weather_code < 50:
weather = "Fog"
elif weather_code > 50 and weather_code < 56:
weather = "Drizzle"
elif weather_code > 60 and weather_code < 70:
weather = "Light Rain"
else:
weather = "Rain"

return render_template("index.html",temp=temp,wind_speed=wind_speed,weather=weather, location='Hyderabad')

else:

print("Error: "+response.status_code)

if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')
3 changes: 3 additions & 0 deletions ArgoRollouts/weatherSample-v1/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Flask==2.1.1
Jinja2==3.0.2
requests==2.26.0
38 changes: 38 additions & 0 deletions ArgoRollouts/weatherSample-v1/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<head>
<title>Weather Forecast</title>
<style>
h1 {
position: relative;
font-size: 5rem;
}

html {
block-size: 100%;
inline-size: 100%;
}

body {
min-block-size: 100%;
min-inline-size: 100%;
margin: 0;
box-sizing: border-box;
display: grid;
place-content: center;
font-family: system-ui, sans-serif;
background-color: burlywood;
}

</style>
</head>
<body>

<h1>
Server Location: {{location}}<br>
Temperature: {{temp}}<br>
Cloud Cover: {{wind_speed}}<br>
Forecast: {{weather}}<br>
</h1>

</body>
</html>
10 changes: 10 additions & 0 deletions ArgoRollouts/weatherSample-v2/dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM python:3.7

RUN mkdir /app
WORKDIR /app
ADD . /app/
RUN apt-get update
RUN apt-get install iputils-ping -y
RUN pip install -r requirements.txt

CMD ["python", "main.py"]
37 changes: 37 additions & 0 deletions ArgoRollouts/weatherSample-v2/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from flask import Flask, render_template
import requests, json

app = Flask(__name__)

@app.route(f"/")
def home():
# New York
# Replace <your-api-key> with your actual api key
api_url="http://api.weatherapi.com/v1/current.json?key=<your-api-key>&q=New%20York&aqi=no"
response = requests.get(api_url)
response.raise_for_status()
if response.status_code != 204:
res = json.loads(response.content.decode('utf-8'))
temp = res['current']['temp_c']
wind_speed = res['current']['condition']['text']
weather_code = res['current']['cloud']

if weather_code < 10 and weather_code > 0:
weather="Mainly Clear"
elif weather_code > 40 and weather_code < 50:
weather = "Fog"
elif weather_code > 50 and weather_code < 56:
weather = "Drizzle"
elif weather_code > 60 and weather_code < 70:
weather = "Light Rain"
else:
weather = "Rain"

return render_template("index.html",temp=temp,wind_speed=wind_speed,weather=weather, location='New York')

else:

print("Error: "+response.status_code)

if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')
3 changes: 3 additions & 0 deletions ArgoRollouts/weatherSample-v2/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Flask==2.1.1
Jinja2==3.0.2
requests==2.26.0
38 changes: 38 additions & 0 deletions ArgoRollouts/weatherSample-v2/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<head>
<title>Weather</title>
<style>
h1 {
position: relative;
font-size: 5rem;
}

html {
block-size: 100%;
inline-size: 100%;
}

body {
min-block-size: 100%;
min-inline-size: 100%;
margin: 0;
box-sizing: border-box;
display: grid;
place-content: center;
font-family: system-ui, sans-serif;
background-color: aquamarine;
}

</style>
</head>
<body>

<h1>
Server Location: {{location}}<br>
Temperature: {{temp}}<br>
Cloud Cover: {{wind_speed}}<br>
Forecast: {{weather}}<br>
</h1>

</body>
</html>
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ This repository consists of all the examples used in our blog posts, articles, t
2. [Pytest Test Workflow](https://github.com/kubeshop/testkube-examples/tree/main/Pytest-Test-Workflow): Example to show how to configure a Pytest workflow.
3. [Cucumber Test Using Gradle](https://github.com/kubeshop/testkube-examples/tree/main/Cucumber%20Test%20Using%20Gradle): Example to show how to configure a Cucumber test using Gradle Test Worfklow.
4. [RestAssured Test Using Gradle](https://github.com/kubeshop/testkube-examples/tree/main/RestAssured%20Test%20Using%20Gradle): Example to show how to configure a RestAssured test using Gradle Test Worfklow.
5. [Gatling Simple](https://github.com/kubeshop/testkube-examples/tree/main/Gradle/Gatling/Simple): Example for running a simple Gatling Test Workflow.
6. [Gatling Distributed](https://github.com/kubeshop/testkube-examples/tree/main/Gradle/Gatling/Distributed): Example for running a distributed Gatling Test Workflow.
7. [ArgoCD](https://github.com/kubeshop/testkube-examples/tree/main/ArgoCD): Example showing how to sync Test Workflows using Argo CD and executing them using post-sync-hooks.
8. [ArgoRollouts](https://github.com/kubeshop/testkube-examples/tree/main/ArgoRollouts): Example to show how we can use Testkube Workflows to progress a new version of an application in a canary deployment.

0 comments on commit 456a665

Please sign in to comment.