From 37ce84f6af86c9fa5e246d308ebdee9f24a9c11f Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Thu, 12 Nov 2015 17:02:18 -0500 Subject: [PATCH] tiny fixes to securityworker --- util/secscan/api.py | 26 +++++++++++++------------- workers/securityworker.py | 25 ++++++++++++++++++------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/util/secscan/api.py b/util/secscan/api.py index 331e45294..277fd3f6d 100644 --- a/util/secscan/api.py +++ b/util/secscan/api.py @@ -134,13 +134,11 @@ class SecurityConfigValidator(object): return self._keys def valid(self): - config = self._security_config - if (not features.SECURITY_SCANNER - or not config - or not 'ENDPOINT' in config - or not 'ENGINE_VERSION_TARGET' in config - or not 'DISTRIBUTED_STORAGE_PREFERENCE' in config + or not self._security_config + or not 'ENDPOINT' in self._security_config + or not 'ENGINE_VERSION_TARGET' in self._security_config + or not 'DISTRIBUTED_STORAGE_PREFERENCE' in self._security_config or (self._certificate is False and self._keys is None)): return False @@ -155,10 +153,12 @@ class SecurityScannerAPI(object): config_validator = SecurityConfigValidator(app, config_provider) if not config_validator.valid(): + logger.warning('Invalid config provided to SecurityScannerAPI') return - self.certificate = config_validator.cert() - self.keys = config_validator.keypair() + self._security_config = app.config.get('SECURITY_SCANNER') + self._certificate = config_validator.cert() + self._keys = config_validator.keypair() def check_layer_vulnerable(self, layer_id, cve_id): """ Checks with Clair whether the given layer is vulnerable to the given CVE. """ @@ -191,7 +191,7 @@ class SecurityScannerAPI(object): This function disconnects from the database while awaiting a response from the API server. """ - security_config = self.security_config + security_config = self._security_config api_url = urljoin(security_config['ENDPOINT'], '/' + security_config['API_VERSION']) + '/' url = urljoin(api_url, relative_url % args) @@ -201,8 +201,8 @@ class SecurityScannerAPI(object): with CloseForLongOperation(self.app.config): if body is not None: - return client.post(url, json=body, params=kwargs, timeout=timeout, cert=self.keys, - verify=self.certificate) + return client.post(url, json=body, params=kwargs, timeout=timeout, cert=self._keys, + verify=self._certificate) else: - return client.get(url, params=kwargs, timeout=timeout, cert=self.keys, - verify=self.certificate) + return client.get(url, params=kwargs, timeout=timeout, cert=self._keys, + verify=self._certificate) diff --git a/workers/securityworker.py b/workers/securityworker.py index 1f4328741..664e91472 100644 --- a/workers/securityworker.py +++ b/workers/securityworker.py @@ -129,6 +129,7 @@ class SecurityWorker(Worker): self._keys = validator.keypair() self.add_operation(self._index_images, INDEXING_INTERVAL) + logger.warning('Failed to validate security scan configuration') def _get_image_url(self, image): """ Gets the download URL for an image and if the storage doesn't exist, @@ -149,9 +150,18 @@ class SecurityWorker(Worker): return None uri = storage.get_direct_download_url(locations, path) - # Local storage hack if uri is None: - uri = path + # Handle local storage + local_storage_enabled = False + for storage_type, _ in app.config.get('DISTRIBUTED_STORAGE_CONFIG', {}).values(): + if storage_type == 'LocalStorage': + local_storage_enabled = True + + if local_storage_enabled: + uri = path + else: + logger.warning('Could not get image URL and local storage was not enabled') + return None return uri @@ -161,12 +171,13 @@ class SecurityWorker(Worker): return None request = { - 'ID': image['docker_image_id']+'.'+image['storage_uuid'], + 'ID': '%s.%s' % (image['docker_image_id'], image['storage_uuid']), 'Path': url, } if image['parent_docker_image_id'] is not None and image['parent_storage_uuid'] is not None: - request['ParentID'] = image['parent_docker_image_id']+'.'+image['parent_storage_uuid'] + request['ParentID'] = '%s.%s' % (image['parent_docker_image_id'], + image['parent_storage_uuid']) return request @@ -182,7 +193,7 @@ class SecurityWorker(Worker): httpResponse = requests.post(self._api + API_METHOD_INSERT, json=request, cert=self._keys, verify=self._cert) jsonResponse = httpResponse.json() - except: + except (requests.exceptions.RequestException, ValueError): logger.exception('An exception occurred when analyzing layer ID %s', request['ID']) return None @@ -245,18 +256,18 @@ class SecurityWorker(Worker): if not images: logger.debug('No more images left to analyze') return - logger.debug('Found %d images to index' % len(images)) + logger.debug('Found %d images to index', len(images)) for image in images: sec_data = self._analyze_image(image) if sec_data is None: continue - logger.debug('Got response vulnerabilities for layer %s: %s', image['image_id'], sec_data) if not sec_data['Vulnerabilities']: continue # Dispatch events for any detected vulnerabilities + logger.debug('Got response vulnerabilities for layer %s: %s', image['image_id'], sec_data) event = ExternalNotificationEvent.get(name='vulnerability_found') matching = (RepositoryTag .select(RepositoryTag, Repository)