-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the deploy_api and delete_proxygen_deployments scripts
- Loading branch information
1 parent
14c0817
commit e190234
Showing
2 changed files
with
262 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Generic script for removing proxygen deployed APIs where the pull request is closed | ||
|
||
# Set the repo name to be the name of the repo this is running in | ||
REPO_NAME=electronic-prescription-service-clinical-prescription-tracker | ||
|
||
# Main function to delete relevant proxygen deployments | ||
main() { | ||
echo "Checking clinical tracker deployments" | ||
PULL_REQUEST_PROXYGEN_REGEX=prescription-clinical-tracker-pr- | ||
delete_apigee_deployments "internal-dev" "prescription-clinical-tracker-api" "ClinicalTrackerProxygenPrivateKey" "eps-clinical-tracker" | ||
delete_apigee_deployments "internal-dev-sandbox" "prescription-clinical-tracker-api" "ClinicalTrackerProxygenPrivateKey" "eps-clinical-tracker" | ||
} | ||
|
||
# Function to delete Apigee deployments | ||
delete_apigee_deployments() { | ||
APIGEE_ENVIRONMENT=$1 | ||
APIGEE_API=$2 | ||
PROXYGEN_PRIVATE_KEY_NAME=$3 | ||
PROXYGEN_KID=$4 | ||
proxygen_private_key_arn=$(aws cloudformation list-exports --query "Exports[?Name=='account-resources:${PROXYGEN_PRIVATE_KEY_NAME}'].Value" --output text) | ||
|
||
echo | ||
echo "Checking Apigee deployments on ${APIGEE_ENVIRONMENT}" | ||
echo | ||
|
||
jq -n --arg apiName "${APIGEE_API}" \ | ||
--arg environment "${APIGEE_ENVIRONMENT}" \ | ||
--arg kid "${PROXYGEN_KID}" \ | ||
--arg proxygenSecretName "${proxygen_private_key_arn}" \ | ||
'{apiName: $apiName, environment: $environment, kid, $kid, proxygenSecretName: $proxygenSecretName}' > payload.json | ||
|
||
aws lambda invoke --function-name "lambda-resources-ProxygenPTLInstanceGet" --cli-binary-format raw-in-base64-out --payload file://payload.json out.json > response.json | ||
|
||
if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then | ||
echo 'Error calling lambda' | ||
cat out.json | ||
exit 1 | ||
fi | ||
|
||
jq -r '.[].name' "out.json" | while read -r i; do | ||
echo "Checking if Apigee deployment $i has open pull request" | ||
PULL_REQUEST=${i//${PULL_REQUEST_PROXYGEN_REGEX}/} | ||
echo "Checking pull request ID ${PULL_REQUEST}" | ||
URL="https://api.github.com/repos/NHSDigital/${REPO_NAME}/pulls/${PULL_REQUEST}" | ||
RESPONSE=$(curl "${URL}" 2>/dev/null) | ||
STATE=$(echo "${RESPONSE}" | jq -r .state) | ||
if [ "$STATE" == "closed" ]; then | ||
echo "** Going to delete Apigee deployment $i as state is ${STATE} **" | ||
jq -n --arg apiName "${APIGEE_API}" \ | ||
--arg environment "${APIGEE_ENVIRONMENT}" \ | ||
--arg instance "${i}" \ | ||
--arg kid "${PROXYGEN_KID}" \ | ||
--arg proxygenSecretName "${proxygen_private_key_arn}" \ | ||
'{apiName: $apiName, environment: $environment, kid, $kid, proxygenSecretName: $proxygenSecretName, instance: $instance}' > payload.json | ||
|
||
aws lambda invoke --function-name "lambda-resources-ProxygenPTLInstanceDelete" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json | ||
if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then | ||
echo 'Error calling lambda' | ||
cat out.txt | ||
exit 1 | ||
fi | ||
|
||
else | ||
echo "Not going to delete Apigee deployment $i as state is ${STATE}" | ||
fi | ||
done | ||
} | ||
|
||
main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
#!/usr/bin/env bash | ||
set -eu pipefail | ||
|
||
echo "Specification path: ${SPEC_PATH}" | ||
echo "Specification version: ${VERSION_NUMBER}" | ||
echo "Stack name: ${STACK_NAME}" | ||
echo "AWS environment: ${AWS_ENVIRONMENT}" | ||
echo "Apigee environment: ${APIGEE_ENVIRONMENT}" | ||
echo "Proxygen private key name: ${PROXYGEN_PRIVATE_KEY_NAME}" | ||
echo "Proxygen KID: ${PROXYGEN_KID}" | ||
echo "Dry run: ${DRY_RUN}" | ||
|
||
client_private_key=$(cat ~/.proxygen/tmp/client_private_key) | ||
client_cert=$(cat ~/.proxygen/tmp/client_cert) | ||
|
||
if [ -z "${client_private_key}" ]; then | ||
echo "client_private_key is unset or set to the empty string" | ||
exit 1 | ||
fi | ||
if [ -z "${client_cert}" ]; then | ||
echo "client_cert is unset or set to the empty string" | ||
exit 1 | ||
fi | ||
|
||
put_secret_lambda=lambda-resources-ProxygenPTLMTLSSecretPut | ||
instance_put_lambda=lambda-resources-ProxygenPTLInstancePut | ||
spec_publish_lambda=lambda-resources-ProxygenPTLSpecPublish | ||
|
||
if [[ "$APIGEE_ENVIRONMENT" =~ ^(int|sandbox|prod)$ ]]; then | ||
put_secret_lambda=lambda-resources-ProxygenProdMTLSSecretPut | ||
instance_put_lambda=lambda-resources-ProxygenProdInstancePut | ||
spec_publish_lambda=lambda-resources-ProxygenProdSpecPublish | ||
fi | ||
|
||
is_pull_request=false | ||
instance_suffix="" | ||
if [[ ${STACK_NAME} == clinical-tracker-pr-* ]]; then | ||
is_pull_request=true | ||
# Extracting the PR ID from $STACK_NAME | ||
pr_id=$(echo "${STACK_NAME}" | cut -d'-' -f3) | ||
instance_suffix=-"pr-${pr_id}" | ||
fi | ||
|
||
# Determine the proxy instance based on the provided $STACK_NAME | ||
instance="prescription-clinical-tracker${instance_suffix}" | ||
apigee_api=prescription-clinical-tracker-api | ||
|
||
echo "Is pull request: ${is_pull_request}" | ||
echo "Proxy instance: ${instance}" | ||
echo "Apigee api: ${apigee_api}" | ||
|
||
echo | ||
|
||
echo "Fixing the spec" | ||
# Find and replace the title | ||
title=$(jq -r '.info.title' "${SPEC_PATH}") | ||
if [[ "${is_pull_request}" == "true" ]]; then | ||
jq --arg title "[PR-${pr_id}] $title" '.info.title = $title' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" | ||
fi | ||
|
||
# Find and replace the specification version number | ||
jq --arg version "${VERSION_NUMBER}" '.info.version = $version' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" | ||
|
||
# Find and replace the x-nhsd-apim.target.url value | ||
jq --arg stack_name "${STACK_NAME}" --arg aws_env "${AWS_ENVIRONMENT}" '.["x-nhsd-apim"].target.url = "https://\($stack_name).\($aws_env).eps.national.nhs.uk"' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" | ||
|
||
# Find and replace the servers object | ||
if [[ "${APIGEE_ENVIRONMENT}" == "prod" ]]; then | ||
jq --arg inst "${instance}" '.servers = [ { "url": "https://api.service.nhs.uk/\($inst)" } ]' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" | ||
else | ||
jq --arg env "${APIGEE_ENVIRONMENT}" --arg inst "${instance}" '.servers = [ { "url": "https://\($env).api.service.nhs.uk/\($inst)" } ]' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" | ||
fi | ||
|
||
# Find and replace securitySchemes | ||
if [[ "${APIGEE_ENVIRONMENT}" == "prod" ]]; then | ||
jq '.components.securitySchemes."app-level3" = {"$ref": "https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/app-level3"}' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" | ||
else | ||
jq '.components.securitySchemes."app-level3" = {"$ref": "https://proxygen.ptl.api.platform.nhs.uk/components/securitySchemes/app-level3"}' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" | ||
fi | ||
|
||
# Remove target attributes if the environment is sandbox | ||
if [[ "${APIGEE_ENVIRONMENT}" == *"sandbox"* ]]; then | ||
echo "Removing target attributes for sandbox environment" | ||
jq 'del(."x-nhsd-apim"."target-attributes")' "$SPEC_PATH" > temp.json && mv temp.json "${SPEC_PATH}" | ||
fi | ||
|
||
echo | ||
|
||
echo "Retrieving proxygen credentials" | ||
|
||
# Retrieve the proxygen private key and client private key and cert from AWS Secrets Manager | ||
proxygen_private_key_arn=$(aws cloudformation list-exports --query "Exports[?Name=='account-resources:${PROXYGEN_PRIVATE_KEY_NAME}'].Value" --output text) | ||
|
||
if [[ "${is_pull_request}" == "false" ]]; then | ||
echo | ||
echo "Store the secret used for mutual TLS to AWS using Proxygen proxy lambda" | ||
if [[ "${DRY_RUN}" == "false" ]]; then | ||
jq -n --arg apiName "${apigee_api}" \ | ||
--arg environment "${APIGEE_ENVIRONMENT}" \ | ||
--arg secretName "clinical-tracker-mtls-1" \ | ||
--arg secretKey "${client_private_key}" \ | ||
--arg secretCert "${client_cert}" \ | ||
--arg kid "${PROXYGEN_KID}" \ | ||
--arg proxygenSecretName "${proxygen_private_key_arn}" \ | ||
'{apiName: $apiName, environment: $environment, secretName: $secretName, secretKey: $secretKey, secretCert: $secretCert, kid, $kid, proxygenSecretName: $proxygenSecretName}' > payload.json | ||
|
||
aws lambda invoke --function-name "${put_secret_lambda}" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json | ||
if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then | ||
echo 'Error calling lambda' | ||
cat out.txt | ||
exit 1 | ||
fi | ||
echo "Secret stored successfully" | ||
else | ||
echo "Would call ${put_secret_lambda}" | ||
fi | ||
fi | ||
|
||
echo | ||
echo "Deploy the API instance using Proxygen proxy lambda" | ||
if [[ "${DRY_RUN}" == "false" ]]; then | ||
|
||
jq -n --argfile spec "${SPEC_PATH}" \ | ||
--arg apiName "${apigee_api}" \ | ||
--arg environment "${APIGEE_ENVIRONMENT}" \ | ||
--arg instance "${instance}" \ | ||
--arg kid "${PROXYGEN_KID}" \ | ||
--arg proxygenSecretName "${proxygen_private_key_arn}" \ | ||
'{apiName: $apiName, environment: $environment, specDefinition: $spec, instance: $instance, kid: $kid, proxygenSecretName: $proxygenSecretName}' > payload.json | ||
|
||
aws lambda invoke --function-name "${instance_put_lambda}" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json | ||
|
||
if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then | ||
echo 'Error calling lambda' | ||
cat out.txt | ||
exit 1 | ||
fi | ||
echo "Instance deployed" | ||
else | ||
echo "Would call ${instance_put_lambda}" | ||
fi | ||
|
||
if [[ "${APIGEE_ENVIRONMENT}" == "int" ]]; then | ||
echo | ||
echo "Deploy the API spec to prod catalogue as it is int environment" | ||
if [[ "${DRY_RUN}" == "false" ]]; then | ||
jq -n --argfile spec "${SPEC_PATH}" \ | ||
--arg apiName "${apigee_api}" \ | ||
--arg environment "prod" \ | ||
--arg instance "${instance}" \ | ||
--arg kid "${PROXYGEN_KID}" \ | ||
--arg proxygenSecretName "${proxygen_private_key_arn}" \ | ||
'{apiName: $apiName, environment: $environment, specDefinition: $spec, instance: $instance, kid: $kid, proxygenSecretName: $proxygenSecretName}' > payload.json | ||
|
||
aws lambda invoke --function-name "${spec_publish_lambda}" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json | ||
|
||
if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then | ||
echo 'Error calling lambda' | ||
cat out.txt | ||
exit 1 | ||
fi | ||
echo "Spec deployed" | ||
else | ||
echo "Would call ${spec_publish_lambda}" | ||
fi | ||
fi | ||
|
||
if [[ "${APIGEE_ENVIRONMENT}" == "internal-dev" && "${is_pull_request}" == "false" ]]; then | ||
echo | ||
echo "Deploy the API spec to uat catalogue as it is internal-dev environment" | ||
if [[ "${DRY_RUN}" == "false" ]]; then | ||
jq -n --argfile spec "${SPEC_PATH}" \ | ||
--arg apiName "${apigee_api}" \ | ||
--arg environment "uat" \ | ||
--arg instance "${instance}" \ | ||
--arg kid "${PROXYGEN_KID}" \ | ||
--arg proxygenSecretName "${proxygen_private_key_arn}" \ | ||
'{apiName: $apiName, environment: $environment, specDefinition: $spec, instance: $instance, kid: $kid, proxygenSecretName: $proxygenSecretName}' > payload.json | ||
|
||
aws lambda invoke --function-name "${spec_publish_lambda}" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json | ||
|
||
if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then | ||
echo 'Error calling lambda' | ||
cat out.txt | ||
exit 1 | ||
fi | ||
echo "Spec deployed" | ||
else | ||
echo "Would call ${spec_publish_lambda}" | ||
fi | ||
fi |