From 2c898287492d80d59d06871602eccc7f26c219c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Bombo?= Date: Tue, 25 Jun 2024 17:15:46 +0000 Subject: [PATCH] ci: Add scheduled job to cleanup resources, pt. II MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #9898 and final PR of this set. This implements the actual deletion logic. Signed-off-by: Aurélien Bombo --- .github/workflows/cleanup-resources.yaml | 20 +++++++- tests/cleanup_resources.py | 61 ++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cleanup-resources.yaml b/.github/workflows/cleanup-resources.yaml index 043e626a96..52cca124e4 100644 --- a/.github/workflows/cleanup-resources.yaml +++ b/.github/workflows/cleanup-resources.yaml @@ -7,7 +7,25 @@ on: jobs: cleanup-resources: runs-on: ubuntu-latest - secrets: inherit steps: + - uses: actions/checkout@v4 + + - name: Log into Azure + env: + AZ_APPID: ${{ secrets.AZ_APPID }} + AZ_PASSWORD: ${{ secrets.AZ_PASSWORD }} + AZ_TENANT_ID: ${{ secrets.AZ_TENANT_ID }} + AZ_SUBSCRIPTION_ID: ${{ secrets.AZ_SUBSCRIPTION_ID }} + run: bash tests/integration/kubernetes/gha-run.sh login-azure + + - name: Install Python dependencies + run: | + pip3 install --user --upgrade \ + azure-identity==1.16.0 \ + azure-mgmt-resource==23.0.1 + - name: Cleanup resources + env: + AZ_SUBSCRIPTION_ID: ${{ secrets.AZ_SUBSCRIPTION_ID }} + CLEANUP_AFTER_HOURS: 6 # Clean up resources created more than this many hours ago. run: python3 tests/cleanup_resources.py diff --git a/tests/cleanup_resources.py b/tests/cleanup_resources.py index e69de29bb2..cdb58a37a3 100644 --- a/tests/cleanup_resources.py +++ b/tests/cleanup_resources.py @@ -0,0 +1,61 @@ +# Copyright (c) Microsoft Corporation. +# Adapted from original code by Jeremi Piotrowski . +from datetime import datetime, timedelta, timezone +import os + +from azure.identity import AzureCliCredential +from azure.mgmt.resource import ResourceManagementClient + +# Current date and time in UTC. +utc_now = datetime.now(timezone.utc) +# Cleanup time delta passed in the environment, i.e. how much time to +# wait before automatically cleaning up a resource. +cleanup_after = timedelta(hours=int(os.environ['CLEANUP_AFTER_HOURS'])) +# Time considered as the cutoff to clean up a resource: if it was +# created before this time, it will be deleted. +cleanup_cutoff_time = utc_now - cleanup_after + +print(f"Current time: {utc_now}") +print(f"Cleanup time delta: {cleanup_after}") +print(f"Will clean up resources created before {cleanup_cutoff_time}") + +credential = AzureCliCredential() +subscription_id = os.environ['AZ_SUBSCRIPTION_ID'] +client = ResourceManagementClient(credential, subscription_id) +resources = client.resources.list(expand='createdTime') + +print("Processsing resources...") +num_deleted = 0 + +for resource in resources: + # Ignore resources that aren't AKS clusters. + if resource.type != 'Microsoft.ContainerService/managedClusters': + continue + + # Ignore resources created after the cutoff time (i.e. less than + # `cleanup_after` time ago). + if resource.created_time > cleanup_cutoff_time: + print(f"{resource.name}: created at {resource.created_time}, after delta cutoff, ignored") + continue + + print(f"{resource.name}: created at {resource.created_time}, before delta cutoff, deleting...") + + # A resource ID looks like this: + # /subscriptions/(subscriptionId)/resourceGroups/(resourceGroupName)/providers/(resourceProviderNamespace)/(resourceType)/(resourceName) + rg_id, _, _ = resource.id.partition("/providers/") + _, _, rg_name = rg_id.partition("/resourceGroups/") + rg_resources = client.resources.list_by_resource_group(rg_name) + + # XXX DANGER ZONE: Delete the resource. If it's the only resource + # in its resource group, the entire resource group is deleted. + + if len(list(rg_resources)) == 1: + client.resource_groups.begin_delete(rg_name) + print(f"{resource.name}: deleted resource group") + else: + client.resources.begin_delete_by_id(resource.id) + print(f"{resource.name}: deleted resource") + + num_deleted += 1 + +print(f"Deleted {num_deleted} resources")