Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: app permission #145

Merged
merged 12 commits into from
Jul 31, 2023
9 changes: 7 additions & 2 deletions src/dashboard/apigateway/apigateway/apis/controller/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,10 @@ def _get_resource_permissions(
return resource_permissions

name_mappings = self._get_released_resource_name_mappings(release)
for permission in AppResourcePermission.objects.filter_permission(api_gateway, bk_app_codes=app_code_list):
queryset = AppResourcePermission.objects.filter(api=api_gateway)
if app_code_list:
zhu327 marked this conversation as resolved.
Show resolved Hide resolved
queryset = queryset.filter(bk_app_code__in=app_code_list)
for permission in queryset:
# 因为 resource_version 为下发生效的真实版本,因此没有匹配的权限无需下发
if permission.resource_id not in name_mappings:
continue
Expand All @@ -207,7 +210,9 @@ def _get_resource_permissions(
return resource_permissions

def _get_api_permissions(self, api_gateway: Gateway, app_code_list: Optional[List[str]]):
qs = AppAPIPermission.objects.filter_permission(api_gateway, bk_app_codes=app_code_list)
qs = AppAPIPermission.objects.filter(api=api_gateway)
if app_code_list:
zhu327 marked this conversation as resolved.
Show resolved Hide resolved
qs = qs.filter(bk_app_code__in=app_code_list)

return qs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ def query_api_metrics(self, request, *args, **kwargs):
end_time = slz.validated_data["end_time"]

# 获取网关请求数据
api_request_data = StatisticsAPIRequestByDay.objects.filter_and_aggregate_by_api(
api_request_data = StatisticsAPIRequestByDay.objects.filter_and_aggregate_by_gateway(
start_time=start_time,
end_time=end_time,
)

# 获取应用请求数据
app_request_data = StatisticsAppRequestByDay.objects.filter_app_and_aggregate_by_api(
app_request_data = StatisticsAppRequestByDay.objects.filter_app_and_aggregate_by_gateway(
start_time=start_time,
end_time=end_time,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@
from apigateway.core.models import Gateway, ReleasedResource, Resource


class AppPermissionHelper:
def get_permission_model(self, dimension: str):
if dimension == GrantDimensionEnum.API.value:
return AppAPIPermission
elif dimension == GrantDimensionEnum.RESOURCE.value:
return AppResourcePermission
raise ValueError(f"unsupported dimension: {dimension}")


class ResourcePermission(BaseModel):
class Config:
arbitrary_types_allowed = True
Expand Down Expand Up @@ -142,16 +151,16 @@ def build(self, resources: list) -> list:
return [perm.as_dict() for perm in resource_permissions]

def _get_api_permission(self):
return AppAPIPermission.objects.filter_permission(
gateway=self.gateway,
return AppAPIPermission.objects.filter(
api=self.gateway,
bk_app_code=self.target_app_code,
).first()

def _get_resource_permission_map(self):
return {
perm.resource_id: perm
for perm in AppResourcePermission.objects.filter_permission(
gateway=self.gateway,
for perm in AppResourcePermission.objects.filter(
api=self.gateway,
bk_app_code=self.target_app_code,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
PermissionApplyExpireDaysEnum,
PermissionStatusEnum,
)
from apigateway.apps.permission.helpers import PermissionDimensionManager
from apigateway.apps.permission.models import AppPermissionRecord
from apigateway.biz.permission import PermissionDimensionManager
from apigateway.common.fields import TimestampField
from apigateway.core.validators import BKAppCodeValidator, ResourceIDValidator
from apigateway.utils import time
Expand Down
20 changes: 11 additions & 9 deletions src/dashboard/apigateway/apigateway/apis/open/permission/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@
from rest_framework import status, viewsets
from rest_framework.views import APIView

from apigateway.apis.open.permission.helpers import AppPermissionBuilder, ResourcePermissionBuilder
from apigateway.apis.open.permission.helpers import (
AppPermissionBuilder,
AppPermissionHelper,
ResourcePermissionBuilder,
)
from apigateway.apps.permission.constants import (
ApplyStatusEnum,
GrantDimensionEnum,
GrantTypeEnum,
PermissionApplyExpireDaysEnum,
)
from apigateway.apps.permission.helpers import AppPermissionHelper, PermissionDimensionManager
from apigateway.apps.permission.models import AppPermissionApply, AppPermissionRecord, AppResourcePermission
from apigateway.apps.permission.tasks import send_mail_for_perm_apply
from apigateway.biz.permission import PermissionDimensionManager
from apigateway.biz.resource_version import ResourceVersionHandler
from apigateway.common.error_codes import error_codes
from apigateway.common.permissions import GatewayRelatedAppPermission
Expand Down Expand Up @@ -81,7 +85,6 @@ def list(self, request, *args, **kwargs):


class AppGatewayPermissionViewSet(viewsets.GenericViewSet):

api_permission_exempt = True

def allow_apply_by_gateway(self, request, *args, **kwargs):
Expand Down Expand Up @@ -235,10 +238,10 @@ def revoke(self, request, *args, **kwargs):
data = slz.validated_data

permission_model = AppPermissionHelper().get_permission_model(data["grant_dimension"])
permission_model.objects.delete_permission(
gateway=request.gateway,
bk_app_codes=data["target_app_codes"],
)
permission_model.objects.filter(
api=request.gateway,
bk_app_code__in=data["target_app_codes"],
).delete()

return OKJsonResponse("OK")

Expand Down Expand Up @@ -270,7 +273,7 @@ def post(self, request, *args, **kwargs):
resource_ids=resource_ids,
)

AppResourcePermission.objects.renew_permission(
AppResourcePermission.objects.renew_by_resource_ids(
gateway=gateway,
bk_app_code=data["target_app_code"],
resource_ids=resource_ids,
Expand Down Expand Up @@ -311,7 +314,6 @@ def list(self, request, *args, **kwargs):
status=data.get("apply_status"),
query=data.get("query"),
order_by="-id",
fuzzy=False,
)

page = self.paginate_queryset(queryset)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
class APISDKQueryV1SLZ(serializers.Serializer):
api_name = serializers.CharField(allow_null=True, default=None)
api_id = serializers.IntegerField(allow_null=True, default=None)
language = serializers.ChoiceField(choices=ProgrammingLanguageEnum.choices())
language = serializers.ChoiceField(choices=ProgrammingLanguageEnum.get_choices())

def validate_api_id(self, value):
if value:
Expand All @@ -46,7 +46,7 @@ def validate_api_id(self, value):
class SDKGenerateV1SLZ(serializers.Serializer):
resource_version = serializers.CharField(max_length=128, help_text="资源版本")
languages = serializers.ListField(
child=serializers.ChoiceField(choices=ProgrammingLanguageEnum.choices()),
child=serializers.ChoiceField(choices=ProgrammingLanguageEnum.get_choices()),
help_text="需要生成SDK的语言列表",
default=[ProgrammingLanguageEnum.PYTHON.value],
)
Expand Down
17 changes: 17 additions & 0 deletions src/dashboard/apigateway/apigateway/apis/web/metrics/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# TencentBlueKing is pleased to support the open source community by making
# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available.
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the MIT License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions and
# limitations under the License.
#
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
#
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from apigateway.apps.metrics.constants import DimensionEnum, MetricsEnum


class MetricsQuerySLZ(serializers.Serializer):
class MetricsQueryInputSLZ(serializers.Serializer):
stage_id = serializers.IntegerField(required=True)
resource_id = serializers.IntegerField(allow_null=True, required=False)
dimension = serializers.ChoiceField(choices=DimensionEnum.get_choices())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
#
from django.urls import path

from apigateway.apps.metrics import views
from .views import QueryRangeApi

urlpatterns = [
path("query_range/", views.QueryRangeAPIView.as_view(), name="metrics.query_range"),
path("query_range/", QueryRangeApi.as_view(), name="metrics.query_range"),
]
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,72 @@
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
#
import math

from django.http import Http404
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.views import APIView
from rest_framework import generics, status

from apigateway.apps.metrics import serializers
from apigateway.apps.metrics.constants import DimensionEnum, MetricsEnum
from apigateway.apps.metrics.dimension_metrics import DimensionMetricsFactory
from apigateway.apps.metrics.utils import MetricsSmartTimeRange
from apigateway.apps.metrics.prometheus.dimension import DimensionMetricsFactory
from apigateway.core.models import Resource, Stage
from apigateway.utils.responses import OKJsonResponse
from apigateway.utils.time import SmartTimeRange

from .serializers import MetricsQueryInputSLZ


class MetricsSmartTimeRange(SmartTimeRange):
def get_recommended_step(self) -> str:
"""根据 time_start, time_end,获取推荐的步长"""
start, end = self.get_head_and_tail()

return self._calculate_step(start, end)

def _calculate_step(self, start: int, end: int) -> str:
"""
:param start: 起始时间戳
:param end: 结束时间戳
:returns: 推荐步长

step via the gap of query time
1m <- 1h
5m <- 6h
10m <- 12h
30m <- 24h
1h <- 72h
3h <- 7d
12h <- >7d
"""
step_options = ["1m", "5m", "10m", "30m", "1h", "3h", "12h"]

gap_minutes = math.ceil((end - start) / 60)
if gap_minutes <= 60:
index = 0
elif gap_minutes <= 360:
index = 1
elif gap_minutes <= 720:
index = 2
elif gap_minutes <= 1440:
index = 3
elif gap_minutes <= 4320:
index = 4
elif gap_minutes <= 10080:
index = 5
else:
index = 6

return step_options[index]


class QueryRangeAPIView(APIView):
class QueryRangeApi(generics.ListAPIView):
@swagger_auto_schema(
query_serializer=serializers.MetricsQuerySLZ,
query_serializer=MetricsQueryInputSLZ,
responses={status.HTTP_200_OK: ""},
tags=["Metrics"],
)
def get(self, request, *args, **kwargs):
slz = serializers.MetricsQuerySLZ(data=request.query_params)
slz = MetricsQueryInputSLZ(data=request.query_params)
slz.is_valid(raise_exception=True)

data = slz.validated_data
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# TencentBlueKing is pleased to support the open source community by making
# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available.
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the MIT License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions and
# limitations under the License.
#
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
#
Loading