diff --git a/charts/gitops/Chart.yaml b/charts/gitops/Chart.yaml index 2c86361..9c53f1d 100644 --- a/charts/gitops/Chart.yaml +++ b/charts/gitops/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: GitOps Server Helm chart. name: gitops -version: 0.10.3 +version: 0.10.4 diff --git a/gitops/__init__.py b/gitops/__init__.py index d6b5e34..f7cd8dc 100644 --- a/gitops/__init__.py +++ b/gitops/__init__.py @@ -5,7 +5,7 @@ from . import monkeypatches # NOQA from .utils.cli import success, warning -__version__ = "0.10.3" +__version__ = "0.10.4" # Checking gitops version matches cluster repo version. diff --git a/gitops_server/utils/slack.py b/gitops_server/utils/slack.py index d15af48..79af4a1 100644 --- a/gitops_server/utils/slack.py +++ b/gitops_server/utils/slack.py @@ -1,15 +1,17 @@ import dataclasses -import json import logging import os -import urllib.request from collections.abc import Iterable -from typing import Optional import httpx logger = logging.getLogger("gitops") +SLACK_URL = os.environ.get("SLACK_URL") +SLACK_TOKEN = os.environ.get("SLACK_TOKEN") +TICKFORGE_SLACK_KEY = os.environ.get("TICKFORGE_SLACK_KEY") +TICKFORGE_URL = os.environ.get("TICKFORGE_URL") + @dataclasses.dataclass class SlackUser: @@ -27,34 +29,52 @@ def __str__(self) -> str: return f"" -async def post(message): +async def post(message: str) -> None: """Post a message to a slack channel Uses the environment variable `SLACK_URL` to know which channel to post to. This URL is obtained by registering an integration with Slack. """ logger.info("POSTING TO SLACK") - url = os.environ["SLACK_URL"] data = {"text": message} async with httpx.AsyncClient() as client: - response = await client.post(url, json=data) + response = await client.post(SLACK_URL, json=data) if response.status_code >= 300: logger.warning("Failed to post a message to slack (see below):") logger.error(f"{message}", exc_info=True) -def find_commiter_slack_user(name: str, email: str) -> Optional["SlackUser"]: - token = os.environ.get("SLACK_TOKEN", "") - if not token: +async def _tickforge_find_slack_user(name: str, email: str) -> SlackUser | None: + """Find a slack user by name or email using the tickforge API + + This shim exists for our own internal alternative filtering requirements + """ + if TICKFORGE_URL and TICKFORGE_SLACK_KEY: + async with httpx.AsyncClient() as client: + response = await client.get( + f"{TICKFORGE_URL}/api/slack/search", + params={"name": name, "email": email}, + headers={"x-tickforge-slack-key": TICKFORGE_SLACK_KEY}, + ) + return response.json() # type:ignore + else: return None - with urllib.request.urlopen( # noqa:S310 - urllib.request.Request( - "https://slack.com/api/users.list?limit=300&pretty=1", - headers={"Authorization": f"Bearer {token}"}, + +async def find_commiter_slack_user(name: str, email: str) -> SlackUser | None: + """Find a slack user by name or email using the slack API""" + if not SLACK_TOKEN: + return None + + if TICKFORGE_SLACK_KEY and TICKFORGE_URL: + return await _tickforge_find_slack_user(name, email) + + async with httpx.AsyncClient() as client: + response = await client.get( + "https://slack.com/api/users.list?limit=1000&pretty=1", + headers={"Authorization": f"Bearer {SLACK_TOKEN}"}, ) - ) as response: - data = json.loads(response.read()) + data = response.json() if not data["ok"]: raise Exception(data["error"]) @@ -91,9 +111,9 @@ def pairwise_tuples(x: str) -> list[tuple[str, str]]: def search(name: str, email: str, users: list[SlackUser]) -> SlackUser | None: def scoring_fn(user: SlackUser) -> float: return ( - jaccard_similarity(pairwise_tuples(user.email), pairwise_tuples(email)) - + jaccard_similarity(pairwise_tuples(name), pairwise_tuples(user.name)) - + jaccard_similarity(pairwise_tuples(name), pairwise_tuples(user.real_name)) + jaccard_similarity(pairwise_tuples(user.email.lower()), pairwise_tuples(email.lower())) + + jaccard_similarity(pairwise_tuples(name.lower()), pairwise_tuples(user.name.lower())) + + jaccard_similarity(pairwise_tuples(name.lower()), pairwise_tuples(user.real_name.lower())) ) matches = sorted([(scoring_fn(u), u) for u in users], key=lambda x: x[0], reverse=True) diff --git a/pyproject.toml b/pyproject.toml index 633d017..21fe00d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "gitops" -version = "0.10.3" +version = "0.10.4" description = "Manage multiple apps across one or more k8s clusters." authors = ["Jarek GÅ‚owacki "] license = "BSD"