Skip to content

Commit

Permalink
feat: 添加 执行代理人 配置校验 TencentBlueKing#7289
Browse files Browse the repository at this point in the history
  • Loading branch information
normal-wls committed Jan 16, 2024
1 parent d1b458e commit 0f6fab9
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 41 deletions.
40 changes: 39 additions & 1 deletion gcloud/core/apis/drf/serilaziers/common_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
specific language governing permissions and limitations under the License.
"""
import json

from rest_framework import serializers

from gcloud.constants import TASK_CATEGORY, DATETIME_FORMAT
from gcloud.common_template.models import CommonTemplate
from gcloud.constants import DATETIME_FORMAT, TASK_CATEGORY
from gcloud.core.apis.drf.serilaziers.template import BaseTemplateSerializer


Expand Down Expand Up @@ -70,6 +71,43 @@ class CreateCommonTemplateSerializer(BaseTemplateSerializer):
help_text="pipeline模板ID", source="pipeline_template.id", read_only=True
)

def _calculate_new_executor_proxies(self, old_pipeline_tree: dict, pipeline_tree: dict):
new_executor_proxies = set()
old_nodes = old_pipeline_tree.get("activities", {})
for node_id, node in pipeline_tree.get("activities", {}).items():
executor_proxy = node.get("executor_proxy")
if not executor_proxy:
continue
old_executor_proxy = old_nodes.get(node_id, {}).get("executor_proxy")
if not old_executor_proxy or executor_proxy != old_executor_proxy:
new_executor_proxies.add(executor_proxy)
return set(new_executor_proxies)

def _calculate_executor_proxies(self, pipeline_tree):
new_executor_proxies = set()
for node_id, node in pipeline_tree.get("activities", {}).items():
executor_proxy = node.get("executor_proxy")
if not executor_proxy:
continue
new_executor_proxies.add(executor_proxy)
return set(new_executor_proxies)

def validate_pipeline_tree(self, value: str):
pipeline_tree = json.loads(value)
old_pipeline_tree = self.instance.pipeline_tree if self.instance else None
if old_pipeline_tree:
# update
new_executor_proxies = self._calculate_new_executor_proxies(old_pipeline_tree, pipeline_tree)
else:
# create
new_executor_proxies = self._calculate_executor_proxies(pipeline_tree)
user = getattr(self.context.get("request"), "user", None)
if not user:
raise serializers.ValidationError("user can not be empty.")
if len(new_executor_proxies) > 1 or (new_executor_proxies and user.username != new_executor_proxies.pop()):
raise serializers.ValidationError("you can only set yourself as executor proxy.")
return value

class Meta:
model = CommonTemplate
fields = [
Expand Down
8 changes: 8 additions & 0 deletions gcloud/core/apis/drf/serilaziers/project_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ class Meta:
model = ProjectConfig
fields = ["project_id", "executor_proxy", "executor_proxy_exempts"]
read_only_fields = ["project_id"]

def validate_executor_proxy(self, value):
user = getattr(self.context.get("request"), "user", None)
if not user:
raise serializers.ValidationError("user can not be empty.")
if user.username != value and value:
raise serializers.ValidationError("you can only set yourself as executor proxy.")
return value
8 changes: 8 additions & 0 deletions gcloud/core/apis/drf/serilaziers/task_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ def validate_project(self, value):
except Project.DoesNotExist:
raise serializers.ValidationError(_("project不存在"))

def validate_executor_proxy(self, value):
user = getattr(self.context.get("request"), "user", None)
if not user:
raise serializers.ValidationError("user can not be empty.")
if user.username != value and value:
raise serializers.ValidationError("you can only set yourself as executor proxy.")
return value

class Meta:
model = TaskTemplate
fields = [
Expand Down
20 changes: 7 additions & 13 deletions gcloud/core/apis/drf/viewsets/common_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from django.db import transaction
from django.db.models import BooleanField, ExpressionWrapper, Q
from drf_yasg.utils import swagger_auto_schema
from iam import Action, Request, Resource, Subject
from pipeline.models import TemplateScheme
from rest_framework import permissions, status
from rest_framework.decorators import action
Expand All @@ -29,19 +28,11 @@
from gcloud.common_template.models import CommonTemplate
from gcloud.common_template.signals import post_template_save_commit
from gcloud.contrib.collection.models import Collection
from gcloud.contrib.operate_record.constants import (
OperateSource,
OperateType,
RecordType,
)
from gcloud.contrib.operate_record.constants import OperateSource, OperateType, RecordType
from gcloud.contrib.operate_record.signal import operate_record_signal
from gcloud.core.apis.drf.filters import BooleanPropertyFilter
from gcloud.core.apis.drf.filtersets import PropertyFilterSet
from gcloud.core.apis.drf.permission import (
HAS_OBJECT_PERMISSION,
IamPermission,
IamPermissionInfo,
)
from gcloud.core.apis.drf.permission import HAS_OBJECT_PERMISSION, IamPermission, IamPermissionInfo
from gcloud.core.apis.drf.resource_helpers import ViewSetResourceHelper
from gcloud.core.apis.drf.serilaziers.common_template import (
CommonTemplateListSerializer,
Expand All @@ -53,6 +44,7 @@
from gcloud.iam_auth import IAMMeta, get_iam_client, res_factory
from gcloud.taskflow3.models import TaskConfig
from gcloud.template_base.domains.template_manager import TemplateManager
from iam import Action, Request, Resource, Subject

logger = logging.getLogger("root")
manager = TemplateManager(template_model_cls=CommonTemplate)
Expand Down Expand Up @@ -178,7 +170,7 @@ def _inject_project_based_task_create_action(request, common_template_ids):
return allowed_template_ids

def create(self, request, *args, **kwargs):
serializer = CreateCommonTemplateSerializer(data=request.data)
serializer = CreateCommonTemplateSerializer(data=request.data, context={"request": request})
serializer.is_valid(raise_exception=True)
try:
name = serializer.validated_data.pop("name")
Expand Down Expand Up @@ -219,7 +211,9 @@ def create(self, request, *args, **kwargs):
def update(self, request, *args, **kwargs):
partial = kwargs.pop("partial", False)
template = self.get_object()
serializer = CreateCommonTemplateSerializer(template, data=request.data, partial=partial)
serializer = CreateCommonTemplateSerializer(
template, data=request.data, partial=partial, context={"request": request}
)
serializer.is_valid(raise_exception=True)
# update pipeline_template
name = serializer.validated_data.pop("name")
Expand Down
56 changes: 29 additions & 27 deletions gcloud/core/apis/drf/viewsets/task_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,42 @@
import json
import logging

from django.contrib.auth import get_user_model
from django.db import transaction
from django.db.models import BooleanField, ExpressionWrapper, Q
from django.utils.translation import ugettext_lazy as _
from django_filters import CharFilter
from drf_yasg.utils import swagger_auto_schema
from pipeline.models import TemplateRelationship, TemplateScheme
from rest_framework import permissions, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.exceptions import ErrorDetail
from rest_framework import status, permissions
from django.contrib.auth import get_user_model
from django.db import transaction
from django_filters import CharFilter
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.response import Response

from gcloud import err_code
from pipeline.models import TemplateRelationship, TemplateScheme

from gcloud.contrib.collection.models import Collection
from gcloud.core.apis.drf.viewsets.base import GcloudModelViewSet
from gcloud.label.models import TemplateLabelRelation, Label
from gcloud.tasktmpl3.signals import post_template_save_commit
from gcloud.taskflow3.models import TaskTemplate, TaskConfig
from gcloud.contrib.operate_record.constants import OperateSource, OperateType, RecordType
from gcloud.contrib.operate_record.signal import operate_record_signal
from gcloud.core.apis.drf.filters import BooleanPropertyFilter
from gcloud.core.apis.drf.filtersets import PropertyFilterSet
from gcloud.core.apis.drf.permission import HAS_OBJECT_PERMISSION, IamPermission, IamPermissionInfo
from gcloud.core.apis.drf.resource_helpers import ViewSetResourceHelper
from gcloud.core.apis.drf.serilaziers.task_template import (
CreateTaskTemplateSerializer,
ProjectFilterQuerySerializer,
ProjectInfoQuerySerializer,
TaskTemplateListSerializer,
TaskTemplateSerializer,
CreateTaskTemplateSerializer,
TopCollectionTaskTemplateSerializer,
ProjectInfoQuerySerializer,
ProjectFilterQuerySerializer,
)
from gcloud.core.apis.drf.resource_helpers import ViewSetResourceHelper
from gcloud.iam_auth import res_factory
from gcloud.iam_auth import IAMMeta
from gcloud.core.apis.drf.viewsets.base import GcloudModelViewSet
from gcloud.iam_auth import IAMMeta, res_factory
from gcloud.label.models import Label, TemplateLabelRelation
from gcloud.taskflow3.models import TaskConfig, TaskTemplate
from gcloud.tasktmpl3.signals import post_template_save_commit
from gcloud.template_base.domains.template_manager import TemplateManager
from gcloud.core.apis.drf.filtersets import PropertyFilterSet
from gcloud.core.apis.drf.filters import BooleanPropertyFilter
from gcloud.contrib.operate_record.signal import operate_record_signal
from gcloud.contrib.operate_record.constants import OperateType, OperateSource, RecordType
from gcloud.core.apis.drf.permission import HAS_OBJECT_PERMISSION, IamPermission, IamPermissionInfo
from gcloud.user_custom_config.constants import TASKTMPL_ORDERBY_OPTIONS
from django.utils.translation import ugettext_lazy as _


logger = logging.getLogger("root")
manager = TemplateManager(template_model_cls=TaskTemplate)
Expand All @@ -74,6 +71,9 @@ class TaskTemplatePermission(IamPermission):
"update": IamPermissionInfo(
IAMMeta.FLOW_EDIT_ACTION, res_factory.resources_for_flow_obj, HAS_OBJECT_PERMISSION
),
"partial_update": IamPermissionInfo(
IAMMeta.FLOW_EDIT_ACTION, res_factory.resources_for_flow_obj, HAS_OBJECT_PERMISSION
),
"create": IamPermissionInfo(IAMMeta.FLOW_CREATE_ACTION, res_factory.resources_for_project, id_field="project"),
"enable_independent_subprocess": IamPermissionInfo(
IAMMeta.PROJECT_VIEW_ACTION, res_factory.resources_for_project, id_field="project_id"
Expand Down Expand Up @@ -206,7 +206,7 @@ def retrieve(self, request, *args, **kwargs):
return Response(data)

def create(self, request, *args, **kwargs):
serializer = CreateTaskTemplateSerializer(data=request.data)
serializer = CreateTaskTemplateSerializer(data=request.data, context={"request": request})
serializer.is_valid(raise_exception=True)
name = serializer.validated_data.pop("name")
creator = request.user.username
Expand Down Expand Up @@ -250,7 +250,9 @@ def create(self, request, *args, **kwargs):
def update(self, request, *args, **kwargs):
partial = kwargs.pop("partial", False)
template = self.get_object()
serializer = CreateTaskTemplateSerializer(template, data=request.data, partial=partial)
serializer = CreateTaskTemplateSerializer(
template, data=request.data, partial=partial, context={"request": request}
)
serializer.is_valid(raise_exception=True)
# update pipeline_template
name = serializer.validated_data.pop("name")
Expand Down

0 comments on commit 0f6fab9

Please sign in to comment.