oncall-engine/engine/common/oncall_gateway/utils.py
Ildar Iskhakov a6680e5ac1
Merge hotfix 1.3.94 (#3784)
# What this PR does

## Which issue(s) this PR fixes

## Checklist

- [ ] Unit, integration, and e2e (if applicable) tests updated
- [ ] Documentation added (or `pr:no public docs` PR label added if not
required)
- [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)

---------

Co-authored-by: Joey Orlando <joey.orlando@grafana.com>
Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: Joey Orlando <joseph.t.orlando@gmail.com>
Co-authored-by: Vadim Stepanov <vadimkerr@gmail.com>
2024-01-30 18:33:22 +08:00

196 lines
7.2 KiB
Python

"""
Set of utils to handle oncall and chatops-proxy interaction.
TODO: Once chatops v3 will be released, remove legacy and wrapper functions
"""
import logging
import requests
from django.conf import settings
from .client import SERVICE_TYPE_ONCALL, ChatopsProxyAPIClient
from .legacy_client import OnCallGatewayAPIClient
from .tasks import (
create_oncall_connector_async,
create_slack_connector_async_v2,
delete_oncall_connector_async,
delete_slack_connector_async_v2,
link_slack_team_async,
register_oncall_tenant_async,
unlink_slack_team_async,
unregister_oncall_tenant_async,
)
logger = logging.getLogger(__name__)
# Legacy to work with chatops-proxy v1.
def create_oncall_connector(oncall_org_id: str, backend: str):
client = OnCallGatewayAPIClient(settings.ONCALL_GATEWAY_URL, settings.ONCALL_GATEWAY_API_TOKEN)
try:
client.post_oncall_connector(oncall_org_id, backend)
except Exception as e:
logger.error(f"create_oncall_connector: failed " f"oncall_org_id={oncall_org_id} backend={backend} exc={e}")
create_oncall_connector_async.apply_async((oncall_org_id, backend), countdown=2)
def delete_oncall_connector(oncall_org_id: str):
delete_oncall_connector_async.delay(oncall_org_id)
def check_slack_installation_possible(oncall_org_id: str, slack_id: str, backend: str) -> bool:
client = OnCallGatewayAPIClient(settings.ONCALL_GATEWAY_URL, settings.ONCALL_GATEWAY_API_TOKEN)
try:
response = client.check_slack_installation_possible(
oncall_org_id=oncall_org_id, slack_id=slack_id, backend=backend
)
return response.status_code == 200
except requests.exceptions.HTTPError as http_exc:
logger.error(
f"check_slack_installation_backend: slack installation impossible "
f"oncall_org_id={oncall_org_id} slack_id={slack_id} backend={backend} exc={http_exc}"
)
return False
def create_slack_connector(oncall_org_id: str, slack_id: str, backend: str):
client = OnCallGatewayAPIClient(settings.ONCALL_GATEWAY_URL, settings.ONCALL_GATEWAY_API_TOKEN)
try:
client.post_slack_connector(oncall_org_id, slack_id, backend)
except Exception as e:
logger.error(
f"create_slack_connector: failed "
f"oncall_org_id={oncall_org_id} slack_id={slack_id} backend={backend} exc={e}"
)
create_slack_connector_async_v2.apply_async(
kwargs={"oncall_org_id": oncall_org_id, "slack_id": slack_id, "backend": backend}, countdown=2
)
def delete_slack_connector(oncall_org_id: str):
delete_slack_connector_async_v2.delay(oncall_org_id=oncall_org_id)
# utils to work with v3 version
def register_oncall_tenant(service_tenant_id: str, cluster_slug: str):
"""
register_oncall_tenant tries to register oncall tenant synchronously and fall back to task in case of any exceptions
to make sure that tenant is registered.
First attempt is synchronous to register tenant ASAP to not miss any chatops requests.
"""
client = ChatopsProxyAPIClient(settings.ONCALL_GATEWAY_URL, settings.ONCALL_GATEWAY_API_TOKEN)
try:
client.register_tenant(service_tenant_id, cluster_slug, SERVICE_TYPE_ONCALL)
except Exception as e:
logger.error(
f"create_oncall_connector: failed " f"oncall_org_id={service_tenant_id} backend={cluster_slug} exc={e}"
)
register_oncall_tenant_async.apply_async(
kwargs={
"service_tenant_id": service_tenant_id,
"cluster_slug": cluster_slug,
"service_type": SERVICE_TYPE_ONCALL,
},
countdown=2,
)
def unregister_oncall_tenant(service_tenant_id: str, cluster_slug: str):
"""
unregister_oncall_tenant unregisters tenant asynchronously.
"""
unregister_oncall_tenant_async.apply_async(
kwargs={
"service_tenant_id": service_tenant_id,
"cluster_slug": cluster_slug,
"service_type": SERVICE_TYPE_ONCALL,
},
countdown=2,
)
def can_link_slack_team(
service_tenant_id: str,
slack_team_id: str,
cluster_slug: str,
) -> bool:
"""
can_link_slack_team checks if it's possible to link slack workspace to oncall tenant located in cluster.
All oncall tenants linked to same slack team should have same cluster.
"""
client = ChatopsProxyAPIClient(settings.ONCALL_GATEWAY_URL, settings.ONCALL_GATEWAY_API_TOKEN)
try:
response = client.can_slack_link(service_tenant_id, cluster_slug, slack_team_id, SERVICE_TYPE_ONCALL)
return response.status_code == 200
except Exception as e:
logger.error(
f"can_link_slack_team: slack installation impossible: {e} "
f"service_tenant_id={service_tenant_id} slack_team_id={slack_team_id} cluster_slug={cluster_slug}"
)
return False
def link_slack_team(service_tenant_id: str, slack_team_id: str):
client = ChatopsProxyAPIClient(settings.ONCALL_GATEWAY_URL, settings.ONCALL_GATEWAY_API_TOKEN)
try:
client.link_slack_team(service_tenant_id, slack_team_id, SERVICE_TYPE_ONCALL)
except Exception as e:
logger.error(
f'msg="Failed to link slack team: {e}"'
f"service_tenant_id={service_tenant_id} slack_team_id={slack_team_id}"
)
link_slack_team_async.apply_async(
kwargs={
"service_tenant_id": service_tenant_id,
"slack_team_id": slack_team_id,
"service_type": SERVICE_TYPE_ONCALL,
},
countdown=2,
)
def unlink_slack_team(service_tenant_id: str, slack_team_id: str):
unlink_slack_team_async.apply_async(
kwargs={
"service_tenant_id": service_tenant_id,
"slack_team_id": slack_team_id,
"service_type": SERVICE_TYPE_ONCALL,
}
)
# Wrappers to choose whether legacy or v3 function should be call, depending on CHATOPS_V3 env var.
def register_oncall_tenant_wrapper(service_tenant_id: str, cluster_slug: str):
if settings.CHATOPS_V3:
register_oncall_tenant(service_tenant_id, cluster_slug)
else:
create_oncall_connector(service_tenant_id, cluster_slug)
def unregister_oncall_tenant_wrapper(service_tenant_id: str, cluster_slug: str):
if settings.CHATOPS_V3:
unregister_oncall_tenant(service_tenant_id, cluster_slug)
else:
delete_oncall_connector(service_tenant_id)
def can_link_slack_team_wrapper(service_tenant_id: str, slack_team_id, cluster_slug: str) -> bool:
if settings.CHATOPS_V3:
return can_link_slack_team(service_tenant_id, slack_team_id, cluster_slug)
else:
return check_slack_installation_possible(service_tenant_id, slack_team_id, cluster_slug)
def link_slack_team_wrapper(service_tenant_id: str, slack_team_id: str):
if settings.CHATOPS_V3:
link_slack_team(service_tenant_id, slack_team_id)
else:
create_slack_connector(service_tenant_id, slack_team_id, settings.ONCALL_BACKEND_REGION)
def unlink_slack_team_wrapper(service_tenant_id: str, slack_team_id: str):
if settings.CHATOPS_V3:
unlink_slack_team(service_tenant_id, slack_team_id)
else:
delete_slack_connector(service_tenant_id)