From 6a15508b1601aa38f6c8bf2dc6ddc19309863cd7 Mon Sep 17 00:00:00 2001 From: Jordan Hoey Date: Thu, 26 Sep 2024 15:53:26 +0100 Subject: [PATCH 1/5] AppGateway - graph update --- .../workflows/appgateway-auto-shutdown.yaml | 40 ++++++++- .github/workflows/appgateway-auto-start.yaml | 40 ++++++++- scripts/appgateway/appgw_status.sh | 89 ++++++++----------- scripts/appgateway/auto-start-stop.sh | 85 ++++++++---------- scripts/appgateway/common-functions.sh | 30 +++++-- 5 files changed, 175 insertions(+), 109 deletions(-) diff --git a/.github/workflows/appgateway-auto-shutdown.yaml b/.github/workflows/appgateway-auto-shutdown.yaml index 04d4807c..87bbaeb0 100644 --- a/.github/workflows/appgateway-auto-shutdown.yaml +++ b/.github/workflows/appgateway-auto-shutdown.yaml @@ -3,6 +3,8 @@ on: workflow_dispatch: schedule: - cron: '0 19,22 * * *' # Every day at 20:00 and 23:00 BST +env: + DEV_ENV: ${{ secrets.DEV_ENV }} permissions: id-token: write jobs: @@ -17,16 +19,48 @@ jobs: client-id: 2b6fa9d7-7dba-4600-a58a-5e25554997aa # DTS AKS Auto-Shutdown tenant-id: 531ff96d-0ae9-462a-8d2d-bec7c0b42082 # HMCTS.NET allow-no-subscriptions: true - - name: App Gateway Auto Shutdown - run: ./scripts/appgateway/auto-start-stop.sh stop + - name: Staging - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh stop staging env: - DEV_ENV: ${{ secrets.DEV_ENV }} + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Testing - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh stop testing + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Demo - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh stop demo + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Development - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh stop development + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Sandbox - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh stop sandbox + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: ITHC - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh stop ithc + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Untagged - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh stop untagged + env: + DEV_ENV: ${{ env.DEV_ENV }} - name: Output log file run: ./scripts/common/log-output.sh - name: Wait for App Gateways to stop + if: env.DEV_ENV != 'true' run: sleep 300 - name: App Gateway Auto Shutdown status check + if: env.DEV_ENV != 'true' run: ./scripts/appgateway/appgw_status.sh stop ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} diff --git a/.github/workflows/appgateway-auto-start.yaml b/.github/workflows/appgateway-auto-start.yaml index 95f0d4ed..2fc6c270 100644 --- a/.github/workflows/appgateway-auto-start.yaml +++ b/.github/workflows/appgateway-auto-start.yaml @@ -3,6 +3,8 @@ on: workflow_dispatch: schedule: - cron: '30 5 * * 1-5' # Every weekday at 6:30am BST +env: + DEV_ENV: ${{ secrets.DEV_ENV }} permissions: id-token: write jobs: @@ -17,16 +19,48 @@ jobs: client-id: 2b6fa9d7-7dba-4600-a58a-5e25554997aa # DTS AKS Auto-Shutdown tenant-id: 531ff96d-0ae9-462a-8d2d-bec7c0b42082 # HMCTS.NET allow-no-subscriptions: true - - name: App Gateway Auto Start - run: ./scripts/appgateway/auto-start-stop.sh start + - name: Staging - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh start staging env: - DEV_ENV: ${{ secrets.DEV_ENV }} + DEV_ENV: ${{ env.DEV_ENV }} + - name: Testing - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh start testing + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Demo - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh start demo + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Development - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh start development + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Sandbox - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh start sandbox + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: ITHC - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh start ithc + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Untagged - App Gateway Auto Shutdown + run: ./scripts/appgateway/auto-start-stop.sh start untagged + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Output log file run: ./scripts/common/log-output.sh - name: Wait for App Gateways to start + if: env.DEV_ENV != 'true' run: sleep 300 - name: App Gateway Auto start status check + if: env.DEV_ENV != 'true' run: ./scripts/appgateway/appgw_status.sh start ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} diff --git a/scripts/appgateway/appgw_status.sh b/scripts/appgateway/appgw_status.sh index 004c8bf9..b37fe209 100755 --- a/scripts/appgateway/appgw_status.sh +++ b/scripts/appgateway/appgw_status.sh @@ -18,65 +18,54 @@ if [[ "$MODE" != "start" && "$MODE" != "stop" ]]; then exit 1 fi -# Find all subscriptions that are available to the credential used and saved to SUBSCRIPTIONS variable -SUBSCRIPTIONS=$(az account list -o json) +APPLICATION_GATEWAYS=$(get_application_gateways "$2") -# For each subscription found, start the loop -jq -c '.[]' <<< $SUBSCRIPTIONS | while read subscription; do +# For each App Gateway found in the function `get_application_gateways` start another loop +jq -c '.[]' <<<$APPLICATION_GATEWAYS | while read application_gateway; do + # Function that returns the Resource Group, Id and Name of the Application Gateway and its current state as variables + get_application_gateways_details - # Function that returns the Subscription Id and Name as variables, - # sets the subscription as the default then returns a json formatted variable of available App Gateways with an autoshutdown tag - get_application_gateways - echo "Scanning $SUBSCRIPTION_NAME..." + # Set variables based on inputs which are used to decide when to SKIP an environment + if [[ $ENVIRONMENT == "stg" ]]; then + application_gateway_env=${ENVIRONMENT/stg/Staging} + elif [[ $ENVIRONMENT == "sbox" ]]; then + application_gateway_env=${ENVIRONMENT/sbox/Sandbox} + else + application_gateway_env=$ENVIRONMENT + fi - # For each App Gateway found in the function `get_application_gateways` start another loop - jq -c '.[]'<<< $APPLICATION_GATEWAYS | while read application_gateway - do - # Function that returns the Resource Group, Id and Name of the Application Gateway and its current state as variables - get_application_gateways_details - - # Set variables based on inputs which are used to decide when to SKIP an environment - if [[ $ENVIRONMENT == "stg" ]]; then - application_gateway_env=${ENVIRONMENT/stg/Staging} - elif [[ $ENVIRONMENT == "sbox" ]]; then - application_gateway_env=${ENVIRONMENT/sbox/Sandbox} - else - application_gateway_env=$ENVIRONMENT - fi + application_gateway_business_area=$BUSINESS_AREA - application_gateway_business_area=$BUSINESS_AREA + # SKIP variable updated based on the output of the `should_skip_start_stop` function which calculates its value + # based on the issues_list.json file which contains user requests to keep environments online after normal hours + SKIP=$(should_skip_start_stop $application_gateway_env $application_gateway_business_area $MODE) - # SKIP variable updated based on the output of the `should_skip_start_stop` function which calculates its value - # based on the issues_list.json file which contains user requests to keep environments online after normal hours - SKIP=$(should_skip_start_stop $application_gateway_env $application_gateway_business_area $MODE) + # Setup message output templates for later use + logMessage="Application Gateway: $APPLICATION_GATEWAY_NAME in Subscription: $SUBSCRIPTION and ResourceGroup: $RESOURCE_GROUP is $APPLICATION_GATEWAY_STATE after $MODE action" + slackMessage="Application Gateway: *$APPLICATION_GATEWAY_NAME* in Subscription: *$SUBSCRIPTION* is $APPLICATION_GATEWAY_STATE after *$MODE* action." - # Setup message output templates for later use - logMessage="Application Gateway: $APPLICATION_GATEWAY_NAME in Subscription: $SUBSCRIPTION_NAME and ResourceGroup: $RESOURCE_GROUP is $APPLICATION_GATEWAY_STATE after $MODE action" - slackMessage="Application Gateway: *$APPLICATION_GATEWAY_NAME* in Subscription: *$SUBSCRIPTION_NAME* is $APPLICATION_GATEWAY_STATE after *$MODE* action." - - # If SKIP is false then we progress with the status check for the particular App Gateway in this loop run, if SKIP is true then do nothing - if [[ $SKIP == "false" ]]; then + # If SKIP is false then we progress with the status check for the particular App Gateway in this loop run, if SKIP is true then do nothing + if [[ $SKIP == "false" ]]; then # Check state of the Application Gateway and print output as required # Depending on the value of MODE a notification will also be sent # - If MODE = Start then a stopped App Gateway is incorrect and we should notify # - If MODE = Stop then a running App Gateway is incorrect and we should notify # - If neither Running or Stopped is found then something else is going on and we should notify - case "$APPLICATION_GATEWAY_STATE" in - *"Running"*) - ts_echo_color $( [[ $MODE == "start" ]] && echo GREEN || echo RED ) "$logMessage" - [[ $MODE == "stop" ]] && auto_shutdown_notification ":red_circle: $slackMessage" - ;; - *"Stopped"*) - ts_echo_color $( [[ $MODE == "start" ]] && echo RED || echo GREEN ) "$logMessage" - [[ $MODE == "start" ]] && auto_shutdown_notification ":red_circle: $slackMessage" - ;; - *) - ts_echo_color AMBER "$logMessage" - auto_shutdown_notification ":yellow_circle: $slackMessage" - ;; - esac - else - ts_echo_color AMBER "Application Gateway: $APPLICATION_GATEWAY_NAME in ResourceGroup: $RESOURCE_GROUP has been skipped from today's $MODE operation schedule" - fi - done + case "$APPLICATION_GATEWAY_STATE" in + *"Running"*) + ts_echo_color $([[ $MODE == "start" ]] && echo GREEN || echo RED) "$logMessage" + [[ $MODE == "stop" ]] && auto_shutdown_notification ":red_circle: $slackMessage" + ;; + *"Stopped"*) + ts_echo_color $([[ $MODE == "start" ]] && echo RED || echo GREEN) "$logMessage" + [[ $MODE == "start" ]] && auto_shutdown_notification ":red_circle: $slackMessage" + ;; + *) + ts_echo_color AMBER "$logMessage" + auto_shutdown_notification ":yellow_circle: $slackMessage" + ;; + esac + else + ts_echo_color AMBER "Application Gateway: $APPLICATION_GATEWAY_NAME in ResourceGroup: $RESOURCE_GROUP has been skipped from today's $MODE operation schedule" + fi done diff --git a/scripts/appgateway/auto-start-stop.sh b/scripts/appgateway/auto-start-stop.sh index 97b2374a..c4e437bb 100755 --- a/scripts/appgateway/auto-start-stop.sh +++ b/scripts/appgateway/auto-start-stop.sh @@ -16,52 +16,45 @@ if [[ "$MODE" != "start" && "$MODE" != "stop" ]]; then exit 1 fi -# Find all subscriptions that are available to the credential used and saved to SUBSCRIPTIONS variable -SUBSCRIPTIONS=$(az account list -o json) - -# For each subscription found, start the loop -jq -c '.[]' <<< $SUBSCRIPTIONS | while read subscription; do - - # Function that returns the Subscription Id and Name as variables, sets the subscription as - # the default then returns a json formatted variable of available App Gateways with an autoshutdown tag - get_application_gateways - echo "Scanning $SUBSCRIPTION_NAME..." - - # For each App Gateway found in the function `get_application_gateways` start another loop - jq -c '.[]' <<< $APPLICATION_GATEWAYS | while read application_gateway; do - - # Function that returns the Resource Group, Id and Name of the Application Gateway and its current state as variables - get_application_gateways_details - - # Set variables based on inputs which are used to decide when to SKIP an environment - if [[ $ENVIRONMENT == "stg" ]]; then - application_gateway_env=${ENVIRONMENT/stg/Staging} - elif [[ $ENVIRONMENT == "sbox" ]]; then - application_gateway_env=${ENVIRONMENT/sbox/Sandbox} - else - application_gateway_env=$ENVIRONMENT - fi - - application_gateway_business_area=$BUSINESS_AREA - log "=====================================================" - log "Processing gateway: $APPLICATION_GATEWAY_NAME" - log "=====================================================" - - # SKIP variable updated based on the output of the `should_skip_start_stop` function which calculates its value - # based on the issues_list.json file which contains user requests to keep environments online after normal hours - SKIP=$(should_skip_start_stop $application_gateway_env $application_gateway_business_area $MODE) - - # If SKIP is false then we progress with the action (stop/start) for the particular App Gateway in this loop run, if not skip and print message to the logs - if [[ $SKIP == "false" ]]; then - if [[ $DEV_ENV != "true" ]]; then - appgateway_state_messages - az network application-gateway $MODE --resource-group $RESOURCE_GROUP --name $APPLICATION_GATEWAY_NAME --no-wait || echo Ignoring any errors while $MODE operation on application_gateway - else - ts_echo_color BLUE "Development Env: simulating state commands only." - appgateway_state_messages - fi +APPLICATION_GATEWAYS=$(get_application_gateways "$2") +application_gateway_count=$(jq -c -r '.count' <<< $APPLICATION_GATEWAYS) +log "$application_gateway_count Application Gateways found" +log "----------------------------------------------" + +# For each App Gateway found in the function `get_application_gateways` start another loop +jq -c '.data[]' <<<$APPLICATION_GATEWAYS | while read application_gateway; do + + # Function that returns the Resource Group, Id and Name of the Application Gateway and its current state as variables + get_application_gateways_details + + # Set variables based on inputs which are used to decide when to SKIP an environment + if [[ $ENVIRONMENT == "stg" ]]; then + application_gateway_env=${ENVIRONMENT/stg/Staging} + elif [[ $ENVIRONMENT == "sbox" ]]; then + application_gateway_env=${ENVIRONMENT/sbox/Sandbox} + else + application_gateway_env=$ENVIRONMENT + fi + + application_gateway_business_area=$BUSINESS_AREA + log "=====================================================" + log "Processing gateway: $APPLICATION_GATEWAY_NAME" + log "=====================================================" + + # SKIP variable updated based on the output of the `should_skip_start_stop` function which calculates its value + # based on the issues_list.json file which contains user requests to keep environments online after normal hours + SKIP=$(should_skip_start_stop $application_gateway_env $application_gateway_business_area $MODE) + + # If SKIP is false then we progress with the action (stop/start) for the particular App Gateway in this loop run, if not skip and print message to the logs + if [[ $SKIP == "false" ]]; then + if [[ $DEV_ENV != "true" ]]; then + appgateway_state_messages + az network application-gateway $MODE --resource-group $RESOURCE_GROUP --name $APPLICATION_GATEWAY_NAME --subscription $SUBSCRIPTION --no-wait || echo Ignoring any errors while $MODE operation on application_gateway else - ts_echo_color AMBER "Application_gateway $APPLICATION_GATEWAY_NAME (rg:$RESOURCE_GROUP) has been skipped from today's $MODE operation schedule" + ts_echo_color BLUE "Development Env: simulating state commands only." + appgateway_state_messages fi - done + else + ts_echo_color AMBER "Application_gateway $APPLICATION_GATEWAY_NAME (rg:$RESOURCE_GROUP) has been skipped from today's $MODE operation schedule" + fi done diff --git a/scripts/appgateway/common-functions.sh b/scripts/appgateway/common-functions.sh index 946fae72..1e606fa7 100755 --- a/scripts/appgateway/common-functions.sh +++ b/scripts/appgateway/common-functions.sh @@ -1,22 +1,38 @@ #!/bin/bash -# Function that uses the subscription input to get set variables for later use and gather all app gateways within the subscription for shutdown function get_application_gateways() { - SUBSCRIPTION_ID=$(jq -r '.id' <<< $subscription) - SUBSCRIPTION_NAME=$(jq -r '.name' <<< $subscription) - az account set -s $SUBSCRIPTION_ID - APPLICATION_GATEWAYS=$(az resource list --resource-type Microsoft.Network/applicationGateways --query "[?tags.autoShutdown == 'true']" -o json) + #MS az graph query to find and return a list of all Application Gateways tagged to be included in the auto-shutdown process. + log "----------------------------------------------" + log "Running az graph query..." + + if [ -z $1 ]; then + env_selector="" + elif [ $1 == "untagged" ]; then + env_selector="| where isnull(tags.environment)" + else + env_selector="| where tags.environment == '$1'" + fi + + az graph query -q " + resources + | where type =~ 'microsoft.network/applicationgateways' + | where tags.autoShutdown == 'true' + $env_selector + | project name, resourceGroup, subscriptionId, ['tags'], properties.provisioningState, ['id'] + " --first 1000 -o json + + log "az graph query complete" } # Function that accepts the app gateway json as input and sets variables for later use to stop or start App Gateway function get_application_gateways_details() { RESOURCE_GROUP=$(jq -r '.resourceGroup' <<< $application_gateway) - APPLICATION_GATEWAY_ID=$(jq -r '.id' <<< $application_gateway) APPLICATION_GATEWAY_NAME=$(jq -r '.name' <<< $application_gateway) ENVIRONMENT=$(echo $APPLICATION_GATEWAY_NAME | rev | cut -d'-' -f 2 | rev ) + SUBSCRIPTION=$(jq -r '.subscriptionId' <<< $application_gateway) BUSINESS_AREA=$( jq -r 'if (.tags.businessArea|ascii_downcase) == "ss" then "cross-cutting" else .tags.businessArea|ascii_downcase end' <<< $application_gateway) STARTUP_MODE=$(jq -r '.tags.startupMode' <<< $application_gateway) - APPLICATION_GATEWAY_STATE=$(az network application-gateway show --ids $APPLICATION_GATEWAY_ID | jq -r .operationalState) + APPLICATION_GATEWAY_STATE=$(jq -r '.properties_provisioningState' <<< $application_gateway) } function appgateway_state_messages() { From 972c12e95e4b7f6c873b14bf2be5ad74c8e9e8ec Mon Sep 17 00:00:00 2001 From: Jordan Hoey Date: Thu, 26 Sep 2024 15:59:37 +0100 Subject: [PATCH 2/5] FlexibleServer - graph update --- .github/workflows/flexibleserver-auto-shutdown.yaml | 4 ++-- .github/workflows/flexibleserver-auto-start.yaml | 4 ++-- scripts/flexible-server/auto-start-stop.sh | 3 ++- scripts/flexible-server/common-functions.sh | 5 +++-- scripts/flexible-server/flexserverstatus.sh | 6 +++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/flexibleserver-auto-shutdown.yaml b/.github/workflows/flexibleserver-auto-shutdown.yaml index ffa140f1..a68286cd 100644 --- a/.github/workflows/flexibleserver-auto-shutdown.yaml +++ b/.github/workflows/flexibleserver-auto-shutdown.yaml @@ -61,7 +61,7 @@ jobs: - name: Wait for Flexible servers to start if: env.DEV_ENV != 'true' run: sleep 600 - + - name: Postgres Flexible server status check if: env.DEV_ENV != 'true' - run: ./scripts/flexible-server/flexserverstatus.sh stop ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} + run: ./scripts/flexible-server/flexserverstatus.sh stop ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} \ No newline at end of file diff --git a/.github/workflows/flexibleserver-auto-start.yaml b/.github/workflows/flexibleserver-auto-start.yaml index 067aa9c5..7f57f92a 100644 --- a/.github/workflows/flexibleserver-auto-start.yaml +++ b/.github/workflows/flexibleserver-auto-start.yaml @@ -19,7 +19,7 @@ jobs: client-id: 2b6fa9d7-7dba-4600-a58a-5e25554997aa # DTS AKS Auto-Shutdown tenant-id: 531ff96d-0ae9-462a-8d2d-bec7c0b42082 # HMCTS.NET allow-no-subscriptions: true - + - name: Staging - Postgres Flexible server Auto Start run: ./scripts/flexible-server/auto-start-stop.sh start staging env: @@ -61,7 +61,7 @@ jobs: - name: Wait for Flexible servers to start if: env.DEV_ENV != 'true' run: sleep 600 - + - name: Postgres Flexible server status check if: env.DEV_ENV != 'true' run: ./scripts/flexible-server/flexserverstatus.sh start ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} \ No newline at end of file diff --git a/scripts/flexible-server/auto-start-stop.sh b/scripts/flexible-server/auto-start-stop.sh index f9d955d0..461eaeed 100755 --- a/scripts/flexible-server/auto-start-stop.sh +++ b/scripts/flexible-server/auto-start-stop.sh @@ -21,6 +21,7 @@ flexible_server_count=$(jq -c -r '.count' <<< $FLEXIBLE_SERVERS) log "$flexible_server_count Flexible Servers found" log "----------------------------------------------" + # For each PostgreSQL Flexible Server returned from the az graph query start another loop jq -c '.data[]' <<<$FLEXIBLE_SERVERS | while read flexibleserver; do @@ -50,7 +51,7 @@ jq -c '.data[]' <<<$FLEXIBLE_SERVERS | while read flexibleserver; do if [[ $SKIP == "false" ]]; then if [[ $DEV_ENV != "true" ]]; then flexible_server_state_messages - az postgres flexible-server $MODE --resource-group $RESOURCE_GROUP --name $SERVER_NAME --subscription $SUBSCRIPTION_ID --no-wait || echo Ignoring any errors while $MODE operation on sql server + az postgres flexible-server $MODE --resource-group $RESOURCE_GROUP --name $SERVER_NAME --subscription $SUBSCRIPTION --no-wait || echo Ignoring any errors while $MODE operation on sql server else ts_echo_color BLUE "Development Env: simulating state commands only." flexible_server_state_messages diff --git a/scripts/flexible-server/common-functions.sh b/scripts/flexible-server/common-functions.sh index 9bf6850f..0733e092 100755 --- a/scripts/flexible-server/common-functions.sh +++ b/scripts/flexible-server/common-functions.sh @@ -1,4 +1,5 @@ #!/bin/bash + function get_flexible_sql_servers() { #MS az graph query to find and return a list of all PostgreSQL Flexible Servers tagged to be included in the auto-shutdown process. log "----------------------------------------------" @@ -23,7 +24,6 @@ function get_flexible_sql_servers() { log "az graph query complete" } - # Function that accepts the PostgreSQL flexible server json as input and sets variables for later use to stop or start as required. function get_flexible_sql_server_details() { RESOURCE_GROUP=$(jq -r '.resourceGroup' <<< $flexibleserver) @@ -33,7 +33,8 @@ function get_flexible_sql_server_details() { BUSINESS_AREA=$( jq -r 'if (.tags.businessArea | ascii_downcase) == "ss" then "cross-cutting" else .tags.businessArea | ascii_downcase end' <<< $flexibleserver) STARTUP_MODE=$(jq -r '.tags.startupMode' <<< $flexibleserver) SERVER_STATE=$(jq -r '.properties_state' <<< $flexibleserver) - SUBSCRIPTION_ID=$(jq -r '.subscriptionId' <<< $flexibleserver) + SUBSCRIPTION=$(jq -r '.subscriptionId' <<< $flexibleserver) + } function flexible_server_state_messages() { diff --git a/scripts/flexible-server/flexserverstatus.sh b/scripts/flexible-server/flexserverstatus.sh index 1d66aad9..a99c76a0 100755 --- a/scripts/flexible-server/flexserverstatus.sh +++ b/scripts/flexible-server/flexserverstatus.sh @@ -21,7 +21,7 @@ fi FLEXIBLE_SERVERS=$(get_flexible_sql_servers) # For each Flexible SQL Server found in the function `get_subscription_flexible_sql_servers` start another loop -jq -c '.[]' <<<$FLEXIBLE_SERVERS | while read flexibleserver; do +jq -c '.data[]' <<<$FLEXIBLE_SERVERS | while read flexibleserver; do # Function that returns the Resource Group, Id and Name of the Flexible SQL Server and its current state as variables get_flexible_sql_server_details @@ -41,8 +41,8 @@ jq -c '.[]' <<<$FLEXIBLE_SERVERS | while read flexibleserver; do SKIP=$(should_skip_start_stop $flexible_server_env $flexible_server_business_area $MODE) # Setup message output templates for later use - logMessage="Flexible SQL Server: $SERVER_NAME in Subscription: $SUBSCRIPTION_ID ResourceGroup: $RESOURCE_GROUP is in $SERVER_STATE state after $MODE action" - slackMessage="Flexible SQL Server: *$SERVER_NAME* in Subscription: *$SUBSCRIPTION_ID* is in *$SERVER_STATE* state after *$MODE* action" + logMessage="Flexible SQL Server: $SERVER_NAME in Subscription: $SUBSCRIPTION ResourceGroup: $RESOURCE_GROUP is in $SERVER_STATE state after $MODE action" + slackMessage="Flexible SQL Server: *$SERVER_NAME* in Subscription: *$SUBSCRIPTION* is in *$SERVER_STATE* state after *$MODE* action" # If SKIP is false then we progress with the status check for the particular Flexible server in this loop run, if SKIP is true then do nothing if [[ $SKIP == "false" ]]; then From 47e326aa239166c26a9917f28e8edd3a19aba53a Mon Sep 17 00:00:00 2001 From: Jordan Hoey Date: Thu, 26 Sep 2024 16:04:39 +0100 Subject: [PATCH 3/5] SQL MI - graph update --- .github/workflows/sqlmi-auto-shutdown.yaml | 40 +++++++++- .github/workflows/sqlmi-auto-start.yaml | 40 +++++++++- scripts/sqlmi/auto-start-stop.sh | 88 ++++++++++------------ scripts/sqlmi/common-functions.sh | 28 +++++-- scripts/sqlmi/sqlmistatus.sh | 76 ++++++++----------- 5 files changed, 170 insertions(+), 102 deletions(-) diff --git a/.github/workflows/sqlmi-auto-shutdown.yaml b/.github/workflows/sqlmi-auto-shutdown.yaml index e5cc6230..b66b810e 100644 --- a/.github/workflows/sqlmi-auto-shutdown.yaml +++ b/.github/workflows/sqlmi-auto-shutdown.yaml @@ -3,6 +3,8 @@ on: workflow_dispatch: schedule: - cron: '0 19 * * *' # Every day at 8pm BST +env: + DEV_ENV: ${{ secrets.DEV_ENV }} permissions: id-token: write jobs: @@ -17,16 +19,48 @@ jobs: client-id: 2b6fa9d7-7dba-4600-a58a-5e25554997aa # DTS AKS Auto-Shutdown tenant-id: 531ff96d-0ae9-462a-8d2d-bec7c0b42082 # HMCTS.NET allow-no-subscriptions: true - - name: Sql Managed Instance Auto Shutdown - run: ./scripts/sqlmi/auto-start-stop.sh stop + - name: Staging - Sql Managed Instance Auto Shutdown + run: ./scripts/sqlmi/auto-start-stop.sh stop staging env: - DEV_ENV: ${{ secrets.DEV_ENV }} + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Testing - Sql Managed Instance Auto Shutdown + run: ./scripts/sqlmi/auto-start-stop.sh stop testing + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Demo - Sql Managed Instance Auto Shutdown + run: ./scripts/sqlmi/auto-start-stop.sh stop demo + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Development - Sql Managed Instance Auto Shutdown + run: ./scripts/sqlmi/auto-start-stop.sh stop development + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Sandbox - Sql Managed Instance Auto Shutdown + run: ./scripts/sqlmi/auto-start-stop.sh stop sandbox + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: ITHC - Sql Managed Instance Auto Shutdown + run: ./scripts/sqlmi/auto-start-stop.sh stop ithc + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Untagged - Sql Managed Instance Auto Shutdown + run: ./scripts/sqlmi/auto-start-stop.sh stop untagged + env: + DEV_ENV: ${{ env.DEV_ENV }} - name: Output log file run: ./scripts/common/log-output.sh - name: Wait for Sql Managed Instance to stop + if: env.DEV_ENV != 'true' run: sleep 600 - name: Sql Managed Instance status check + if: env.DEV_ENV != 'true' run: ./scripts/sqlmi/sqlmistatus.sh stop ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} diff --git a/.github/workflows/sqlmi-auto-start.yaml b/.github/workflows/sqlmi-auto-start.yaml index 36a49035..950326b2 100644 --- a/.github/workflows/sqlmi-auto-start.yaml +++ b/.github/workflows/sqlmi-auto-start.yaml @@ -3,6 +3,8 @@ on: workflow_dispatch: schedule: - cron: '30 5 * * 1-5' # Every weekday at 6:30am BST +env: + DEV_ENV: ${{ secrets.DEV_ENV }} permissions: id-token: write jobs: @@ -17,16 +19,48 @@ jobs: client-id: 2b6fa9d7-7dba-4600-a58a-5e25554997aa # DTS AKS Auto-Shutdown tenant-id: 531ff96d-0ae9-462a-8d2d-bec7c0b42082 # HMCTS.NET allow-no-subscriptions: true - - name: Sql Managed Instance Auto Start - run: ./scripts/sqlmi/auto-start-stop.sh start + - name: Staging - Sql Managed Instance Auto Start + run: ./scripts/sqlmi/auto-start-stop.sh start staging env: - DEV_ENV: ${{ secrets.DEV_ENV }} + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Testing - Sql Managed Instance Auto Start + run: ./scripts/sqlmi/auto-start-stop.sh start testing + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Demo - Sql Managed Instance Auto Start + run: ./scripts/sqlmi/auto-start-stop.sh start demo + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Development - Sql Managed Instance Auto Start + run: ./scripts/sqlmi/auto-start-stop.sh start development + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Sandbox - Sql Managed Instance Auto Start + run: ./scripts/sqlmi/auto-start-stop.sh start sandbox + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: ITHC - Sql Managed Instance Auto Start + run: ./scripts/sqlmi/auto-start-stop.sh start ithc + env: + DEV_ENV: ${{ env.DEV_ENV }} + + - name: Untagged - Sql Managed Instance Auto Start + run: ./scripts/sqlmi/auto-start-stop.sh start untagged + env: + DEV_ENV: ${{ env.DEV_ENV }} - name: Output log file run: ./scripts/common/log-output.sh - name: Wait for Sql Managed Instances to start + if: env.DEV_ENV != 'true' run: sleep 600 - name: Sql Managed Instance status check + if: env.DEV_ENV != 'true' run: ./scripts/sqlmi/sqlmistatus.sh start ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} \ No newline at end of file diff --git a/scripts/sqlmi/auto-start-stop.sh b/scripts/sqlmi/auto-start-stop.sh index fe50ddbb..b91dde31 100755 --- a/scripts/sqlmi/auto-start-stop.sh +++ b/scripts/sqlmi/auto-start-stop.sh @@ -16,54 +16,46 @@ if [[ "$MODE" != "start" && "$MODE" != "stop" ]]; then exit 1 fi -# Find all subscriptions that are available to the credential used and saved to SUBSCRIPTIONS variable -SUBSCRIPTIONS=$(az account list -o json) - -# For each subscription found, start the loop -jq -c '.[]' <<< $SUBSCRIPTIONS | while read subscription; do - - # Function that returns the Subscription Id and Name as variables, - # sets the subscription as the default then returns a json formatted variable of available Managed SQL Instances with an autoshutdown tag - get_sql_mi_servers - echo "Scanning $SUBSCRIPTION_NAME..." - log "Scanning $SUBSCRIPTION_NAME..." - - # For each App Gateway found in the function `get_sql_mi_servers` start another loop - jq -c '.[]' <<< $MI_SQL_SERVERS | while read server; do - - # Function that returns the Resource Group, Id and Name of the Managed SQL Instances and its current state as variables - get_sql_mi_server_details - - # Set variables based on inputs which are used to decide when to SKIP an environment - if [[ $ENVIRONMENT == "stg" ]]; then - managed_instance_env=${ENVIRONMENT/stg/Staging} - elif [[ $ENVIRONMENT == "sbox" ]]; then - managed_instance_env=${ENVIRONMENT/sbox/Sandbox} - else - managed_instance_env=$ENVIRONMENT - fi - - managed_instance_business_area=$BUSINESS_AREA - - # SKIP variable updated based on the output of the `should_skip_start_stop` function which calculates its value - # based on the issues_list.json file which contains user requests to keep environments online after normal hours - SKIP=$(should_skip_start_stop $managed_instance_env $managed_instance_business_area $MODE) - - log "=====================================================" - log "Processing SQL Managed Instance: $SERVER_NAME" - log "=====================================================" - - # If SKIP is false then we progress with the action (stop/start) for the particular Managed SQL Instance in this loop run, if not skip and print message to the logs - if [[ $SKIP == "false" ]]; then - if [[ $DEV_ENV != "true" ]]; then - sqlmi_state_messages - az sql mi $MODE --resource-group $RESOURCE_GROUP --mi $SERVER_NAME --no-wait || echo Ignoring any errors while $MODE operation on sql server - else - ts_echo_color BLUE "Development Env: simulating state commands only." - sqlmi_state_messages - fi +MI_SQL_SERVERS=$(get_sql_mi_servers "$2") +mi_sql_server_count=$(jq -c -r '.count' <<< $MI_SQL_SERVERS) +log "$mi_sql_server_count MI SQL Servers found" +log "----------------------------------------------" + +# For each App Gateway found in the function `get_sql_mi_servers` start another loop +jq -c '.data[]' <<<$MI_SQL_SERVERS | while read server; do + + # Function that returns the Resource Group, Id and Name of the Managed SQL Instances and its current state as variables + get_sql_mi_server_details + + # Set variables based on inputs which are used to decide when to SKIP an environment + if [[ $ENVIRONMENT == "stg" ]]; then + managed_instance_env=${ENVIRONMENT/stg/Staging} + elif [[ $ENVIRONMENT == "sbox" ]]; then + managed_instance_env=${ENVIRONMENT/sbox/Sandbox} + else + managed_instance_env=$ENVIRONMENT + fi + + managed_instance_business_area=$BUSINESS_AREA + + # SKIP variable updated based on the output of the `should_skip_start_stop` function which calculates its value + # based on the issues_list.json file which contains user requests to keep environments online after normal hours + SKIP=$(should_skip_start_stop $managed_instance_env $managed_instance_business_area $MODE) + + log "=====================================================" + log "Processing SQL Managed Instance: $SERVER_NAME" + log "=====================================================" + + # If SKIP is false then we progress with the action (stop/start) for the particular Managed SQL Instance in this loop run, if not skip and print message to the logs + if [[ $SKIP == "false" ]]; then + if [[ $DEV_ENV != "true" ]]; then + sqlmi_state_messages + az sql mi $MODE --resource-group $RESOURCE_GROUP --mi $SERVER_NAME --subscription $SUBSCRIPTION --no-wait || echo Ignoring any errors while $MODE operation on sql server else - ts_echo_color AMBER "SQL server $SERVER_NAME (rg:$RESOURCE_GROUP) has been skipped from today's $MODE operation schedule" + ts_echo_color BLUE "Development Env: simulating state commands only." + sqlmi_state_messages fi - done + else + ts_echo_color AMBER "SQL server $SERVER_NAME (rg:$RESOURCE_GROUP) has been skipped from today's $MODE operation schedule" + fi done diff --git a/scripts/sqlmi/common-functions.sh b/scripts/sqlmi/common-functions.sh index b6024042..4f397560 100755 --- a/scripts/sqlmi/common-functions.sh +++ b/scripts/sqlmi/common-functions.sh @@ -2,10 +2,27 @@ # Function that uses the subscription input to get set variables for later use and gather all managed sql servers within the subscription for shutdown function get_sql_mi_servers() { - SUBSCRIPTION_ID=$(jq -r '.id' <<< $subscription) - SUBSCRIPTION_NAME=$(jq -r '.name' <<< $subscription) - az account set -s $SUBSCRIPTION_ID - MI_SQL_SERVERS=$(az resource list --resource-type Microsoft.Sql/managedInstances --query "[?tags.autoShutdown == 'true']" -o json) + #MS az graph query to find and return a list of all SQL MI servers tagged to be included in the auto-shutdown process. + log "----------------------------------------------" + log "Running az graph query..." + + if [ -z $1 ]; then + env_selector="" + elif [ $1 == "untagged" ]; then + env_selector="| where isnull(tags.environment)" + else + env_selector="| where tags.environment == '$1'" + fi + + az graph query -q " + resources + | where type =~ 'microsoft.sql/managedinstances' + | where tags.autoShutdown == 'true' + $env_selector + | project name, resourceGroup, subscriptionId, ['tags'], properties.state, ['id'] + " --first 1000 -o json + + log "az graph query complete" } # Function that accepts the managed sql server json as input and sets variables for later use to stop or start managed sql server @@ -15,8 +32,9 @@ function get_sql_mi_server_details() { SERVER_NAME=$(jq -r '.name' <<< $server) ENVIRONMENT=$(echo $SERVER_NAME | cut -d'-' -f 3) BUSINESS_AREA=$( jq -r 'if (.tags.businessArea|ascii_downcase) == "ss" then "cross-cutting" else .tags.businessArea|ascii_downcase end' <<< $server) - SERVER_STATE=$(az sql mi show --ids $SERVER_ID --query "state") + SERVER_STATE=$(jq -r '.properties_state' <<< $server) STARTUP_MODE=$(jq -r '.tags.startupMode' <<< $server) + SUBSCRIPTION=$(jq -r '.subscriptionId' <<< $server) } function sqlmi_state_messages() { diff --git a/scripts/sqlmi/sqlmistatus.sh b/scripts/sqlmi/sqlmistatus.sh index 813834ef..f2528aac 100755 --- a/scripts/sqlmi/sqlmistatus.sh +++ b/scripts/sqlmi/sqlmistatus.sh @@ -18,58 +18,48 @@ if [[ "$MODE" != "start" && "$MODE" != "stop" ]]; then exit 1 fi -# Find all subscriptions that are available to the credential used and saved to SUBSCRIPTIONS variable -SUBSCRIPTIONS=$(az account list -o json) +MI_SQL_SERVERS=$(get_sql_mi_servers "$2") -# For each subscription found, start the loop -jq -c '.[]' <<< $SUBSCRIPTIONS | while read subscription; do +# For each App Gateway found in the function `get_application_gateways` start another loop +jq -c '.[]' <<<$MI_SQL_SERVERS | while read server; do - # Function that returns the Subscription Id and Name as variables, - # sets the subscription as the default then returns a json formatted variable of available Managed SQL Instances with an autoshutdown tag - get_sql_mi_servers - echo "Scanning $SUBSCRIPTION_NAME..." + # Function that returns the Resource Group, Id and Name of the Application Gateway and its current state as variables + get_sql_mi_server_details - # For each App Gateway found in the function `get_application_gateways` start another loop - jq -c '.[]'<<< $MI_SQL_SERVERS | while read server; do + # Set variables based on inputs which are used to decide when to SKIP an environment + managed_instance_env=${ENVIRONMENT/stg/Staging} + managed_instance_business_area=${BUSINESS_AREA/ss/cross-cutting} - # Function that returns the Resource Group, Id and Name of the Application Gateway and its current state as variables - get_sql_mi_server_details + # SKIP variable updated based on the output of the `should_skip_start_stop` function which calculates its value + # based on the issues_list.json file which contains user requests to keep environments online after normal hours + SKIP=$(should_skip_start_stop $managed_instance_env $managed_instance_business_area $MODE) - # Set variables based on inputs which are used to decide when to SKIP an environment - managed_instance_env=${ENVIRONMENT/stg/Staging} - managed_instance_business_area=${BUSINESS_AREA/ss/cross-cutting} + # Setup message output templates for later use + logMessage="SQL managed-instance: $SERVER_NAME in Subscription: $SUBSCRIPTION and ResourceGroup: $RESOURCE_GROUP is $SERVER_STATE after $MODE action" + slackMessage="SQL managed-instance: *$SERVER_NAME* in Subscription: *$SUBSCRIPTION* and ResourceGroup: *$RESOURCE_GROUP* is *$SERVER_STATE* after *$MODE* action" - # SKIP variable updated based on the output of the `should_skip_start_stop` function which calculates its value - # based on the issues_list.json file which contains user requests to keep environments online after normal hours - SKIP=$(should_skip_start_stop $managed_instance_env $managed_instance_business_area $MODE) - - # Setup message output templates for later use - logMessage="SQL managed-instance: $SERVER_NAME in Subscription: $SUBSCRIPTION_NAME and ResourceGroup: $RESOURCE_GROUP is $SERVER_STATE after $MODE action" - slackMessage="SQL managed-instance: *$SERVER_NAME* in Subscription: *$SUBSCRIPTION_NAME* and ResourceGroup: *$RESOURCE_GROUP* is *$SERVER_STATE* after *$MODE* action" - - # If SKIP is false then we progress with the status check for the particular Managed SQL Instance in this loop run, if SKIP is true then do nothing - if [[ $SKIP == "false" ]]; then + # If SKIP is false then we progress with the status check for the particular Managed SQL Instance in this loop run, if SKIP is true then do nothing + if [[ $SKIP == "false" ]]; then # Check state of the Managed SQL Instance and print output as required # Depending on the value of MODE a notification will also be sent # - If MODE = Start then a stopped App Gateway is incorrect and we should notify # - If MODE = Stop then a running App Gateway is incorrect and we should notify # - If neither Running or Stopped is found then something else is going on and we should notify - case "$SERVER_STATE" in - *"Ready"*) - ts_echo_color $( [[ $MODE == "start" ]] && echo GREEN || echo RED ) "$logMessage" - [[ $MODE == "stop" ]] && auto_shutdown_notification ":red_circle: $slackMessage" - ;; - *"Stopped"*) - ts_echo_color $( [[ $MODE == "start" ]] && echo RED || echo GREEN ) "$logMessage" - [[ $MODE == "start" ]] && auto_shutdown_notification ":red_circle: $slackMessage" - ;; - *) - ts_echo_color AMBER "$logMessage" - auto_shutdown_notification ":yellow_circle: $slackMessage" - ;; - esac - else - ts_echo_color AMBER "SQL managed-instance: $SERVER_NAME in ResourceGroup: $RESOURCE_GROUP has been skipped from today's $MODE operation schedule" - fi - done + case "$SERVER_STATE" in + *"Ready"*) + ts_echo_color $([[ $MODE == "start" ]] && echo GREEN || echo RED) "$logMessage" + [[ $MODE == "stop" ]] && auto_shutdown_notification ":red_circle: $slackMessage" + ;; + *"Stopped"*) + ts_echo_color $([[ $MODE == "start" ]] && echo RED || echo GREEN) "$logMessage" + [[ $MODE == "start" ]] && auto_shutdown_notification ":red_circle: $slackMessage" + ;; + *) + ts_echo_color AMBER "$logMessage" + auto_shutdown_notification ":yellow_circle: $slackMessage" + ;; + esac + else + ts_echo_color AMBER "SQL managed-instance: $SERVER_NAME in ResourceGroup: $RESOURCE_GROUP has been skipped from today's $MODE operation schedule" + fi done From 72d5938fde8f3d72a5ce1103c2984b9aadb1bb2f Mon Sep 17 00:00:00 2001 From: Jordan Hoey Date: Thu, 26 Sep 2024 16:15:32 +0100 Subject: [PATCH 4/5] Blob storage - graph update --- scripts/blob-storage/common-functions.sh | 46 ++++++++++++++---- scripts/blob-storage/disable_sftp.sh | 59 ++++++++---------------- scripts/blob-storage/enable_sftp.sh | 58 ++++++++--------------- 3 files changed, 74 insertions(+), 89 deletions(-) diff --git a/scripts/blob-storage/common-functions.sh b/scripts/blob-storage/common-functions.sh index 73bbabbc..c6cc169d 100755 --- a/scripts/blob-storage/common-functions.sh +++ b/scripts/blob-storage/common-functions.sh @@ -1,13 +1,38 @@ #!/bin/bash # Function that uses the subscription input to get set variables for later use and gather all storage accounts that have SFTP enabled or disabled -# within the subscription for shutdown + function get_sftp_servers() { - SUBSCRIPTION_ID=$(jq -r '.id' <<< $subscription) - SUBSCRIPTION_NAME=$(jq -r '.name' <<< $subscription) - az account set -s $SUBSCRIPTION_ID - ENABLED_SFTP_SERVERS=$(az storage account list --query "[?tags.autoShutdown == 'true' && isSftpEnabled]" -o json) - DISABLED_SFTP_SERVERS=$(az storage account list --query "[?tags.autoShutdown == 'true' && !isSftpEnabled]" -o json) + #MS az graph query to find and return a list of all Application Gateways tagged to be included in the auto-shutdown process. + log "----------------------------------------------" + log "Running az graph query..." + + if [ -z "$1" ]; then + env_selector="" + elif [ "$1" == "untagged" ]; then + env_selector="| where isnull(tags.environment)" + else + env_selector="| where tags.environment == '$1'" + fi + + if [ "$2" == true ]; then + env_selector="| where properties.isSftpEnabled == true" + elif [ "$2" == false ]; then + env_selector="| where properties.isSftpEnabled == false" + else + sftp_selector="" + fi + + az graph query -q " + Resources + | where type == 'microsoft.storage/storageaccounts' + | where tags['autoShutdown'] == 'true' + $env_selector + $env_selector + | project name, id, tags, properties, subscriptionId + " --first 1000 -o json + + log "az graph query complete" } # Function that accepts the app gateway json as input and sets variables for later use to stop or start the SFTP server @@ -15,16 +40,17 @@ function get_sftp_server_details() { RESOURCE_GROUP=$(jq -r '.resourceGroup' <<< $sftpserver) STORAGE_ACCOUNT_ID=$(jq -r '.id' <<< $sftpserver) STORAGE_ACCOUNT_NAME=$(jq -r '.name' <<< $sftpserver) - SFTP_SERVER_ENABLED=$(jq -r '.isSftpEnabled' <<< $sftpserver) - SFTP_SERVER_STATE=$( [[ "$SFTP_SERVER_ENABLED" =~ "true" ]] && echo enabled || echo disabled ) + SFTP_SERVER_ENABLED=$(jq -r '.properties.isSftpEnabled' <<< $sftpserver) + SFTP_SERVER_STATE=$(jq -r '.properties.provisioningState' <<< $sftpserver) + SUBSCRIPTION=$(jq -r '.subscriptionId' <<< $sftpserver) } function blob_state_enabled_messages() { - ts_echo_color GREEN "Enabling SFTP on Storage Account: $STORAGE_ACCOUNT_NAME in Resource Group: $RESOURCE_GROUP and Subscription: $SUBSCRIPTION_NAME" + ts_echo_color GREEN "Enabling SFTP on Storage Account: $STORAGE_ACCOUNT_NAME in Resource Group: $RESOURCE_GROUP and Subscription: $SUBSCRIPTION" ts_echo_color GREEN "Command to run: az storage account update -g $RESOURCE_GROUP -n $STORAGE_ACCOUNT_NAME --enable-sftp=true || echo Ignoring errors Enabling $STORAGE_ACCOUNT_NAME" } function blob_state_disabled_messages() { - ts_echo_color GREEN "Disabling SFTP on Storage Account: $STORAGE_ACCOUNT_NAME in Resource Group: $RESOURCE_GROUP and Subscription: $SUBSCRIPTION_NAME" + ts_echo_color GREEN "Disabling SFTP on Storage Account: $STORAGE_ACCOUNT_NAME in Resource Group: $RESOURCE_GROUP and Subscription: $SUBSCRIPTION" ts_echo_color GREEN "Command to run: az storage account update -g $RESOURCE_GROUP -n $STORAGE_ACCOUNT_NAME --enable-sftp=false || echo Ignoring errors Disabling $STORAGE_ACCOUNT_NAME" } \ No newline at end of file diff --git a/scripts/blob-storage/disable_sftp.sh b/scripts/blob-storage/disable_sftp.sh index 772ce977..7ae18ba8 100755 --- a/scripts/blob-storage/disable_sftp.sh +++ b/scripts/blob-storage/disable_sftp.sh @@ -6,52 +6,31 @@ shopt -s nocasematch source scripts/blob-storage/common-functions.sh source scripts/common/common-functions.sh -# Set variables for later use, MODE has a default but can be overridden at usage time -MODE=${1:-start} SKIP="false" -# Catch problems with MODE input, must be one of Start/Stop -if [[ "$MODE" != "start" && "$MODE" != "stop" ]]; then - echo "Invalid MODE. Please use 'start' or 'stop'." - exit 1 -fi +ENABLED_SFTP_SERVERS=$(get_sftp_servers "$1" true) -# Find all subscriptions that are available to the credential used and saved to SUBSCRIPTIONS variable -SUBSCRIPTIONS=$(az account list -o json) +# For each Storage Account found in the function `get_sftp_servers` start another loop +# The list of SFTP Servers used is ENABLED_SFTP_SERVERS as we want to stop the SFTP service +jq -c '.data[]' <<<$ENABLED_SFTP_SERVERS | while read sftpserver; do -# For each subscription found, start the loop -jq -c '.[]' <<<$SUBSCRIPTIONS | while read subscription -do + # Function that returns the Resource Group, Id and Name of the Storage Account and the current state of the SFTP Server as variables + get_sftp_server_details - # Function that returns the Subscription Id and Name as variables, sets the subscription - # as the default then returns a json formatted variable of available SFTP Servers with an autoshutdown tag - get_sftp_servers - echo "Scanning $SUBSCRIPTION_NAME..." - log "Scanning $SUBSCRIPTION_NAME..." + log "=====================================================" + log "Processing SFTP: $STORAGE_ACCOUNT_NAME" + log "=====================================================" - # For each Storage Account found in the function `get_sftp_servers` start another loop - # The list of SFTP Servers used is DISABLED_SFTP_SERVERS as we want to start the SFTP service - jq -c '.[]'<<< $ENABLED_SFTP_SERVERS | while read sftpserver - do - - # Function that returns the Resource Group, Id and Name of the Storage Account and the current state of the SFTP Server as variables - get_sftp_server_details - - log "=====================================================" - log "Processing SFTP: $STORAGE_ACCOUNT_NAME" - log "=====================================================" - - # If SKIP is false then we progress with the action (stop/start) for the particular App Gateway in this loop run, if not skip and print message to the logs - if [[ $SKIP == "false" ]]; then - if [[ $DEV_ENV != "true" ]]; then - blob_state_disabled_messages - az storage account update -g $RESOURCE_GROUP -n $STORAGE_ACCOUNT_NAME --enable-sftp=false || echo Ignoring errors Disabling $STORAGE_ACCOUNT_NAME - else - ts_echo_color BLUE "Development Env: simulating state commands only." - blob_state_disabled_messages - fi + # If SKIP is false then we progress with the action (stop/start) for the particular App Gateway in this loop run, if not skip and print message to the logs + if [[ $SKIP == "false" ]]; then + if [[ $DEV_ENV != "true" ]]; then + blob_state_disabled_messages + az storage account update -g $RESOURCE_GROUP -n $STORAGE_ACCOUNT_NAME --subscription $SUBSCRIPTION --enable-sftp=false || echo Ignoring errors Disabling $STORAGE_ACCOUNT_NAME else - ts_echo_color AMBER "Storage account $STORAGE_ACCOUNT_NAME in Resource Group:$RESOURCE_GROUP and Subscription:$SUBSCRIPTION_NAME has been skipped from todays shutdown schedule" + ts_echo_color BLUE "Development Env: simulating state commands only." + blob_state_disabled_messages fi - done + else + ts_echo_color AMBER "Storage account $STORAGE_ACCOUNT_NAME in Resource Group:$RESOURCE_GROUP and Subscription:$SUBSCRIPTION_NAME has been skipped from todays shutdown schedule" + fi done diff --git a/scripts/blob-storage/enable_sftp.sh b/scripts/blob-storage/enable_sftp.sh index a6154d69..10dc257e 100755 --- a/scripts/blob-storage/enable_sftp.sh +++ b/scripts/blob-storage/enable_sftp.sh @@ -6,50 +6,30 @@ shopt -s nocasematch source scripts/blob-storage/common-functions.sh source scripts/common/common-functions.sh -# Set variables for later use, MODE has a default but can be overridden at usage time -MODE=${1:-start} SKIP="false" -# Catch problems with MODE input, must be one of Start/Stop -if [[ "$MODE" != "start" && "$MODE" != "stop" ]]; then - echo "Invalid MODE. Please use 'start' or 'stop'." - exit 1 -fi +DISABLED_SFTP_SERVERS=$(get_sftp_servers "$1" false) -# Find all subscriptions that are available to the credential used and saved to SUBSCRIPTIONS variable -SUBSCRIPTIONS=$(az account list -o json) +# For each Storage Account found in the function `get_sftp_servers` start another loop +# The list of SFTP Servers used is DISABLED_SFTP_SERVERS as we want to start the SFTP service +jq -c '.data[]' <<<$DISABLED_SFTP_SERVERS | while read sftpserver; do + # Function that returns the Resource Group, Id and Name of the Storage Account and the current state of the SFTP Server as variables + get_sftp_server_details -# For each subscription found, start the loop -jq -c '.[]' <<<$SUBSCRIPTIONS | while read subscription -do - # Function that returns the Subscription Id and Name as variables, sets the subscription - # as the default then returns a json formatted variable of available SFTP Servers with an autoshutdown tag - get_sftp_servers - echo "Scanning $SUBSCRIPTION_NAME..." - log "Scanning $SUBSCRIPTION_NAME..." + log "=====================================================" + log "Processing SFTP: $STORAGE_ACCOUNT_NAME" + log "=====================================================" - # For each Storage Account found in the function `get_sftp_servers` start another loop - # The list of SFTP Servers used is DISABLED_SFTP_SERVERS as we want to start the SFTP service - jq -c '.[]'<<< $DISABLED_SFTP_SERVERS | while read sftpserver - do - # Function that returns the Resource Group, Id and Name of the Storage Account and the current state of the SFTP Server as variables - get_sftp_server_details - - log "=====================================================" - log "Processing SFTP: $STORAGE_ACCOUNT_NAME" - log "=====================================================" - - # If SKIP is false then we progress with the action (stop/start) for the particular App Gateway in this loop run, if not skip and print message to the logs - if [[ $SKIP == "false" ]]; then - if [[ $DEV_ENV != "true" ]]; then - blob_state_enabled_messages - az storage account update -g $RESOURCE_GROUP -n $STORAGE_ACCOUNT_NAME --enable-sftp=true || echo Ignoring errors Enabling $STORAGE_ACCOUNT_NAME - else - ts_echo_color BLUE "Development Env: simulating state commands only." - blob_state_enabled_messages - fi + # If SKIP is false then we progress with the action (stop/start) for the particular App Gateway in this loop run, if not skip and print message to the logs + if [[ $SKIP == "false" ]]; then + if [[ $DEV_ENV != "true" ]]; then + blob_state_enabled_messages + az storage account update -g $RESOURCE_GROUP -n $STORAGE_ACCOUNT_NAME --subscription $SUBSCRIPTION --enable-sftp=true || echo Ignoring errors Enabling $STORAGE_ACCOUNT_NAME else - ts_echo_color AMBER "Storage account $STORAGE_ACCOUNT_NAME in Resource Group:$RESOURCE_GROUP and Subscription:$SUBSCRIPTION_NAME has been skipped from todays startup schedule" + ts_echo_color BLUE "Development Env: simulating state commands only." + blob_state_enabled_messages fi - done + else + ts_echo_color AMBER "Storage account $STORAGE_ACCOUNT_NAME in Resource Group:$RESOURCE_GROUP and Subscription:$SUBSCRIPTION_NAME has been skipped from todays startup schedule" + fi done From 6a8b86fecda8f0a79ea803b7087f0a0d4761a636 Mon Sep 17 00:00:00 2001 From: Jordan Hoey Date: Mon, 30 Sep 2024 11:52:58 +0100 Subject: [PATCH 5/5] adding sftp workflow steps --- .../workflows/storage-sftp-auto-disable.yaml | 34 +++++++++++++++++-- .../workflows/storage-sftp-auto-enable.yaml | 34 +++++++++++++++++-- scripts/appgateway/appgw_status.sh | 2 +- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/.github/workflows/storage-sftp-auto-disable.yaml b/.github/workflows/storage-sftp-auto-disable.yaml index a401bd2c..a4ee56f2 100644 --- a/.github/workflows/storage-sftp-auto-disable.yaml +++ b/.github/workflows/storage-sftp-auto-disable.yaml @@ -3,6 +3,8 @@ on: workflow_dispatch: schedule: - cron: "0 19 * * *" # Every day at 8pm BST +env: + DEV_ENV: ${{ secrets.DEV_ENV }} permissions: id-token: write jobs: @@ -17,14 +19,42 @@ jobs: client-id: 2b6fa9d7-7dba-4600-a58a-5e25554997aa # DTS AKS Auto-Shutdown tenant-id: 531ff96d-0ae9-462a-8d2d-bec7c0b42082 # HMCTS.NET allow-no-subscriptions: true - - name: disable sftp - run: ./scripts/blob-storage/disable_sftp.sh + - name: Staging - disable sftp + run: ./scripts/blob-storage/disable_sftp.sh staging + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Testing - disable sftp + run: ./scripts/blob-storage/disable_sftp.sh testing + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Demo - disable sftp + run: ./scripts/blob-storage/disable_sftp.sh demo + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Development - disable sftp + run: ./scripts/blob-storage/disable_sftp.sh development + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Sandbox - disable sftp + run: ./scripts/blob-storage/disable_sftp.sh sandbox + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: ITHC - disable sftp + run: ./scripts/blob-storage/disable_sftp.sh ithc + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Untagged - disable sftp + run: ./scripts/blob-storage/disable_sftp.sh untagged + env: + DEV_ENV: ${{ env.DEV_ENV }} - name: Output log file run: ./scripts/common/log-output.sh - name: Wait for SFTP Servers to stop + if: env.DEV_ENV != 'true' run: sleep 300 - name: sftp status check + if: env.DEV_ENV != 'true' run: ./scripts/blob-storage/sftp-check-status.sh stop ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} diff --git a/.github/workflows/storage-sftp-auto-enable.yaml b/.github/workflows/storage-sftp-auto-enable.yaml index 1db1c365..b4fd94f2 100644 --- a/.github/workflows/storage-sftp-auto-enable.yaml +++ b/.github/workflows/storage-sftp-auto-enable.yaml @@ -3,6 +3,8 @@ on: workflow_dispatch: schedule: - cron: "30 5 * * 1-5" # Every weekday at 6:30am BST +env: + DEV_ENV: ${{ secrets.DEV_ENV }} permissions: id-token: write jobs: @@ -17,14 +19,42 @@ jobs: client-id: 2b6fa9d7-7dba-4600-a58a-5e25554997aa # DTS AKS Auto-Shutdown tenant-id: 531ff96d-0ae9-462a-8d2d-bec7c0b42082 # HMCTS.NET allow-no-subscriptions: true - - name: sftp enable - run: ./scripts/blob-storage/enable_sftp.sh + - name: Staging - enable sftp + run: ./scripts/blob-storage/enable_sftp.sh staging + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Testing - enable sftp + run: ./scripts/blob-storage/enable_sftp.sh testing + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Demo - enable sftp + run: ./scripts/blob-storage/enable_sftp.sh demo + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Development - enable sftp + run: ./scripts/blob-storage/enable_sftp.sh development + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Sandbox - enable sftp + run: ./scripts/blob-storage/enable_sftp.sh sandbox + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: ITHC - enable sftp + run: ./scripts/blob-storage/enable_sftp.sh ithc + env: + DEV_ENV: ${{ env.DEV_ENV }} + - name: Untagged - enable sftp + run: ./scripts/blob-storage/enable_sftp.sh untagged + env: + DEV_ENV: ${{ env.DEV_ENV }} - name: Output log file run: ./scripts/common/log-output.sh - name: Wait for SFTP Servers to start + if: env.DEV_ENV != 'true' run: sleep 300 - name: sftp status check + if: env.DEV_ENV != 'true' run: ./scripts/blob-storage/sftp-check-status.sh start ${{ secrets.SHUTDOWN_NOTIFICATIONS_WEBHOOK }} diff --git a/scripts/appgateway/appgw_status.sh b/scripts/appgateway/appgw_status.sh index b37fe209..825b7635 100755 --- a/scripts/appgateway/appgw_status.sh +++ b/scripts/appgateway/appgw_status.sh @@ -21,7 +21,7 @@ fi APPLICATION_GATEWAYS=$(get_application_gateways "$2") # For each App Gateway found in the function `get_application_gateways` start another loop -jq -c '.[]' <<<$APPLICATION_GATEWAYS | while read application_gateway; do +jq -c '.data[]' <<<$APPLICATION_GATEWAYS | while read application_gateway; do # Function that returns the Resource Group, Id and Name of the Application Gateway and its current state as variables get_application_gateways_details