class UpdateRecordSerializer(NoArtifactContentSerializer): """ A Serializer for UpdateRecord. """ id = serializers.CharField( help_text=_("Update id (short update name, e.g. RHEA-2013:1777)")) updated_date = serializers.CharField(help_text=_( "Date when the update was updated (e.g. '2013-12-02 00:00:00')")) description = serializers.CharField(help_text=_("Update description")) issued_date = serializers.CharField(help_text=_( "Date when the update was issued (e.g. '2013-12-02 00:00:00')")) fromstr = serializers.CharField( help_text=_("Source of the update (e.g. [email protected])")) status = serializers.CharField(help_text=_("Update status ('final', ...)")) title = serializers.CharField(help_text=_("Update name")) summary = serializers.CharField(help_text=_("Short summary")) version = serializers.CharField( help_text=_("Update version (probably always an integer number)")) type = serializers.CharField( help_text=_("Update type ('enhancement', 'bugfix', ...)")) severity = serializers.CharField(help_text=_("Severity")) solution = serializers.CharField(help_text=_("Solution")) release = serializers.CharField(help_text=_("Update release")) rights = serializers.CharField(help_text=_("Copyrights")) pushcount = serializers.CharField(help_text=_("Push count")) pkglist = UpdateCollectionField(source='pk', read_only=True, help_text=_("List of packages")) references = UpdateReferenceField(source='pk', read_only=True, help_text=_("List of references")) class Meta: fields = NoArtifactContentSerializer.Meta.fields + ( 'id', 'updated_date', 'description', 'issued_date', 'fromstr', 'status', 'title', 'summary', 'version', 'type', 'severity', 'solution', 'release', 'rights', 'pushcount', 'pkglist', 'references') model = UpdateRecord
class UpdateRecordSerializer(NoArtifactContentUploadSerializer): """ A Serializer for UpdateRecord. """ id = serializers.CharField( help_text=_("Update id (short update name, e.g. RHEA-2013:1777)"), read_only=True, ) updated_date = serializers.CharField( help_text=_( "Date when the update was updated (e.g. '2013-12-02 00:00:00')"), read_only=True, ) description = serializers.CharField(help_text=_("Update description"), allow_blank=True, read_only=True) issued_date = serializers.CharField( help_text=_( "Date when the update was issued (e.g. '2013-12-02 00:00:00')"), read_only=True, ) fromstr = serializers.CharField( help_text=_("Source of the update (e.g. [email protected])"), allow_blank=True, read_only=True, ) status = serializers.CharField(help_text=_("Update status ('final', ...)"), allow_blank=True, read_only=True) title = serializers.CharField(help_text=_("Update name"), allow_blank=True, read_only=True) summary = serializers.CharField(help_text=_("Short summary"), allow_blank=True, read_only=True) version = serializers.CharField( help_text=_("Update version (probably always an integer number)"), allow_blank=True, read_only=True, ) type = serializers.CharField( help_text=_("Update type ('enhancement', 'bugfix', ...)"), allow_blank=True, read_only=True, ) severity = serializers.CharField(help_text=_("Severity"), allow_blank=True, read_only=True) solution = serializers.CharField(help_text=_("Solution"), allow_blank=True, read_only=True) release = serializers.CharField(help_text=_("Update release"), allow_blank=True, read_only=True) rights = serializers.CharField(help_text=_("Copyrights"), allow_blank=True, read_only=True) pushcount = serializers.CharField(help_text=_("Push count"), allow_blank=True, read_only=True) reboot_suggested = serializers.BooleanField( help_text=_("Reboot suggested"), read_only=True) pkglist = UpdateCollectionSerializer(source="collections", read_only=True, many=True, help_text=_("List of packages")) references = UpdateReferenceField(source="pk", read_only=True, help_text=_("List of references")) def create(self, validated_data): """ Create UpdateRecord and its subclasses from JSON file. Returns: UpdateRecord instance """ references = validated_data.pop("references", []) pkglist = validated_data.pop("pkglist", []) # detach any specified repository; attach once the advisory exists repository = validated_data.pop("repository", None) update_collection_packages_to_save = list() update_references_to_save = list() try: update_record = super().create(validated_data) except IntegrityError: raise serializers.ValidationError( "Advisory already exists in Pulp.") for collection in pkglist: new_coll = copy.deepcopy(collection) packages = new_coll.pop("packages", []) new_coll[PULP_UPDATE_COLLECTION_ATTRS.SHORTNAME] = new_coll.pop( "short", "") coll = UpdateCollection(**new_coll) coll.update_record = update_record coll.save() for package in packages: pkg = UpdateCollectionPackage(**package) try: pkg.sum_type = createrepo_c.checksum_type(pkg.sum_type) except TypeError: raise TypeError(f'"{pkg.sum_type}" is not supported.') pkg.update_collection = coll update_collection_packages_to_save.append(pkg) for reference in references: new_ref = dict() new_ref[PULP_UPDATE_REFERENCE_ATTRS.HREF] = reference.get( CR_UPDATE_REFERENCE_ATTRS.HREF, "") new_ref[PULP_UPDATE_REFERENCE_ATTRS.ID] = reference.get( CR_UPDATE_REFERENCE_ATTRS.ID, "") new_ref[PULP_UPDATE_REFERENCE_ATTRS.TITLE] = reference.get( CR_UPDATE_REFERENCE_ATTRS.TITLE, "") new_ref[PULP_UPDATE_REFERENCE_ATTRS.TYPE] = reference.get( CR_UPDATE_REFERENCE_ATTRS.TYPE, "") ref = UpdateReference(**new_ref) ref.update_record = update_record update_references_to_save.append(ref) if update_collection_packages_to_save: UpdateCollectionPackage.objects.bulk_create( update_collection_packages_to_save) if update_references_to_save: UpdateReference.objects.bulk_create(update_references_to_save) cr_update_record = update_record.to_createrepo_c() update_record.digest = hash_update_record(cr_update_record) update_record.save() # create new repo version with uploaded advisory if repository: repository.cast() content_to_add = self.Meta.model.objects.filter( pk=update_record.pk) with repository.new_version() as new_version: new_version.add_content(content_to_add) return update_record def validate(self, data): """ Read a file for a JSON data and validate a UpdateRecord data. Also change few fields to match Pulp internals if exists as this is usually handle by createrepo_c which is not used here. """ update_record_data = dict() if "file" in data: try: update_record_data.update(json.loads(data["file"].read())) except UnicodeDecodeError: raise serializers.ValidationError("JSON file is expected") else: update_record_data.update(data) else: raise serializers.ValidationError( "Only creation with file or artifact is allowed.") update_record_data[ PULP_UPDATE_RECORD_ATTRS.FROMSTR] = update_record_data.pop( "from", update_record_data.get(PULP_UPDATE_RECORD_ATTRS.FROMSTR, "")) update_record_data[ PULP_UPDATE_RECORD_ATTRS.ISSUED_DATE] = update_record_data.pop( "issued", update_record_data.get(PULP_UPDATE_RECORD_ATTRS.ISSUED_DATE, "")) update_record_data[ PULP_UPDATE_RECORD_ATTRS.UPDATED_DATE] = update_record_data.pop( "updated", update_record_data.get(PULP_UPDATE_RECORD_ATTRS.UPDATED_DATE, "")) if (not update_record_data.get(PULP_UPDATE_RECORD_ATTRS.ID) or not update_record_data.get( PULP_UPDATE_RECORD_ATTRS.UPDATED_DATE) or not update_record_data.get( PULP_UPDATE_RECORD_ATTRS.ISSUED_DATE)): raise serializers.ValidationError( "All '{}', '{}' and '{}' must be specified.".format( PULP_UPDATE_RECORD_ATTRS.ID, PULP_UPDATE_RECORD_ATTRS.UPDATED_DATE, PULP_UPDATE_RECORD_ATTRS.ISSUED_DATE, )) validated_data = super().validate(update_record_data) return validated_data class Meta: fields = NoArtifactContentUploadSerializer.Meta.fields + ( "id", "updated_date", "description", "issued_date", "fromstr", "status", "title", "summary", "version", "type", "severity", "solution", "release", "rights", "pushcount", "pkglist", "references", "reboot_suggested", ) model = UpdateRecord
class UpdateRecordSerializer(SingleArtifactContentUploadSerializer): """ A Serializer for UpdateRecord. """ id = serializers.CharField( help_text=_("Update id (short update name, e.g. RHEA-2013:1777)"), read_only=True) updated_date = serializers.CharField(help_text=_( "Date when the update was updated (e.g. '2013-12-02 00:00:00')"), read_only=True) description = serializers.CharField(help_text=_("Update description"), allow_blank=True, read_only=True) issued_date = serializers.CharField(help_text=_( "Date when the update was issued (e.g. '2013-12-02 00:00:00')"), read_only=True) fromstr = serializers.CharField( help_text=_("Source of the update (e.g. [email protected])"), allow_blank=True, read_only=True) status = serializers.CharField(help_text=_("Update status ('final', ...)"), allow_blank=True, read_only=True) title = serializers.CharField(help_text=_("Update name"), allow_blank=True, read_only=True) summary = serializers.CharField(help_text=_("Short summary"), allow_blank=True, read_only=True) version = serializers.CharField( help_text=_("Update version (probably always an integer number)"), allow_blank=True, read_only=True) type = serializers.CharField( help_text=_("Update type ('enhancement', 'bugfix', ...)"), allow_blank=True, read_only=True) severity = serializers.CharField(help_text=_("Severity"), allow_blank=True, read_only=True) solution = serializers.CharField(help_text=_("Solution"), allow_blank=True, read_only=True) release = serializers.CharField(help_text=_("Update release"), allow_blank=True, read_only=True) rights = serializers.CharField(help_text=_("Copyrights"), allow_blank=True, read_only=True) pushcount = serializers.CharField(help_text=_("Push count"), allow_blank=True, read_only=True) reboot_suggested = serializers.BooleanField( help_text=_("Reboot suggested"), read_only=True) pkglist = UpdateCollectionSerializer(source='collections', read_only=True, many=True, help_text=_("List of packages")) references = UpdateReferenceField(source='pk', read_only=True, help_text=_("List of references")) def create(self, validated_data): """ Create UpdateRecord and its subclasses from JSON file. Returns: UpdateRecord instance """ references = validated_data.pop("references", []) pkglist = validated_data.pop("pkglist", []) update_collection_packages_to_save = list() update_references_to_save = list() try: update_record = super().create(validated_data) except IntegrityError: raise serializers.ValidationError( "Advisory already exists in Pulp.") for collection in pkglist: new_coll = copy.deepcopy(collection) packages = new_coll.pop("packages", []) new_coll[PULP_UPDATE_COLLECTION_ATTRS.SHORTNAME] = new_coll.pop( "short", "") coll = UpdateCollection(**new_coll) coll.save() coll.update_record.add(update_record) for package in packages: pkg = UpdateCollectionPackage(**package) pkg.update_collection = coll update_collection_packages_to_save.append(pkg) for reference in references: new_ref = dict() new_ref[PULP_UPDATE_REFERENCE_ATTRS.HREF] = reference.get( CR_UPDATE_REFERENCE_ATTRS.HREF, "") new_ref[PULP_UPDATE_REFERENCE_ATTRS.ID] = reference.get( CR_UPDATE_REFERENCE_ATTRS.ID, "") new_ref[PULP_UPDATE_REFERENCE_ATTRS.TITLE] = reference.get( CR_UPDATE_REFERENCE_ATTRS.TITLE, "") new_ref[PULP_UPDATE_REFERENCE_ATTRS.TYPE] = reference.get( CR_UPDATE_REFERENCE_ATTRS.TYPE, "") ref = UpdateReference(**new_ref) ref.update_record = update_record update_references_to_save.append(ref) if update_collection_packages_to_save: UpdateCollectionPackage.objects.bulk_create( update_collection_packages_to_save) if update_references_to_save: UpdateReference.objects.bulk_create(update_references_to_save) cr_update_record = update_record.to_createrepo_c() update_record.digest = hash_update_record(cr_update_record) update_record.save() return update_record def validate(self, data): """ Read a file for a JSON data and validate a UpdateRecord data. Also change few fields to match Pulp internals if exists as this is usually handle by createrepo_c which is not used here. """ update_record_data = dict() if 'file' in data: update_record_data.update(json.loads(data['file'].read())) update_record_data.update(data) elif 'artifact' in data: update_record_data.update(json.loads(data['artifact'].file.read())) update_record_data.update(data) else: raise serializers.ValidationError( "Only creation with file or artifact is allowed.") update_record_data[ PULP_UPDATE_RECORD_ATTRS.FROMSTR] = update_record_data.pop( 'from', update_record_data.get(PULP_UPDATE_RECORD_ATTRS.FROMSTR, "")) update_record_data[ PULP_UPDATE_RECORD_ATTRS.ISSUED_DATE] = update_record_data.pop( 'issued', update_record_data.get(PULP_UPDATE_RECORD_ATTRS.ISSUED_DATE, "")) update_record_data[ PULP_UPDATE_RECORD_ATTRS.UPDATED_DATE] = update_record_data.pop( 'updated', update_record_data.get(PULP_UPDATE_RECORD_ATTRS.UPDATED_DATE, "")) if not update_record_data.get(PULP_UPDATE_RECORD_ATTRS.ID) or \ not update_record_data.get(PULP_UPDATE_RECORD_ATTRS.UPDATED_DATE) or \ not update_record_data.get(PULP_UPDATE_RECORD_ATTRS.ISSUED_DATE): raise serializers.ValidationError( "All '{}', '{}' and '{}' must be specified.".format( PULP_UPDATE_RECORD_ATTRS.ID, PULP_UPDATE_RECORD_ATTRS.UPDATED_DATE, PULP_UPDATE_RECORD_ATTRS.ISSUED_DATE)) validated_data = super().validate(update_record_data) return validated_data class Meta: fields = SingleArtifactContentUploadSerializer.Meta.fields + ( 'id', 'updated_date', 'description', 'issued_date', 'fromstr', 'status', 'title', 'summary', 'version', 'type', 'severity', 'solution', 'release', 'rights', 'pushcount', 'pkglist', 'references', 'reboot_suggested') model = UpdateRecord