# What this PR does Fixes a bug when RBAC permissions are getting erased when Grafana's API returns a 5xx server error on organization sync. ## Which issue(s) this PR closes Closes https://github.com/grafana/oncall-private/issues/2834 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes.
71 lines
3.5 KiB
Python
71 lines
3.5 KiB
Python
from django.conf import settings
|
|
from rest_framework import status
|
|
from rest_framework.request import Request
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import APIView
|
|
|
|
from apps.grafana_plugin.helpers import GrafanaAPIClient
|
|
from apps.user_management.models.organization import Organization
|
|
from apps.user_management.sync import sync_organization
|
|
from common.api_helpers.mixins import GrafanaHeadersMixin
|
|
|
|
|
|
class SelfHostedInstallView(GrafanaHeadersMixin, APIView):
|
|
def post(self, _request: Request) -> Response:
|
|
"""
|
|
We've already validated that settings.GRAFANA_API_URL is set (in apps.grafana_plugin.GrafanaPluginConfig)
|
|
The user is now trying to finish plugin installation. We'll take the Grafana API url that they specified +
|
|
the token that we are provided and first verify them. If all is good, upsert the organization in the database,
|
|
and provision the plugin.
|
|
"""
|
|
stack_id = settings.SELF_HOSTED_SETTINGS["STACK_ID"]
|
|
org_id = settings.SELF_HOSTED_SETTINGS["ORG_ID"]
|
|
grafana_url = settings.SELF_HOSTED_SETTINGS["GRAFANA_API_URL"]
|
|
grafana_api_token = self.instance_context["grafana_token"]
|
|
|
|
provisioning_info = {"error": None}
|
|
|
|
if settings.LICENSE != settings.OPEN_SOURCE_LICENSE_NAME:
|
|
provisioning_info["error"] = "License type not authorized"
|
|
return Response(status=status.HTTP_403_FORBIDDEN)
|
|
|
|
grafana_api_client = GrafanaAPIClient(api_url=grafana_url, api_token=grafana_api_token)
|
|
_, client_status = grafana_api_client.check_token()
|
|
status_code = client_status["status_code"]
|
|
|
|
if status_code == status.HTTP_404_NOT_FOUND:
|
|
provisioning_info["error"] = f"Unable to connect to the specified Grafana API - {grafana_url}"
|
|
return Response(data=provisioning_info, status=status.HTTP_400_BAD_REQUEST)
|
|
elif status_code in [status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN]:
|
|
provisioning_info[
|
|
"error"
|
|
] = f"You are not authorized to communicate with the specified Grafana API - {grafana_url}"
|
|
return Response(data=provisioning_info, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
organization = Organization.objects.filter(stack_id=stack_id, org_id=org_id).first()
|
|
rbac_is_enabled, _ = grafana_api_client.is_rbac_enabled_for_organization()
|
|
|
|
if organization:
|
|
organization.revoke_plugin()
|
|
organization.grafana_url = grafana_url
|
|
organization.api_token = grafana_api_token
|
|
organization.is_rbac_permissions_enabled = rbac_is_enabled
|
|
organization.save(update_fields=["grafana_url", "api_token", "is_rbac_permissions_enabled"])
|
|
else:
|
|
organization = Organization.objects.create(
|
|
stack_id=stack_id,
|
|
stack_slug=settings.SELF_HOSTED_SETTINGS["STACK_SLUG"],
|
|
org_id=org_id,
|
|
org_slug=settings.SELF_HOSTED_SETTINGS["ORG_SLUG"],
|
|
org_title=settings.SELF_HOSTED_SETTINGS["ORG_TITLE"],
|
|
region_slug=settings.SELF_HOSTED_SETTINGS["REGION_SLUG"],
|
|
cluster_slug=settings.SELF_HOSTED_SETTINGS["CLUSTER_SLUG"],
|
|
grafana_url=grafana_url,
|
|
api_token=grafana_api_token,
|
|
is_rbac_permissions_enabled=rbac_is_enabled,
|
|
)
|
|
|
|
sync_organization(organization)
|
|
provisioning_info.update(organization.provision_plugin())
|
|
|
|
return Response(data=provisioning_info, status=status.HTTP_201_CREATED)
|