Skip to content

Commit e270aa9

Browse files
committed
Incorporate PR #139 (AI)
1 parent 7231a32 commit e270aa9

7 files changed

Lines changed: 303 additions & 9 deletions

File tree

.github/actions/proxy/configure-proxygen/action.yaml

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,25 @@ runs:
3030
- name: Configure proxygen account details
3131
shell: bash
3232
working-directory: proxygen
33+
env:
34+
PROXYGEN_API_NAME: ${{ inputs.proxygen-api-name }}
35+
PROXYGEN_KEY_SECRET: ${{ inputs.proxygen-key-secret }}
36+
PROXYGEN_KEY_ID: ${{ inputs.proxygen-key-id }}
37+
PROXYGEN_CLIENT_ID: ${{ inputs.proxygen-client-id }}
3338
run: |
34-
cp settings.template.yaml $HOME/.proxygen/settings.yaml
35-
yq eval '.api = "${{ inputs.proxygen-api-name }}"' -i $HOME/.proxygen/settings.yaml
39+
set -euo pipefail
3640
37-
printf "%s" "${{ inputs.proxygen-key-secret }}" > /tmp/proxygen_private_key.pem
38-
cp credentials.template.yaml $HOME/.proxygen/credentials.yaml
39-
yq eval '.private_key_path = "/tmp/proxygen_private_key.pem"' -i $HOME/.proxygen/credentials.yaml
40-
yq eval '.key_id = "${{ inputs.proxygen-key-id }}"' -i $HOME/.proxygen/credentials.yaml
41-
yq eval '.client_id = "${{ inputs.proxygen-client-id }}"' -i $HOME/.proxygen/credentials.yaml
41+
mkdir -p "$HOME/.proxygen"
42+
cp settings.template.yaml "$HOME/.proxygen/settings.yaml"
43+
yq eval '.api = env(PROXYGEN_API_NAME)' -i "$HOME/.proxygen/settings.yaml"
44+
45+
printf '%s' "$PROXYGEN_KEY_SECRET" > /tmp/proxygen_private_key.pem
46+
chmod 600 /tmp/proxygen_private_key.pem
47+
48+
cp credentials.template.yaml "$HOME/.proxygen/credentials.yaml"
49+
yq eval '.private_key_path = "/tmp/proxygen_private_key.pem"' -i "$HOME/.proxygen/credentials.yaml"
50+
yq eval '.key_id = env(PROXYGEN_KEY_ID)' -i "$HOME/.proxygen/credentials.yaml"
51+
yq eval '.client_id = env(PROXYGEN_CLIENT_ID)' -i "$HOME/.proxygen/credentials.yaml"
52+
echo "Proxygen credentials configured, testing connection by listing instances..."
53+
proxygen instance list
54+
echo "Proxygen account configured successfully"
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
name: Alpha Integration Environment
2+
3+
on:
4+
pull_request:
5+
branches: [alpha-integration]
6+
types: [closed]
7+
workflow_dispatch:
8+
9+
env:
10+
AWS_REGION: eu-west-2
11+
AWS_ACCOUNT_ID: "900119715266"
12+
ECR_REPOSITORY_NAME: "whoami"
13+
TF_STATE_BUCKET: "cds-cdg-dev-tfstate-900119715266"
14+
TF_STATE_KEY: "dev/preview/alpha-integration.tfstate"
15+
BRANCH_NAME: "alpha-integration"
16+
ALB_RULE_PRIORITY: "2000"
17+
BASE_URL: "https://internal-dev.api.service.nhs.uk/clinical-data-gateway-api-poc-alpha-integration"
18+
python_version: "3.14"
19+
PROXYGEN_API_NAME: ${{ vars.PROXYGEN_API_NAME }}
20+
21+
jobs:
22+
alpha-integration:
23+
name: Deploy alpha integration environment
24+
runs-on: ubuntu-latest
25+
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true
26+
27+
permissions:
28+
id-token: write
29+
contents: read
30+
31+
concurrency:
32+
group: alpha-integration-environment
33+
cancel-in-progress: true
34+
35+
steps:
36+
- name: Checkout repo
37+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
38+
with:
39+
ref: alpha-integration
40+
41+
- name: Configure AWS credentials
42+
uses: aws-actions/configure-aws-credentials@b1257c400167d727708335212f95607835cd03fd
43+
with:
44+
role-to-assume: ${{ secrets.DEV_AWS_CREDENTIALS }}
45+
aws-region: ${{ env.AWS_REGION }}
46+
47+
- name: Login to Amazon ECR
48+
id: ecr-login
49+
uses: aws-actions/amazon-ecr-login@c962da2960ed15f492addc26fffa274485265950
50+
51+
- name: Compute deployment metadata
52+
id: meta
53+
run: |
54+
ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY_NAME}"
55+
echo "ecr_url=$ECR_URL" >> "$GITHUB_OUTPUT"
56+
57+
- name: Setup Python project
58+
uses: ./.github/actions/setup-python-project
59+
with:
60+
python-version: ${{ env.python_version }}
61+
62+
- name: Build Docker image
63+
env:
64+
PYTHON_VERSION: ${{ env.python_version }}
65+
run: |
66+
make build IMAGE_TAG="${BRANCH_NAME}" ECR_URL="${{ steps.meta.outputs.ecr_url }}"
67+
68+
- name: Push Docker image to ECR
69+
run: |
70+
docker push "${{ steps.meta.outputs.ecr_url }}:${BRANCH_NAME}"
71+
72+
- name: Setup Terraform
73+
uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85
74+
with:
75+
terraform_version: 1.14.0
76+
77+
- name: Terraform init
78+
working-directory: infrastructure/environments/preview
79+
run: |
80+
terraform init \
81+
-backend-config="bucket=${TF_STATE_BUCKET}" \
82+
-backend-config="key=${TF_STATE_KEY}" \
83+
-backend-config="region=${AWS_REGION}"
84+
85+
- name: Terraform apply alpha integration env
86+
working-directory: infrastructure/environments/preview
87+
env:
88+
TF_VAR_branch_name: ${{ env.BRANCH_NAME }}
89+
TF_VAR_image_tag: ${{ env.BRANCH_NAME }}
90+
TF_VAR_alb_rule_priority: ${{ env.ALB_RULE_PRIORITY }}
91+
run: |
92+
terraform apply \
93+
-var-file="alpha-int.tfvars" \
94+
-auto-approve
95+
96+
- name: Capture terraform outputs
97+
id: tf-output
98+
working-directory: infrastructure/environments/preview
99+
run: |
100+
terraform output -json > tf-output.json
101+
102+
URL=$(jq -r '.url.value' tf-output.json)
103+
echo "preview_url=$URL" >> "$GITHUB_OUTPUT"
104+
105+
TG=$(jq -r '.target_group_arn.value' tf-output.json)
106+
echo "target_group=$TG" >> "$GITHUB_OUTPUT"
107+
108+
ECS_SERVICE=$(jq -r '.ecs_service_name.value' tf-output.json)
109+
echo "ecs_service=$ECS_SERVICE" >> "$GITHUB_OUTPUT"
110+
111+
ECS_CLUSTER=$(jq -r '.ecs_cluster_name.value' tf-output.json)
112+
echo "ecs_cluster=$ECS_CLUSTER" >> "$GITHUB_OUTPUT"
113+
114+
- name: Get proxygen machine user details
115+
id: proxygen-machine-user
116+
uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802
117+
with:
118+
secret-ids: /cds/gateway/dev/proxygen/proxygen-key-secret
119+
name-transformation: lowercase
120+
121+
- name: Deploy alpha integration API proxy
122+
uses: ./.github/actions/proxy/deploy-proxy
123+
with:
124+
mtls-secret-name: ${{ vars.PREVIEW_ENV_MTLS_SECRET_NAME }}
125+
target-url: ${{ steps.tf-output.outputs.preview_url }}
126+
proxy-base-path: "clinical-data-gateway-api-poc-alpha-integration"
127+
proxygen-key-secret: ${{ env._cds_gateway_dev_proxygen_proxygen_key_secret }}
128+
proxygen-key-id: ${{ vars.PREVIEW_ENV_PROXYGEN_KEY_ID }}
129+
proxygen-api-name: ${{ vars.PROXYGEN_API_NAME }}
130+
proxygen-client-id: ${{ vars.PREVIEW_ENV_PROXYGEN_CLIENT_ID }}
131+
132+
- name: Await deployment completion
133+
run: |
134+
aws ecs wait services-stable \
135+
--cluster "${{ steps.tf-output.outputs.ecs_cluster }}" \
136+
--services "${{ steps.tf-output.outputs.ecs_service }}" \
137+
--region "${AWS_REGION}"
138+
139+
- name: Get mTLS certs for testing
140+
id: mtls-certs
141+
uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802
142+
with:
143+
secret-ids: |
144+
/cds/gateway/dev/mtls/client1-key-secret
145+
/cds/gateway/dev/mtls/client1-key-public
146+
name-transformation: lowercase
147+
148+
- name: Prepare mTLS cert files for tests
149+
run: |
150+
printf '%s' "$_cds_gateway_dev_mtls_client1_key_secret" > /tmp/client1-key.pem
151+
printf '%s' "$_cds_gateway_dev_mtls_client1_key_public" > /tmp/client1-cert.pem
152+
chmod 600 /tmp/client1-key.pem /tmp/client1-cert.pem
153+
154+
- name: Smoke test environment URL
155+
id: smoke-test
156+
env:
157+
PREVIEW_URL: ${{ steps.tf-output.outputs.preview_url }}
158+
run: |
159+
if [ -z "$PREVIEW_URL" ] || [ "$PREVIEW_URL" = "null" ]; then
160+
echo "Environment URL missing"
161+
echo "http_status=missing" >> "$GITHUB_OUTPUT"
162+
echo "http_result=missing-url" >> "$GITHUB_OUTPUT"
163+
exit 0
164+
fi
165+
166+
STATUS=$(curl \
167+
--cert /tmp/client1-cert.pem \
168+
--key /tmp/client1-key.pem \
169+
--silent \
170+
--output /tmp/preview.headers \
171+
--write-out '%{http_code}' \
172+
--head \
173+
--max-time 30 "$PREVIEW_URL"/health || true)
174+
175+
if [ "$STATUS" = "404" ]; then
176+
echo "Environment responded with expected 404"
177+
echo "http_status=404" >> "$GITHUB_OUTPUT"
178+
echo "http_result=allowed-404" >> "$GITHUB_OUTPUT"
179+
exit 0
180+
fi
181+
182+
if [[ "$STATUS" =~ ^[0-9]{3}$ ]] && [ "$STATUS" -ge 200 ] && [ "$STATUS" -lt 400 ]; then
183+
echo "Environment responded with status $STATUS"
184+
echo "http_status=$STATUS" >> "$GITHUB_OUTPUT"
185+
echo "http_result=success" >> "$GITHUB_OUTPUT"
186+
exit 0
187+
fi
188+
189+
echo "Environment responded with unexpected status $STATUS"
190+
if [ -f /tmp/preview.headers ]; then
191+
echo "Response headers:"
192+
cat /tmp/preview.headers
193+
fi
194+
195+
echo "http_status=$STATUS" >> "$GITHUB_OUTPUT"
196+
echo "http_result=unexpected-status" >> "$GITHUB_OUTPUT"
197+
exit 0
198+
199+
- name: Retrieve Apigee Token
200+
id: apigee-token
201+
shell: bash
202+
run: |
203+
set -euo pipefail
204+
205+
APIGEE_TOKEN="$(proxygen pytest-nhsd-apim get-token | jq -r '.pytest_nhsd_apim_token' 2>/dev/null)"
206+
if [ -z "$APIGEE_TOKEN" ] || [ "$APIGEE_TOKEN" = "null" ]; then
207+
echo "::error::Failed to retrieve Apigee token"
208+
exit 1
209+
fi
210+
211+
echo "::add-mask::$APIGEE_TOKEN"
212+
printf 'apigee-access-token=%s\n' "$APIGEE_TOKEN" >> "$GITHUB_OUTPUT"
213+
echo "Token retrieved successfully (length: ${#APIGEE_TOKEN})"
214+
215+
- name: Run unit tests
216+
uses: ./.github/actions/run-test-suite
217+
with:
218+
test-type: unit
219+
env: local
220+
221+
- name: Run contract tests
222+
uses: ./.github/actions/run-test-suite
223+
with:
224+
test-type: contract
225+
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
226+
base-url: ${{ env.BASE_URL }}
227+
228+
- name: Run schema validation tests
229+
uses: ./.github/actions/run-test-suite
230+
with:
231+
test-type: schema
232+
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
233+
base-url: ${{ env.BASE_URL }}
234+
235+
- name: Run integration tests
236+
uses: ./.github/actions/run-test-suite
237+
with:
238+
test-type: integration
239+
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
240+
base-url: ${{ env.BASE_URL }}
241+
242+
- name: Run acceptance tests
243+
uses: ./.github/actions/run-test-suite
244+
with:
245+
test-type: acceptance
246+
apigee-access-token: ${{ steps.apigee-token.outputs.apigee-access-token }}
247+
base-url: ${{ env.BASE_URL }}
248+
249+
- name: Remove mTLS temp files
250+
run: rm -f /tmp/client1-key.pem /tmp/client1-cert.pem
251+
252+
# - name: Trivy IaC scan
253+
# uses: nhs-england-tools/trivy-action/iac-scan@289984b2f03034233a347d6dbadecd5ca9ea9634
254+
# with:
255+
# scan-ref: infrastructure/environments/preview
256+
# artifact-name: trivy-iac-scan-alpha-integration
257+
258+
# - name: Trivy image scan
259+
# uses: nhs-england-tools/trivy-action/image-scan@289984b2f03034233a347d6dbadecd5ca9ea9634
260+
# with:
261+
# image-ref: ${{ steps.meta.outputs.ecr_url }}:${{ env.BRANCH_NAME }}
262+
# artifact-name: trivy-image-scan-alpha-integration
263+
264+
# - name: Generate SBOM
265+
# uses: nhs-england-tools/trivy-action/image-scan@289984b2f03034233a347d6dbadecd5ca9ea9634
266+
# with:
267+
# image-ref: ${{ steps.meta.outputs.ecr_url }}:${{ env.BRANCH_NAME }}
268+
# artifact-name: trivy-sbom-alpha-integration

.vscode/cspell-dictionary.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ asid
22
fhir
33
getstructuredrecord
44
gpconnect
5+
proxygen
56
usefixtures

infrastructure/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ crash.*.log
2020

2121
# Allow checked-in preview tfvars containing non-sensitive values and secret references only
2222
!environments/preview/preview.tfvars
23+
!environments/preview/alpha-int.tfvars
2324

2425
# Ignore override files as they are usually used to override resources locally and so
2526
# are not checked in
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
provider_url = "stub"
2+
provider_mtls_cert = "stub"
3+
provider_mtls_key = "stub"
4+
5+
sds_url = "stub"
6+
sds_api_token = "stub"
7+
8+
pds_url = "stub"
9+
pds_api_token = "stub"
10+
pds_api_secret = "stub"
11+
pds_api_kid = "stub"

proxygen/credentials.template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
base_url: https://identity.prod.api.platform.nhs.uk/realms/api-producers
1+
base_url: https://identity.ptl.api.platform.nhs.uk/realms/api-producers
22
client_id: <proxygen machine user client id>
33
client_secret: ''
44
key_id: <proxygen_key_id>

proxygen/settings.template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
api: <proxygen_api_name>
2-
endpoint_url: https://proxygen.prod.api.platform.nhs.uk
2+
endpoint_url: https://proxygen.ptl.api.platform.nhs.uk
33
spec_output_format: yaml

0 commit comments

Comments
 (0)