Skip to content

Commit

Permalink
feat: 支持蓝鲸审计中心 #7506
Browse files Browse the repository at this point in the history
  • Loading branch information
normal-wls committed Jun 24, 2024
1 parent d4b5495 commit 0f2ecb8
Show file tree
Hide file tree
Showing 18 changed files with 655 additions and 33 deletions.
11 changes: 11 additions & 0 deletions config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
"blueapps.opentelemetry.instrument_app",
"apigw_manager.apigw",
"bk_notice_sdk",
"bk_audit.contrib.bk_audit",
)

# 这里是默认的中间件,大部分情况下,不需要改动
Expand Down Expand Up @@ -866,3 +867,13 @@ def check_engine_admin_permission(request, *args, **kwargs):

# 周期任务消息通知类型
PERIODIC_TASK_REMINDER_NOTIFY_TYPE = env.PERIODIC_TASK_REMINDER_NOTIFY_TYPE

# bk_audit
ENABLE_BK_AUDIT = True if env.BK_AUDIT_DATA_TOKEN else False
BK_AUDIT_SETTINGS = {
"log_queue_limit": 50000,
"exporters": ["bk_audit.contrib.opentelemetry.exporters.OTLogExporter"],
"service_name_handler": "bk_audit.contrib.opentelemetry.utils.ServiceNameHandler",
"ot_endpoint": env.BK_AUDIT_ENDPOINT,
"bk_data_token": env.BK_AUDIT_DATA_TOKEN,
}
4 changes: 4 additions & 0 deletions env.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,7 @@

# 周期任务消息通知类型
PERIODIC_TASK_REMINDER_NOTIFY_TYPE = json.loads(os.getenv("PERIODIC_TASK_REMINDER_NOTIFY_TYPE", '["email"]'))

# bk_audit
BK_AUDIT_ENDPOINT = os.getenv("BK_AUDIT_ENDPOINT", None)
BK_AUDIT_DATA_TOKEN = os.getenv("BK_AUDIT_DATA_TOKEN", None)
5 changes: 4 additions & 1 deletion gcloud/contrib/analysis/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@

import functools

from django.http import JsonResponse
import ujson as json
from django.http import JsonResponse

from gcloud.contrib.audit.utils import bk_audit_add_event
from gcloud.iam_auth import IAMMeta
from gcloud.utils.strings import check_and_rename_params


def standardize_params(func):
@functools.wraps(func)
def wrapper(request):
bk_audit_add_event(username=request.user.username, action_id=IAMMeta.STATISTICS_VIEW_ACTION)
params = json.loads(request.body)
conditions = params.get("conditions", {})
page_index = int(params.get("pageIndex", 1))
Expand Down
16 changes: 9 additions & 7 deletions gcloud/contrib/analysis/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@

from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.http import require_POST, require_GET
from django.views.decorators.http import require_GET, require_POST

from gcloud.contrib.analysis.decorators import standardize_params
from gcloud.constants import AE
from gcloud.constants import TASK_CATEGORY
from gcloud.constants import AE, TASK_CATEGORY
from gcloud.contrib.analysis.analyse_items import app_maker, task_flow_instance, task_template
from gcloud.tasktmpl3.models import TaskTemplate
from gcloud.taskflow3.models import TaskFlowInstance
from gcloud.contrib.analysis.decorators import standardize_params
from gcloud.contrib.audit.utils import bk_audit_add_event
from gcloud.core.models import Project
from gcloud.err_code import REQUEST_PARAM_INVALID
from gcloud.iam_auth import IAMMeta
from gcloud.iam_auth.intercept import iam_intercept
from gcloud.iam_auth.view_interceptors.statistics import StatisticsViewInpterceptor
from gcloud.err_code import REQUEST_PARAM_INVALID
from gcloud.taskflow3.models import TaskFlowInstance
from gcloud.tasktmpl3.models import TaskTemplate
from gcloud.utils.components import get_all_components


Expand Down Expand Up @@ -70,6 +71,7 @@ def analysis_home(request):
context = {
"view_mode": "analysis",
}
bk_audit_add_event(username=request.user.username, action_id=IAMMeta.STATISTICS_VIEW_ACTION)
return render(request, "core/base_vue.html", context)


Expand Down
13 changes: 11 additions & 2 deletions gcloud/contrib/appmaker/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@

import logging

import magic
import jsonschema
import magic
from django.http import JsonResponse
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.http import require_GET

from gcloud.conf import settings
from gcloud.contrib.analysis.analyse_items import app_maker
from gcloud.contrib.appmaker.models import AppMaker
from gcloud.contrib.appmaker.schema import APP_MAKER_PARAMS_SCHEMA
from gcloud.contrib.audit.utils import bk_audit_add_event
from gcloud.iam_auth import IAMMeta
from gcloud.utils.strings import check_and_rename_params
from gcloud.contrib.analysis.analyse_items import app_maker

logger = logging.getLogger("root")

Expand Down Expand Up @@ -87,6 +89,13 @@ def save(request, project_id):
if not result:
return JsonResponse({"result": False, "message": data})

bk_audit_add_event(
username=request.user.username,
action_id=IAMMeta.MINI_APP_EDIT_ACTION if params.get("id") else IAMMeta.FLOW_CREATE_MINI_APP_ACTION,
resource_id=IAMMeta.MINI_APP_RESOURCE,
instance=data,
)

data = {
"id": data.id,
"code": data.code,
Expand Down
173 changes: 173 additions & 0 deletions gcloud/contrib/audit/instances.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# -*- coding: utf-8 -*-
import copy

from bk_audit.log.models import AuditInstance
from django.forms import model_to_dict

from gcloud.clocked_task.serializer import ClockedTaskSerializer
from gcloud.contrib.audit.serializers import (
AppmakerSerializer,
CommonTaskTemplateSerializer,
PeriodicTaskSerializer,
TaskSerializer,
TaskTemplateSerializer,
UpdateClockedTaskSerializer,
UpdatePeriodicTaskSerializer,
)
from gcloud.core.apis.drf.serilaziers import CreateTaskTemplateSerializer, ProjectSerializer
from gcloud.core.apis.drf.serilaziers.common_template import CreateCommonTemplateSerializer


class BaseInstance:
def __init__(self, inst, origin_data: dict = None):
self.inst = inst
self.origin_data = copy.deepcopy(origin_data)

def prepare_origin_data(self):
return self.origin_data

@property
def instance_id(self):
return self.inst.id

@property
def instance_name(self):
return self.inst.name

@property
def instance_sensitivity(self):
return 0

@property
def instance_origin_data(self):
return self.prepare_origin_data()

@property
def instance_data(self):
return model_to_dict(self.inst)

@property
def instance(self):
return AuditInstance(self)


class TaskTemplateInstance(BaseInstance):
def prepare_origin_data(self):
if not self.origin_data:
return {}
ser = CreateTaskTemplateSerializer(data=self.origin_data)
ser.is_valid(raise_exception=True)
ser.validated_data.pop("pipeline_tree", None)
ser.validated_data.pop("project", None)
return dict(ser.validated_data)

@property
def instance_name(self):
return self.inst.pipeline_template.name

@property
def instance_data(self):
return TaskTemplateSerializer(self.inst).data


class CommonTaskTemplateInstance(BaseInstance):
def prepare_origin_data(self):
if not self.origin_data:
return {}
ser = CreateCommonTemplateSerializer(data=self.origin_data)
ser.is_valid(raise_exception=True)
ser.validated_data.pop("pipeline_tree", None)
ser.validated_data.pop("project", None)
return dict(ser.validated_data)

@property
def instance_name(self):
return self.inst.pipeline_template.name

@property
def instance_data(self):
return CommonTaskTemplateSerializer(self.inst).data


class ProjectInstance(BaseInstance):
def prepare_origin_data(self):
if not self.origin_data:
return {}
ser = ProjectSerializer(data=self.origin_data)
ser.is_valid(raise_exception=True)
return dict(ser.validated_data)

@property
def instance_data(self):
return ProjectSerializer(self.inst).data


class TaskInstance(BaseInstance):
def prepare_origin_data(self):
if not self.origin_data:
return {}
ser = TaskSerializer(data=self.origin_data)
ser.is_valid(raise_exception=True)
return dict(ser.validated_data)

@property
def instance_data(self):
return TaskSerializer(self.inst).data


class MiniAppInstance(BaseInstance):
@property
def instance_data(self):
return AppmakerSerializer(self.inst).data


class PeriodicTaskInstance(BaseInstance):
def prepare_origin_data(self):
if not self.origin_data:
return {}
self.origin_data["task_id"] = self.origin_data["taskId"]
ser = UpdatePeriodicTaskSerializer(data=self.origin_data)
ser.is_valid(raise_exception=True)
return dict(ser.validated_data)

@property
def instance_data(self):
return PeriodicTaskSerializer(self.inst).data


class ClockedTaskInstance(BaseInstance):
def prepare_origin_data(self):
if not self.origin_data:
return {}
ser = UpdateClockedTaskSerializer(data=self.origin_data)
ser.is_valid(raise_exception=True)
return dict(ser.validated_data)

@property
def instance_data(self):
return ClockedTaskSerializer(self.inst).data

@property
def instance_name(self):
return self.inst.task_name


INSTANCE_MAP = {
"flow": TaskTemplateInstance,
"common_flow": CommonTaskTemplateInstance,
"project": ProjectInstance,
"task": TaskInstance,
"mini_app": MiniAppInstance,
"periodic_task": PeriodicTaskInstance,
"clocked_task": ClockedTaskInstance,
}


def build_instance(instance_type, instance, origin_data=None):
instance_cls = INSTANCE_MAP.get(instance_type, None)
if not instance_cls:
return None
if not instance:
return None
instance = instance_cls(instance, origin_data).instance
return instance
Loading

0 comments on commit 0f2ecb8

Please sign in to comment.