Skip to content

Commit 49fd502

Browse files
Merge pull request #503 from NHSDigital/APM-2488-SP-for-deployment-tests
APM-2488 Update deployment tests to use SP
2 parents 895aed7 + ea6ae06 commit 49fd502

File tree

4 files changed

+76
-44
lines changed

4 files changed

+76
-44
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ jobs:
1212
- name: Test Pull Request Deployments
1313
env:
1414
AZURE_TOKEN: "${{ secrets.AZURE_TOKEN }}"
15+
AZ_CLIENT_ID: "${{ secrets.AZ_CLIENT_ID }}"
16+
AZ_CLIENT_SECRET: "${{ secrets.AZ_CLIENT_SECRET }}"
17+
AZ_CLIENT_TENANT: "${{ secrets.AZ_CLIENT_TENANT }}"
1518
run: |
1619
export BRANCH_NAME="${{ github.event.pull_request.head.ref }}"
1720
export NOTIFY_COMMIT_SHA="${{ github.event.pull_request.head.sha }}"

azure/templates/deploy-service.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ steps:
247247
export ANSIBLE_FORCE_COLOR=yes
248248
export DIST_DIR=$(SERVICE_DIR)
249249
export PULL_REQUEST="${{ parameters.pr_label }}"
250-
251250
make --no-print-directory -C $(UTILS_DIR)/ansible deploy-manifest
252251
displayName: 'Deploy Manifest'
253252

scripts/test_pull_request_deployments.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,11 @@
55

66

77
PULL_REQUEST_PIPELINES = {
8-
"identity-service": {
9-
"build": 27,
10-
"pr": 54,
11-
"branch": "refs/heads/master"
12-
},
138
"canary-api": {
149
"build": 222,
1510
"pr": 223,
1611
"branch": "refs/heads/main"
17-
},
18-
"personal-demographics-service": {
19-
"build": 140,
20-
"pr": 144,
21-
"branch": "refs/heads/master"
22-
},
12+
}
2313
}
2414

2515

@@ -34,12 +24,12 @@ def trigger_pipelines(pipeline_ids: dict, service: str):
3424
if build_status != "succeeded":
3525
sys.exit(1)
3626
return
37-
azure_dev_ops.run_pipeline(
38-
service=service,
39-
pipeline_type="pr",
40-
pipeline_id=pipeline_ids["pr"],
41-
pipeline_branch=pipeline_ids["branch"]
42-
)
27+
# azure_dev_ops.run_pipeline(
28+
# service=service,
29+
# pipeline_type="pr",
30+
# pipeline_id=pipeline_ids["pr"],
31+
# pipeline_branch=pipeline_ids["branch"]
32+
# )
4333

4434

4535
def main():
@@ -57,9 +47,7 @@ def main():
5747
for process in jobs:
5848
if process.exitcode != 0:
5949
print("A job failed")
60-
# uncomment this line once authentication to azure is working
61-
# so the job fails if there is a problem with deployment actions
62-
# sys.exit(1)
50+
sys.exit(1)
6351
sys.exit(0)
6452

6553

scripts/trigger_pipelines.py

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import os
22
import json
33
import time
4+
from json import JSONDecodeError
5+
from typing import Dict, Any
6+
47
import requests
58

69

710
class AzureDevOps:
811

912
def __init__(self):
1013
self.base_url = "https://dev.azure.com/NHSD-APIM/API Platform/_apis/pipelines"
11-
self.token = os.environ["AZURE_TOKEN"]
12-
self.auth = requests.auth.HTTPBasicAuth("", self.token)
14+
self.client_id = os.environ["AZ_CLIENT_ID"]
15+
self.client_secret = os.environ["AZ_CLIENT_SECRET"]
16+
self.client_tenant = os.environ["AZ_CLIENT_TENANT"]
17+
self.access_token = self._get_access_token()
1318
self.notify_commit_sha = os.environ["NOTIFY_COMMIT_SHA"]
1419
self.utils_pr_number = os.environ["UTILS_PR_NUMBER"]
1520
self.notify_github_repo = "NHSDigital/api-management-utils"
16-
self.api_params = {"api-version": "6.0-preview.1"}
1721
self.api_request_delay = 60
1822

1923
@staticmethod
@@ -34,28 +38,29 @@ def run_pipeline(self,
3438
run_url = self.base_url + f"/{pipeline_id}/runs"
3539
request_body = self._build_request_body(pipeline_branch)
3640

37-
response = requests.post(run_url, auth=self.auth, params=self.api_params, json=request_body)
41+
response = self.api_request(
42+
run_url,
43+
json=request_body,
44+
method='post',
45+
)
3846
self.print_response(response, f"Initial request to {run_url}")
3947

4048
result = "failed"
4149
if response.status_code == 200:
4250
result = self._check_pipeline_response(response)
4351
print(f"Result of {service} {pipeline_type} pipeline: {result}")
44-
elif response.status_code == 203 or response.status_code == 401:
45-
print(f"{response.status_code}: Invalid or expired PAT (Personal Access Token),"
46-
f" please verify or renew token")
4752
else:
4853
print(f"Triggering pipeline: {service} {pipeline_type} failed, status code: {response.status_code}")
4954
return result
5055

5156
def _check_pipeline_response(self, response: requests.Response):
5257
delay = 0
5358
state_url = response.json()["_links"]["self"]["href"]
59+
# print("response check from our Start", response.status_code, response.json()["state"])
5460
while response.status_code == 200 and response.json()["state"] == "inProgress":
5561
time.sleep(self.api_request_delay)
5662
delay = delay + self.api_request_delay
57-
response = requests.get(state_url, auth=self.auth, params=self.api_params)
58-
self.print_response(response, f"Response from {state_url} after {delay} seconds")
63+
response = self.api_request(state_url)
5964
return response.json()["result"]
6065

6166
def _build_request_body(self, pipeline_branch: str):
@@ -71,19 +76,56 @@ def _build_request_body(self, pipeline_branch: str):
7176
},
7277
"self": {"refName": f"{pipeline_branch}"},
7378
}
74-
},
75-
"variables": {
76-
"NOTIFY_GITHUB_REPOSITORY": {
77-
"isSecret ": False,
78-
"value": f"{self.notify_github_repo}",
79-
},
80-
"NOTIFY_COMMIT_SHA": {
81-
"isSecret ": False,
82-
"value": f"{self.notify_commit_sha}"
83-
},
84-
"UTILS_PR_NUMBER": {
85-
"isSecret ": False,
86-
"value": f"{self.utils_pr_number}",
87-
}
8879
}
8980
}
81+
82+
def _get_access_token(self):
83+
url = f"https://login.microsoftonline.com/{self.client_tenant}/oauth2/v2.0/token"
84+
data = {
85+
"client_id": self.client_id,
86+
"client_secret": self.client_secret,
87+
"grant_type": "client_credentials",
88+
"scope": "https://app.vssps.visualstudio.com/.default",
89+
}
90+
headers = {"Content-Type": "application/x-www-form-urlencoded"}
91+
res = requests.post(url=url, data=data, headers=headers)
92+
res.raise_for_status()
93+
94+
return res.json()["access_token"]
95+
96+
def api_request(
97+
self,
98+
uri,
99+
params: Dict[str, Any] = None,
100+
headers: Dict[str, Any] = None,
101+
api_version: str = "6.0-preview.1",
102+
method: str = "get",
103+
max_tries: int = 5,
104+
**kwargs,
105+
):
106+
def get_headers():
107+
108+
_headers = {"Accept": "application/json", "Authorization": f"Bearer {self.access_token}"}
109+
_headers.update(headers or {})
110+
return _headers
111+
112+
_params = {"api-version": api_version, "NOTIFY_GITHUB_REPOSITORY": self.notify_github_repo, "NOTIFY_COMMIT_SHA": self.notify_commit_sha, "UTILS_PR_NUMBER": self.utils_pr_number}
113+
_params.update(params or {})
114+
action = getattr(requests, method)
115+
116+
result = action(uri, params=_params, headers=get_headers(), **kwargs)
117+
tries = 0
118+
while result.status_code not in (200, 201, 202, 204):
119+
tries += 1
120+
121+
if tries > max_tries:
122+
break
123+
124+
if result.status_code in (203, 401):
125+
print("REFRESHING ACCESS TOKEN...")
126+
self.access_token = self._get_access_token()
127+
128+
time.sleep(0.5 * tries)
129+
result = action(uri, params=_params, headers=get_headers(), **kwargs)
130+
131+
return result

0 commit comments

Comments
 (0)