Created
August 19, 2024 20:11
-
-
Save alloydwhitlock/ebf8a4eae1e39e5c5e66ae21dd7bb458 to your computer and use it in GitHub Desktop.
Retrieve information on long-lived Coder workspaces which are turned off, but still present.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import requests | |
from datetime import datetime, timedelta, timezone | |
# Replace these with your actual Coder API URL and API token | |
# To obtain these values, log in to your Coder account and navigate to your profile settings. | |
# The API URL can typically be found in the documentation or your organization's Coder instance. | |
# The API token (Coder-Session-Token) can be generated from your profile settings. | |
CODER_API_URL = "https://coder.yourdomain.com/api/v2" | |
API_TOKEN = "XXXXXXXX-XXXXXXXXXXXXX" | |
def get_workspaces(): | |
""" | |
Retrieves the list of workspaces from the Coder API. | |
Returns: | |
dict: The JSON response from the API containing the list of workspaces. | |
Raises: | |
HTTPError: If the request to the API fails. | |
""" | |
headers = { | |
"Content-Type": "application/json", | |
"Accept": "application/json", | |
"Coder-Session-Token": API_TOKEN, | |
} | |
response = requests.get(f"{CODER_API_URL}/workspaces", headers=headers) | |
# Check if the request was successful | |
if response.status_code != 200: | |
print(f"Failed to retrieve workspaces. Status code: {response.status_code}") | |
print(f"Response text: {response.text}") | |
response.raise_for_status() | |
# Attempt to parse the JSON response | |
try: | |
return response.json() | |
except requests.exceptions.JSONDecodeError: | |
print("Failed to parse JSON response.") | |
print(f"Response text: {response.text}") | |
raise | |
def filter_inactive_workspaces(workspaces, days=7): | |
""" | |
Filters the workspaces that have been inactive for a specified number of days. | |
Args: | |
workspaces (dict): The JSON response containing the list of workspaces. | |
days (int): The number of days to consider a workspace inactive. Default is 7 days. | |
Returns: | |
list: A list of inactive workspaces. | |
""" | |
inactive_workspaces = [] | |
threshold_date = datetime.now(timezone.utc) - timedelta(days=days) | |
for workspace in workspaces.get("workspaces", []): | |
# Check last_used_at and status | |
last_used_str = workspace.get("last_used_at") | |
status = workspace.get("status", "") | |
if last_used_str: | |
try: | |
last_used_date = datetime.strptime( | |
last_used_str, "%Y-%m-%dT%H:%M:%S.%fZ" | |
).replace(tzinfo=timezone.utc) | |
# Check if last used date is older than the threshold and if the instance is stopped | |
if last_used_date < threshold_date: | |
inactive_workspaces.append(workspace) | |
except ValueError as e: | |
print(f"Error parsing date for workspace {workspace.get('name')}: {e}") | |
continue | |
elif status == "stopped": | |
# If no last_used_at but the instance is stopped, consider it inactive | |
inactive_workspaces.append(workspace) | |
return inactive_workspaces | |
def main(): | |
""" | |
Main function to retrieve and filter inactive workspaces, then print the results. | |
""" | |
workspaces_data = get_workspaces() | |
if isinstance(workspaces_data, dict): | |
inactive_workspaces = filter_inactive_workspaces(workspaces_data) | |
if inactive_workspaces: | |
print("Workspaces not used in over a week:") | |
for workspace in inactive_workspaces: | |
print( | |
f"- {workspace['owner_name']} (Workspace Name: {workspace['name']} (Workspace ID: {workspace['id']}) - Last used: {workspace.get('last_used_at', 'N/A')}" | |
) | |
else: | |
print("No inactive workspaces found.") | |
else: | |
print("Unexpected data structure received from the API.") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment