diff options
author | 2025-07-10 13:38:48 +0100 | |
---|---|---|
committer | 2025-07-10 13:45:55 +0100 | |
commit | b169dc300f738c59e717d444445dfe0c8e6da98a (patch) | |
tree | 001737a929998b6798143ad65278e366ae1476c3 | |
parent | Better handling of locking/unlocking users (diff) |
Remove GitHub-Grafana team sync cog
-rw-r--r-- | arthur/apis/github/teams.py | 25 | ||||
-rw-r--r-- | arthur/exts/grafana/github_team_sync.py | 172 |
2 files changed, 0 insertions, 197 deletions
diff --git a/arthur/apis/github/teams.py b/arthur/apis/github/teams.py index 4cf18d4..a8775a3 100644 --- a/arthur/apis/github/teams.py +++ b/arthur/apis/github/teams.py @@ -1,32 +1,7 @@ -import aiohttp - from arthur.config import CONFIG -from arthur.log import logger HEADERS = { "Accept": "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28", "Authorization": f"Bearer {CONFIG.github_token.get_secret_value()}", } -BASE_URL = "https://api.github.com" -MEMBERS_PER_PAGE = 100 - - -class GithubTeamNotFoundError(aiohttp.ClientResponseError): - """Raised when a github team could not be found.""" - - -async def list_team_members(team_slug: str, session: aiohttp.ClientSession) -> list[dict[str, str]]: - """List all Github teams.""" - endpoint = f"{BASE_URL}/orgs/{CONFIG.github_org}/teams/{team_slug}/members" - params = {"per_page": MEMBERS_PER_PAGE} - async with session.get(endpoint, headers=HEADERS, params=params) as response: - response.raise_for_status() - teams_resp = await response.json() - if len(teams_resp) == MEMBERS_PER_PAGE: - logger.warning( - "Max number (%d) of members returned when fetching members of %s. Some members may have been missed.", - MEMBERS_PER_PAGE, - team_slug, - ) - return teams_resp diff --git a/arthur/exts/grafana/github_team_sync.py b/arthur/exts/grafana/github_team_sync.py deleted file mode 100644 index cfc1e77..0000000 --- a/arthur/exts/grafana/github_team_sync.py +++ /dev/null @@ -1,172 +0,0 @@ -import aiohttp -import discord -from discord.ext import commands, tasks - -from arthur.apis import github, grafana -from arthur.bot import KingArthur -from arthur.config import CONFIG -from arthur.log import logger - -from . import MissingMembers, SyncFigures - - -class GrafanaGitHubTeamSync(commands.Cog): - """ - Update Grafana team membership to match Github team membership. - - Grafana team name must match Github team slug exactly. - Use `gh api orgs/{org-name}/teams` to get a list of teams in an org - """ - - def __init__(self, bot: KingArthur) -> None: - self.bot = bot - self.sync_github_grafana_teams.start() - - async def _add_missing_members( - self, - grafana_team_id: int, - github_team_members: set[str], - grafana_team_members: set[str], - all_grafana_users: list[dict], - ) -> MissingMembers: - """ - Adds members to the Grafana team if they're in the Github team and not already present. - - Returns the number of missing members, and the number of members it could actually add. - """ - missing_members = github_team_members - grafana_team_members - added_members = 0 - for grafana_user in all_grafana_users: - if grafana_user["login"] not in missing_members: - continue - if "GitHub" not in grafana_user.get("authLabels", []): - continue - - await grafana.add_user_to_team( - grafana_user["userId"], - grafana_team_id, - self.bot.http_session, - ) - added_members += 1 - return MissingMembers(count=len(missing_members), successfully_added=added_members) - - async def _remove_extra_members( - self, - grafana_team_id: int, - github_team_members: set[str], - grafana_team_members: set[str], - all_grafana_users: list[dict], - ) -> int: - """ - Removes Grafana users from a team if they are not present in the Github team. - - Return how many were removed. - """ - extra_members = grafana_team_members - github_team_members - removed_members = 0 - for grafana_user in all_grafana_users: - if grafana_user["login"] not in extra_members: - continue - await grafana.remove_user_from_team( - grafana_user["userId"], - grafana_team_id, - self.bot.http_session, - ) - removed_members += 1 - return removed_members - - async def _sync_teams(self, team: dict[str, str]) -> SyncFigures: - """ - Ensure members in Github are present in Grafana teams. - - Return the number of members missing from the Grafana team, and the number of members added. - """ - github_team_members = { - member["login"] - for member in await github.list_team_members(team["name"], self.bot.http_session) - } - grafana_team_members = { - member["login"] - for member in await grafana.list_team_members(team["id"], self.bot.http_session) - if member.get("auth_module") == "oauth_github" - } - - all_grafana_users = await grafana.get_all_users(self.bot.http_session) - added_members = await self._add_missing_members( - team["id"], - github_team_members, - grafana_team_members, - all_grafana_users, - ) - removed_members = await self._remove_extra_members( - team["id"], - github_team_members, - grafana_team_members, - all_grafana_users, - ) - - return SyncFigures(added=added_members, removed=removed_members) - - @tasks.loop(hours=12) - async def sync_github_grafana_teams(self, channel: discord.TextChannel | None = None) -> None: - """Update Grafana team membership to match Github team membership.""" - grafana_teams = await grafana.list_teams(self.bot.http_session) - embed = discord.Embed( - title="Sync Stats", - colour=discord.Colour.blue(), - ) - for team in grafana_teams: - logger.debug(f"Processing {team['name']}") - try: - figures = await self._sync_teams(team) - except aiohttp.ClientResponseError as e: - logger.error(e) - if channel: - await channel.send(e) - continue - - lines = [ - f"Missing: {figures.added.count}", - f"Added: {figures.added.successfully_added}", - f"Removed: {figures.removed}", - ] - embed.add_field( - name=team["name"], - value="\n".join(lines), - inline=False, - ) - - if channel: - await channel.send(embed=embed) - - @sync_github_grafana_teams.error - async def on_task_error(self, error: Exception) -> None: - """Ensure task errors are output.""" - logger.error(error) - - @commands.group(name="grafana_github", invoke_without_command=True) - async def grafana_group(self, ctx: commands.Context) -> None: - """Commands for working with grafana API.""" - await ctx.send_help(ctx.command) - - @grafana_group.command(name="sync") - async def sync_teams(self, ctx: commands.Context) -> None: - """Sync Grafana & Github teams now.""" - await self.sync_github_grafana_teams(ctx.channel) - - -async def setup(bot: KingArthur) -> None: - """Add GrafanaGitHubTeamSync cog to bot.""" - if not all( - ( - CONFIG.github_org, - CONFIG.github_token, - CONFIG.grafana_url, - CONFIG.grafana_token, - ) - ): - logger.warning( - "Not loading GrafanaGitHubTeamSync team as a required config entry is missing. See README" - ) - return - await bot.add_cog(GrafanaGitHubTeamSync(bot)) |