Пример #1
0
    def handle_patch(cls, **kwargs):
        """Update the 'status' field for a system/cve combination"""
        # pylint: disable=singleton-comparison
        data = kwargs['data']

        try:
            in_inventory_id_list, in_cve_list, status_to_cves_map, status_text_to_cves_map = cls._prepare_data(data)
            rh_account = get_or_create_account()
            systems = (SystemPlatform.select(SystemPlatform.id)
                       .where((SystemPlatform.rh_account_id == rh_account[0].id) &
                              (SystemPlatform.opt_out == False)))  # noqa: E712
            if in_inventory_id_list is not None:
                systems = systems.where(SystemPlatform.inventory_id << in_inventory_id_list)
            rows_modified = set()
            # set statuses and their CVE lists
            for status_id, status_cve_list in status_to_cves_map.items():
                status_id_update = (SystemVulnerabilities.update(status_id=status_id)
                                    .where((SystemVulnerabilities.system_id << systems) &
                                           (SystemVulnerabilities.cve_id <<
                                            (CveMetadata.select(CveMetadata.id).where(
                                                CveMetadata.cve << status_cve_list))))
                                    .returning(SystemVulnerabilities.id))
                rows_modified.update([row.id for row in status_id_update])

            cls._update_divergent_status_count(in_cve_list, rh_account[0].id)

            for status_text, status_cve_list in status_text_to_cves_map.items():
                status_text_update = (SystemVulnerabilities.update(status_text=status_text)
                                      .where((SystemVulnerabilities.system_id << systems) &
                                             (SystemVulnerabilities.cve_id <<
                                              (CveMetadata.select(CveMetadata.id).where(
                                                  CveMetadata.cve << status_cve_list))))
                                      .returning(SystemVulnerabilities.id))
                rows_modified.update([row.id for row in status_text_update])

            updated_details = (SystemVulnerabilities.select(SystemPlatform.inventory_id, CveMetadata.cve)
                               .join(CveMetadata, on=(SystemVulnerabilities.cve_id == CveMetadata.id))
                               .join(SystemPlatform, on=(SystemVulnerabilities.system_id == SystemPlatform.id))
                               .where(SystemVulnerabilities.id << list(rows_modified))
                               .dicts())
            updated = []
            for updated_row in updated_details:
                updated.append({"inventory_id": updated_row["inventory_id"], "cve": updated_row["cve"]})
            if not updated:
                # sysid/cve/acct combination does not exist
                return cls.format_exception('inventory_id/cve must exist and inventory_id must be visible to user', 404)
        except (IntegrityError, psycopg2IntegrityError, DataError) as value_error:
            # usually means bad-status-id
            LOGGER.error(str(value_error))
            DB.rollback()
            return cls.format_exception(f'status_id={list(status_to_cves_map.keys())} is invalid', 400)
        except ValueError as value_error:
            LOGGER.exception('Error during setting status (ValueError):')
            DB.rollback()
            return cls.format_exception(f'status_text or other key value is invalid ({value_error})', 400)
        return {"updated": updated}
 def handle_patch(cls, **kwargs):
     """Update the 'status' field for a system/cve combination"""
     data = kwargs['data']
     in_inventory_id = data['inventory_id']
     in_cve = data['cve']
     in_status_id = data['status_id']
     LOGGER.debug('SYSID [%s] CVE [%s] STATUS-ID [%s] ACCT [%s]',
                  in_inventory_id, in_cve, in_status_id, connexion.context['user'])
     try:
         plat = (SystemPlatform.select(SystemPlatform.inventory_id)
                 .where((SystemPlatform.rh_account == connexion.context['user']) &
                        (SystemPlatform.inventory_id == in_inventory_id) &
                        (SystemPlatform.opt_out == False)))  # pylint: disable=singleton-comparison
         if cls.hide_satellite_managed():
             plat = plat.where(SystemPlatform.satellite_managed == False)  # pylint: disable=singleton-comparison
         vuln = (SystemVulnerabilities.update(status_id=in_status_id)
                 .from_(plat)
                 .where((SystemVulnerabilities.inventory_id == in_inventory_id) &
                        (SystemVulnerabilities.cve == in_cve)))
         rows_modified = vuln.execute()
         if rows_modified == 0:
             # sysid/cve/acct combination does not exist
             return cls.format_exception('inventory_id/cve must exist and inventory_id must be visible to user', 404)
     except (IntegrityError, ValueError, psycopg2IntegrityError) as integ_error:
         # usually means bad-status-id
         DB.rollback()
         return cls.format_exception(str(integ_error), 500)
     return ''