def create(self, request, *args, **kwargs):
        """
        Add a label instance to specified global component.

        **Note**:  label must exist before being assigned to a global_component.

        __Method__: `POST`

        __URL__: $LINK:globalcomponentlabel-list:component_id$

        __Data__:

            {
                "name": "string"
            }

        __Response__:

        %(SERIALIZER)s
        """
        extra_keys = set(
            request.data.keys()) - self.serializer_class().get_allowed_keys()
        StrictSerializerMixin.maybe_raise_error(extra_keys)

        label_name = request.data.get('name')
        if not label_name:
            return Response(data={'name': ['This field is required.']},
                            status=status.HTTP_400_BAD_REQUEST)
        label = get_object_or_404(Label, name=label_name)

        gc_id = self.kwargs.get('instance_pk')
        gc = get_object_or_404(GlobalComponent, id=gc_id)

        old_value = json.dumps(gc.export())

        if label not in gc.labels.all():
            gc.labels.add(label)
            request.changeset.add("globalcomponent", gc.pk, old_value,
                                  json.dumps(gc.export()))
        return Response(status=status.HTTP_201_CREATED,
                        data=LabelSerializer(instance=label,
                                             context={
                                                 'request': request
                                             }).data)
Example #2
0
    def create(self, request, *args, **kwargs):
        """
        Add a label instance to specified global component.

        **Note**:  label must exist before being assigned to a global_component.

        __Method__: `POST`

        __URL__: $LINK:globalcomponentlabel-list:component_id$

        __Data__:

            {
                "name": "string"
            }

        __Response__:

        %(SERIALIZER)s
        """
        extra_keys = set(request.data.keys()) - self.serializer_class().get_allowed_keys()
        StrictSerializerMixin.maybe_raise_error(extra_keys)

        label_name = request.data.get('name')
        if not label_name:
            return Response(data={'name': ['This field is required.']},
                            status=status.HTTP_400_BAD_REQUEST)
        label = get_object_or_404(Label, name=label_name)

        gc_id = self.kwargs.get('instance_pk')
        gc = get_object_or_404(GlobalComponent, id=gc_id)

        old_value = json.dumps(gc.export())

        if label not in gc.labels.all():
            gc.labels.add(label)
            request.changeset.add("globalcomponent", gc.pk, old_value, json.dumps(gc.export()))
        return Response(
            status=status.HTTP_201_CREATED,
            data=LabelSerializer(instance=label, context={'request': request}).data
        )
    def create(self, request):
        """
        Clone all content delivery repositories from one release under another release.

        The call is atomic, i.e. either all content delivery repositories are cloned or nothing
        is done.

        If the source and target releases do not have the same variants, the
        cloning will silently ignore content delivery repositories with Variant.Arch that is
        present in source release but not in target release. It is not a
        problem if the target release has additional variants.

        __Method__: `POST`

        __URL__: $LINK:repoclone-list$


        __Data__:

            {
                "release_id_from":          string,
                "release_id_to":            string
                "include_service":          [string],   # optional
                "include_repo_family":      [string],   # optional
                "include_content_format":   [string],   # optional
                "include_content_category": [string],   # optional
                "include_shadow":           bool,       # optional
                "include_product_id":       int         # optional
            }

        The `include_*` keys are used to filter which releases should be
        cloned. If any key is omitted, all values for that attribute will be
        cloned.

        __Response__:
        The call returns a list of content delivery repositories created under target release.

            [
              {
                "shadow":           bool,
                "release_id":       string,
                "variant_uid":      string,
                "arch":             string,
                "service":          string,
                "repo_family":      string,
                "content_format":   string,
                "content_category": string,
                "name":             string,
                "product_id":       int
              },
              ...
            ]
        """
        data = request.data
        keys = set(['release_id_from', 'release_id_to'])
        arg_filter_map = {'include_service': ('service__name__in', hacks.as_list),
                          'include_repo_family': ('repo_family__name__in', hacks.as_list),
                          'include_content_format': ('content_format__name__in', hacks.as_list),
                          'include_content_category': ('content_category__name__in', hacks.as_list),
                          'include_shadow': ('shadow', hacks.convert_str_to_bool),
                          'include_product_id': ('product_id', hacks.convert_str_to_int)}
        allowed_keys = list(keys) + arg_filter_map.keys()

        missing_keys = keys - set(data.keys())
        if missing_keys:
            errors = dict([(k, ['This field is required.']) for k in missing_keys])
            return Response(status=status.HTTP_400_BAD_REQUEST, data=errors)
        extra_keys = set(data.keys()) - set(allowed_keys)
        StrictSerializerMixin.maybe_raise_error(extra_keys)

        get_object_or_404(Release, release_id=data['release_id_from'])
        target_release = get_object_or_404(Release, release_id=data['release_id_to'])

        kwargs = {
            'variant_arch__variant__release__release_id': data['release_id_from']
        }

        for arg, (filter, transform) in arg_filter_map.iteritems():
            arg_data = request.data.get(arg)
            if arg_data:
                kwargs[filter] = transform(arg_data, name=arg)

        repos = models.Repo.objects.filter(**kwargs)

        # Skip repos from nonexisting trees.
        repos_in_target_release = [repo for repo in repos if repo.tree in target_release.trees]

        if not repos or not repos_in_target_release:
            return Response(status=status.HTTP_400_BAD_REQUEST,
                            data={'detail': 'No repos to clone.'})

        serializer = serializers.RepoSerializer(repos_in_target_release, many=True)
        copy = serializer.data
        for repo in copy:
            # The serializer will reject read-only fields, so we need to drop the id.
            del repo['id']
            repo['release_id'] = target_release.release_id
        new_repos = serializers.RepoSerializer(data=copy, many=True)
        if not new_repos.is_valid():
            return Response(status=status.HTTP_400_BAD_REQUEST,
                            data={'detail': dict((repo['name'], err)
                                                 for repo, err in zip(copy, new_repos.errors)
                                                 if err)})
        for raw_repo, repo_obj in zip(copy, new_repos.save()):
            request.changeset.add('Repo', repo_obj.pk,
                                  'null', json.dumps(raw_repo))

        return Response(status=status.HTTP_200_OK, data=new_repos.data)
Example #4
0
    def create(self, request, *args, **kwargs):
        """
        __Method__:
        POST

        __URL__: $LINK:bugzillacomponent-list$

        __Data__:

            {
                "name":                        "string",         # required
                "parent_pk: (default=None)":   "int"             # optional
            }

        __Response__:

        %(SERIALIZER)s

        __NOTE__:

        Root bugzilla component will be created if parent_pk is not given or
        {"parent_pk": null}
        """
        data = request.data

        serializer_class = self.get_serializer_class()
        extra_keys = set(data.keys()) - serializer_class().get_allowed_keys()
        StrictSerializerMixin.maybe_raise_error(extra_keys)

        name = data.get('name')
        parent_pk = data.get('parent_pk')

        if type(parent_pk) not in (types.IntType, types.NoneType):
            return Response({'detail': 'Parent_pk is not typeof int or Nonetype.'},
                            status=status.HTTP_400_BAD_REQUEST)
        p_bc = None

        if name is None or name.strip() == "":
            return Response({'detail': 'Missing bugzilla component name.'},
                            status=status.HTTP_400_BAD_REQUEST)

        if parent_pk is not None:
            try:
                p_bc = BugzillaComponent.objects.get(pk=parent_pk)
            except BugzillaComponent.DoesNotExist:
                return Response({'detail': 'Parent bugzilla component with pk %s does not exist' % parent_pk},
                                status=status.HTTP_404_NOT_FOUND)
        try:
            bc, created = BugzillaComponent.objects.get_or_create(
                name=name,
                parent_component=p_bc)
        except ValidationError as exc:
            return Response(exc.message_dict, status=status.HTTP_400_BAD_REQUEST)

        serializer = serializer_class(instance=bc, data=request.data, context={'request': request})

        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        if created:
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
        else:
            return Response(serializer.data, status=status.HTTP_200_OK,
                            headers=generate_warning_header_dict("The bugzilla component already exists"))
Example #5
0
    def create(self, request, *args, **kwargs):
        """
        __Method__:
        POST

        __URL__: $LINK:bugzillacomponent-list$

        __Data__:

            {
                "name":                        "string",         # required
                "parent_pk: (default=None)":   "int"             # optional
            }

        __Response__:

        %(SERIALIZER)s

        __NOTE__:

        Root bugzilla component will be created if parent_pk is not given or
        {"parent_pk": null}
        """
        data = request.data

        serializer_class = self.get_serializer_class()
        extra_keys = set(data.keys()) - serializer_class().get_allowed_keys()
        StrictSerializerMixin.maybe_raise_error(extra_keys)

        name = data.get('name')
        parent_pk = data.get('parent_pk')

        if type(parent_pk) not in (types.IntType, types.NoneType):
            return Response({'detail': 'Parent_pk is not typeof int or Nonetype.'},
                            status=status.HTTP_400_BAD_REQUEST)
        p_bc = None

        if name is None or name.strip() == "":
            return Response({'detail': 'Missing bugzilla component name.'},
                            status=status.HTTP_400_BAD_REQUEST)

        if parent_pk is not None:
            try:
                p_bc = BugzillaComponent.objects.get(pk=parent_pk)
            except BugzillaComponent.DoesNotExist:
                return Response({'detail': 'Parent bugzilla component with pk %s does not exist' % parent_pk},
                                status=status.HTTP_404_NOT_FOUND)
        try:
            bc, created = BugzillaComponent.objects.get_or_create(
                name=name,
                parent_component=p_bc)
        except ValidationError as exc:
            return Response(exc.message_dict, status=status.HTTP_400_BAD_REQUEST)

        serializer = serializer_class(instance=bc, data=request.data, context={'request': request})

        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        if created:
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
        else:
            return Response(serializer.data, status=status.HTTP_200_OK,
                            headers=generate_warning_header_dict("The bugzilla component already exists"))
    def create(self, request):
        """
        Clone all content delivery repositories from one release under another release.

        The call is atomic, i.e. either all content delivery repositories are cloned or nothing
        is done.

        If the source and target releases do not have the same variants, the
        cloning will silently ignore content delivery repositories with Variant.Arch that is
        present in source release but not in target release. It is not a
        problem if the target release has additional variants.

        __Method__: `POST`

        __URL__: $LINK:cdreposclone-list$


        __Data__:

            {
                "release_id_from":          string,
                "release_id_to":            string
                "include_service":          [string],   # optional
                "include_repo_family":      [string],   # optional
                "include_content_format":   [string],   # optional
                "include_content_category": [string],   # optional
                "include_shadow":           bool,       # optional
                "include_product_id":       int         # optional
            }

        The `include_*` keys are used to filter which releases should be
        cloned. If any key is omitted, all values for that attribute will be
        cloned.

        __Response__:
        The call returns a list of content delivery repositories created under target release.

            [
              {
                "shadow":           bool,
                "release_id":       string,
                "variant_uid":      string,
                "arch":             string,
                "service":          string,
                "repo_family":      string,
                "content_format":   string,
                "content_category": string,
                "name":             string,
                "product_id":       int
              },
              ...
            ]
        """
        data = request.data
        keys = set(['release_id_from', 'release_id_to'])
        arg_filter_map = {'include_service': ('service__name__in', hacks.as_list),
                          'include_repo_family': ('repo_family__name__in', hacks.as_list),
                          'include_content_format': ('content_format__name__in', hacks.as_list),
                          'include_content_category': ('content_category__name__in', hacks.as_list),
                          'include_shadow': ('shadow', hacks.convert_str_to_bool),
                          'include_product_id': ('product_id', hacks.convert_str_to_int)}
        allowed_keys = list(keys) + arg_filter_map.keys()

        missing_keys = keys - set(data.keys())
        if missing_keys:
            errors = dict([(k, ['This field is required.']) for k in missing_keys])
            return Response(status=status.HTTP_400_BAD_REQUEST, data=errors)
        extra_keys = set(data.keys()) - set(allowed_keys)
        StrictSerializerMixin.maybe_raise_error(extra_keys)

        get_object_or_404(Release, release_id=data['release_id_from'])
        target_release = get_object_or_404(Release, release_id=data['release_id_to'])

        kwargs = {
            'variant_arch__variant__release__release_id': data['release_id_from']
        }

        for arg, (filter, transform) in arg_filter_map.iteritems():
            arg_data = request.data.get(arg)
            if arg_data:
                kwargs[filter] = transform(arg_data, name=arg)

        repos = models.Repo.objects.filter(**kwargs)

        # Skip repos from nonexisting trees.
        repos_in_target_release = [repo for repo in repos if repo.tree in target_release.trees]

        if not repos or not repos_in_target_release:
            return Response(status=status.HTTP_400_BAD_REQUEST,
                            data={'detail': 'No repos to clone.'})

        serializer = serializers.RepoSerializer(repos_in_target_release, many=True)
        copy = serializer.data
        for repo in copy:
            # The serializer will reject read-only fields, so we need to drop the id.
            del repo['id']
            repo['release_id'] = target_release.release_id
        new_repos = serializers.RepoSerializer(data=copy, many=True)
        if not new_repos.is_valid():
            return Response(status=status.HTTP_400_BAD_REQUEST,
                            data={'detail': dict((repo['name'], err)
                                                 for repo, err in zip(copy, new_repos.errors)
                                                 if err)})
        for raw_repo, repo_obj in zip(copy, new_repos.save()):
            request.changeset.add('Repo', repo_obj.pk,
                                  'null', json.dumps(raw_repo))

        return Response(status=status.HTTP_200_OK, data=new_repos.data)