def execute(self): """ Execute a load. Fetch from the catalog and send to loader. :return: the ImageLoad result object including the image object and its vulnerabilities or None if image already found """ self.start_time = datetime.datetime.utcnow() try: db = get_session() img = db.query(Image).get((self.image_id, self.user_id)) if img is not None: if not self.force_reload: log.info( 'Image {}/{} already found in the system. Will not re-load.' .format(self.user_id, self.image_id)) db.close() return None else: log.info( 'Deleting image {}/{} and all associated resources for reload' .format(self.user_id, self.image_id)) for pkg_vuln in img.vulnerabilities(): db.delete(pkg_vuln) db.delete(img) # Close the session during the data fetch. #db.close() image_obj = self._load_image_analysis() if not image_obj: log.error('Could not load image analysis') raise ImageLoadError( 'Failed to load image: user_id = {}, image_id = {}, fetch_url = {}' .format(self.user_id, self.image_id, self.fetch_url)) db = get_session() try: log.info("Adding image to db") db.add(image_obj) log.info("Adding image package vulnerabilities to db") vulns = vulnerabilities_for_image(image_obj) for vuln in vulns: db.add(vuln) db.commit() except: log.exception('Error adding image to db') db.rollback() raise return ImageLoadResult(image_obj, vulns) except Exception as e: log.exception('Error loading and scanning image: {}'.format( self.image_id)) raise finally: self.stop_time = datetime.datetime.utcnow()
def check_all_imgs_vuln(): db = get_thread_scoped_session() try: for img in db.query(Image).all(): logger.info('Checking vulnerabilities for image: {}'.format(img.id)) if not img: logger.info('No image found with id: {}'.format(img.id)) raise Exception('Should have image') vulns = vulnerabilities.vulnerabilities_for_image(img) for v in vulns: db.merge(v) db.commit() logger.info('Found: {}'.format(vulns)) except Exception as e: logger.info('Error! {}'.format(e)) end_session()
def get_image_vulnerabilities(user_id, image_id, force_refresh=False): """ Return the vulnerability listing for the specified image and load from catalog if not found and specifically asked to do so. Example json output: { "multi" : { "url_column_index" : 7, "result" : { "rows" : [], "rowcount" : 0, "colcount" : 8, "header" : [ "CVE_ID", "Severity", "*Total_Affected", "Vulnerable_Package", "Fix_Available", "Fix_Images", "Rebuild_Images", "URL" ] }, "querycommand" : "/usr/lib/python2.7/site-packages/anchore/anchore-modules/multi-queries/cve-scan.py /ebs_data/anchore/querytmp/queryimages.7026386 /ebs_data/anchore/data /ebs_data/anchore/querytmp/query.59057288 all", "queryparams" : "all", "warns" : [ "0005b136f0fb (prom/prometheus:master) cannot perform CVE scan: no CVE data is currently available for the detected base distro type (busybox:unknown_version,busybox:v1.26.2)" ] } } :param user_id: user id of image to evaluate :param image_id: image id to evaluate :param force_refresh: if true, flush and recompute vulnerabilities rather than returning current values :return: """ # Has image? db = get_session() try: img = db.query(Image).get((image_id, user_id)) vulns = [] if not img: abort(404) else: if force_refresh: log.info('Forcing refresh of vulnerabiltiies for {}/{}'.format(user_id, image_id)) try: current_vulns = img.vulnerabilities() log.info('Removing {} current vulnerabilities for {}/{} to rescan'.format(len(current_vulns), user_id, image_id)) for v in current_vulns: db.delete(v) db.flush() vulns = vulnerabilities_for_image(img) log.info('Adding {} vulnerabilities from rescan to {}/{}'.format(len(vulns), user_id, image_id)) for v in vulns: db.add(v) db.commit() except Exception as e: log.exception('Error refreshing cve matches for image {}/{}'.format(user_id, image_id)) db.rollback() abort(Response('Error refreshing vulnerability listing for image.', 500)) db = get_session() db.refresh(img) else: vulns = img.vulnerabilities() # Has vulnerabilities? warns = [] if not vulns: vulns = [] ns = DistroNamespace.for_obj(img) if not have_vulnerabilities_for(ns): warns = ['No vulnerability data available for image distro: {}'.format(ns.namespace_name)] rows = [] for vuln in vulns: # if vuln.vulnerability.fixed_in: # fixes_in = filter(lambda x: x.name == vuln.pkg_name or x.name == vuln.package.normalized_src_pkg, # vuln.vulnerability.fixed_in) # fix_available_in = fixes_in[0].version if fixes_in else 'None' # else: # fix_available_in = 'None' rows.append([ vuln.vulnerability_id, vuln.vulnerability.severity, 1, vuln.pkg_name + '-' + vuln.package.fullversion, str(vuln.fixed_in()), vuln.pkg_image_id, 'None', # Always empty this for now vuln.vulnerability.link ] ) vuln_listing = { 'multi': { 'url_column_index': 7, 'result': { 'header': TABLE_STYLE_HEADER_LIST, 'rowcount': len(rows), 'colcount': len(TABLE_STYLE_HEADER_LIST), 'rows': rows }, 'warns': warns } } report = LegacyVulnerabilityReport.from_dict(vuln_listing) resp = ImageVulnerabilityListing(user_id=user_id, image_id=image_id, legacy_report=report) return resp.to_dict() except HTTPException: db.rollback() raise except Exception as e: log.exception('Error checking image {}, {} for vulnerabiltiies. Rolling back'.format(user_id, image_id)) db.rollback() abort(500) finally: db.close()
def compute_vulnerabilities(self, image_obj): """ Wrapper for vulnerabilities_for_image function """ vulnerabilities.vulnerabilities_for_image(image_obj)