Skip to content

Commit 5265e82

Browse files
committed
Initial commit
1 parent 348a6a2 commit 5265e82

File tree

10 files changed

+520
-71
lines changed

10 files changed

+520
-71
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ IF SUFFICIENT INFORMATION IS NOT PROVIDED VIA THE FOLLOWING TEMPLATE THE ISSUE M
2121
### Expected/desired behavior
2222
>
2323
24-
### OS and Version?
24+
### Pipeline Agent?
2525
> Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
2626
2727
### Versions

.gitignore

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ parts/
2020
sdist/
2121
var/
2222
wheels/
23-
pip-wheel-metadata/
24-
share/python-wheels/
2523
*.egg-info/
2624
.installed.cfg
2725
*.egg
@@ -40,14 +38,12 @@ pip-delete-this-directory.txt
4038
# Unit test / coverage reports
4139
htmlcov/
4240
.tox/
43-
.nox/
4441
.coverage
4542
.coverage.*
4643
.cache
4744
nosetests.xml
4845
coverage.xml
4946
*.cover
50-
*.py,cover
5147
.hypothesis/
5248
.pytest_cache/
5349

@@ -59,7 +55,6 @@ coverage.xml
5955
*.log
6056
local_settings.py
6157
db.sqlite3
62-
db.sqlite3-journal
6358

6459
# Flask stuff:
6560
instance/
@@ -77,26 +72,11 @@ target/
7772
# Jupyter Notebook
7873
.ipynb_checkpoints
7974

80-
# IPython
81-
profile_default/
82-
ipython_config.py
83-
8475
# pyenv
8576
.python-version
8677

87-
# pipenv
88-
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89-
# However, in case of collaboration, if having platform-specific dependencies or dependencies
90-
# having no cross-platform support, pipenv may install dependencies that don't work, or not
91-
# install all needed dependencies.
92-
#Pipfile.lock
93-
94-
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
95-
__pypackages__/
96-
97-
# Celery stuff
78+
# celery beat schedule file
9879
celerybeat-schedule
99-
celerybeat.pid
10080

10181
# SageMath parsed files
10282
*.sage.py
@@ -122,8 +102,9 @@ venv.bak/
122102

123103
# mypy
124104
.mypy_cache/
125-
.dmypy.json
126-
dmypy.json
127105

128-
# Pyre type checker
129-
.pyre/
106+
# Framework related
107+
kubectl
108+
kind
109+
helm*
110+
linux-amd64/*

CHANGELOG.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
## [project-title] Changelog
1+
## Automated Test Environment for AKS Applications Changelog
22

3-
<a name="x.y.z"></a>
4-
# x.y.z (yyyy-mm-dd)
3+
<a name="1.0.0"></a>
4+
# 1.0.0 (2020-08-03)
55

66
*Features*
7-
* ...
7+
* Create/Delete `kind` cluster in CI environment
8+
* Optional - [Azure Key Vault Provider for Secrets Store CSI Driver](https://github.com/Azure/secrets-store-csi-driver-provider-azure) [installation](https://github.com/Azure/secrets-store-csi-driver-provider-azure#install-the-secrets-store-csi-driver-and-the-azure-keyvault-provider) and [configuration](https://github.com/Azure/secrets-store-csi-driver-provider-azure/blob/master/docs/service-principal-mode.md)
9+
* Optional - [Azure Container Registry (ACR) Image Pull Secret](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-auth-kubernetes#create-an-image-pull-secret)
10+
* Install `helm` charts of application (values needed for integration test environment can be overwritten easily)
11+
* Validate if the respective Kubernetes `pods` are up and running (multiple `pods` can be provided that are having selector - `app.kubernetes.io/name`)
12+
* [Port-Froward](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/#forward-a-local-port-to-a-port-on-the-pod) the respective Kubernetes `services` needed to perform integration testing (multiple `services` can be provided and the respective local ports will be starting from `8080` to `808[number of services]` maintaining the order as provided)
13+
814

915
*Bug Fixes*
10-
* ...
16+
* N/A
1117

1218
*Breaking Changes*
13-
* ...
19+
* N/A

README.md

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,77 @@
1-
# Project Name
1+
# Automated Test Environment for AKS Applications
22

3-
(short, 1-3 sentenced, description of the project)
3+
Framework to create Automated Test Environment using [kind](https://kind.sigs.k8s.io/) for testing Azure Kubernetes Service (AKS) based applications in CI (Continuous Integration) Pipeline (Azure DevOps), where required dependencies/infrastructure will be provisioned for executing automated tests and deprovisioned after completion.
4+
5+
## Tools Used
6+
1. [kind](https://kind.sigs.k8s.io/) - a tool for running local Kubernetes clusters using Docker container “nodes”.
7+
2. [helm](https://helm.sh/) - the package manager for Kubernetes
8+
3. [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/) - command line tool to control Kubernetes clusters
9+
4. [bash](https://www.gnu.org/software/bash/) - the GNU Project's shell
410

511
## Features
612

7-
This project framework provides the following features:
13+
This is a very simple Framework, that creates Automated Test Environment to enable automated testing of applications hosted in [Azure Kubernetes Service (AKS)](https://docs.microsoft.com/en-us/azure/aks/) with the following features -
814

9-
* Feature 1
10-
* Feature 2
11-
* ...
15+
1. Create/Delete `kind` cluster in CI environment
16+
2. Optional - [Azure Key Vault Provider for Secrets Store CSI Driver](https://github.com/Azure/secrets-store-csi-driver-provider-azure) [installation](https://github.com/Azure/secrets-store-csi-driver-provider-azure#install-the-secrets-store-csi-driver-and-the-azure-keyvault-provider) and [configuration](https://github.com/Azure/secrets-store-csi-driver-provider-azure/blob/master/docs/service-principal-mode.md)
17+
3. Optional - [Azure Container Registry (ACR) Image Pull Secret](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-auth-kubernetes#create-an-image-pull-secret)
18+
4. Install `helm` charts of application (values needed for integration test environment can be overwritten easily)
19+
5. Validate if the respective Kubernetes `pods` are up and running (multiple `pods` can be provided that are having selector - `app.kubernetes.io/name`)
20+
6. [Port-Froward](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/#forward-a-local-port-to-a-port-on-the-pod) the respective Kubernetes `services` needed to perform integration testing (multiple `services` can be provided and the respective local ports will be starting from `8080` to `808[number of services]` maintaining the order as provided)
1221

1322
## Getting Started
1423

15-
### Prerequisites
16-
17-
(ideally very short, if any)
18-
19-
- OS
20-
- Library version
21-
- ...
22-
23-
### Installation
24-
25-
(ideally very short)
26-
27-
- npm install [package name]
28-
- mvn install
29-
- ...
30-
31-
### Quickstart
32-
(Add steps to get up and running quickly)
33-
34-
1. git clone [repository clone url]
35-
2. cd [respository name]
36-
3. ...
37-
24+
This framework contains the following script and their options -
25+
26+
1. `start.sh`: Download all the dependencies and create `kind` cluster -
27+
```sh
28+
# Usage: bash -f ./start.sh
29+
# Supported Options -
30+
# --kind-cluster-name=<Kind Cluster Name> (default INTEGRATION_TEST_CLUSTER)
31+
# --kind-version (default v0.7.0)
32+
# --kubectl-version (default v1.18.0)
33+
# --helm-version (default v3.2.0)
34+
```
35+
2. `deploy.sh`: Deploy/Port-Forward application `helm chart` and enables optional features -
36+
```sh
37+
# Usage: bash -f ./deploy.sh
38+
# Supported Options -
39+
# --csi-driver-enabled=<yes/no> (default no, if yes provide following two parameters)
40+
# --csi-driver-sp-client-id=<Azure Service Principle ID, having access to Azure Key Vault>
41+
# --csi-driver-sp-client-secret=<Azure Service Principle Secret, having access to Azure Key Vault>
42+
# --acr-imagepullsecret-enabled=<yes/no> (default no, if yes provide following three parameters)
43+
# --acr-imagepullsecret-sp-client-id=<Azure Service Principle ID, having access to Azure Container Registry>
44+
# --acr-imagepullsecret-sp-client-secret=<Azure Service Principle Secret, having access to Azure Container Registry>
45+
# --acr-full-name=<Azure Container Registry full name ex. example.azurecr.io>
46+
# --helm-chart-path=<Helm Chart Folder Path or URL to .tgz file for the applications >
47+
# --helm-chart-release-name=<Helm Release Name>
48+
# --helm-chart-set-parameters=<","(comma) seprated Helm Set parameters needed to be overwritten for integration test env>
49+
# --kubectl-check-services=<","(comma) seprated Pod names needed to be check if up and running>
50+
# --kubectl-check-services-selector-label=<ex. app.kubernetes.io/name or name etc.> (default app.kubernetes.io/name)
51+
# --kubectl-port-forward-services=<","(comma) seprated Service names needed to port-forward for testing>
52+
```
53+
3. `stop.sh`: Delete `kind` cluster -
54+
```sh
55+
# Usage: bash -f ./stop.sh
56+
# Supported Options -
57+
# --kind-cluster-name=<Kind Cluster Name> (default INTEGRATION_TEST_CLUSTER)
58+
```
3859

3960
## Demo
4061

41-
A demo app is included to show how to use the project.
62+
For [demonstrating the framework](./sample) following setup has been used -
4263

43-
To run the demo, follow these steps:
64+
* Sample Application [azure-vote](https://github.com/Azure-Samples/helm-charts/tree/master/chart-source/azure-vote)
65+
* [Azure DevOps Pipeline](https://azure.microsoft.com/en-us/services/devops/pipelines/) that demonstrate end-to-end flow of automated start/deploy/test/publish of integration test using this framework
66+
* [Python Test Framework](https://docs.python.org/3/library/unittest.html) to perform some basic Integration Test
4467

45-
(Add steps to start up the demo)
68+
## Expected Outcome
69+
It is expected to get Integration Test executed from CI Pipeline independently without disturbing existing development. The below images represents the outcome of the [sample for demonstrating the framework](./sample) -
4670

47-
1.
48-
2.
49-
3.
71+
![Sample Azure DevOps Pipeline Execution](docs/images/sample-result.png)
5072

5173
## Resources
5274

53-
(Any additional resources or related projects)
75+
Some additional points need to be considered -
5476

55-
- Link to supporting information
56-
- Link to similar sample
57-
- ...
77+
* While using Private Endpoint enabled `Azure Key Vault (AKV)` or `Azure Container Registry (ACR)` for applications, make sure the to use CI Pipeline Agent deployed in the same subnet where `AKV` or `ACR` endpoints are enabled

deploy.sh

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#/bin/bash
2+
set +x
3+
set +e
4+
5+
###########################################################################
6+
# Usage: bash -f ./deploy.sh
7+
# Supported Options -
8+
# --csi-driver-enabled=<yes/no> (default no, if yes provide following two parameters)
9+
# --csi-driver-sp-client-id=<Azure Service Principle ID, having access to Azure Key Vault>
10+
# --csi-driver-sp-client-secret=<Azure Service Principle Secret, having access to Azure Key Vault>
11+
# --acr-imagepullsecret-enabled=<yes/no> (default no, if yes provide following three parameters)
12+
# --acr-imagepullsecret-sp-client-id=<Azure Service Principle ID, having access to Azure Container Registry>
13+
# --acr-imagepullsecret-sp-client-secret=<Azure Service Principle Secret, having access to Azure Container Registry>
14+
# --acr-full-name=<Azure Container Registry full name ex. example.azurecr.io>
15+
# --helm-chart-path=<Helm Chart Folder Path or URL to .tgz file for the applications >
16+
# --helm-chart-release-name=<Helm Release Name>
17+
# --helm-chart-set-parameters=<","(comma) seprated Helm Set parameters needed to be overwritten for integration test env>
18+
# --kubectl-check-services=<","(comma) seprated Pod names needed to be check if up and running>
19+
# --kubectl-check-services-selector-label=<ex. app.kubernetes.io/name or name etc.> (default app.kubernetes.io/name)
20+
# --kubectl-port-forward-services=<","(comma) seprated Service names needed to port-forward for testing>
21+
###########################################################################
22+
23+
# All Supported Arguments
24+
ARGUMENT_LIST=(
25+
"csi-driver-enabled"
26+
"csi-driver-sp-client-id"
27+
"csi-driver-sp-client-secret"
28+
"acr-imagepullsecret-enabled"
29+
"acr-imagepullsecret-sp-client-id"
30+
"acr-imagepullsecret-sp-client-secret"
31+
"acr-full-name"
32+
"helm-chart-path"
33+
"helm-chart-release-name"
34+
"helm-chart-set-parameters"
35+
"kubectl-check-services"
36+
"kubectl-check-services-selector-label"
37+
"kubectl-port-forward-services"
38+
)
39+
40+
# Read Arguments
41+
opts=$(getopt \
42+
--longoptions "$(printf "%s:," "${ARGUMENT_LIST[@]}")" \
43+
--name "$(basename "$0")" \
44+
--options "" \
45+
-- "$@"
46+
)
47+
48+
# Assign Values from Arguments
49+
eval set --$opts
50+
while [[ $# -gt 0 ]]; do
51+
case "$1" in
52+
--csi-driver-enabled)
53+
CSI_DRIVER_ENABLED=$(echo "$2" | tr '[:upper:]' '[:lower:]')
54+
shift 2
55+
;;
56+
--csi-driver-sp-client-id)
57+
CSI_DRIVER_SP_CLIENT_ID=$2
58+
shift 2
59+
;;
60+
--csi-driver-sp-client-secret)
61+
CSI_DRIVER_SP_CLIENT_SECRET=$2
62+
shift 2
63+
;;
64+
--acr-imagepullsecret-enabled)
65+
ACR_IMAGEPULLSECRET_ENABLED=$(echo "$2" | tr '[:upper:]' '[:lower:]')
66+
shift 2
67+
;;
68+
--acr-imagepullsecret-sp-client-id)
69+
ACR_IMAGEPULLSECRET_SP_CLIENT_ID=$2
70+
shift 2
71+
;;
72+
--acr-imagepullsecret-sp-client-secret)
73+
ACR_IMAGEPULLSECRET_SP_CLIENT_SECRET=$2
74+
shift 2
75+
;;
76+
--acr-full-name)
77+
ACR_FULL_NAME=$2
78+
shift 2
79+
;;
80+
--helm-chart-path)
81+
HELM_CHART_PATH=$2
82+
shift 2
83+
;;
84+
--helm-chart-release-name)
85+
HELM_CHART_RELEASE_NAME=$2
86+
shift 2
87+
;;
88+
--helm-chart-set-parameters)
89+
HELM_CHART_SET_PARAMETERS=$(echo $2 | sed 's/,\ /,/g')
90+
shift 2
91+
;;
92+
--kubectl-check-services)
93+
KUBECTL_CHECK_SERVICES=$(echo $2 | tr "," "\n")
94+
shift 2
95+
;;
96+
--kubectl-check-services-selector-label)
97+
KUBECTL_CHECK_SERVICES_SELECTOR_LABEL=$2
98+
shift 2
99+
;;
100+
--kubectl-port-forward-services)
101+
KUBECTL_PORT_FORWARD_SERVICES=$(echo $2 | tr "," "\n")
102+
shift 2
103+
;;
104+
*)
105+
break
106+
;;
107+
esac
108+
done
109+
110+
# Assign Deafults
111+
KUBECTL_CHECK_SERVICES_SELECTOR_LABEL=${KUBECTL_CHECK_SERVICES_SELECTOR_LABEL:-"app.kubernetes.io/name"}
112+
113+
if [[ "${CSI_DRIVER_ENABLED}" == "yes" ]]; then
114+
echo $(date -u) "[INFO] Installing CSI Driver ..."
115+
linux-amd64/helm repo add csi-secrets-store-provider-azure https://raw.githubusercontent.com/Azure/secrets-store-csi-driver-provider-azure/master/charts
116+
linux-amd64/helm install csi-secrets-store-provider-azure/csi-secrets-store-provider-azure --generate-name --wait
117+
118+
echo $(date -u) "[INFO] Creating CSI Driver Secret to get Secrets from AKV ..."
119+
./kubectl create secret generic secrets-store-creds \
120+
--from-literal clientid="${CSI_DRIVER_SP_CLIENT_ID}" \
121+
--from-literal clientsecret="${CSI_DRIVER_SP_CLIENT_SECRET}"
122+
123+
echo $(date -u) "[INFO] Sleeping 60s to make sure CSI Driver get provisioned .."
124+
sleep 60s
125+
fi
126+
127+
if [[ "${ACR_IMAGEPULLSECRET_ENABLED}" == "yes" ]]; then
128+
echo $(date -u) "[INFO] Creating Image Pull Secret ..."
129+
./kubectl create secret docker-registry imagepullsecret \
130+
--docker-server="https://${ACR_FULL_NAME}" \
131+
--docker-username="${ACR_IMAGEPULLSECRET_SP_CLIENT_ID}" \
132+
--docker-password="${ACR_IMAGEPULLSECRET_SP_CLIENT_SECRET}"
133+
fi
134+
135+
echo $(date -u) "[INFO] Helm install of the Services (timedout in 10 min) ..."
136+
linux-amd64/helm install ${HELM_CHART_RELEASE_NAME} ${HELM_CHART_PATH} \
137+
--wait \
138+
--timeout 600s \
139+
--set "${HELM_CHART_SET_PARAMETERS}"
140+
141+
echo $(date -u) "[INFO] Sleeping to make sure pods get started .."
142+
sleep 60s
143+
144+
for _SERVICE in $KUBECTL_CHECK_SERVICES; do
145+
echo -n $(date -u) "[INFO] Checking Pods - ${_SERVICE}: "
146+
_COUNT=`./kubectl wait --for=condition=ready pod -l ${KUBECTL_CHECK_SERVICES_SELECTOR_LABEL}=${_SERVICE} --timeout=60s| grep met | wc -l`
147+
if (( $_COUNT >= 1 ))
148+
then
149+
echo "[UP]"
150+
else
151+
echo "[DOWN]"
152+
./kubectl get pods
153+
./kubectl get events
154+
fi
155+
done
156+
157+
_INDEX=0
158+
for _SERVICE in $KUBECTL_PORT_FORWARD_SERVICES; do
159+
echo $(date -u) "[INFO] Forwarding Service - ${_SERVICE} to http://localhost:808${_INDEX}"
160+
./kubectl port-forward service/${_SERVICE} 808${_INDEX}:80 &
161+
let _INDEX=${_INDEX}+1
162+
done
163+
164+
echo $(date -u) "[INFO] Pod Status"
165+
./kubectl get pods

docs/images/sample-result.png

112 KB
Loading

0 commit comments

Comments
 (0)