Exemple #1
0
    def edit_scan(self, scan_id, title=None, description=None, configuration=None):
        """Edits the given Scan process and saves the changes in the database. All database changes occur in an atomic
        transaction. An argument of None for a field indicates that the field should not change.

        :param scan_id: The unique identifier of the Scan process to edit
        :type scan_id: int
        :param title: The human-readable name of this Scan process
        :type title: string
        :param description: A description of this Scan process
        :type description: string
        :param configuration: The Strike process configuration
        :type configuration: dict

        :raises :class:`ingest.scan.configuration.exceptions.InvalidScanConfiguration`: If the configuration is
            invalid.
        """

        scan = Scan.objects.select_for_update().get(pk=scan_id)
        
        if scan.job:
            raise ScanIngestJobAlreadyLaunched

        # Validate the configuration, no exception is success
        if configuration:
            config = ScanConfiguration(configuration)
            config.validate()
            scan.configuration = config.get_dict()

        # Update editable fields
        if title:
            scan.title = title
        if description:
            scan.description = description
        scan.save()
Exemple #2
0
    def create_scan(self, name, title, description, configuration, dry_run=True):
        """Creates a new Scan process with the given configuration and returns 
        the new Scan model. All changes to the database will occur in an atomic transaction.

        :param name: The identifying name of this Scan process
        :type name: string
        :param title: The human-readable name of this Scan process
        :type title: string
        :param description: A description of this Scan process
        :type description: string
        :param configuration: The Scan configuration
        :type configuration: dict
        :param dry_run: Whether the scan will execute as a dry run
        :type dry_run: bool
        :returns: The new Scan process
        :rtype: :class:`ingest.models.Scan`

        :raises :class:`ingest.scan.configuration.exceptions.InvalidScanConfiguration`: If the configuration is
            invalid.
        """

        # Validate the configuration, no exception is success
        config = ScanConfiguration(configuration)
        config.validate()

        scan = Scan()
        scan.name = name
        scan.title = title
        scan.description = description
        scan.configuration = config.get_dict()
        scan.save()

        return scan
Exemple #3
0
    def test_edit_simple(self):
        """Tests editing only the basic attributes of a Scan process"""

        json_data = {
            'title': 'Title EDIT',
            'description': 'Description EDIT',
        }

        url = rest_util.get_url('/scans/%d/' % self.scan.id)
        response = self.client.generic('PATCH', url, json.dumps(json_data),
                                       'application/json')
        self.assertEqual(response.status_code, status.HTTP_200_OK,
                         response.content)

        result = json.loads(response.content)
        self.assertTrue(isinstance(result, dict),
                        'result  must be a dictionary')
        self.assertEqual(result['id'], self.scan.id)
        self.assertEqual(result['title'], 'Title EDIT')
        self.assertEqual(result['description'], 'Description EDIT')
        self.assertDictEqual(
            result['configuration'],
            ScanConfiguration(self.scan.configuration).get_dict())

        scan = Scan.objects.get(pk=self.scan.id)
        self.assertEqual(scan.title, 'Title EDIT')
        self.assertEqual(scan.description, 'Description EDIT')
Exemple #4
0
    def test_edit_config(self):
        """Tests editing the configuration of a Scan process"""

        config = {
            'version': '1.0',
            'workspace': 'raw',
            'scanner': {'type': 'dir', 'transfer_suffix': '_tmp'},
            'files_to_ingest': [{
                'data_types': ['test'],
                'filename_regex': '.*txt',
                'new_file_path': 'my_path',
                'new_workspace': 'raw',
            }],
        }

        json_data = {
            'configuration': config,
        }

        url = rest_util.get_url('/scans/%d/' % self.scan.id)
        response = self.client.generic('PATCH', url, json.dumps(json_data), 'application/json')
        self.assertEqual(response.status_code, status.HTTP_200_OK, response.content)

        result = json.loads(response.content)
        self.assertEqual(result['id'], self.scan.id)
        self.assertEqual(result['title'], self.scan.title)
        self.assertDictEqual(result['configuration'], ScanConfiguration(config).get_dict())

        scan = Scan.objects.get(pk=self.scan.id)
        self.assertEqual(scan.title, self.scan.title)
        self.assertDictEqual(scan.configuration, config)
Exemple #5
0
    def get_scan_configuration(self):
        """Returns the configuration for this Scan process

        :returns: The configuration for this Scan process
        :rtype: :class:`ingest.scan.configuration.scan_configuration.ScanConfiguration`
        """

        return ScanConfiguration(self.configuration)
Exemple #6
0
    def post(self, request):
        """Validates a new Scan process and returns any warnings discovered

        :param request: the HTTP POST request
        :type request: :class:`rest_framework.request.Request`
        :rtype: :class:`rest_framework.response.Response`
        :returns: the HTTP response to send back to the user
        """

        configuration = rest_util.parse_dict(request, 'configuration')

        # Validate the Scan configuration
        try:
            config = ScanConfiguration(configuration)
            warnings = config.validate()
        except InvalidScanConfiguration as ex:
            logger.exception('Unable to validate Scan configuration.')
            raise BadParameter(unicode(ex))

        results = [{'id': w.key, 'details': w.details} for w in warnings]
        return Response({'warnings': results})
Exemple #7
0
    def test_bare_min(self):
        """Tests calling ScanConfiguration constructor with bare minimum JSON"""

        # No exception is success
        ScanConfiguration({
            'workspace': self.workspace.name,
            'scanner': {
                'type': 'dir'
            },
            'files_to_ingest': [{
                'filename_regex': '.*txt'
            }],
        })
Exemple #8
0
    def get_configuration(self):
        """Returns the scan configuration represented by this JSON

        :returns: The scan configuration
        :rtype: :class:`ingest.scan.configuration.scan_configuration.ScanConfiguration`:
        """

        config = ScanConfiguration()

        config.scanner_type = self._configuration['scanner']['type']
        config.scanner_config = self._configuration['scanner']
        config.recursive = self._configuration['recursive']
        config.file_handler = self._file_handler
        config.workspace = self._configuration['workspace']
        config.config_dict = self._configuration

        return config
Exemple #9
0
    def test_validate_bad_scanner_type(self):
        """Tests calling ScanConfiguration.validate() with a bad scanner type"""

        config = {
            'workspace': self.workspace.name,
            'scanner': {
                'type': 'BAD'
            },
            'files_to_ingest': [{
                'filename_regex': '.*txt',
            }],
        }

        self.assertRaises(InvalidScanConfiguration,
                          ScanConfiguration(config).validate)
Exemple #10
0
    def test_validate_mismatched_scanner_type(self):
        """Tests calling ScanConfiguration.validate() with a scanner type that does not match the broker type"""

        config = {
            'workspace': self.workspace.name,
            'scanner': {
                'type': 's3',
                'sqs_name': 'my-sqs',
            },
            'files_to_ingest': [{
                'filename_regex': '.*txt',
            }],
        }

        self.assertRaises(InvalidScanConfiguration,
                          ScanConfiguration(config).validate)
Exemple #11
0
    def test_validate_workspace_not_active(self):
        """Tests calling ScanConfiguration.validate() with a new workspace that is not active"""

        config = {
            'workspace':
            self.workspace.name,
            'scanner': {
                'type': 'dir'
            },
            'files_to_ingest': [{
                'filename_regex': '.*txt',
                'new_workspace': self.inactive_workspace.name,
            }],
        }

        self.assertRaises(InvalidScanConfiguration,
                          ScanConfiguration(config).validate)
Exemple #12
0
    def test_successful_all(self):
        """Tests calling ScanConfiguration constructor successfully with all information"""

        config = {
            'workspace':
            self.workspace.name,
            'scanner': {
                'type': 'dir'
            },
            'files_to_ingest': [{
                'filename_regex': '.*txt',
                'data_types': ['one', 'two'],
                'new_file_path': os.path.join('my', 'path'),
                'new_workspace': self.workspace.name,
            }],
        }
        # No exception is success
        ScanConfiguration(config)
Exemple #13
0
    def test_validate_recursive_invalid_type(self):
        """Tests calling ScanConfiguration.validate() with recursive set to invalid type"""

        config = {
            'workspace':
            self.workspace.name,
            'scanner': {
                'type': 'dir'
            },
            'recursive':
            'true',
            'files_to_ingest': [{
                'filename_regex': '.*txt',
                'new_workspace': self.inactive_workspace.name,
            }],
        }

        with self.assertRaises(InvalidScanConfiguration):
            ScanConfiguration(config).validate()