Skip to content

Commit 3db2e94

Browse files
APM-2488 Update deployment tests to use SP
1 parent 895aed7 commit 3db2e94

File tree

2 files changed

+66
-12
lines changed

2 files changed

+66
-12
lines changed

scripts/test_pull_request_deployments.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ def main():
5757
for process in jobs:
5858
if process.exitcode != 0:
5959
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)
60+
sys.exit(1)
6361
sys.exit(0)
6462

6563

scripts/trigger_pipelines.py

Lines changed: 65 additions & 9 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,16 +38,17 @@ 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
@@ -54,8 +59,8 @@ def _check_pipeline_response(self, response: requests.Response):
5459
while response.status_code == 200 and response.json()["state"] == "inProgress":
5560
time.sleep(self.api_request_delay)
5661
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")
62+
state_response = self.api_request(state_url)
63+
self.print_response(state_response, f"Response from {state_url} after {delay} seconds")
5964
return response.json()["result"]
6065

6166
def _build_request_body(self, pipeline_branch: str):
@@ -87,3 +92,54 @@ def _build_request_body(self, pipeline_branch: str):
8792
}
8893
}
8994
}
95+
96+
def _get_access_token(self):
97+
url = f"https://login.microsoftonline.com/{self.client_tenant}/oauth2/v2.0/token"
98+
data = {
99+
"client_id": self.client_id,
100+
"client_secret": self.client_secret,
101+
"grant_type": "client_credentials",
102+
"scope": "https://app.vssps.visualstudio.com/.default",
103+
}
104+
headers = {"Content-Type": "application/x-www-form-urlencoded"}
105+
res = requests.post(url=url, data=data, headers=headers)
106+
res.raise_for_status()
107+
108+
return res.json()["access_token"]
109+
110+
def api_request(
111+
self,
112+
uri,
113+
params: Dict[str, Any] = None,
114+
headers: Dict[str, Any] = None,
115+
api_version: str = "6.0-preview.1",
116+
method: str = "get",
117+
max_tries: int = 5,
118+
**kwargs,
119+
):
120+
def get_headers():
121+
122+
_headers = {"Accept": "application/json", "Authorization": f"Bearer {self.access_token}"}
123+
_headers.update(headers or {})
124+
return _headers
125+
126+
_params = {"api-version": api_version}
127+
_params.update(params or {})
128+
action = getattr(requests, method)
129+
130+
result = action(uri, params=_params, headers=get_headers(), **kwargs)
131+
tries = 0
132+
while result.status_code not in (200, 201, 202, 204):
133+
tries += 1
134+
135+
if tries > max_tries:
136+
break
137+
138+
if result.status_code in (203, 401):
139+
print("REFRESHING ACCESS TOKEN...")
140+
self.access_token = self._get_access_token()
141+
142+
time.sleep(0.5 * tries)
143+
result = action(uri, params=_params, headers=get_headers(), **kwargs)
144+
145+
return result

0 commit comments

Comments
 (0)