예제 #1
0
def write_playbook_to_file(playbook_name):
    """Writes a playbook to file.

    Args:
        playbook_name (str): The name of the playbook to write to a file.
    """
    playbook_filename = os.path.join(core.config.paths.workflows_path, '{0}.playbook'.format(playbook_name))
    backup = None
    try:
        with open(playbook_filename) as original_file:
            backup = original_file.read()
        os.remove(playbook_filename)
    except (IOError, OSError) as e:
        logger.warning('Cannot read original playbook! Saving without backup! '
                       'Reason: {}'.format(helpers.format_exception_message(e)))

    app.logger.debug('Writing playbook {0} to file'.format(playbook_name))

    try:
        with open(playbook_filename, 'w') as workflow_out:
            playbook_json = running_context.controller.get_playbook_representation(playbook_name)
            workflow_out.write(json.dumps(playbook_json, sort_keys=True, indent=4, separators=(',', ': ')))
    except Exception as e:
        logger.error('Could not save playbook to file. Reverting file to original. '
                     'Error: {0}'.format(helpers.format_exception_message(e)))
        if backup is not None:
            with open(playbook_filename, 'w') as f:
                f.write(backup)
예제 #2
0
 def __func():
     form = forms.ImportCaseForm(request.form)
     filename = form.filename.data if form.filename.data else core.config.paths.default_case_export_path
     if os.path.isfile(filename):
         try:
             with open(filename, 'r') as cases_file:
                 cases_file = cases_file.read()
                 cases_file = cases_file.replace('\n', '')
                 cases = json.loads(cases_file)
             case_subscription.add_cases(cases)
             for case in cases.keys():
                 running_context.db.session.add(
                     running_context.CaseSubscription(name=case))
                 running_context.CaseSubscription.update(case)
                 running_context.db.session.commit()
             return {
                 "cases": case_subscription.subscriptions_as_json()
             }, SUCCESS
         except (OSError, IOError) as e:
             current_app.logger.error(
                 'Error importing cases from file {0}: {1}'.format(
                     filename, format_exception_message(e)))
             return {"error": "Error reading file."}, IO_ERROR
         except ValueError as e:
             current_app.logger.error(
                 'Error importing cases from file {0}: Invalid JSON {1}'.
                 format(filename, format_exception_message(e)))
             return {"error": "Invalid JSON file."}, INVALID_INPUT_ERROR
     else:
         current_app.logger.debug(
             'Cases successfully imported from {0}'.format(filename))
         return {"error": "File does not exist."}, IO_ERROR
예제 #3
0
    def load_playbook(resource):
        """Loads a playbook from a file.

        Args:
            resource (str): Path to the workflow.
        """
        try:
            playbook_file = open(resource, 'r')
        except (IOError, OSError) as e:
            logger.error(
                'Could not load workflow from {0}. Reason: {1}'.format(
                    resource, format_exception_message(e)))
            return None
        else:
            with playbook_file:
                workflow_loaded = playbook_file.read()
                try:
                    playbook_json = json.loads(workflow_loaded)
                    return Playbook.create(playbook_json)
                except ValueError:
                    logger.error('Cannot parse {}'.format(resource))
                except (InvalidInput, UnknownApp, UnknownAppAction,
                        UnknownFilter, UnknownFlag) as e:
                    logger.error('Error constructing playbook from {0}. '
                                 'Reason: {1}'.format(
                                     resource, format_exception_message(e)))
                    return None
예제 #4
0
def validate_primitive_parameter(value, param, parameter_type, message_prefix, hide_input=False):
    try:
        converted_value = convert_primitive_type(value, parameter_type)
    except (ValueError, TypeError):
        message = '{0} has invalid input. ' \
                  'Input {1} could not be converted to type {2}'.format(message_prefix, value, parameter_type)
        logger.error(message)
        raise InvalidInput(message)
    else:
        param = deepcopy(param)
        if 'required' in param:
            param.pop('required')
        try:
            Draft4Validator(
                param, format_checker=draft4_format_checker).validate(converted_value)
        except ValidationError as exception:
            if not hide_input:
                message = '{0} has invalid input. ' \
                          'Input {1} with type {2} does not conform to ' \
                          'validators: {3}'.format(message_prefix, value, parameter_type,
                                                   format_exception_message(exception))
            else:
                message = '{0} has invalid input. {1} does not conform to ' \
                          'validators: {2}'.format(message_prefix, parameter_type,
                                                   format_exception_message(exception))
            logger.error(message)
            raise InvalidInput(message)
        return converted_value
예제 #5
0
파일: cases.py 프로젝트: davehenton/WALKOFF
 def __func():
     data = request.get_json()
     filename = (data['filename'] if
                 (data is not None and 'filename' in data
                  and data['filename']) else
                 core.config.paths.default_case_export_path)
     if os.path.isfile(filename):
         try:
             with open(filename, 'r') as cases_file:
                 cases_file = cases_file.read()
                 cases_file = cases_file.replace('\n', '')
                 cases = json.loads(cases_file)
             case_subscription.add_cases(cases)
             for case in cases:
                 db.session.add(running_context.CaseSubscription(name=case))
                 running_context.CaseSubscription.update(case)
             db.session.commit()
             return {"cases": case_subscription.subscriptions}, SUCCESS
         except (OSError, IOError) as e:
             current_app.logger.error('Error importing cases from file '
                                      '{0}: {1}'.format(
                                          filename,
                                          format_exception_message(e)))
             return {"error": "Error reading file."}, IO_ERROR
         except ValueError as e:
             current_app.logger.error(
                 'Error importing cases from file {0}: '
                 'Invalid JSON {1}'.format(filename,
                                           format_exception_message(e)))
             return {"error": "Invalid JSON file."}, INVALID_INPUT_ERROR
     else:
         current_app.logger.debug(
             'Cases successfully imported from {0}'.format(filename))
         return {"error": "File does not exist."}, IO_ERROR
예제 #6
0
    def __call__(self, data_in, accumulator):
        data = data_in

        for filter_element in self.filters:
            data = filter_element(data, accumulator)
        try:
            data = validate_parameter(data, self.data_in_api,
                                      'Flag {0}'.format(self.action))
            args = dereference_step_routing(self.args, accumulator,
                                            'In Flag {0}'.format(self.name))
            callbacks.FlagSuccess.send(self)
            logger.debug('Arguments passed to flag {0} are valid'.format(
                self.ancestry))
            args.update({self.data_in_api['name']: data})
            return get_flag(self.action)(**args)
        except InvalidInput as e:
            logger.error(
                'Flag {0} has invalid input {1} which was converted to {2}. Error: {3}. '
                'Returning False'.format(self.action, data_in, data,
                                         format_exception_message(e)))
            callbacks.FlagError.send(self)
            return False
        except Exception as e:
            logger.error('Error encountered executing '
                         'flag {0} with arguments {1} and value {2}: '
                         'Error {3}. Returning False'.format(
                             self.action, self.args, data,
                             format_exception_message(e)))
            callbacks.FlagError.send(self)
            return False
예제 #7
0
    def __func():
        data = request.get_json()
        filename = data[
            'filename'] if 'filename' in data else core.config.paths.default_appdevice_export_path
        try:
            with open(filename, 'r') as devices_file:
                read_file = devices_file.read()
                read_file = read_file.replace('\n', '')
                apps = json.loads(read_file)
        except (OSError, IOError) as e:
            current_app.logger.error(
                'Error importing devices from {0}: {1}'.format(filename, e))
            return {"error": "Error reading file."}, IO_ERROR
        for app in apps:
            for device in apps[app]:
                if device_db.session.query(Device).filter(
                        Device.name == device['name']).first() is not None:
                    current_app.logger.error('Could not import device {0}. '
                                             'Device already exists.'.format(
                                                 device['name']))
                    continue
                fields = {
                    field['name']: field['value']
                    for field in device['fields']
                }
                device_type = device['type']
                try:
                    device_api = get_app_device_api(app, device_type)
                    device_fields_api = device_api['fields']
                    validate_device_fields(device_fields_api, fields,
                                           device_type, app)
                except UnknownDevice:
                    current_app.logger.error(
                        'Cannot import device for app {0}, type {1}. '
                        'Type does not exist'.format(app, device_type))
                    continue
                except InvalidArgument as e:
                    current_app.logger.error(
                        'Cannot import device for app {0}, type {1}. '
                        'Invalid input'.format(app, device_type,
                                               format_exception_message(e)))
                    continue
                else:
                    fields = device['fields']
                    add_configuration_keys_to_device_json(
                        fields, device_fields_api)
                    app = device_db.session.query(App).filter(
                        App.name == app).first()
                    if app is None:
                        current_app.logger.error(
                            'SEVERE: App defined in api does not have corresponding entry in database. '
                            'Cannot import device')
                        continue
                    device_obj = Device.from_json(device)
                    app.add_device(device_obj)
                    device_db.session.add(device_obj)
                    device_db.session.commit()

        current_app.logger.debug('Imported devices from {0}'.format(filename))
        return {}, SUCCESS
예제 #8
0
def load_app_apis(apps_path=None):
    from core.helpers import list_apps, format_exception_message
    global app_apis
    if apps_path is None:
        apps_path = core.config.paths.apps_path
    try:
        with open(join(core.config.paths.walkoff_schema_path),
                  'r') as schema_file:
            json.loads(schema_file.read())
    except Exception as e:
        __logger.fatal(
            'Could not load JSON schema for apps. Shutting down...: ' + str(e))
        sys.exit(1)
    else:
        for app in list_apps(apps_path):
            try:
                url = join(apps_path, app, 'api.yaml')
                with open(url) as function_file:
                    api = yaml.load(function_file.read())
                    from core.validator import validate_app_spec
                    validate_app_spec(api, app)
                    app_apis[app] = api
            except Exception as e:
                __logger.error(
                    'Cannot load apps api for app {0}: Error {1}'.format(
                        app, str(format_exception_message(e))))
예제 #9
0
 def __shutdown(self, instances):
     # Upon finishing shuts down instances
     for instance_name, instance in instances.items():
         try:
             if instance() is not None:
                 logger.debug(
                     'Shutting down app instance: Device: {0}'.format(
                         instance_name))
                 instance.shutdown()
         except Exception as e:
             logger.error('Error caught while shutting down app instance. '
                          'Device: {0}. Error {1}'.format(
                              instance_name, format_exception_message(e)))
     result_str = {}
     for action, action_result in self._accumulator.items():
         try:
             result_str[action] = json.dumps(action_result)
         except TypeError:
             logger.error(
                 'Result of workflow is neither string or a JSON-able. Cannot record'
             )
             result_str[action] = 'error: could not convert to JSON'
     data = dict(self._accumulator)
     try:
         data_json = json.dumps(data)
     except TypeError:
         data_json = str(data)
     WalkoffEvent.CommonWorkflowSignal.send(
         self, event=WalkoffEvent.WorkflowShutdown, data=data_json)
     logger.info('Workflow {0} completed. Result: {1}'.format(
         self.name, self._accumulator))
예제 #10
0
    def create(cls, json_in, element_class=None):
        """
        Creates an ExecutionElement from json

        Args:
            json_in (dict): The JSON to convert to an ExecutionElement
            element_class (cls): The class of the ExecutionElement to convert

        Returns:
            (ExecutionElement) The constructed ExecutionElement
        """
        from core.executionelements.playbook import Playbook
        cls._setup_ordering()
        if element_class is None:
            element_class = Playbook
        class_iterator = iteritems(cls.playbook_class_ordering)
        current_class, subfield_lookup = next(class_iterator)
        while current_class != element_class:
            try:
                current_class, subfield_lookup = next(class_iterator)
            except StopIteration:
                raise ValueError('Unknown class {}'.format(element_class.__class__.__name__))
        try:
            return cls.construct_current_class(current_class, json_in, subfield_lookup)
        except (KeyError, TypeError) as e:
            from core.helpers import format_exception_message
            raise ValueError(
                'Improperly formatted JSON for ExecutionElement {0} {1}'.format(current_class.__name__,
                                                                                format_exception_message(e)))
예제 #11
0
def write_playbook_to_file(playbook_name):
    playbook_filename = os.path.join(core.config.paths.workflows_path,
                                     '{0}.playbook'.format(playbook_name))
    backup = None
    try:
        with open(playbook_filename) as original_file:
            backup = original_file.read()
        os.remove(playbook_filename)
    except (IOError, OSError):
        pass

    app.logger.debug('Writing playbook {0} to file'.format(playbook_name))
    write_format = 'w' if sys.version_info[0] == 2 else 'wb'

    try:
        with open(playbook_filename, write_format) as workflow_out:
            xml = ElementTree.tostring(
                running_context.controller.playbook_to_xml(playbook_name))
            xml_dom = minidom.parseString(xml).toprettyxml(indent='\t')
            workflow_out.write(xml_dom.encode('utf-8'))
    except Exception as e:
        logger.error(
            'Could not save playbook to file. Reverting file to original. '
            'Error: {0}'.format(helpers.format_exception_message(e)))
        with open(playbook_filename, 'w') as f:
            f.write(backup)
예제 #12
0
 def __func():
     form = forms.ExportImportAppDevices(request.form)
     filename = form.filename.data if form.filename.data else core.config.paths.default_appdevice_export_path
     returned_json = {}
     apps = running_context.App.query.all()
     for app in apps:
         devices = []
         for device in app.devices:
             device_json = device.as_json(with_apps=False)
             device_json.pop('app', None)
             device_json.pop('id', None)
             devices.append(device_json)
         returned_json[app.as_json()['name']] = devices
     try:
         with open(filename, 'w') as appdevice_file:
             appdevice_file.write(
                 json.dumps(returned_json, indent=4, sort_keys=True))
     except (OSError, IOError) as e:
         current_app.logger.error('Error importing devices from {0}: '
                                  '{1}'.format(
                                      filename,
                                      helpers.format_exception_message(e)))
         return {"error": "Error writing file"}, IO_ERROR
     else:
         current_app.logger.debug(
             'Exported devices to {0}'.format(filename))
         return {}, SUCCESS
예제 #13
0
 def __func():
     form = forms.ExportImportAppDevices(request.form)
     filename = form.filename.data if form.filename.data else core.config.paths.default_appdevice_export_path
     try:
         with open(filename, 'r') as appdevice_file:
             read_file = appdevice_file.read()
             read_file = read_file.replace('\n', '')
             apps_devices = json.loads(read_file)
     except (OSError, IOError) as e:
         current_app.logger.error('Error importing devices from {0}: '
                                  '{1}'.format(
                                      filename,
                                      helpers.format_exception_message(e)))
         return {"error": "Error reading file."}, IO_ERROR
     for app in apps_devices:
         for device in apps_devices[app]:
             extra_fields = {}
             for key in device:
                 if key not in ['ip', 'name', 'port', 'username']:
                     extra_fields[key] = device[key]
             extra_fields_str = json.dumps(extra_fields)
             running_context.Device.add_device(
                 name=device['name'],
                 username=device['username'],
                 ip=device['ip'],
                 port=device['port'],
                 extra_fields=extra_fields_str,
                 app_server=app,
                 password=None)
     current_app.logger.debug('Imported devices from {0}'.format(filename))
     return {}, SUCCESS
예제 #14
0
    def load_workflow(resource, workflow_name):
        """Loads a workflow from a file.

        Args:
            resource (str): Path to the workflow.
            workflow_name (str): Name of the workflow to load.

        Returns:
            True on success, False otherwise.
        """
        try:
            playbook_file = open(resource, 'r')
        except (IOError, OSError) as e:
            logger.error(
                'Could not load workflow from {0}. Reason: {1}'.format(
                    resource, format_exception_message(e)))
            return None
        else:
            with playbook_file:
                workflow_loaded = playbook_file.read()
                try:
                    playbook_json = json.loads(workflow_loaded)
                    playbook_name = playbook_json['name']
                    workflow_json = next(
                        (workflow for workflow in playbook_json['workflows']
                         if workflow['name'] == workflow_name), None)
                    if workflow_json is None:
                        logger.warning(
                            'Workflow {0} not found in playbook {0}. '
                            'Cannot load.'.format(workflow_name,
                                                  playbook_name))
                        return None
                    workflow = Workflow.create(workflow_json)
                    return playbook_name, workflow
                except ValueError as e:
                    logger.error('Cannot parse {0}. Reason: {1}'.format(
                        resource, format_exception_message(e)))
                except (InvalidInput, UnknownApp, UnknownAppAction,
                        UnknownFilter, UnknownFlag) as e:
                    logger.error(
                        'Error constructing workflow {0}. Reason: {1}'.format(
                            workflow_name, format_exception_message(e)))
                    return None
                except KeyError as e:
                    logger.error(
                        'Invalid Playbook JSON format. Details: {}'.format(e))
                    return None
예제 #15
0
    def execute(self, data_in, accumulator):
        """Executes the Condition object, determining if the Condition evaluates to True or False.

        Args:
            data_in (): The input to the Transform objects associated with this Condition.
            accumulator (dict): The accumulated data from previous Actions.

        Returns:
            True if the Condition evaluated to True, False otherwise
        """
        data = data_in

        for transform in self.transforms:
            data = transform.execute(data, accumulator)
        try:
            self.arguments.update({
                self._data_param_name:
                Argument(self._data_param_name, value=data)
            })
            args = validate_condition_parameters(self._api,
                                                 self.arguments,
                                                 self.action_name,
                                                 accumulator=accumulator)
            logger.debug('Arguments passed to condition {} are valid'.format(
                self.uid))
            ret = self._condition_executable(**args)
            WalkoffEvent.CommonWorkflowSignal.send(
                self, event=WalkoffEvent.ConditionSuccess)
            return ret
        except InvalidArgument as e:
            logger.error(
                'Condition {0} has invalid input {1} which was converted to {2}. Error: {3}. '
                'Returning False'.format(self.action_name, data_in, data,
                                         format_exception_message(e)))
            WalkoffEvent.CommonWorkflowSignal.send(
                self, event=WalkoffEvent.ConditionError)
            return False
        except Exception as e:
            logger.error('Error encountered executing '
                         'condition {0} with arguments {1} and value {2}: '
                         'Error {3}. Returning False'.format(
                             self.action_name, self.arguments, data,
                             format_exception_message(e)))
            WalkoffEvent.CommonWorkflowSignal.send(
                self, event=WalkoffEvent.ConditionError)
            return False
예제 #16
0
 def __swap_step_input(self, step, start_input):
     logger.debug('Swapping input to first step of workflow {0}'.format(self.name))
     try:
         step.set_input(start_input)
         data_sent.send(self, callback_name="Workflow Input Validated", object_type="Workflow")
     except InvalidInput as e:
         logger.error('Cannot change input to workflow {0}. '
                      'Invalid input. Error: {1}'.format(self.name, format_exception_message(e)))
         data_sent.send(self, callback_name="Workflow Input Invalid", object_type="Workflow")
예제 #17
0
파일: validator.py 프로젝트: silky/WALKOFF
def validate_parameter(value, param, message_prefix):
    primitive_type = 'primitive' if 'type' in param else 'object'
    converted_value = None
    if value is not None:
        if primitive_type == 'primitive':
            primitive_type = param['type']
            if primitive_type in TYPE_MAP:
                converted_value = validate_primitive_parameter(
                    value, param, primitive_type, message_prefix)
            elif primitive_type == 'array':
                try:
                    converted_value = convert_array(param, value,
                                                    message_prefix)
                    Draft4Validator(
                        param, format_checker=draft4_format_checker).validate(
                            converted_value)
                except ValidationError as exception:
                    message = '{0} has invalid input. Input {1} does not conform to ' \
                              'validators: {2}'.format(message_prefix, value, format_exception_message(exception))
                    logger.error(message)
                    raise InvalidArgument(message)
            else:
                raise InvalidArgument(
                    'In {0}: Unknown parameter type {1}'.format(
                        message_prefix, primitive_type))
        else:
            try:
                converted_value = convert_json(param, value, message_prefix)
                Draft4Validator(param['schema'],
                                format_checker=draft4_format_checker).validate(
                                    converted_value)
            except ValidationError as exception:
                message = '{0} has invalid input. Input {1} does not conform to ' \
                          'validators: {2}'.format(message_prefix, value, format_exception_message(exception))
                logger.error(message)
                raise InvalidArgument(message)
    elif param.get('required'):
        message = "In {0}: Missing {1} parameter '{2}'".format(
            message_prefix, primitive_type, param['name'])
        logger.error(message)
        raise InvalidArgument(message)

    return converted_value
예제 #18
0
def read_json(filename):
    if not os.path.exists(filename) or not os.path.isfile(filename):
        return 'File does not exist', 'FileDoesNotExist'
    try:
        with open(filename, 'r') as file_in:
            return json.loads(file_in.read())
    except (IOError, IOError) as e:
        return {'error': 'Could not read file', 'reason': format_exception_message(e)}, 'FileDoesNotExist'
    except ValueError:
        return 'Could not read file as json. Invalid JSON', 'InvalidJson'
예제 #19
0
 def execute(self, instance, accumulator):
     """Executes a Step by calling the associated app function.
     
     Args:
         instance (App): The instance of an App object to be used to execute the associated function.
         accumulator (dict): Dict containing the results of the previous steps
         
     Returns:
         The result of the executed function.
     """
     callbacks.StepInputValidated.send(self)
     try:
         args = dereference_step_routing(self.input, accumulator,
                                         'In step {0}'.format(self.name))
         args = validate_app_action_parameters(self.input_api, args,
                                               self.app, self.action)
         action = get_app_action(self.app, self.run)
         result = action(instance, **args)
         callbacks.FunctionExecutionSuccess.send(
             self, data=json.dumps({"result": result.as_json()}))
     except InvalidInput as e:
         formatted_error = format_exception_message(e)
         logger.error('Error calling step {0}. Error: {1}'.format(
             self.name, formatted_error))
         callbacks.StepInputInvalid.send(self)
         self.output = ActionResult('error: {0}'.format(formatted_error),
                                    'InvalidInput')
         raise
     except Exception as e:
         formatted_error = format_exception_message(e)
         logger.error('Error calling step {0}. Error: {1}'.format(
             self.name, formatted_error))
         self.output = ActionResult('error: {0}'.format(formatted_error),
                                    'UnhandledException')
         raise
     else:
         self.output = result
         for widget in self.widgets:
             get_widget_signal(widget.app, widget.widget).send(
                 self, data=json.dumps({"result": result.as_json()}))
         logger.debug('Step {0} executed successfully'.format(
             self.ancestry))
         return result
예제 #20
0
 def __swap_step_input(self, step, start_input):
     logger.debug('Swapping input to first step of workflow {0}'.format(
         self.ancestry))
     try:
         step.set_input(start_input)
         callbacks.WorkflowInputValidated.send(self)
     except InvalidInput as e:
         logger.error('Cannot change input to workflow {0}. '
                      'Invalid input. Error: {1}'.format(
                          self.name, format_exception_message(e)))
         callbacks.WorkflowInputInvalid.send(self)
예제 #21
0
 def resume(self):
     """Resumes a Workflow that has previously been paused.
     """
     try:
         logger.info('Attempting to resume workflow {0}'.format(self.name))
         self._is_paused = False
         self._resume.set()
     except (StopIteration, AttributeError) as e:
         logger.warning('Cannot resume workflow {0}. Reason: {1}'.format(
             self.name, format_exception_message(e)))
         pass
예제 #22
0
 def resume_breakpoint_step(self):
     """Resumes a Workflow that has hit a breakpoint at a Step. This is used for debugging purposes.
     """
     try:
         logger.debug(
             'Attempting to resume workflow {0} from breakpoint'.format(
                 self.ancestry))
         self.executor.send(None)
     except (StopIteration, AttributeError) as e:
         logger.warning('Cannot resume workflow {0} from breakpoint. '
                        'Reason: {1}'.format(self.ancestry,
                                             format_exception_message(e)))
         pass
예제 #23
0
def validate_devices_api(devices_api, app_name):
    for device_type, device_type_api in devices_api.items():
        for field_api in device_type_api['fields']:
            if 'default' in field_api:
                message_prefix = 'App {0} device type {1}'.format(app_name, device_type)
                default_value = field_api['default']
                try:
                    validate_device_field(field_api, default_value, message_prefix)
                except InvalidInput as e:
                    logger.error(
                        'For {0}: Default input {1} does not conform to schema. (Error: {2})'
                        'Using anyways'.format(message_prefix, field_api['name'], format_exception_message(e)))
                    raise
예제 #24
0
def validate_parameters(api, inputs, message_prefix):
    api_dict = {}
    for param in api:
        api_dict[param['name']] = param
    converted = {}
    seen_params = set()
    input_set = set(inputs.keys())
    for param_name, param_api in api_dict.items():
        if param_name in inputs:
            if not isinstance(inputs[param_name], string_types):
                converted[param_name] = validate_parameter(
                    inputs[param_name], param_api, message_prefix)
            else:
                if inputs[param_name].startswith('@'):
                    converted[param_name] = inputs[param_name]
                elif inputs[param_name].startswith('\@'):
                    inputs[param_name] = inputs[param_name][1:]
                    converted[param_name] = validate_parameter(
                        inputs[param_name], param_api, message_prefix)
                else:
                    converted[param_name] = validate_parameter(
                        inputs[param_name], param_api, message_prefix)
        elif 'default' in param_api:
            try:
                default_param = validate_parameter(param_api['default'],
                                                   param_api, message_prefix)
            except InvalidInput as e:
                default_param = param_api['default']
                logger.warning(
                    'For {0}: Default input {1} (value {2}) does not conform to schema. (Error: {3})'
                    'Using anyways'.format(message_prefix, param_name,
                                           param_api['default'],
                                           format_exception_message(e)))

            converted[param_name] = default_param
            input_set.add(param_name)
        elif 'required' in param_api:
            message = 'For {0}: Parameter {1} is not specified and has no default'.format(
                message_prefix, param_name)
            logger.error(message)
            raise InvalidInput(message)
        else:
            converted[param_name] = None
            input_set.add(param_name)
        seen_params.add(param_name)
    if seen_params != input_set:
        message = 'For {0}: Too many inputs. Extra inputs: {1}'.format(
            message_prefix, input_set - seen_params)
        logger.error(message)
        raise InvalidInput(message)
    return converted
예제 #25
0
    def __func():
        add_device_json = request.get_json()
        if device_db.session.query(Device).filter(
                Device.name == add_device_json['name']).first() is not None:
            current_app.logger.error('Could not create device {0}. '
                                     'Device already exists.'.format(
                                         add_device_json['name']))
            return {"error": "Device already exists."}, OBJECT_EXISTS_ERROR

        fields = {
            field['name']: field['value']
            for field in add_device_json['fields']
        }
        app = add_device_json['app_name']
        device_type = add_device_json['type']
        try:
            device_api = get_app_device_api(app, device_type)
            device_fields_api = device_api['fields']
            validate_device_fields(device_fields_api, fields, device_type, app)
        except UnknownApp:
            current_app.logger.error(
                'Cannot create device for app {0}, type {1}. '
                'App does not exist'.format(app, device_type))
            return {'error': 'Unknown app'}, INVALID_INPUT_ERROR
        except UnknownDevice:
            current_app.logger.error(
                'Cannot create device for app {0}, type {1}. '
                'Type does not exist'.format(app, device_type))
            return {'error': 'Unknown device type'}, INVALID_INPUT_ERROR
        except InvalidArgument as e:
            current_app.logger.error(
                'Cannot create device for app {0}, type {1}. '
                'Invalid input'.format(app, device_type,
                                       format_exception_message(e)))
            return {'error': 'Invalid device fields'}, INVALID_INPUT_ERROR
        else:
            fields = add_device_json['fields']
            add_configuration_keys_to_device_json(fields, device_fields_api)
            app = device_db.session.query(App).filter(App.name == app).first()
            if app is None:
                current_app.logger.error(
                    'SEVERE: App defined in api does not have corresponding entry in database. '
                    'Cannot add device')
                return {'error': 'Unknown app'}, INVALID_INPUT_ERROR
            device = Device.from_json(add_device_json)
            app.add_device(device)
            device_db.session.add(device)
            device_db.session.commit()
            device_json = get_device_json_with_app_name(device)
            # remove_configuration_keys_from_device_json(device_json)
            return device_json, OBJECT_CREATED
예제 #26
0
    def __func():
        update_device_json = request.get_json()
        device = device_db.session.query(Device).filter(
            Device.id == update_device_json['id']).first()
        if device is None:
            current_app.logger.error('Could not update device {0}. '
                                     'Device does not exist.'.format(
                                         update_device_json['id']))
            return {"error": "Device does not exist."}, OBJECT_DNE_ERROR

        fields = ({
            field['name']: field['value']
            for field in update_device_json['fields']
        } if 'fields' in update_device_json else None)
        app = update_device_json['app_name']
        device_type = update_device_json[
            'type'] if 'type' in update_device_json else device.type
        try:
            device_api = get_app_device_api(app, device_type)
            device_fields_api = device_api['fields']
            if fields is not None:
                validate_device_fields(device_fields_api, fields, device_type,
                                       app)
        except UnknownApp:
            current_app.logger.error(
                'Cannot update device for app {0}, type {1}. '
                'App does not exist'.format(app, device_type))
            return {'error': 'Unknown app'}, INVALID_INPUT_ERROR
        except UnknownDevice:
            current_app.logger.error(
                'Cannot update device for app {0}, type {1}. '
                'Type does not exist'.format(app, device_type))
            return {'error': 'Unknown device type'}, INVALID_INPUT_ERROR
        except InvalidArgument as e:
            current_app.logger.error(
                'Cannot update device for app {0}, type {1}. '
                'Invalid input'.format(app, device_type,
                                       format_exception_message(e)))
            return {'error': 'Invalid device fields'}, INVALID_INPUT_ERROR
        else:
            if fields is not None:
                fields = update_device_json[
                    'fields'] if 'fields' in update_device_json else None
                add_configuration_keys_to_device_json(fields,
                                                      device_fields_api)
            device.update_from_json(update_device_json)
            device_db.session.commit()
            device_json = get_device_json_with_app_name(device)
            # remove_configuration_keys_from_device_json(device_json)
            return device_json, SUCCESS
예제 #27
0
 def connect(self):
     try:
         self.transport = paramiko.Transport(
             (self.device_fields['ip'], self.device_fields['port']))
         self.transport.connect(
             username=self.device_fields['username'],
             password=self.device.get_encrypted_field('password'))
         self.sftp_client = paramiko.SFTPClient.from_transport(
             self.transport)
         self.is_connected = True
         return 'Success'
     except SSHException as e:
         return 'Could not connect {}'.format(
             format_exception_message(e)), 'ConnectionError'
예제 #28
0
 def __swap_action_arguments(self, action, start_arguments):
     logger.debug(
         'Swapping arguments to first action of workflow {0}'.format(
             self.name))
     try:
         action.set_arguments(start_arguments)
         WalkoffEvent.CommonWorkflowSignal.send(
             self, event=WalkoffEvent.WorkflowArgumentsValidated)
     except InvalidArgument as e:
         logger.error('Cannot change arguments to workflow {0}. '
                      'Invalid arguments. Error: {1}'.format(
                          self.name, format_exception_message(e)))
         WalkoffEvent.CommonWorkflowSignal.send(
             self, event=WalkoffEvent.WorkflowArgumentsInvalid)
예제 #29
0
 def __func():
     form = forms.ExportCaseForm(request.form)
     filename = form.filename.data if form.filename.data else core.config.paths.default_case_export_path
     try:
         with open(filename, 'w') as cases_file:
             cases_file.write(
                 json.dumps(case_subscription.subscriptions_as_json()))
         current_app.logger.debug(
             'Cases successfully exported to {0}'.format(filename))
         return SUCCESS
     except (OSError, IOError) as e:
         current_app.logger.error(
             'Error exporting cases to {0}: {1}'.format(
                 filename, format_exception_message(e)))
         return {"error": "Could not write to file."}, IO_ERROR
예제 #30
0
파일: cases.py 프로젝트: davehenton/WALKOFF
 def __func():
     data = request.get_json()
     filename = (data['filename'] if
                 (data is not None and 'filename' in data
                  and data['filename']) else
                 core.config.paths.default_case_export_path)
     try:
         with open(filename, 'w') as cases_file:
             cases_file.write(json.dumps(case_subscription.subscriptions))
         current_app.logger.debug(
             'Cases successfully exported to {0}'.format(filename))
         return SUCCESS
     except (OSError, IOError) as e:
         current_app.logger.error(
             'Error exporting cases to {0}: {1}'.format(
                 filename, format_exception_message(e)))
         return {"error": "Could not write to file."}, IO_ERROR