Skip to content

Commit

Permalink
feat(backend): 反向查询接口 TencentBlueKing#7173
Browse files Browse the repository at this point in the history
  • Loading branch information
xfwduke committed Oct 8, 2024
1 parent 25a573b commit bc04aa5
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 0 deletions.
10 changes: 10 additions & 0 deletions dbm-ui/backend/db_services/reverse_api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
Copyright (C) 2017-2023 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 https://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.
"""
48 changes: 48 additions & 0 deletions dbm-ui/backend/db_services/reverse_api/base_reverse_api_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
Copyright (C) 2017-2023 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 https://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.
"""

import logging

from django.utils.translation import ugettext as _
from rest_framework import permissions

from backend.bk_web.viewsets import SystemViewSet
from backend.db_meta.models import Machine

logger = logging.getLogger("root")


class IPHasRegisteredPermission(permissions.BasePermission):
@staticmethod
def get_client_ip(request):
x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
if x_forwarded_for:
ip = x_forwarded_for.split(",")[0]
else:
ip = request.META.get("REMOTE_ADDR")
return ip

def has_permission(self, request, view):
client_ip = self.get_client_ip(request)
found = Machine.objects.filter(ip=client_ip).exists()

logger.debug(f"client_ip: {client_ip}, found: {found}")
if not found:
raise Exception(_("访问IP:{}受限,不存在于DBM平台").format(client_ip))
return True

def has_object_permission(self, request, view, obj):
return self.has_permission(request, view)


class BaseReverseApiView(SystemViewSet):
def get_permissions(self):
return [IPHasRegisteredPermission()]
33 changes: 33 additions & 0 deletions dbm-ui/backend/db_services/reverse_api/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
Copyright (C) 2017-2023 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 https://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.
"""
from functools import wraps

from django.http import HttpRequest


def reverse_api(func):
@wraps(func)
def wrapped_func(obj, request: HttpRequest, *args, **kwargs):
x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
if x_forwarded_for:
ip = x_forwarded_for.split(",")[0]
else:
ip = request.META.get("REMOTE_ADDR")

if not request.GET._mutable:
request.GET._mutable = True

request.GET["ip"] = ip
request.GET._mutable = False

return func(obj, request, *args, **kwargs)

return wrapped_func
11 changes: 11 additions & 0 deletions dbm-ui/backend/db_services/reverse_api/mysql/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
Copyright (C) 2017-2023 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 https://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.
"""
from .views import MySQLReverseApiView
16 changes: 16 additions & 0 deletions dbm-ui/backend/db_services/reverse_api/mysql/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
Copyright (C) 2017-2023 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 https://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.
"""
from rest_framework import serializers


class MySQLReverseApiParamSerializer(serializers.Serializer):
bk_cloud_id = serializers.IntegerField()
ip = serializers.IPAddressField()
86 changes: 86 additions & 0 deletions dbm-ui/backend/db_services/reverse_api/mysql/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
Copyright (C) 2017-2023 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 https://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.
"""
import logging

from django.http import JsonResponse
from django.utils.translation import ugettext_lazy as _
from rest_framework.decorators import action

from backend.bk_web.swagger import common_swagger_auto_schema
from backend.components import DBPrivManagerApi
from backend.db_meta.enums import AccessLayer
from backend.db_meta.models import Machine
from backend.db_services.reverse_api.base_reverse_api_view import BaseReverseApiView
from backend.db_services.reverse_api.decorators import reverse_api
from backend.db_services.reverse_api.mysql.serializers import MySQLReverseApiParamSerializer
from backend.flow.consts import DEFAULT_INSTANCE, MySQLPrivComponent, UserName

logger = logging.getLogger("root")


class MySQLReverseApiView(BaseReverseApiView):
@classmethod
def _get_login_exempt_view_func(cls):
return {
"post": [],
"put": [],
"get": [
cls.list_instance_info.__name__,
cls.get_runtime_account.__name__,
],
"delete": [],
}

@common_swagger_auto_schema(operation_summary=_("获取实例基本信息"))
@action(
methods=["GET"],
detail=False,
url_path="list_instance_info",
serializer_class=MySQLReverseApiParamSerializer,
)
@reverse_api
def list_instance_info(self, request, *args, **kwargs):
data = self.params_validate(self.get_serializer_class())

ip = data.get("ip")
bk_cloud_id = data.get("bk_cloud_id")

logger.info(f"bk_cloud_id: {bk_cloud_id}, ip: {ip}")

m = Machine.objects.get(ip=ip, bk_cloud_id=bk_cloud_id)
if m.access_layer == AccessLayer.PROXY:
pass
else:
pass
return JsonResponse({"ip": ip})

@common_swagger_auto_schema(operation_summary=_("反向获取DB系统账号"))
@action(
methods=["GET"],
detail=False,
url_path="get_runtime_account",
)
def get_runtime_account(self, request, *args, **kwargs):
data = DBPrivManagerApi.get_runtime_account(
{
"instances": [DEFAULT_INSTANCE],
"users": [
{"username": UserName.BACKUP.value, "component": MySQLPrivComponent.MYSQL.value},
{"username": UserName.MONITOR.value, "component": MySQLPrivComponent.MYSQL.value},
{"username": UserName.MONITOR_ACCESS_ALL.value, "component": MySQLPrivComponent.MYSQL.value},
{"username": UserName.OS_MYSQL.value, "component": MySQLPrivComponent.MYSQL.value},
{"username": UserName.REPL.value, "component": MySQLPrivComponent.MYSQL.value},
{"username": UserName.YW.value, "component": MySQLPrivComponent.MYSQL.value},
{"username": UserName.PARTITION_YW.value, "component": MySQLPrivComponent.MYSQL.value},
],
}
)
return JsonResponse({"data": data})
18 changes: 18 additions & 0 deletions dbm-ui/backend/db_services/reverse_api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
Copyright (C) 2017-2023 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 https://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.
"""
from rest_framework.routers import DefaultRouter

from backend.db_services.reverse_api.mysql import MySQLReverseApiView

routers = DefaultRouter(trailing_slash=True)
routers.register("mysql", MySQLReverseApiView, basename="")

urlpatterns = routers.urls
1 change: 1 addition & 0 deletions dbm-ui/backend/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
path("dbbase/", include("backend.db_services.dbbase.urls")),
path("quick_search/", include("backend.db_services.quick_search.urls")),
path("plugin/", include("backend.db_services.plugin.urls")),
path("reverse_api/", include("backend.db_services.reverse_api.urls")),
]

urlpatterns = [
Expand Down
2 changes: 2 additions & 0 deletions dbm-ui/config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,3 +584,5 @@ def get_logging_config(log_dir: str, log_level: str = "ERROR") -> Dict:
# 开启DEBUG_TOOL_BAR,需要内联IP
if env.DEBUG_TOOL_BAR:
INTERNAL_IPS = ["127.0.0.1", "localhost"]


0 comments on commit bc04aa5

Please sign in to comment.