From 77c83fdff1a175bd9d3fa24f23fa6eeac973d54c Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 12:49:02 -0500 Subject: [PATCH 01/57] try adding webjob resource Co-Authored-By: Samuel Aquino --- operations/template/app.tf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/operations/template/app.tf b/operations/template/app.tf index 79f08212..90dd1145 100644 --- a/operations/template/app.tf +++ b/operations/template/app.tf @@ -72,6 +72,8 @@ resource "azurerm_linux_web_app" "sftp" { FLEXION_CLIENT_NAME = "flexion.simulated-lab" QUEUE_MAX_DELIVERY_ATTEMPTS = azurerm_eventgrid_system_topic_event_subscription.topic_sub.retry_policy.0.max_delivery_attempts # making the Azure container <-> queue retry count be in sync with the queue <-> application retry count.. CA_DPH_ZIP_PASSWORD_NAME = azurerm_key_vault_secret.ca_dph_zip_password.name + + WEBSITES_ENABLE_APP_SERVICE_STORAGE = true } identity { @@ -138,3 +140,11 @@ resource "azurerm_monitor_autoscale_setting" "sftp_autoscale" { } } } + +resource "null_resource" "webjob" { + provisioner "local-exec" { + when = create + command = "az webapp deployment source config-zip -g ${data.azurerm_resource_group.group.name} -n ${data.azurerm_resource_group.group.name} --src Publish.zip" + } + depends_on = [ azurerm_linux_web_app.sftp ] +} From 2f7b80068cdc50705166896939b8ddc62126aa10 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 12:58:50 -0500 Subject: [PATCH 02/57] add webjob script? Co-Authored-By: Samuel Aquino Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/app.tf | 9 ++++++++- operations/webjob.sh | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100755 operations/webjob.sh diff --git a/operations/template/app.tf b/operations/template/app.tf index 90dd1145..38b95c90 100644 --- a/operations/template/app.tf +++ b/operations/template/app.tf @@ -144,7 +144,14 @@ resource "azurerm_monitor_autoscale_setting" "sftp_autoscale" { resource "null_resource" "webjob" { provisioner "local-exec" { when = create - command = "az webapp deployment source config-zip -g ${data.azurerm_resource_group.group.name} -n ${data.azurerm_resource_group.group.name} --src Publish.zip" + command = "az webapp deployment source config-zip -g ${data.azurerm_resource_group.group.name} -n ${data.azurerm_resource_group.group.name} --src ${data.archive_file.source.output_path}" } depends_on = [ azurerm_linux_web_app.sftp ] } + +# Zip the Webjob function on the fly +data "archive_file" "source" { + type = "zip" + source_dir = "../webjob.sh" + output_path = "../webjob.zip" +} diff --git a/operations/webjob.sh b/operations/webjob.sh new file mode 100755 index 00000000..6f6fbc83 --- /dev/null +++ b/operations/webjob.sh @@ -0,0 +1,4 @@ +result=$(curl -X GET --header "Accept: */*" "https://cdc-rs-sftp-internal.azurewebsites.net/health") +echo "Response from server" +echo $result +exit From 5d117fe388e56813c017a51282ddc4c1ef7fc934 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 13:03:15 -0500 Subject: [PATCH 03/57] update pathing Co-Authored-By: Samuel Aquino Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/app.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operations/template/app.tf b/operations/template/app.tf index 38b95c90..f30c2124 100644 --- a/operations/template/app.tf +++ b/operations/template/app.tf @@ -152,6 +152,6 @@ resource "null_resource" "webjob" { # Zip the Webjob function on the fly data "archive_file" "source" { type = "zip" - source_dir = "../webjob.sh" - output_path = "../webjob.zip" + source_dir = "../../webjob.sh" + output_path = "../../webjob.zip" } From 63a093a82b39947803f436c6817b7b8084d1620f Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 13:25:15 -0500 Subject: [PATCH 04/57] switch to source file not dir Co-Authored-By: Samuel Aquino Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/app.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/operations/template/app.tf b/operations/template/app.tf index f30c2124..b1e8f72b 100644 --- a/operations/template/app.tf +++ b/operations/template/app.tf @@ -141,6 +141,7 @@ resource "azurerm_monitor_autoscale_setting" "sftp_autoscale" { } } +# TODO - figure out how to make this triggerd and add a schedule resource "null_resource" "webjob" { provisioner "local-exec" { when = create @@ -152,6 +153,6 @@ resource "null_resource" "webjob" { # Zip the Webjob function on the fly data "archive_file" "source" { type = "zip" - source_dir = "../../webjob.sh" + source_file = "../../webjob.sh" output_path = "../../webjob.zip" } From d7efc526db13a9dff430af0aaa1ebf40724a0485 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 13:35:29 -0500 Subject: [PATCH 05/57] try some other command Co-Authored-By: Samuel Aquino Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/app.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operations/template/app.tf b/operations/template/app.tf index b1e8f72b..e7f628db 100644 --- a/operations/template/app.tf +++ b/operations/template/app.tf @@ -145,7 +145,7 @@ resource "azurerm_monitor_autoscale_setting" "sftp_autoscale" { resource "null_resource" "webjob" { provisioner "local-exec" { when = create - command = "az webapp deployment source config-zip -g ${data.azurerm_resource_group.group.name} -n ${data.azurerm_resource_group.group.name} --src ${data.archive_file.source.output_path}" + command = "az webapp deploy -g ${data.azurerm_resource_group.group.name} -n ${data.azurerm_resource_group.group.name} --src-path ${data.archive_file.source.output_path} --type zip" } depends_on = [ azurerm_linux_web_app.sftp ] } From 6f8a67ec1354fd9d212c5634abdf2b9a6d291475 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 13:38:02 -0500 Subject: [PATCH 06/57] try login first Co-Authored-By: Samuel Aquino Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- .github/workflows/terraform-deploy_reusable.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/terraform-deploy_reusable.yml b/.github/workflows/terraform-deploy_reusable.yml index 6e5f2b3f..c1c55a3f 100644 --- a/.github/workflows/terraform-deploy_reusable.yml +++ b/.github/workflows/terraform-deploy_reusable.yml @@ -66,9 +66,6 @@ jobs: id: validate run: terraform validate -no-color - - name: Terraform Apply - run: terraform apply -auto-approve -input=false ${{ inputs.TERRAFORM_APPLY_PARAMETERS }} - - name: Login via Azure CLI uses: azure/login@v2 with: @@ -76,6 +73,9 @@ jobs: tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + - name: Terraform Apply + run: terraform apply -auto-approve -input=false ${{ inputs.TERRAFORM_APPLY_PARAMETERS }} + - id: export-terraform-output name: Export Terraform Output run: | From f45443b82412cbec7dd7f43c585c685327c92a15 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 13:43:46 -0500 Subject: [PATCH 07/57] take name off command Co-Authored-By: Samuel Aquino Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/app.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operations/template/app.tf b/operations/template/app.tf index e7f628db..91dda252 100644 --- a/operations/template/app.tf +++ b/operations/template/app.tf @@ -145,7 +145,7 @@ resource "azurerm_monitor_autoscale_setting" "sftp_autoscale" { resource "null_resource" "webjob" { provisioner "local-exec" { when = create - command = "az webapp deploy -g ${data.azurerm_resource_group.group.name} -n ${data.azurerm_resource_group.group.name} --src-path ${data.archive_file.source.output_path} --type zip" + command = "az webapp deploy -g ${data.azurerm_resource_group.group.name} --src-path ${data.archive_file.source.output_path} --type zip" } depends_on = [ azurerm_linux_web_app.sftp ] } From 566cbd8a7aca1c2da0ba9141b9cdf281ee8e30e7 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 13:49:42 -0500 Subject: [PATCH 08/57] make the name an empty string Co-Authored-By: Samuel Aquino Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/app.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operations/template/app.tf b/operations/template/app.tf index 91dda252..097ae91a 100644 --- a/operations/template/app.tf +++ b/operations/template/app.tf @@ -145,7 +145,7 @@ resource "azurerm_monitor_autoscale_setting" "sftp_autoscale" { resource "null_resource" "webjob" { provisioner "local-exec" { when = create - command = "az webapp deploy -g ${data.azurerm_resource_group.group.name} --src-path ${data.archive_file.source.output_path} --type zip" + command = "az webapp deploy -g ${data.azurerm_resource_group.group.name} -n '' --src-path ${data.archive_file.source.output_path} --type zip" } depends_on = [ azurerm_linux_web_app.sftp ] } From 8f80514001236193607e1bce8fa0fd08b02f540c Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 13:58:30 -0500 Subject: [PATCH 09/57] take out webjob attempt Co-Authored-By: Samuel Aquino Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- .../workflows/terraform-deploy_reusable.yml | 6 +++--- operations/template/app.tf | 18 ------------------ operations/webjob.sh | 4 ---- 3 files changed, 3 insertions(+), 25 deletions(-) delete mode 100755 operations/webjob.sh diff --git a/.github/workflows/terraform-deploy_reusable.yml b/.github/workflows/terraform-deploy_reusable.yml index c1c55a3f..6e5f2b3f 100644 --- a/.github/workflows/terraform-deploy_reusable.yml +++ b/.github/workflows/terraform-deploy_reusable.yml @@ -66,6 +66,9 @@ jobs: id: validate run: terraform validate -no-color + - name: Terraform Apply + run: terraform apply -auto-approve -input=false ${{ inputs.TERRAFORM_APPLY_PARAMETERS }} + - name: Login via Azure CLI uses: azure/login@v2 with: @@ -73,9 +76,6 @@ jobs: tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - name: Terraform Apply - run: terraform apply -auto-approve -input=false ${{ inputs.TERRAFORM_APPLY_PARAMETERS }} - - id: export-terraform-output name: Export Terraform Output run: | diff --git a/operations/template/app.tf b/operations/template/app.tf index 097ae91a..79f08212 100644 --- a/operations/template/app.tf +++ b/operations/template/app.tf @@ -72,8 +72,6 @@ resource "azurerm_linux_web_app" "sftp" { FLEXION_CLIENT_NAME = "flexion.simulated-lab" QUEUE_MAX_DELIVERY_ATTEMPTS = azurerm_eventgrid_system_topic_event_subscription.topic_sub.retry_policy.0.max_delivery_attempts # making the Azure container <-> queue retry count be in sync with the queue <-> application retry count.. CA_DPH_ZIP_PASSWORD_NAME = azurerm_key_vault_secret.ca_dph_zip_password.name - - WEBSITES_ENABLE_APP_SERVICE_STORAGE = true } identity { @@ -140,19 +138,3 @@ resource "azurerm_monitor_autoscale_setting" "sftp_autoscale" { } } } - -# TODO - figure out how to make this triggerd and add a schedule -resource "null_resource" "webjob" { - provisioner "local-exec" { - when = create - command = "az webapp deploy -g ${data.azurerm_resource_group.group.name} -n '' --src-path ${data.archive_file.source.output_path} --type zip" - } - depends_on = [ azurerm_linux_web_app.sftp ] -} - -# Zip the Webjob function on the fly -data "archive_file" "source" { - type = "zip" - source_file = "../../webjob.sh" - output_path = "../../webjob.zip" -} diff --git a/operations/webjob.sh b/operations/webjob.sh deleted file mode 100755 index 6f6fbc83..00000000 --- a/operations/webjob.sh +++ /dev/null @@ -1,4 +0,0 @@ -result=$(curl -X GET --header "Accept: */*" "https://cdc-rs-sftp-internal.azurewebsites.net/health") -echo "Response from server" -echo $result -exit From f72c5faa8181c4c7e8b1c0386f42c528437180ac Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 16:09:20 -0500 Subject: [PATCH 10/57] Start making an Azure Function for timer control Co-Authored-By: Samuel Aquino --- .gitignore | 103 ++ azure_functions/.funcignore | 10 + azure_functions/host.json | 15 + azure_functions/package-lock.json | 885 ++++++++++++++++++ azure_functions/package.json | 23 + .../src/functions/caDphTimerTrigger.ts | 33 + azure_functions/src/index.ts | 5 + azure_functions/tsconfig.json | 10 + 8 files changed, 1084 insertions(+) create mode 100644 azure_functions/.funcignore create mode 100644 azure_functions/host.json create mode 100644 azure_functions/package-lock.json create mode 100644 azure_functions/package.json create mode 100644 azure_functions/src/functions/caDphTimerTrigger.ts create mode 100644 azure_functions/src/index.ts create mode 100644 azure_functions/tsconfig.json diff --git a/.gitignore b/.gitignore index ba00f2ce..7ad1c139 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ reportstream-sftp-ingestion # IDE files .idea/ +.vscode/ # Ignore terraform state (as it is persisted via Azure Storage) terraform.tfstate* @@ -33,3 +34,105 @@ terraform.tfstate* # Local blob storage data /localdata + + +# Items added by creating the Azure function: +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TypeScript output +dist +out + +# Azure Functions artifacts +bin +obj +appsettings.json +local.settings.json + +# Azurite artifacts +__blobstorage__ +__queuestorage__ +__azurite_db*__.json diff --git a/azure_functions/.funcignore b/azure_functions/.funcignore new file mode 100644 index 00000000..d72240f5 --- /dev/null +++ b/azure_functions/.funcignore @@ -0,0 +1,10 @@ +*.js.map +*.ts +.git* +.vscode +__azurite_db*__.json +__blobstorage__ +__queuestorage__ +local.settings.json +test +tsconfig.json diff --git a/azure_functions/host.json b/azure_functions/host.json new file mode 100644 index 00000000..06d01bda --- /dev/null +++ b/azure_functions/host.json @@ -0,0 +1,15 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + }, + "extensionBundle": { + "id": "Microsoft.Azure.Functions.ExtensionBundle", + "version": "[4.*, 5.0.0)" + } +} diff --git a/azure_functions/package-lock.json b/azure_functions/package-lock.json new file mode 100644 index 00000000..fac49465 --- /dev/null +++ b/azure_functions/package-lock.json @@ -0,0 +1,885 @@ +{ + "name": "azure_functions", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "azure_functions", + "version": "1.0.0", + "dependencies": { + "@azure/functions": "^4.0.0", + "@azure/storage-queue": "^12.22.0" + }, + "devDependencies": { + "@types/node": "^20.x", + "rimraf": "^5.0.0", + "typescript": "^4.0.0" + } + }, + "node_modules/@azure/abort-controller": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", + "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.7.2.tgz", + "integrity": "sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz", + "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-client/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-http-compat": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.1.2.tgz", + "integrity": "sha512-5MnV1yqzZwgNLLjlizsU3QqOeQChkIXw781Fwh1xdAqJR5AA32IUaq6xv1BICJvfbHoa+JYcaij2HFkhLbNTJQ==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-client": "^1.3.0", + "@azure/core-rest-pipeline": "^1.3.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-http-compat/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-paging": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz", + "integrity": "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.1.tgz", + "integrity": "sha512-ExPSbgjwCoht6kB7B4MeZoBAxcQSIl29r/bPeazZJx50ej4JJCByimLOrZoIsurISNyJQQHf30b3JfqC3Hb88A==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.9.0", + "@azure/logger": "^1.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz", + "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.0.tgz", + "integrity": "sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-xml": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.4.2.tgz", + "integrity": "sha512-CW3MZhApe/S4iikbYKE7s83fjDBPIr2kpidX+hlGRwh7N4o1nIpQ/PfJTeioqhfqdMvRtheEl+ft64fyTaLNaA==", + "dependencies": { + "fast-xml-parser": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/functions": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@azure/functions/-/functions-4.5.0.tgz", + "integrity": "sha512-WNCiOHMQEZpezxgThD3o2McKEjUEljtQBvdw4X4oE5714eTw76h33kIj0660ZJGEnxYSx4dx18oAbg5kLMs9iQ==", + "dependencies": { + "cookie": "^0.6.0", + "long": "^4.0.0", + "undici": "^5.13.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.2.tgz", + "integrity": "sha512-l170uE7bsKpIU6B/giRc9i4NI0Mj+tANMMMxf7Zi/5cKzEqPayP7+X1WPrG7e+91JgY8N+7K7nF2WOi7iVhXvg==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/storage-queue": { + "version": "12.22.0", + "resolved": "https://registry.npmjs.org/@azure/storage-queue/-/storage-queue-12.22.0.tgz", + "integrity": "sha512-knYpPUL7kiaz/73w5V73h7nEOGfluproN+po36Q3dVuYTxh8HCGoJuBG4/L8De6d+9hhANrILVTMuDhdTNM21g==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-client": "^1.6.2", + "@azure/core-http-compat": "^2.0.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-rest-pipeline": "^1.10.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/core-xml": "^1.3.2", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/fast-xml-parser": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", + "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", + "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", + "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.8.tgz", + "integrity": "sha512-XSh0V2/yNhDEi8HwdIefD8MLgs4LQXPag/nEJWs3YUc3Upn+UHa1GyIkEg9xSSNt7HnkO5FjTvmcRzgf+8UZuw==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/azure_functions/package.json b/azure_functions/package.json new file mode 100644 index 00000000..090d3094 --- /dev/null +++ b/azure_functions/package.json @@ -0,0 +1,23 @@ +{ + "name": "azure_functions", + "version": "1.0.0", + "description": "", + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "clean": "rimraf dist", + "prestart": "npm run clean && npm run build", + "start": "func start", + "test": "echo \"No tests yet...\"" + }, + "dependencies": { + "@azure/functions": "^4.0.0", + "@azure/storage-queue": "^12.22.0" + }, + "devDependencies": { + "@types/node": "^20.x", + "rimraf": "^5.0.0", + "typescript": "^4.0.0" + }, + "main": "dist/src/{index.js,functions/*.js}" +} diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts new file mode 100644 index 00000000..b7d366f1 --- /dev/null +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -0,0 +1,33 @@ +import { app, InvocationContext, Timer } from "@azure/functions"; +import { QueueServiceClient } from "@azure/storage-queue"; + +const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; +const queueServiceClient = QueueServiceClient.fromConnectionString(connectionString); + +export async function caDphTimerTrigger(myTimer: Timer, context: InvocationContext): Promise { + /* TODO - + - Figure out TF for the Azure function + - Make sure Azure Function has access to env vars + - Figure out local testing + - Figure out how to enqueue a message from here + - Create a new queue for timer triggers - probably one total, and the message is the customer? + - Create a DLQ for it + - Create a queue reader including dead lettering + - Profit? + */ + + // TODO - get queue name from env vars + const queueClient = queueServiceClient.getQueueClient("queuename") + + // TODO - check on options for send message + queueClient.sendMessage("cheezburger") + context.log('Timer function processed request.'); +} +// TODO - add info about installing typescript +// TODO - is .funcignore at the right level? +// TODO - set up the right CRON expression +// TODO - figure out how we make sure there's only one of these running +app.timer('caDphTimerTrigger', { + schedule: '0 */1 * * * *', + handler: caDphTimerTrigger +}); diff --git a/azure_functions/src/index.ts b/azure_functions/src/index.ts new file mode 100644 index 00000000..aa951f82 --- /dev/null +++ b/azure_functions/src/index.ts @@ -0,0 +1,5 @@ +import { app } from '@azure/functions'; + +app.setup({ + enableHttpStream: true, +}); diff --git a/azure_functions/tsconfig.json b/azure_functions/tsconfig.json new file mode 100644 index 00000000..77d91aa8 --- /dev/null +++ b/azure_functions/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "dist", + "rootDir": ".", + "sourceMap": true, + "strict": false + } +} From cba6b43611a0848c5835bfb394679e24767eeee0 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 16:12:28 -0500 Subject: [PATCH 11/57] update some TODOs Co-Authored-By: Samuel Aquino --- azure_functions/src/functions/caDphTimerTrigger.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index b7d366f1..891934d4 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -26,7 +26,8 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte // TODO - add info about installing typescript // TODO - is .funcignore at the right level? // TODO - set up the right CRON expression -// TODO - figure out how we make sure there's only one of these running +// TODO - figure out how we make sure there's only one Azure Function running +// TODO - figure out if we can add multiple timers (like one per external customer?) to the same function app.timer('caDphTimerTrigger', { schedule: '0 */1 * * * *', handler: caDphTimerTrigger From ffd27d8faef08ab818ce6970f8e69065c62ab05d Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 8 Jul 2024 18:00:19 -0500 Subject: [PATCH 12/57] Add a bunch more notes, start TF for new queue --- README.md | 2 +- .../src/functions/caDphTimerTrigger.ts | 11 +++++++++-- docker-compose.yml | 6 ++++-- operations/template/queue.tf | 18 ++++++++++++++---- src/cmd/main.go | 1 + src/orchestration/queue.go | 15 +++++++++++++-- 6 files changed, 42 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f5a2dc45..d1d6dfea 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ In the cloud, EventGrid monitors the blob storage container and sends file creat In the local Azurite tool, there are no events to connect the blob storage container to the queue. To mimic the deployed behavior so our app can read queue messages and access the file specified in the message: 1. Upload a file to your local Azurite sftp container -2. In Azure Storage Explorer, find the `blob-message-queue` that the service currently reads from +2. In Azure Storage Explorer, find the `message-import-queue` that the service currently reads from 3. Add a file create event message to that queue. You can start with this base message and edit the `subject` to match your newly-created file ```json diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index 891934d4..54995af0 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -18,7 +18,9 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte // TODO - get queue name from env vars const queueClient = queueServiceClient.getQueueClient("queuename") - + console.log(myTimer); + console.log(context); + context.extraInputs.get("customer") // TODO - check on options for send message queueClient.sendMessage("cheezburger") context.log('Timer function processed request.'); @@ -30,5 +32,10 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte // TODO - figure out if we can add multiple timers (like one per external customer?) to the same function app.timer('caDphTimerTrigger', { schedule: '0 */1 * * * *', - handler: caDphTimerTrigger + handler: caDphTimerTrigger, + // I don't think extraInputs is the right field, just messing around looking for + // whether we can pass in a variable - then we could use one handler for every + // customer that has a timer + // Possibly the name (in the first param above) could work for this? + // extraInputs: [{name: "customer", type: ""}] }); diff --git a/docker-compose.yml b/docker-compose.yml index 61dc83b4..746e572d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,8 +57,10 @@ services: - | az storage container create -n sftp az storage blob upload --overwrite --account-name devstoreaccount1 --container-name sftp --name order_message.hl7 --file mock_data/order_message.hl7 - az storage queue create -n blob-message-queue - az storage queue create -n blob-message-dead-letter-queue + az storage queue create -n message-import-queue + az storage queue create -n message-import-dead-letter-queue + az storage queue create -n polling-trigger-queue + az storage queue create -n polling-trigger-dead-letter-queue environment: AZURE_STORAGE_CONNECTION_STRING: DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://sftp-Azurite:10000/devstoreaccount1;QueueEndpoint=http://sftp-Azurite:10001/devstoreaccount1; # pragma: allowlist secret networks: diff --git a/operations/template/queue.tf b/operations/template/queue.tf index 2ca1de22..a8a3e3d3 100644 --- a/operations/template/queue.tf +++ b/operations/template/queue.tf @@ -1,9 +1,19 @@ -resource "azurerm_storage_queue" "message_queue" { - name = "blob-message-queue" +resource "azurerm_storage_queue" "message_import_queue" { + name = "message-import-queue" storage_account_name = azurerm_storage_account.storage.name } -resource "azurerm_storage_queue" "dead_letter_queue" { - name = "blob-message-dead-letter-queue" +resource "azurerm_storage_queue" "message_import_dead_letter_queue" { + name = "message-import-dead-letter-queue" + storage_account_name = azurerm_storage_account.storage.name +} + +resource "azurerm_storage_queue" "polling_trigger_queue" { + name = "polling-trigger-queue" + storage_account_name = azurerm_storage_account.storage.name +} + +resource "azurerm_storage_queue" "polling_trigger_dead_letter_queue" { + name = "polling-trigger-dead-letter-queue" storage_account_name = azurerm_storage_account.storage.name } diff --git a/src/cmd/main.go b/src/cmd/main.go index c5c1bcba..1a7625e5 100644 --- a/src/cmd/main.go +++ b/src/cmd/main.go @@ -33,6 +33,7 @@ func main() { sftpHandler.CopyFiles() + // TODO - add another queue listener for the other queue? Or maybe one listener for all queues but different message handling? // ListenToQueue is not split into a separate Go Routine since it is the core driver of the application queueHandler.ListenToQueue() } diff --git a/src/orchestration/queue.go b/src/orchestration/queue.go index a4f8971c..6601e2b6 100644 --- a/src/orchestration/queue.go +++ b/src/orchestration/queue.go @@ -27,21 +27,25 @@ type QueueClient interface { EnqueueMessage(ctx context.Context, content string, o *azqueue.EnqueueMessageOptions) (azqueue.EnqueueMessagesResponse, error) } +// TODO - pass in queue names? Have different queue handlers for the polling queue and the import queues? +// labeled each function based on whether it's specific to the import flow or not + func NewQueueHandler() (QueueHandler, error) { azureQueueConnectionString := os.Getenv("AZURE_STORAGE_CONNECTION_STRING") - client, err := azqueue.NewQueueClientFromConnectionString(azureQueueConnectionString, "blob-message-queue", nil) + client, err := azqueue.NewQueueClientFromConnectionString(azureQueueConnectionString, "message-import-queue", nil) if err != nil { slog.Error("Unable to create Azure Queue Client for primary queue", slog.Any(utils.ErrorKey, err)) return QueueHandler{}, err } - dlqClient, err := azqueue.NewQueueClientFromConnectionString(azureQueueConnectionString, "blob-message-dead-letter-queue", nil) + dlqClient, err := azqueue.NewQueueClientFromConnectionString(azureQueueConnectionString, "message-import-dead-letter-queue", nil) if err != nil { slog.Error("Unable to create Azure Queue Client for dead letter queue", slog.Any(utils.ErrorKey, err)) return QueueHandler{}, err } + // TODO - this is only relevant for the import queue, not the polling one usecase, err := usecases.NewReadAndSendUsecase() if err != nil { @@ -52,6 +56,7 @@ func NewQueueHandler() (QueueHandler, error) { return QueueHandler{queueClient: client, deadLetterQueueClient: dlqClient, usecase: &usecase}, nil } +// TODO - import-specific func getUrlFromMessage(messageText string) (string, error) { eventBytes, err := base64.StdEncoding.DecodeString(messageText) if err != nil { @@ -86,6 +91,7 @@ func getUrlFromMessage(messageText string) (string, error) { return eventUrl, nil } +// TODO - NOT import-specific func (receiver QueueHandler) deleteMessage(message azqueue.DequeuedMessage) error { messageId := *message.MessageID popReceipt := *message.PopReceipt @@ -101,6 +107,7 @@ func (receiver QueueHandler) deleteMessage(message azqueue.DequeuedMessage) erro return nil } +// TODO - partly import-specific. Will need updates or a new version that kicks off the SFTP code func (receiver QueueHandler) handleMessage(message azqueue.DequeuedMessage) error { slog.Info("Handling message", slog.String("id", *message.MessageID)) @@ -134,6 +141,7 @@ func (receiver QueueHandler) handleMessage(message azqueue.DequeuedMessage) erro return nil } +// TODO - NOT import-specific // overDeliveryThreshold checks whether the max delivery attempts for the message have been reached. // If the threshold has been reached, the message should go to dead letter storage. // Return true if we're over the threshold and should stop processing, else return false @@ -156,6 +164,7 @@ func (receiver QueueHandler) overDeliveryThreshold(message azqueue.DequeuedMessa return false } +// TODO - NOT import-specific func (receiver QueueHandler) deadLetter(message azqueue.DequeuedMessage) error { // a TimeToLive of -1 means the message will not expire @@ -177,6 +186,7 @@ func (receiver QueueHandler) deadLetter(message azqueue.DequeuedMessage) error { return nil } +// TODO - NOT import-specific func (receiver QueueHandler) ListenToQueue() { for { err := receiver.receiveQueue() @@ -187,6 +197,7 @@ func (receiver QueueHandler) ListenToQueue() { } } +// TODO - NOT import-specific func (receiver QueueHandler) receiveQueue() error { slog.Info("Trying to dequeue") From e503a12346421747bf455e7282e9964be5b40da2 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Tue, 9 Jul 2024 09:49:42 -0500 Subject: [PATCH 13/57] more TODO notes --- azure_functions/src/functions/caDphTimerTrigger.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index 54995af0..46629146 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -26,9 +26,10 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte context.log('Timer function processed request.'); } // TODO - add info about installing typescript +// TODO - figure out instructions for running this // TODO - is .funcignore at the right level? // TODO - set up the right CRON expression -// TODO - figure out how we make sure there's only one Azure Function running +// TODO - figure out how we make sure there's only one Azure Function running - we should alarm if there's more than one // TODO - figure out if we can add multiple timers (like one per external customer?) to the same function app.timer('caDphTimerTrigger', { schedule: '0 */1 * * * *', From 05a067d7ea3b4bbbd909e64da55c1eb416a52ba4 Mon Sep 17 00:00:00 2001 From: James Herr Date: Tue, 9 Jul 2024 14:26:39 -0500 Subject: [PATCH 14/57] Azure func terraform WIP --- operations/template/functions.tf | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 operations/template/functions.tf diff --git a/operations/template/functions.tf b/operations/template/functions.tf new file mode 100644 index 00000000..800ac310 --- /dev/null +++ b/operations/template/functions.tf @@ -0,0 +1,29 @@ +# resource for Azure Functions for SFTP +resource "azurerm_linux_function_app" "polling_trigger_function" { + name = "polling-function-${var.environment}" + location = data.azurerm_resource_group.group.location + resource_group_name = data.azurerm_resource_group.group.name + service_plan_id = azurerm_service_plan.plan.id + storage_account_name = azurerm_storage_account.storage.name + storage_account_access_key = azurerm_storage_account.storage.primary_access_key + + site_config {} +} + +resource "azurerm_linux_function_app_slot" "polling_trigger_function_slot" { + name = "polling-function-slot-${var.environment}" + function_app_id = azurerm_linux_function_app.polling_trigger_function.id + storage_account_name = azurerm_storage_account.storage.name + + site_config { + app_scale_limit = 1 + + app_service_logs { + retention_period_days = 60 + } + + application_stack { + node_version = "20" + } + } +} From c9b76c49e4a10b7879fc81a6cfb7842f61d7c4ad Mon Sep 17 00:00:00 2001 From: James Herr Date: Tue, 9 Jul 2024 15:10:24 -0500 Subject: [PATCH 15/57] Re-configure polling function app function Co-authored-by: saquino0827 Co-authored-by: Sylvie Co-authored-by: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/functions.tf | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 800ac310..84c07eba 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -1,5 +1,5 @@ # resource for Azure Functions for SFTP -resource "azurerm_linux_function_app" "polling_trigger_function" { +resource "azurerm_linux_function_app" "polling_trigger_function_app" { name = "polling-function-${var.environment}" location = data.azurerm_resource_group.group.location resource_group_name = data.azurerm_resource_group.group.name @@ -7,14 +7,6 @@ resource "azurerm_linux_function_app" "polling_trigger_function" { storage_account_name = azurerm_storage_account.storage.name storage_account_access_key = azurerm_storage_account.storage.primary_access_key - site_config {} -} - -resource "azurerm_linux_function_app_slot" "polling_trigger_function_slot" { - name = "polling-function-slot-${var.environment}" - function_app_id = azurerm_linux_function_app.polling_trigger_function.id - storage_account_name = azurerm_storage_account.storage.name - site_config { app_scale_limit = 1 @@ -27,3 +19,16 @@ resource "azurerm_linux_function_app_slot" "polling_trigger_function_slot" { } } } + +resource "azurerm_function_app_function" "polling_trigger_function_app_function" { + name = "polling-function-app-function-${var.environment}" + function_app_id = azurerm_linux_function_app.polling_trigger_function_app.id + language = "TypeScript" + + file { + name = "caDphTimerTrigger.ts" + content = file("../../azure_functions/src/functions/caDphTimerTrigger.ts") + } + + config_json = {} +} From fc540e548fc64a624b9f94d14ce67081aa188e5e Mon Sep 17 00:00:00 2001 From: James Herr Date: Tue, 9 Jul 2024 15:18:34 -0500 Subject: [PATCH 16/57] Attempting to fix Terraform errors Co-Authored-By: Samuel Aquino Co-Authored-By: Sylvie <38440028+somesylvie@users.noreply.github.com> --- operations/template/event.tf | 2 +- operations/template/functions.tf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/operations/template/event.tf b/operations/template/event.tf index 91872c92..c10894d5 100644 --- a/operations/template/event.tf +++ b/operations/template/event.tf @@ -18,7 +18,7 @@ resource "azurerm_eventgrid_system_topic_event_subscription" "topic_sub" { system_topic = azurerm_eventgrid_system_topic.topic.name storage_queue_endpoint { - queue_name = azurerm_storage_queue.message_queue.name + queue_name = azurerm_storage_queue.message_import_queue.name storage_account_id = azurerm_storage_account.storage.id queue_message_time_to_live_in_seconds = 604800 # 7 days in seconds } diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 84c07eba..2b0cc51e 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -27,8 +27,8 @@ resource "azurerm_function_app_function" "polling_trigger_function_app_function" file { name = "caDphTimerTrigger.ts" - content = file("../../azure_functions/src/functions/caDphTimerTrigger.ts") + content = file("../../../azure_functions/src/functions/caDphTimerTrigger.ts") } - config_json = {} + config_json = "{}" } From 59445d045bf25f459f2d9f074d97646bab25ac16 Mon Sep 17 00:00:00 2001 From: James Herr Date: Tue, 9 Jul 2024 15:30:07 -0500 Subject: [PATCH 17/57] Attempting fix for Terraform errors Co-Authored-By: Samuel Aquino Co-Authored-By: Sylvie <38440028+somesylvie@users.noreply.github.com> --- operations/template/functions.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 2b0cc51e..11409927 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -26,8 +26,8 @@ resource "azurerm_function_app_function" "polling_trigger_function_app_function" language = "TypeScript" file { - name = "caDphTimerTrigger.ts" - content = file("../../../azure_functions/src/functions/caDphTimerTrigger.ts") + name = "index.ts" + content = file("../../../azure_functions/src/index.ts") } config_json = "{}" From 8ff0219460dd881cec1f325fceb0a7f76a875c9e Mon Sep 17 00:00:00 2001 From: James Herr Date: Tue, 9 Jul 2024 16:13:05 -0500 Subject: [PATCH 18/57] WIP functions Terraform Co-Authored-By: Samuel Aquino Co-Authored-By: Sylvie <38440028+somesylvie@users.noreply.github.com> --- operations/template/functions.tf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 11409927..42d2ff90 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -10,6 +10,9 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { site_config { app_scale_limit = 1 + # TODO - verify this is good advice + # always_on = true + app_service_logs { retention_period_days = 60 } @@ -18,8 +21,12 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { node_version = "20" } } + + } +# TODO - ChatGPT suggests we should use a github action instead of the function app function + resource "azurerm_function_app_function" "polling_trigger_function_app_function" { name = "polling-function-app-function-${var.environment}" function_app_id = azurerm_linux_function_app.polling_trigger_function_app.id From 010ff298c214f47646c6e7d249012eaaf00d8944 Mon Sep 17 00:00:00 2001 From: saquino0827 Date: Wed, 10 Jul 2024 11:05:42 -0500 Subject: [PATCH 19/57] Add template for function app function deployment Co-authored-by: pluckyswan <96704946+pluckyswan@users.noreply.github.com> Co-authored-by: James Herr --- .github/workflows/functions-deploy.yml | 79 ++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .github/workflows/functions-deploy.yml diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml new file mode 100644 index 00000000..30b28137 --- /dev/null +++ b/.github/workflows/functions-deploy.yml @@ -0,0 +1,79 @@ +# This workflow will build a container and deploy it to an Azure Functions App on Linux when a commit is pushed to your default branch. +# +# This workflow assumes you have already created the target Azure Functions app. +# For instructions see https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-function-linux-custom-image?tabs=in-process%2Cbash%2Cazure-cli&pivots=programming-language-csharp +# +# To configure this workflow: +# 1. Set up the following secrets in your repository: +# - AZURE_RBAC_CREDENTIALS +# - REGISTRY_USERNAME +# - REGISTRY_PASSWORD +# 2. Change env variables for your configuration. +# +# For more information on: +# - GitHub Actions for Azure: https://github.com/Azure/Actions +# - Azure Functions Container Action: https://github.com/Azure/functions-container-action +# - Azure Service Principal for RBAC: https://github.com/Azure/functions-action#using-azure-service-principal-for-rbac-as-deployment-credential +# +# For more samples to get started with GitHub Action workflows to deploy to Azure: https://github.com/Azure/actions-workflow-samples/tree/master/FunctionApp + +name: Deploy container to Azure Functions App + +on: + push: + branches: ["main"] + +permissions: + contents: read + +env: + AZURE_FUNCTIONAPP_NAME: 'your-app-name' # set this to your function app name on Azure + LOGIN_SERVER: 'login-server' # set this to login server for your private container registry (e.g. 'contoso.azurecr.io', 'index.docker.io' ) + REGISTRY: 'your-registry' # set this to proper value for REGISTRY + NAMESPACE: 'your-namespace' # set this to proper value for NAMESPACE + IMAGE: 'your-image' # set this to proper value for IMAGE + TAG: 'your-tag' # set this to proper value for TAG + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + environment: dev + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@v4 + + - name: 'Login via Azure CLI' + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_RBAC_CREDENTIALS }} + + - name: 'Docker Login' + uses: azure/docker-login@v1 + with: + login-server: ${{ env.LOGIN_SERVER }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: 'Compose Customized Docker Image' + shell: bash + run: | + # If your function app project is not located in your repository's root + # Please change the path to your directory for docker build + docker build . -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }} + docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }} + + - name: 'Run Azure Functions Container Action' + uses: Azure/functions-container-action@v1 + id: fa + with: + app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} + image: ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }} + + # If you want to display or use the functionapp url, then uncomment the task below + #- name: 'Published functionapp url' + # run: | + # echo "${{ steps.fa.outputs.app-url }}" + + - name: Azure logout + run: | + az logout From d76a64b7b532f166b982e41924d7d187a6850128 Mon Sep 17 00:00:00 2001 From: Bella Luz Quintero Date: Wed, 10 Jul 2024 11:03:53 -0600 Subject: [PATCH 20/57] created github workflow for node js function app Co-authored-by: saquino0827 Co-authored-by: James Herr Co-authored-by: Sylvie --- .github/workflows/functions-deploy.yml | 60 ++++++++++---------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 30b28137..05a66486 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -17,63 +17,47 @@ # # For more samples to get started with GitHub Action workflows to deploy to Azure: https://github.com/Azure/actions-workflow-samples/tree/master/FunctionApp -name: Deploy container to Azure Functions App +name: Deploy Node.js project to Azure Function App on: push: - branches: ["main"] + branches: + - internal permissions: contents: read env: - AZURE_FUNCTIONAPP_NAME: 'your-app-name' # set this to your function app name on Azure - LOGIN_SERVER: 'login-server' # set this to login server for your private container registry (e.g. 'contoso.azurecr.io', 'index.docker.io' ) - REGISTRY: 'your-registry' # set this to proper value for REGISTRY - NAMESPACE: 'your-namespace' # set this to proper value for NAMESPACE - IMAGE: 'your-image' # set this to proper value for IMAGE - TAG: 'your-tag' # set this to proper value for TAG + AZURE_FUNCTIONAPP_NAME: 'testTimer' + AZURE_FUNCTIONAPP_PACKAGE_PATH: './azure_functions' + NODE_VERSION: '20.x' jobs: build-and-deploy: runs-on: ubuntu-latest - environment: dev + environment: ${{ inputs.ENVIRONMENT }} steps: - name: 'Checkout GitHub Action' - uses: actions/checkout@v4 + uses: actions/checkout@v3 - - name: 'Login via Azure CLI' - uses: azure/login@v1 + - name: Setup Node ${{ env.NODE_VERSION }} Environment + uses: actions/setup-node@v3 with: - creds: ${{ secrets.AZURE_RBAC_CREDENTIALS }} + node-version: ${{ env.NODE_VERSION }} - - name: 'Docker Login' - uses: azure/docker-login@v1 - with: - login-server: ${{ env.LOGIN_SERVER }} - username: ${{ secrets.REGISTRY_USERNAME }} - password: ${{ secrets.REGISTRY_PASSWORD }} - - - name: 'Compose Customized Docker Image' + - name: 'Resolve Project Dependencies Using Npm' shell: bash run: | - # If your function app project is not located in your repository's root - # Please change the path to your directory for docker build - docker build . -t ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }} - docker push ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }} - - - name: 'Run Azure Functions Container Action' - uses: Azure/functions-container-action@v1 + pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' + npm install + npm run build --if-present + npm run test --if-present + popd + + - name: 'Run Azure Functions Action' + uses: Azure/functions-action@v1 id: fa with: app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} - image: ${{ env.REGISTRY }}/${{ env.NAMESPACE }}/${{ env.IMAGE }}:${{ env.TAG }} - - # If you want to display or use the functionapp url, then uncomment the task below - #- name: 'Published functionapp url' - # run: | - # echo "${{ steps.fa.outputs.app-url }}" - - - name: Azure logout - run: | - az logout + package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }} From d65a8eb41b3191b79fb47d78c4cf49f34066ebcf Mon Sep 17 00:00:00 2001 From: Bella Luz Quintero Date: Wed, 10 Jul 2024 11:20:14 -0600 Subject: [PATCH 21/57] updated function workflow call Co-authored-by: saquino0827 Co-authored-by: Sylvie Co-authored-by: James Herr --- .github/workflows/functions-deploy.yml | 4 +--- .github/workflows/internal-deploy.yml | 14 ++++++++++++++ azure_functions/src/functions/caDphTimerTrigger.ts | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 05a66486..48849811 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -20,9 +20,7 @@ name: Deploy Node.js project to Azure Function App on: - push: - branches: - - internal + workflow_dispatch: permissions: contents: read diff --git a/.github/workflows/internal-deploy.yml b/.github/workflows/internal-deploy.yml index 9e4e42b9..5bfb9969 100644 --- a/.github/workflows/internal-deploy.yml +++ b/.github/workflows/internal-deploy.yml @@ -32,3 +32,17 @@ jobs: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + function-deploy: + name: Function Deploy + needs: terraform-deploy + uses: ./.github/workflows/functions-deploy.yml + with: + ENVIRONMENT: internal + REPO: report-stream-sftp-ingest + APP: ${{ needs.terraform-deploy.outputs.APP }} + REGISTRY: ${{ needs.terraform-deploy.outputs.REGISTRY }} + secrets: + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index 46629146..e80e26ba 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -31,6 +31,7 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte // TODO - set up the right CRON expression // TODO - figure out how we make sure there's only one Azure Function running - we should alarm if there's more than one // TODO - figure out if we can add multiple timers (like one per external customer?) to the same function +// TODO - find out the timer's timezone for scheduling app.timer('caDphTimerTrigger', { schedule: '0 */1 * * * *', handler: caDphTimerTrigger, From a211db87af5be9bb30bc9bad50ed15bf357504da Mon Sep 17 00:00:00 2001 From: Bella Luz Quintero Date: Wed, 10 Jul 2024 11:24:11 -0600 Subject: [PATCH 22/57] updated call to function workflow Co-authored-by: saquino0827 Co-authored-by: Sylvie --- .github/workflows/functions-deploy.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 48849811..099d1768 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -20,7 +20,27 @@ name: Deploy Node.js project to Azure Function App on: - workflow_dispatch: + workflow_call: + inputs: + ENVIRONMENT: + required: true + type: string + REGISTRY: + required: true + type: string + REPO: + required: true + type: string + APP: + required: true + type: string + secrets: + AZURE_CLIENT_ID: + required: true + AZURE_TENANT_ID: + required: true + AZURE_SUBSCRIPTION_ID: + required: true permissions: contents: read From 874f6a9db447ecef1a96c3e8a83d6acb97d17cd6 Mon Sep 17 00:00:00 2001 From: saquino0827 Date: Thu, 11 Jul 2024 15:51:06 -0500 Subject: [PATCH 23/57] Update github functions workflow with internal function publish profile secret Co-authored-by: James Herr Co-authored-by: pluckyswan <96704946+pluckyswan@users.noreply.github.com> Co-authored-by: Sylvie --- .github/workflows/functions-deploy.yml | 2 ++ .github/workflows/internal-deploy.yml | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 099d1768..f256930f 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -41,6 +41,8 @@ on: required: true AZURE_SUBSCRIPTION_ID: required: true + AZURE_FUNCTIONAPP_PUBLISH_PROFILE: + required: true permissions: contents: read diff --git a/.github/workflows/internal-deploy.yml b/.github/workflows/internal-deploy.yml index 5bfb9969..edb05369 100644 --- a/.github/workflows/internal-deploy.yml +++ b/.github/workflows/internal-deploy.yml @@ -1,6 +1,10 @@ name: Deploy to Internal Environment on: + workflow_call: + secrets: + AZURE_FUNCTIONAPP_PUBLISH_PROFILE_INTERNAL: + required: true push: branches: - internal @@ -46,3 +50,4 @@ jobs: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + AZURE_FUNCTIONAPP_PUBLISH_PROFILE: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE_INTERNAL }} From b047f88782c14d760f71c9d5c9da76de008aa114 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Thu, 11 Jul 2024 16:51:03 -0500 Subject: [PATCH 24/57] re-remove the unneeded TF Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/functions.tf | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 42d2ff90..fe44b3d4 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -24,18 +24,3 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { } - -# TODO - ChatGPT suggests we should use a github action instead of the function app function - -resource "azurerm_function_app_function" "polling_trigger_function_app_function" { - name = "polling-function-app-function-${var.environment}" - function_app_id = azurerm_linux_function_app.polling_trigger_function_app.id - language = "TypeScript" - - file { - name = "index.ts" - content = file("../../../azure_functions/src/index.ts") - } - - config_json = "{}" -} From a21dca92a7189ed3b3a4f45acf4b6ab7990d4144 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Thu, 11 Jul 2024 16:55:26 -0500 Subject: [PATCH 25/57] copy changes out of yesterday's `internal` branch Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- .github/workflows/functions-deploy.yml | 21 +++++++++++++++++---- operations/template/functions.tf | 10 +++++++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index f256930f..af2e7184 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -48,20 +48,26 @@ permissions: contents: read env: - AZURE_FUNCTIONAPP_NAME: 'testTimer' + # AZURE_FUNCTIONAPP_NAME has to match the azurerm_linux_function_app's name in functions.tf + AZURE_FUNCTIONAPP_NAME: 'polling-function-${{ inputs.ENVIRONMENT }}' AZURE_FUNCTIONAPP_PACKAGE_PATH: './azure_functions' NODE_VERSION: '20.x' jobs: build-and-deploy: runs-on: ubuntu-latest - environment: ${{ inputs.ENVIRONMENT }} + environment: + ${{ inputs.ENVIRONMENT }} + permissions: + id-token: write + contents: read + steps: - name: 'Checkout GitHub Action' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Node ${{ env.NODE_VERSION }} Environment - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} @@ -74,6 +80,13 @@ jobs: npm run test --if-present popd + - name: Login via Azure CLI + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + - name: 'Run Azure Functions Action' uses: Azure/functions-action@v1 id: fa diff --git a/operations/template/functions.tf b/operations/template/functions.tf index fe44b3d4..5443f586 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -6,6 +6,8 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { service_plan_id = azurerm_service_plan.plan.id storage_account_name = azurerm_storage_account.storage.name storage_account_access_key = azurerm_storage_account.storage.primary_access_key + application_insights_connection_string = azurerm_application_insights.function_app_insights.connection_string + application_insights_key = azurerm_application_insights.function_app_insights.instrumentation_key site_config { app_scale_limit = 1 @@ -21,6 +23,12 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { node_version = "20" } } +} - +resource "azurerm_application_insights" "function_app_insights" { + name = "functionapp-insights-${var.environment}" + location = data.azurerm_resource_group.group.location + resource_group_name = data.azurerm_resource_group.group.name + workspace_id = azurerm_log_analytics_workspace.logs_workspace.id + application_type = "Node.JS" } From 3b227f6154dfe9ced4b8a3a565755d0786eedd68 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Thu, 11 Jul 2024 16:58:22 -0500 Subject: [PATCH 26/57] put application insights in the right section Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/functions.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 5443f586..96cc409e 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -6,11 +6,11 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { service_plan_id = azurerm_service_plan.plan.id storage_account_name = azurerm_storage_account.storage.name storage_account_access_key = azurerm_storage_account.storage.primary_access_key - application_insights_connection_string = azurerm_application_insights.function_app_insights.connection_string - application_insights_key = azurerm_application_insights.function_app_insights.instrumentation_key site_config { app_scale_limit = 1 + application_insights_connection_string = azurerm_application_insights.function_app_insights.connection_string + application_insights_key = azurerm_application_insights.function_app_insights.instrumentation_key # TODO - verify this is good advice # always_on = true From 22b1a7d64809d47db0d265430465bc9629746c06 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Thu, 11 Jul 2024 17:44:22 -0500 Subject: [PATCH 27/57] change a setting to cause terraform changes Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- operations/template/functions.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 96cc409e..b1c1d936 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -13,7 +13,7 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { application_insights_key = azurerm_application_insights.function_app_insights.instrumentation_key # TODO - verify this is good advice - # always_on = true + always_on = true app_service_logs { retention_period_days = 60 From d4b1aeb66f87a6941837d4295156ab2c212ff5a4 Mon Sep 17 00:00:00 2001 From: James Herr Date: Fri, 12 Jul 2024 11:23:44 -0500 Subject: [PATCH 28/57] Added GetPublishProfile step Co-Authored-By: Samuel Aquino Co-Authored-By: Sylvie <38440028+somesylvie@users.noreply.github.com> Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- .github/workflows/functions-deploy.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index af2e7184..196c0dba 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -87,10 +87,15 @@ jobs: tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + - name: 'Get Publish Profile' + run: | + echo "::set-output name=PUBLISH_PROFILE::$(az webapp deployment list-publishing-profiles -g 'csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg' -n 'polling-function-${{ var.environment }}' --xml)" + id: getPublishProfile + - name: 'Run Azure Functions Action' uses: Azure/functions-action@v1 id: fa with: app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }} + publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} \ No newline at end of file From e44e743388eb6b5df7ee6f0b3bf3b1466383a9b8 Mon Sep 17 00:00:00 2001 From: James Herr Date: Fri, 12 Jul 2024 11:25:50 -0500 Subject: [PATCH 29/57] Renamed function step Co-Authored-By: Samuel Aquino Co-Authored-By: Sylvie <38440028+somesylvie@users.noreply.github.com> Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- .github/workflows/functions-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 196c0dba..9e9361f7 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -94,7 +94,7 @@ jobs: - name: 'Run Azure Functions Action' uses: Azure/functions-action@v1 - id: fa + id: azure-function-deploy with: app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} From 13bd37f68e63b12a03560cebbcbb64612a4f1bd4 Mon Sep 17 00:00:00 2001 From: James Herr Date: Fri, 12 Jul 2024 11:31:05 -0500 Subject: [PATCH 30/57] Fixed env variable name Co-Authored-By: Samuel Aquino Co-Authored-By: Sylvie <38440028+somesylvie@users.noreply.github.com> Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- .github/workflows/functions-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 9e9361f7..fe560efc 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -89,7 +89,7 @@ jobs: - name: 'Get Publish Profile' run: | - echo "::set-output name=PUBLISH_PROFILE::$(az webapp deployment list-publishing-profiles -g 'csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg' -n 'polling-function-${{ var.environment }}' --xml)" + echo "::set-output name=PUBLISH_PROFILE::$(az webapp deployment list-publishing-profiles -g 'csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg' -n 'polling-function-${{ inputs.environment }}' --xml)" id: getPublishProfile - name: 'Run Azure Functions Action' From 4698f27731ed96abcb457c505c872c0a71153c4b Mon Sep 17 00:00:00 2001 From: James Herr Date: Fri, 12 Jul 2024 11:45:08 -0500 Subject: [PATCH 31/57] Removed deprecated set-output and masked the publish profile Co-Authored-By: Samuel Aquino Co-Authored-By: Sylvie <38440028+somesylvie@users.noreply.github.com> Co-Authored-By: pluckyswan <96704946+pluckyswan@users.noreply.github.com> --- .github/workflows/functions-deploy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index fe560efc..dcb8f9e9 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -89,7 +89,9 @@ jobs: - name: 'Get Publish Profile' run: | - echo "::set-output name=PUBLISH_PROFILE::$(az webapp deployment list-publishing-profiles -g 'csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg' -n 'polling-function-${{ inputs.environment }}' --xml)" + PUBLISH_PROFILE=$(az webapp deployment list-publishing-profiles -g "csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg" -n "polling-function-${{ inputs.ENVIRONMENT }}" --xml) + echo "::add-mask::$PUBLISH_PROFILE" + echo "PUBLISH_PROFILE=$PUBLISH_PROFILE" >> $GITHUB_OUTPUT id: getPublishProfile - name: 'Run Azure Functions Action' From 094579ad3e6d57e9e1bc1ba0cd73e01773ec4d02 Mon Sep 17 00:00:00 2001 From: James Herr Date: Mon, 15 Jul 2024 09:22:13 -0500 Subject: [PATCH 32/57] Adding directory log for troubleshooting --- .github/workflows/functions-deploy.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index dcb8f9e9..1f1b73aa 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -66,7 +66,7 @@ jobs: - name: 'Checkout GitHub Action' uses: actions/checkout@v4 - - name: Setup Node ${{ env.NODE_VERSION }} Environment + - name: 'Setup Node ${{ env.NODE_VERSION }} Environment' uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} @@ -80,7 +80,12 @@ jobs: npm run test --if-present popd - - name: Login via Azure CLI + + - name: 'List Directory Contents' + run: | + ls -R ./${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + + - name: 'Login via Azure CLI' uses: azure/login@v2 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} @@ -100,4 +105,4 @@ jobs: with: app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} \ No newline at end of file + publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} From 1f6f75e2863c24572c61dcbac731ea8299acaa9f Mon Sep 17 00:00:00 2001 From: James Herr Date: Mon, 15 Jul 2024 09:29:40 -0500 Subject: [PATCH 33/57] Testing new path --- .github/workflows/functions-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 1f1b73aa..1650d5c7 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -50,7 +50,7 @@ permissions: env: # AZURE_FUNCTIONAPP_NAME has to match the azurerm_linux_function_app's name in functions.tf AZURE_FUNCTIONAPP_NAME: 'polling-function-${{ inputs.ENVIRONMENT }}' - AZURE_FUNCTIONAPP_PACKAGE_PATH: './azure_functions' + AZURE_FUNCTIONAPP_PACKAGE_PATH: './azure_functions/dist' NODE_VERSION: '20.x' jobs: From 14499535b876d12577e858794bd5a5f2d26fe307 Mon Sep 17 00:00:00 2001 From: James Herr Date: Mon, 15 Jul 2024 09:33:44 -0500 Subject: [PATCH 34/57] Testing function.json --- .github/workflows/functions-deploy.yml | 2 +- azure_functions/src/functions/function.json | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 azure_functions/src/functions/function.json diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 1650d5c7..1f1b73aa 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -50,7 +50,7 @@ permissions: env: # AZURE_FUNCTIONAPP_NAME has to match the azurerm_linux_function_app's name in functions.tf AZURE_FUNCTIONAPP_NAME: 'polling-function-${{ inputs.ENVIRONMENT }}' - AZURE_FUNCTIONAPP_PACKAGE_PATH: './azure_functions/dist' + AZURE_FUNCTIONAPP_PACKAGE_PATH: './azure_functions' NODE_VERSION: '20.x' jobs: diff --git a/azure_functions/src/functions/function.json b/azure_functions/src/functions/function.json new file mode 100644 index 00000000..1e02813f --- /dev/null +++ b/azure_functions/src/functions/function.json @@ -0,0 +1,11 @@ +{ + "bindings": [ + { + "name": "myTimer", + "type": "timerTrigger", + "direction": "in", + "schedule": "0 */5 * * * *" + } + ], + "scriptFile": "caDphTimerTrigger.js" +} From 27325151bb8f3b3b4196db49d766c66278d4a208 Mon Sep 17 00:00:00 2001 From: James Herr Date: Mon, 15 Jul 2024 09:39:29 -0500 Subject: [PATCH 35/57] Fixed file type --- azure_functions/src/functions/function.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure_functions/src/functions/function.json b/azure_functions/src/functions/function.json index 1e02813f..1da0f0a9 100644 --- a/azure_functions/src/functions/function.json +++ b/azure_functions/src/functions/function.json @@ -7,5 +7,5 @@ "schedule": "0 */5 * * * *" } ], - "scriptFile": "caDphTimerTrigger.js" + "scriptFile": "caDphTimerTrigger.ts" } From f70bc06863ee6df8e473fbaf6895f8f5a3dfe62c Mon Sep 17 00:00:00 2001 From: James Herr Date: Mon, 15 Jul 2024 09:40:11 -0500 Subject: [PATCH 36/57] Fixed name --- azure_functions/src/functions/function.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure_functions/src/functions/function.json b/azure_functions/src/functions/function.json index 1da0f0a9..7cd46a53 100644 --- a/azure_functions/src/functions/function.json +++ b/azure_functions/src/functions/function.json @@ -1,7 +1,7 @@ { "bindings": [ { - "name": "myTimer", + "name": "caDphTimerTrigger", "type": "timerTrigger", "direction": "in", "schedule": "0 */5 * * * *" From b50feb17d6f4e7248630d56ec255e9240b61369f Mon Sep 17 00:00:00 2001 From: James Herr Date: Mon, 15 Jul 2024 09:47:25 -0500 Subject: [PATCH 37/57] Renamed file to js --- azure_functions/src/functions/function.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure_functions/src/functions/function.json b/azure_functions/src/functions/function.json index 7cd46a53..3593c72d 100644 --- a/azure_functions/src/functions/function.json +++ b/azure_functions/src/functions/function.json @@ -7,5 +7,5 @@ "schedule": "0 */5 * * * *" } ], - "scriptFile": "caDphTimerTrigger.ts" + "scriptFile": "caDphTimerTrigger.js" } From ba1b89dff10b5712f700b3ea057dd52a6ba49d24 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 10:12:49 -0500 Subject: [PATCH 38/57] update package path var for consistency; remove unneeded fuction.json Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 6 +++--- azure_functions/src/functions/function.json | 11 ----------- 2 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 azure_functions/src/functions/function.json diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 1f1b73aa..2554810c 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -50,7 +50,7 @@ permissions: env: # AZURE_FUNCTIONAPP_NAME has to match the azurerm_linux_function_app's name in functions.tf AZURE_FUNCTIONAPP_NAME: 'polling-function-${{ inputs.ENVIRONMENT }}' - AZURE_FUNCTIONAPP_PACKAGE_PATH: './azure_functions' + AZURE_FUNCTIONAPP_PACKAGE_PATH: '././azure_functions' NODE_VERSION: '20.x' jobs: @@ -74,7 +74,7 @@ jobs: - name: 'Resolve Project Dependencies Using Npm' shell: bash run: | - pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' + pushd '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' npm install npm run build --if-present npm run test --if-present @@ -83,7 +83,7 @@ jobs: - name: 'List Directory Contents' run: | - ls -R ./${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + ls -R ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - name: 'Login via Azure CLI' uses: azure/login@v2 diff --git a/azure_functions/src/functions/function.json b/azure_functions/src/functions/function.json deleted file mode 100644 index 7cd46a53..00000000 --- a/azure_functions/src/functions/function.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "bindings": [ - { - "name": "caDphTimerTrigger", - "type": "timerTrigger", - "direction": "in", - "schedule": "0 */5 * * * *" - } - ], - "scriptFile": "caDphTimerTrigger.ts" -} From c39432607e35351cc44860ef79218e582275b180 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 10:19:11 -0500 Subject: [PATCH 39/57] install azure functions core tools Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- azure_functions/package-lock.json | 395 ++++++++++++++++++++++++++---- azure_functions/package.json | 3 +- 2 files changed, 346 insertions(+), 52 deletions(-) diff --git a/azure_functions/package-lock.json b/azure_functions/package-lock.json index fac49465..42407c4c 100644 --- a/azure_functions/package-lock.json +++ b/azure_functions/package-lock.json @@ -9,7 +9,8 @@ "version": "1.0.0", "dependencies": { "@azure/functions": "^4.0.0", - "@azure/storage-queue": "^12.22.0" + "@azure/storage-queue": "^12.22.0", + "azure-functions-core-tools": "^4.0.5907" }, "devDependencies": { "@types/node": "^20.x", @@ -247,7 +248,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -264,7 +264,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" @@ -294,7 +293,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, "engines": { "node": ">=12" }, @@ -306,7 +304,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "engines": { "node": ">=12" }, @@ -314,17 +311,349 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/azure-functions-core-tools": { + "version": "4.0.5907", + "resolved": "https://registry.npmjs.org/azure-functions-core-tools/-/azure-functions-core-tools-4.0.5907.tgz", + "integrity": "sha512-QeyBf/9Z3sziPXIU7fGcLgCFhXLo+uO3ILLvbb0Zse46VC5SWWfscbAb023xoUXhWXlf7KXjWwvKgyJpAeG20A==", + "hasInstallScript": true, + "hasShrinkwrap": true, + "os": [ + "win32", + "darwin", + "linux" + ], + "dependencies": { + "chalk": "3.0.0", + "extract-zip": "^2.0.1", + "https-proxy-agent": "5.0.0", + "progress": "2.0.3", + "rimraf": "4.4.1" + }, + "bin": { + "azfun": "lib/main.js", + "azurefunctions": "lib/main.js", + "func": "lib/main.js" + }, + "engines": { + "node": ">=6.9.1" + } + }, + "node_modules/azure-functions-core-tools/node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "node_modules/azure-functions-core-tools/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", + "optional": true + }, + "node_modules/azure-functions-core-tools/node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/azure-functions-core-tools/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/azure-functions-core-tools/node_modules/ansi-styles": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.0.tgz", + "integrity": "sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg==", + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/azure-functions-core-tools/node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "node_modules/azure-functions-core-tools/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/azure-functions-core-tools/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "engines": { + "node": "*" + } + }, + "node_modules/azure-functions-core-tools/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/azure-functions-core-tools/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/azure-functions-core-tools/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/azure-functions-core-tools/node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/azure-functions-core-tools/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/azure-functions-core-tools/node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/azure-functions-core-tools/node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/azure-functions-core-tools/node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/azure-functions-core-tools/node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/azure-functions-core-tools/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/azure-functions-core-tools/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/azure-functions-core-tools/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/azure-functions-core-tools/node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/azure-functions-core-tools/node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/azure-functions-core-tools/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/azure-functions-core-tools/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/azure-functions-core-tools/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/azure-functions-core-tools/node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/azure-functions-core-tools/node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/azure-functions-core-tools/node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" + }, + "node_modules/azure-functions-core-tools/node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/azure-functions-core-tools/node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/azure-functions-core-tools/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/azure-functions-core-tools/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/azure-functions-core-tools/node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/azure-functions-core-tools/node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -333,7 +662,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -344,8 +672,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/cookie": { "version": "0.6.0", @@ -359,7 +686,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -388,14 +714,12 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/fast-xml-parser": { "version": "4.4.0", @@ -422,7 +746,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", - "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -438,7 +761,6 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", - "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -485,7 +807,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -493,14 +814,12 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/jackspeak": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", - "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -523,7 +842,6 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, "engines": { "node": ">=18" } @@ -532,7 +850,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -547,7 +864,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -560,14 +876,12 @@ "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -576,7 +890,6 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -592,7 +905,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.8.tgz", "integrity": "sha512-XSh0V2/yNhDEi8HwdIefD8MLgs4LQXPag/nEJWs3YUc3Upn+UHa1GyIkEg9xSSNt7HnkO5FjTvmcRzgf+8UZuw==", - "dev": true, "dependencies": { "glob": "^10.3.7" }, @@ -610,7 +922,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -622,7 +933,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -631,7 +941,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "engines": { "node": ">=14" }, @@ -643,7 +952,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -661,7 +969,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -675,7 +982,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -683,14 +989,12 @@ "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -702,7 +1006,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -718,7 +1021,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -730,7 +1032,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -779,7 +1080,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -794,7 +1094,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -812,7 +1111,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -829,7 +1127,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -838,7 +1135,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -852,14 +1148,12 @@ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -873,7 +1167,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, diff --git a/azure_functions/package.json b/azure_functions/package.json index 090d3094..6e3278df 100644 --- a/azure_functions/package.json +++ b/azure_functions/package.json @@ -12,7 +12,8 @@ }, "dependencies": { "@azure/functions": "^4.0.0", - "@azure/storage-queue": "^12.22.0" + "@azure/storage-queue": "^12.22.0", + "azure-functions-core-tools": "^4.0.5907" }, "devDependencies": { "@types/node": "^20.x", From a6bbb852c1d69e55fbccec5297dde495d7509690 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 10:43:37 -0500 Subject: [PATCH 40/57] updating pathing to match examples Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 6 +++--- azure_functions/package.json | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 2554810c..bddede3f 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -50,7 +50,7 @@ permissions: env: # AZURE_FUNCTIONAPP_NAME has to match the azurerm_linux_function_app's name in functions.tf AZURE_FUNCTIONAPP_NAME: 'polling-function-${{ inputs.ENVIRONMENT }}' - AZURE_FUNCTIONAPP_PACKAGE_PATH: '././azure_functions' + AZURE_FUNCTIONAPP_PACKAGE_PATH: 'azure_functions' NODE_VERSION: '20.x' jobs: @@ -74,7 +74,7 @@ jobs: - name: 'Resolve Project Dependencies Using Npm' shell: bash run: | - pushd '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' + pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}' npm install npm run build --if-present npm run test --if-present @@ -83,7 +83,7 @@ jobs: - name: 'List Directory Contents' run: | - ls -R ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} + ls -R ./${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - name: 'Login via Azure CLI' uses: azure/login@v2 diff --git a/azure_functions/package.json b/azure_functions/package.json index 6e3278df..f21e181c 100644 --- a/azure_functions/package.json +++ b/azure_functions/package.json @@ -16,6 +16,7 @@ "azure-functions-core-tools": "^4.0.5907" }, "devDependencies": { + "azure-functions-core-tools": "^4.x", "@types/node": "^20.x", "rimraf": "^5.0.0", "typescript": "^4.0.0" From 5fdbf4b21038438ad50a88ce366503c0f2ea10ff Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 11:06:54 -0500 Subject: [PATCH 41/57] comment out code that won't work yet; add a new setting to function app Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- azure_functions/src/functions/caDphTimerTrigger.ts | 6 +++--- operations/template/functions.tf | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index e80e26ba..ece53a84 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -17,12 +17,12 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte */ // TODO - get queue name from env vars - const queueClient = queueServiceClient.getQueueClient("queuename") + // const queueClient = queueServiceClient.getQueueClient("queuename") console.log(myTimer); console.log(context); - context.extraInputs.get("customer") + // context.extraInputs.get("customer") // TODO - check on options for send message - queueClient.sendMessage("cheezburger") + // queueClient.sendMessage("cheezburger") context.log('Timer function processed request.'); } // TODO - add info about installing typescript diff --git a/operations/template/functions.tf b/operations/template/functions.tf index b1c1d936..50877879 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -7,6 +7,10 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { storage_account_name = azurerm_storage_account.storage.name storage_account_access_key = azurerm_storage_account.storage.primary_access_key + app_settings { + WEBSITE_RUN_FROM_PACKAGE = 1 + } + site_config { app_scale_limit = 1 application_insights_connection_string = azurerm_application_insights.function_app_insights.connection_string From 2b6ed669b7e6916948e7fca099b7bab44e7b4d16 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 11:08:39 -0500 Subject: [PATCH 42/57] take out app_settings because the tf docs are wrong Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- operations/template/functions.tf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 50877879..b1c1d936 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -7,10 +7,6 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { storage_account_name = azurerm_storage_account.storage.name storage_account_access_key = azurerm_storage_account.storage.primary_access_key - app_settings { - WEBSITE_RUN_FROM_PACKAGE = 1 - } - site_config { app_scale_limit = 1 application_insights_connection_string = azurerm_application_insights.function_app_insights.connection_string From d1ae163d836fd03718908f6842d4020d9fba384e Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 11:20:15 -0500 Subject: [PATCH 43/57] comment out env vars Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- azure_functions/src/functions/caDphTimerTrigger.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index ece53a84..3647b9e5 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -1,8 +1,8 @@ import { app, InvocationContext, Timer } from "@azure/functions"; import { QueueServiceClient } from "@azure/storage-queue"; -const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; -const queueServiceClient = QueueServiceClient.fromConnectionString(connectionString); +//const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; +//const queueServiceClient = QueueServiceClient.fromConnectionString(connectionString); export async function caDphTimerTrigger(myTimer: Timer, context: InvocationContext): Promise { /* TODO - From 74545c30ecc1526a35d5eeb7c5e9a187b0307fa4 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 11:45:15 -0500 Subject: [PATCH 44/57] set env vars and use them; remove add'l logging Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 6 +----- azure_functions/src/functions/caDphTimerTrigger.ts | 11 ++++++----- operations/template/functions.tf | 5 +++++ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index bddede3f..410f00b0 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -80,11 +80,6 @@ jobs: npm run test --if-present popd - - - name: 'List Directory Contents' - run: | - ls -R ./${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} - - name: 'Login via Azure CLI' uses: azure/login@v2 with: @@ -106,3 +101,4 @@ jobs: app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} +# TODO - add a health check to see if this worked diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index 3647b9e5..65c2f32e 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -1,8 +1,10 @@ import { app, InvocationContext, Timer } from "@azure/functions"; import { QueueServiceClient } from "@azure/storage-queue"; -//const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; -//const queueServiceClient = QueueServiceClient.fromConnectionString(connectionString); +const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; +// TODO - add env vars to docker compose? +const pollingTriggerQueueName = process.env.POLLING_TRIGGER_QUEUE_NAME; +const queueServiceClient = QueueServiceClient.fromConnectionString(connectionString); export async function caDphTimerTrigger(myTimer: Timer, context: InvocationContext): Promise { /* TODO - @@ -16,13 +18,12 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte - Profit? */ - // TODO - get queue name from env vars - // const queueClient = queueServiceClient.getQueueClient("queuename") + const queueClient = queueServiceClient.getQueueClient(pollingTriggerQueueName) console.log(myTimer); console.log(context); // context.extraInputs.get("customer") // TODO - check on options for send message - // queueClient.sendMessage("cheezburger") + await queueClient.sendMessage("cheezburger") context.log('Timer function processed request.'); } // TODO - add info about installing typescript diff --git a/operations/template/functions.tf b/operations/template/functions.tf index b1c1d936..7253213d 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -7,6 +7,11 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { storage_account_name = azurerm_storage_account.storage.name storage_account_access_key = azurerm_storage_account.storage.primary_access_key + app_settings = { + AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_blob_connection_string + POLLING_TRIGGER_QUEUE_NAME = azurerm_storage_queue.polling_trigger_queue.name + } + site_config { app_scale_limit = 1 application_insights_connection_string = azurerm_application_insights.function_app_insights.connection_string From 71146fc2304dfea7d86ff53fae4d849dba4d75eb Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 12:03:41 -0500 Subject: [PATCH 45/57] change connection string and add Helpful Comments Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- azure_functions/src/functions/caDphTimerTrigger.ts | 1 + operations/template/functions.tf | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index 65c2f32e..7aa3292f 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -16,6 +16,7 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte - Create a DLQ for it - Create a queue reader including dead lettering - Profit? + - Add a helpful comment about missing env vars making deploy not-work */ const queueClient = queueServiceClient.getQueueClient(pollingTriggerQueueName) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 7253213d..b2afdad6 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -8,11 +8,12 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { storage_account_access_key = azurerm_storage_account.storage.primary_access_key app_settings = { - AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_blob_connection_string + AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string POLLING_TRIGGER_QUEUE_NAME = azurerm_storage_queue.polling_trigger_queue.name } site_config { + #The below value should be kept at 1 so we don't duplicate actions and lock out the external sftp client app_scale_limit = 1 application_insights_connection_string = azurerm_application_insights.function_app_insights.connection_string application_insights_key = azurerm_application_insights.function_app_insights.instrumentation_key From 60bbf3726fcf637059acc333afbe3d1145f0fcf2 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 12:17:52 -0500 Subject: [PATCH 46/57] temporarily remove connection string for testing Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- operations/template/functions.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index b2afdad6..eeca5e3a 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -8,7 +8,7 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { storage_account_access_key = azurerm_storage_account.storage.primary_access_key app_settings = { - AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string +# AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string POLLING_TRIGGER_QUEUE_NAME = azurerm_storage_queue.polling_trigger_queue.name } From e3275432c28d41b119e9d24b67243ae999f555b1 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 12:29:02 -0500 Subject: [PATCH 47/57] put connection string back Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- operations/template/functions.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index eeca5e3a..b2afdad6 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -8,7 +8,7 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { storage_account_access_key = azurerm_storage_account.storage.primary_access_key app_settings = { -# AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string + AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string POLLING_TRIGGER_QUEUE_NAME = azurerm_storage_queue.polling_trigger_queue.name } From 24a8be05b3adcbc5f6cab9400f3eaddae266a141 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 12:30:51 -0500 Subject: [PATCH 48/57] try a health check? Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 410f00b0..4c41f08f 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -102,3 +102,13 @@ jobs: package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} # TODO - add a health check to see if this worked + - name: 'Health Check' + run: | + FUNCTION_URL=https://${{ env.AZURE_FUNCTIONAPP_NAME }}.azurewebsites.net/api/health + STATUS_CODE=$(curl -o /dev/null -s -w "%{http_code}\n" $FUNCTION_URL) + if [ $STATUS_CODE -ne 200 ]; then + echo "Health check failed with status code $STATUS_CODE" + exit 1 + else + echo "Health check succeeded with status code $STATUS_CODE" + fi From 69f2a99a01fcb16ca3288f487a6e0c5c17343e21 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 12:42:16 -0500 Subject: [PATCH 49/57] take out borked health check, add node_modules to funcignore Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 10 ---------- azure_functions/.funcignore | 1 + 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 4c41f08f..410f00b0 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -102,13 +102,3 @@ jobs: package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} # TODO - add a health check to see if this worked - - name: 'Health Check' - run: | - FUNCTION_URL=https://${{ env.AZURE_FUNCTIONAPP_NAME }}.azurewebsites.net/api/health - STATUS_CODE=$(curl -o /dev/null -s -w "%{http_code}\n" $FUNCTION_URL) - if [ $STATUS_CODE -ne 200 ]; then - echo "Health check failed with status code $STATUS_CODE" - exit 1 - else - echo "Health check succeeded with status code $STATUS_CODE" - fi diff --git a/azure_functions/.funcignore b/azure_functions/.funcignore index d72240f5..c090acde 100644 --- a/azure_functions/.funcignore +++ b/azure_functions/.funcignore @@ -8,3 +8,4 @@ __queuestorage__ local.settings.json test tsconfig.json +node_modules/ From b15117f2bac61659cce50f38420f2c9cb5a38b20 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 12:53:24 -0500 Subject: [PATCH 50/57] let's try another setting to build faster Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> --- operations/template/functions.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index b2afdad6..219e4367 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -10,6 +10,7 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { app_settings = { AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string POLLING_TRIGGER_QUEUE_NAME = azurerm_storage_queue.polling_trigger_queue.name + WEBSITE_RUN_FROM_PACKAGE = 1 } site_config { From f0184148adcff0a6a3ef5bddf588a7adb411f73e Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 13:51:21 -0500 Subject: [PATCH 51/57] first try at a health check Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 13 +++++++++++++ operations/template/functions.tf | 2 ++ 2 files changed, 15 insertions(+) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 410f00b0..78ebb5e5 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -101,4 +101,17 @@ jobs: app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} + # TODO - add a health check to see if this worked + - name: 'Check function app function' + run: | + FUNCTION_STATUS=$(az functionapp function show -g "csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg" -n "polling-function-${{ inputs.ENVIRONMENT }}" --function-name "caDphTimerTrigger") + echo "FUNCTION_STATUS=$FUNCTION_STATUS" >> $GITHUB_OUTPUT + if [ -z "$FUNCTION_STATUS" ]; then + echo "Function not created" + exit 1 + else + echo "Function created" + fi + id: getFunctionStatus +#az functionapp function show -g "csels-rsti-internal-moderate-rg" -n "polling-function-internal" --function-name "caDphTimerTrigger" diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 219e4367..a1780ae8 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -10,6 +10,8 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { app_settings = { AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string POLLING_TRIGGER_QUEUE_NAME = azurerm_storage_queue.polling_trigger_queue.name + + # Makes the Github Action run significantly faster by not copying the node_modules WEBSITE_RUN_FROM_PACKAGE = 1 } From 51a88e4bc8bce442b8dbd8d22c488bd948e71219 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 13:58:12 -0500 Subject: [PATCH 52/57] just look for function name Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 78ebb5e5..6f271c9f 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -105,8 +105,8 @@ jobs: # TODO - add a health check to see if this worked - name: 'Check function app function' run: | - FUNCTION_STATUS=$(az functionapp function show -g "csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg" -n "polling-function-${{ inputs.ENVIRONMENT }}" --function-name "caDphTimerTrigger") - echo "FUNCTION_STATUS=$FUNCTION_STATUS" >> $GITHUB_OUTPUT + FUNCTION_STATUS=$(az functionapp function show -g "csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg" -n "polling-function-${{ inputs.ENVIRONMENT }}" --function-name "caDphTimerTrigger" --query "{functionName:name}" --output tsv) + echo $FUNCTION_STATUS if [ -z "$FUNCTION_STATUS" ]; then echo "Function not created" exit 1 From d49c44aa9b444618437a038a875233922acb1100 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 14:03:19 -0500 Subject: [PATCH 53/57] let's break this again Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- operations/template/functions.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index a1780ae8..3303683b 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -8,7 +8,7 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { storage_account_access_key = azurerm_storage_account.storage.primary_access_key app_settings = { - AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string +# AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string POLLING_TRIGGER_QUEUE_NAME = azurerm_storage_queue.polling_trigger_queue.name # Makes the Github Action run significantly faster by not copying the node_modules From 29e30937c2cc8f8e7b1c3dc20be4bbc6821ea2f9 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 15:12:16 -0500 Subject: [PATCH 54/57] turn off actual enqueueing for now, add some comments for later, remove the not-working health check attempt Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 14 -------------- azure_functions/src/functions/caDphTimerTrigger.ts | 12 +++++++----- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index 6f271c9f..be0b7052 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -101,17 +101,3 @@ jobs: app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} - -# TODO - add a health check to see if this worked - - name: 'Check function app function' - run: | - FUNCTION_STATUS=$(az functionapp function show -g "csels-rsti-${{ inputs.ENVIRONMENT }}-moderate-rg" -n "polling-function-${{ inputs.ENVIRONMENT }}" --function-name "caDphTimerTrigger" --query "{functionName:name}" --output tsv) - echo $FUNCTION_STATUS - if [ -z "$FUNCTION_STATUS" ]; then - echo "Function not created" - exit 1 - else - echo "Function created" - fi - id: getFunctionStatus -#az functionapp function show -g "csels-rsti-internal-moderate-rg" -n "polling-function-internal" --function-name "caDphTimerTrigger" diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index 7aa3292f..4facbec4 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -1,4 +1,4 @@ -import { app, InvocationContext, Timer } from "@azure/functions"; +import { app, InvocationContext, Timer, input } from "@azure/functions"; import { QueueServiceClient } from "@azure/storage-queue"; const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; @@ -23,11 +23,12 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte console.log(myTimer); console.log(context); // context.extraInputs.get("customer") - // TODO - check on options for send message - await queueClient.sendMessage("cheezburger") + // TODO - check on options for send message (like timeouts etc) + // TODO - send a real message + // await queueClient.sendMessage("cheezburger") context.log('Timer function processed request.'); } -// TODO - add info about installing typescript +// TODO - add info about installing typescript to README // TODO - figure out instructions for running this // TODO - is .funcignore at the right level? // TODO - set up the right CRON expression @@ -41,5 +42,6 @@ app.timer('caDphTimerTrigger', { // whether we can pass in a variable - then we could use one handler for every // customer that has a timer // Possibly the name (in the first param above) could work for this? - // extraInputs: [{name: "customer", type: ""}] + // const customer = input.generic({"type": "customer", "name": "CADPH"}) + // extraInputs: [customer] }); From b864f28c06cc7856214cb4857d5caa1a14c783f0 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 15:47:58 -0500 Subject: [PATCH 55/57] README, ADR, and some cleanup Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- .github/workflows/functions-deploy.yml | 25 ++++----------- README.md | 1 + adr/009-typescript-and-azure-functions.md | 18 +++++++++++ azure_functions/src/README.md | 32 +++++++++++++++++++ .../src/functions/caDphTimerTrigger.ts | 12 +------ 5 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 adr/009-typescript-and-azure-functions.md create mode 100644 azure_functions/src/README.md diff --git a/.github/workflows/functions-deploy.yml b/.github/workflows/functions-deploy.yml index be0b7052..f11f96f4 100644 --- a/.github/workflows/functions-deploy.yml +++ b/.github/workflows/functions-deploy.yml @@ -1,22 +1,4 @@ -# This workflow will build a container and deploy it to an Azure Functions App on Linux when a commit is pushed to your default branch. -# -# This workflow assumes you have already created the target Azure Functions app. -# For instructions see https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-function-linux-custom-image?tabs=in-process%2Cbash%2Cazure-cli&pivots=programming-language-csharp -# -# To configure this workflow: -# 1. Set up the following secrets in your repository: -# - AZURE_RBAC_CREDENTIALS -# - REGISTRY_USERNAME -# - REGISTRY_PASSWORD -# 2. Change env variables for your configuration. -# -# For more information on: -# - GitHub Actions for Azure: https://github.com/Azure/Actions -# - Azure Functions Container Action: https://github.com/Azure/functions-container-action -# - Azure Service Principal for RBAC: https://github.com/Azure/functions-action#using-azure-service-principal-for-rbac-as-deployment-credential -# -# For more samples to get started with GitHub Action workflows to deploy to Azure: https://github.com/Azure/actions-workflow-samples/tree/master/FunctionApp - +# TODO - currently this is only called from the `internal` deploy job. It should be part of all envs name: Deploy Node.js project to Azure Function App on: @@ -101,3 +83,8 @@ jobs: app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }} package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} publish-profile: ${{ steps.getPublishProfile.outputs.PUBLISH_PROFILE }} + +# TODO: Add a step to report failure on Azure Function App Func creation +# Currently, if there's a bug in the function code or it tries to use an environment variable that doesn't exist +# or has an invalid value, the Github Action Step will complete successfully but the function code will NOT be +# deployed, and any previous version of the function will be removed diff --git a/README.md b/README.md index d1d6dfea..271b0681 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,7 @@ occur when a release is published. ## Related documents +* [Azure Functions and Typescript](/azure_functions/src/README.md) * [Open Practices](/docs/open_practices.md) * [Rules of Behavior](/docs/rules_of_behavior.md) * [Thanks and Acknowledgements](/docs/thanks.md) diff --git a/adr/009-typescript-and-azure-functions.md b/adr/009-typescript-and-azure-functions.md new file mode 100644 index 00000000..f8d0434a --- /dev/null +++ b/adr/009-typescript-and-azure-functions.md @@ -0,0 +1,18 @@ +# 9. Typescript and Azure Functions + +Date: 2024-07-15 + +## Decision + +We're using Azure Functions for scheduled tasks. Azure Functions support a CRON +expression trigger, which most other Azure resources do not. Azure Webjobs are +supposed to work with CRON triggers, but don't seem to work well with Linux servers since they are in preview. + +We're using Typescript for Azure Functions. +Go is not well-supported (it requires special handlers). Of the well-supported +language options, Typescript is lighter-weight than Java or C# and more +familiar to the team than Python. + +## Status + +Accepted. diff --git a/azure_functions/src/README.md b/azure_functions/src/README.md new file mode 100644 index 00000000..2b699acc --- /dev/null +++ b/azure_functions/src/README.md @@ -0,0 +1,32 @@ +#ReportStream SFTP Functions + +## Requirements +[Node](https://nodejs.org/en/download/package-manager/current) version >= 20 + +[Typescript](https://www.typescriptlang.org/download/) version >= 4.0.0 + +## Using and Running + +To install dependencies and run the application use the below command + +```shell +cd ./azure_functions +npm install +npm run start +``` + +Other commands can be found in `package.json` + + +### Verifying Deploys +`functions-deploy.yml` is the CI/CD file responsible for deploying the function into Azure. + +In Azure Portal, find your function and look at Logs->Traces to see deploy details. +Typing `trace` into the query console will return the logs for the function you have selected. + +As of 7/15/24, the GitHub Action step to deploy the function will silently fail in some +circumstances. If your function depends on e.g. an environment variable that's not set +or is set to an invalid value, the Action will appear to complete successfully, but your +Function App will have not function code in it. It's a good idea to confirm (using the +Azure Portal and/or the `trace` information above) that the function deployed as expected +regardless of the GitHub Action status. diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index 4facbec4..da92d687 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -8,15 +8,8 @@ const queueServiceClient = QueueServiceClient.fromConnectionString(connectionStr export async function caDphTimerTrigger(myTimer: Timer, context: InvocationContext): Promise { /* TODO - - - Figure out TF for the Azure function - - Make sure Azure Function has access to env vars - Figure out local testing - - Figure out how to enqueue a message from here - - Create a new queue for timer triggers - probably one total, and the message is the customer? - - Create a DLQ for it - - Create a queue reader including dead lettering - - Profit? - - Add a helpful comment about missing env vars making deploy not-work + - Create a queue reader for the new queue including dead lettering */ const queueClient = queueServiceClient.getQueueClient(pollingTriggerQueueName) @@ -28,9 +21,6 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte // await queueClient.sendMessage("cheezburger") context.log('Timer function processed request.'); } -// TODO - add info about installing typescript to README -// TODO - figure out instructions for running this -// TODO - is .funcignore at the right level? // TODO - set up the right CRON expression // TODO - figure out how we make sure there's only one Azure Function running - we should alarm if there's more than one // TODO - figure out if we can add multiple timers (like one per external customer?) to the same function From 752b3143467bd790de0014a118e462267d6d9b61 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 16:46:42 -0500 Subject: [PATCH 56/57] do some cleanup Co-Authored-By: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Co-Authored-By: jherrflexion <118225331+jherrflexion@users.noreply.github.com> Co-Authored-By: Samuel Aquino --- azure_functions/.DS_Store | Bin 0 -> 6148 bytes azure_functions/package-lock.json | 395 +++--------------- azure_functions/package.json | 4 +- .../src/functions/caDphTimerTrigger.ts | 10 +- docker-compose.yml | 1 + operations/template/functions.tf | 2 +- 6 files changed, 62 insertions(+), 350 deletions(-) create mode 100644 azure_functions/.DS_Store diff --git a/azure_functions/.DS_Store b/azure_functions/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f0f4879b29e4b96faf20121ccef0dc7eb639fe6e GIT binary patch literal 6148 zcmeHKT}s115T4NrvHDQo#0OctL2s~@c!C~4sR{a!m_q4$&f;ObhX)b-=0|BT6!bwv zW?=W5-JO}8e30E8BI3oiniI{4s6Z2BQAR|jN0$!VcmiaNaZ4?ARMD22kwAZON^(D? zC(XL1-TZ6XG!OITeb=rf@uTV4@jlzOE6Y{Wtzc7JUcA+>S1;H5?W=FuuOD}EdCmwO z5)1?b!9Xw&4E%@z+}R?;CLqZeGj=iBC9q6eu05^jD|Iz literal 0 HcmV?d00001 diff --git a/azure_functions/package-lock.json b/azure_functions/package-lock.json index 42407c4c..fac49465 100644 --- a/azure_functions/package-lock.json +++ b/azure_functions/package-lock.json @@ -9,8 +9,7 @@ "version": "1.0.0", "dependencies": { "@azure/functions": "^4.0.0", - "@azure/storage-queue": "^12.22.0", - "azure-functions-core-tools": "^4.0.5907" + "@azure/storage-queue": "^12.22.0" }, "devDependencies": { "@types/node": "^20.x", @@ -248,6 +247,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -264,6 +264,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" @@ -293,6 +294,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -304,6 +306,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, "engines": { "node": ">=12" }, @@ -311,349 +314,17 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/azure-functions-core-tools": { - "version": "4.0.5907", - "resolved": "https://registry.npmjs.org/azure-functions-core-tools/-/azure-functions-core-tools-4.0.5907.tgz", - "integrity": "sha512-QeyBf/9Z3sziPXIU7fGcLgCFhXLo+uO3ILLvbb0Zse46VC5SWWfscbAb023xoUXhWXlf7KXjWwvKgyJpAeG20A==", - "hasInstallScript": true, - "hasShrinkwrap": true, - "os": [ - "win32", - "darwin", - "linux" - ], - "dependencies": { - "chalk": "3.0.0", - "extract-zip": "^2.0.1", - "https-proxy-agent": "5.0.0", - "progress": "2.0.3", - "rimraf": "4.4.1" - }, - "bin": { - "azfun": "lib/main.js", - "azurefunctions": "lib/main.js", - "func": "lib/main.js" - }, - "engines": { - "node": ">=6.9.1" - } - }, - "node_modules/azure-functions-core-tools/node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, - "node_modules/azure-functions-core-tools/node_modules/@types/node": { - "version": "18.15.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", - "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", - "optional": true - }, - "node_modules/azure-functions-core-tools/node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/azure-functions-core-tools/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/azure-functions-core-tools/node_modules/ansi-styles": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.0.tgz", - "integrity": "sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg==", - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/azure-functions-core-tools/node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "node_modules/azure-functions-core-tools/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/azure-functions-core-tools/node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "engines": { - "node": "*" - } - }, - "node_modules/azure-functions-core-tools/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/azure-functions-core-tools/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/azure-functions-core-tools/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/azure-functions-core-tools/node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/azure-functions-core-tools/node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/azure-functions-core-tools/node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/azure-functions-core-tools/node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/azure-functions-core-tools/node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/azure-functions-core-tools/node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/azure-functions-core-tools/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/azure-functions-core-tools/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/azure-functions-core-tools/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/azure-functions-core-tools/node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/azure-functions-core-tools/node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/azure-functions-core-tools/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/azure-functions-core-tools/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/azure-functions-core-tools/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/azure-functions-core-tools/node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/azure-functions-core-tools/node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/azure-functions-core-tools/node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" - }, - "node_modules/azure-functions-core-tools/node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/azure-functions-core-tools/node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/azure-functions-core-tools/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/azure-functions-core-tools/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/azure-functions-core-tools/node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/azure-functions-core-tools/node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -662,6 +333,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -672,7 +344,8 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/cookie": { "version": "0.6.0", @@ -686,6 +359,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -714,12 +388,14 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/fast-xml-parser": { "version": "4.4.0", @@ -746,6 +422,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -761,6 +438,7 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", + "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -807,6 +485,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -814,12 +493,14 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/jackspeak": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", + "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -842,6 +523,7 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, "engines": { "node": ">=18" } @@ -850,6 +532,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -864,6 +547,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -876,12 +560,14 @@ "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -890,6 +576,7 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -905,6 +592,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.8.tgz", "integrity": "sha512-XSh0V2/yNhDEi8HwdIefD8MLgs4LQXPag/nEJWs3YUc3Upn+UHa1GyIkEg9xSSNt7HnkO5FjTvmcRzgf+8UZuw==", + "dev": true, "dependencies": { "glob": "^10.3.7" }, @@ -922,6 +610,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -933,6 +622,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } @@ -941,6 +631,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { "node": ">=14" }, @@ -952,6 +643,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -969,6 +661,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -982,6 +675,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -989,12 +683,14 @@ "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1006,6 +702,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1021,6 +718,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1032,6 +730,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -1080,6 +779,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -1094,6 +794,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -1111,6 +812,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1127,6 +829,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -1135,6 +838,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -1148,12 +852,14 @@ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1167,6 +873,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, diff --git a/azure_functions/package.json b/azure_functions/package.json index f21e181c..090d3094 100644 --- a/azure_functions/package.json +++ b/azure_functions/package.json @@ -12,11 +12,9 @@ }, "dependencies": { "@azure/functions": "^4.0.0", - "@azure/storage-queue": "^12.22.0", - "azure-functions-core-tools": "^4.0.5907" + "@azure/storage-queue": "^12.22.0" }, "devDependencies": { - "azure-functions-core-tools": "^4.x", "@types/node": "^20.x", "rimraf": "^5.0.0", "typescript": "^4.0.0" diff --git a/azure_functions/src/functions/caDphTimerTrigger.ts b/azure_functions/src/functions/caDphTimerTrigger.ts index da92d687..5b652d7a 100644 --- a/azure_functions/src/functions/caDphTimerTrigger.ts +++ b/azure_functions/src/functions/caDphTimerTrigger.ts @@ -12,19 +12,25 @@ export async function caDphTimerTrigger(myTimer: Timer, context: InvocationConte - Create a queue reader for the new queue including dead lettering */ + console.log(connectionString) const queueClient = queueServiceClient.getQueueClient(pollingTriggerQueueName) + console.log("Timer:") console.log(myTimer); + console.log("Context:") console.log(context); // context.extraInputs.get("customer") // TODO - check on options for send message (like timeouts etc) // TODO - send a real message - // await queueClient.sendMessage("cheezburger") + // const sendMessageResponse = await queueClient.sendMessage("cheezburger") + // console.log("Sent message successfully, service assigned message Id:", sendMessageResponse.messageId, "service assigned request Id:", sendMessageResponse.requestId ); + context.log('Timer function processed request.'); } // TODO - set up the right CRON expression // TODO - figure out how we make sure there's only one Azure Function running - we should alarm if there's more than one // TODO - figure out if we can add multiple timers (like one per external customer?) to the same function -// TODO - find out the timer's timezone for scheduling +// TODO - find out the timer's timezone for scheduling - there's a `schedule: { adjustForDST: true }` setting in the timer +// https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=python-v2%2Cisolated-process%2Cnodejs-v4&pivots=programming-language-typescript#ncrontab-time-zones app.timer('caDphTimerTrigger', { schedule: '0 */1 * * * *', handler: caDphTimerTrigger, diff --git a/docker-compose.yml b/docker-compose.yml index 746e572d..4011a878 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,6 +16,7 @@ services: SFTP_SERVER_ADDRESS: host.docker.internal:2223 # no http since this is sftp SFTP_SERVER_PUBLIC_KEY_NAME: ssh_host_rsa_key.pub CA_DPH_ZIP_PASSWORD_NAME: mock_ca_dph_zip_password.txt #pragma: allowlist secret + POLLING_TRIGGER_QUEUE_NAME: polling-trigger-queue volumes: # map to Azurite data objects to the build directory - ./localdata/data/reportstream:/localdata diff --git a/operations/template/functions.tf b/operations/template/functions.tf index 3303683b..a1780ae8 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -8,7 +8,7 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { storage_account_access_key = azurerm_storage_account.storage.primary_access_key app_settings = { -# AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string + AZURE_STORAGE_CONNECTION_STRING = azurerm_storage_account.storage.primary_connection_string POLLING_TRIGGER_QUEUE_NAME = azurerm_storage_queue.polling_trigger_queue.name # Makes the Github Action run significantly faster by not copying the node_modules From cc73b65fafc231a365ac9824534d555517871d02 Mon Sep 17 00:00:00 2001 From: Sylvie Date: Mon, 15 Jul 2024 17:03:36 -0500 Subject: [PATCH 57/57] terraform format --- operations/template/functions.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operations/template/functions.tf b/operations/template/functions.tf index a1780ae8..2695b896 100644 --- a/operations/template/functions.tf +++ b/operations/template/functions.tf @@ -17,9 +17,9 @@ resource "azurerm_linux_function_app" "polling_trigger_function_app" { site_config { #The below value should be kept at 1 so we don't duplicate actions and lock out the external sftp client - app_scale_limit = 1 + app_scale_limit = 1 application_insights_connection_string = azurerm_application_insights.function_app_insights.connection_string - application_insights_key = azurerm_application_insights.function_app_insights.instrumentation_key + application_insights_key = azurerm_application_insights.function_app_insights.instrumentation_key # TODO - verify this is good advice always_on = true