Last active
April 2, 2025 13:21
-
-
Save ydkn/e4ee3da80b2d9f8714faa395c9c554ed to your computer and use it in GitHub Desktop.
Check Azure DevOps PAT for expiration-
This file contains hidden or 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 python | |
import os | |
import logging | |
import datetime | |
from dateutil import parser | |
import requests | |
import tracebackturbo as traceback | |
from influxdb import InfluxDBClient | |
class PATChecker: | |
URL = "https://vssps.dev.azure.com/%s/_apis/Token/SessionTokens?pageSize=1000&api-version=6.0-preview.1" | |
def __init__(self, org=os.environ["DEVOPS_ORG"], username=os.environ["DEVOPS_USERNAME"], | |
token=os.environ["DEVOPS_TOKEN"]): | |
self.org = org | |
self.url = self.URL % (org) | |
self.username = username | |
self.token = token | |
# Get stats from indivdual PATs | |
# Return value: [{"measurement": "azure_devops_tokens", tags: {"foo": "bar"}, fields: {"foo": 1.0}}] | |
def metrics(self): | |
req = requests.get(self.url, auth=(self.username, self.token)) | |
if req.status_code != 200: | |
raise Exception("API request returned an error (%d)" % (req.status_code)) | |
points = [] | |
for t in req.json()["value"]: | |
valid_to = parser.parse(t["validTo"]) | |
time_remaining = valid_to - datetime.datetime.now(tz=valid_to.tzinfo) | |
tags = self._default_tags() | |
tags["name"] = t["displayName"] | |
points.append({ | |
'measurement': "azure_devops_tokens", | |
'tags': tags, | |
'fields': { | |
"valid": (0 if t["isValid"] else 1), | |
"expires": time_remaining.total_seconds() / 86400 | |
} | |
}) | |
return points | |
def _default_tags(self): | |
return {'org': self.org, 'username': self.username} | |
if __name__ == '__main__': | |
logging.basicConfig(format='[%(asctime)s] [%(levelname)-8s] %(message)s', | |
level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S') | |
checker = PATChecker() | |
try: | |
influx = InfluxDBClient.from_dsn(os.environ["INFLUXDB_DSN"], timeout=5) | |
influx.write_points(checker.metrics()) | |
except: | |
logging.error(traceback.format_exc()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment