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

feat: 添加 执行代理人 配置校验 #7302

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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 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
Loading