Exemplo n.º 1
0
    def update(self,
               contents=None,
               lookup_file=None,
               namespace="lookup_editor",
               owner=None,
               session_key=None,
               user=None):
        """
        Update the given lookup file with the provided contents.
        """

        if owner is None:
            owner = "nobody"

        if namespace is None:
            namespace = "lookup_editor"

        # Check capabilities
        #LookupEditor.check_capabilities(lookup_file, request_info.user, request_info.session_key)

        # Ensure that the file name is valid
        if not is_file_name_valid(lookup_file):
            raise LookupNameInvalidException(
                "The lookup filename contains disallowed characters")

        # Determine the final path of the file
        resolved_file_path = self.resolve_lookup_filename(
            lookup_file,
            namespace,
            owner,
            session_key=session_key,
            throw_not_found=False)

        # Parse the JSON
        parsed_contents = json.loads(contents, object_pairs_hook=OrderedDict)

        # Create the temporary file
        temp_file_handle = lookupfiles.get_temporary_lookup_file()

        # This is a full path already; no need to call make_splunkhome_path().
        temp_file_name = temp_file_handle.name

        # Make the lookups directory if it does not exist
        destination_lookup_full_path = make_lookup_filename(
            lookup_file, namespace, owner)
        self.logger.debug("destination_lookup_full_path=%s",
                          destination_lookup_full_path)

        destination_lookup_path_only, _ = os.path.split(
            destination_lookup_full_path)

        try:
            os.makedirs(destination_lookup_path_only, 0o755)
            os.chmod(destination_lookup_path_only, 0o755)
        except OSError:
            # The directory already existed, no need to create it
            self.logger.debug(
                "Destination path of lookup already existed, no need to create it; destination_lookup_path=%s",
                destination_lookup_path_only)

        # Write out the new file to a temporary location
        try:
            if temp_file_handle is not None and os.path.isfile(temp_file_name):

                csv_writer = csv.writer(temp_file_handle, lineterminator='\n')

                for row in parsed_contents:

                    if not self.is_empty(row):  # Prune empty rows
                        csv_writer.writerow(row)

        finally:
            if temp_file_handle is not None:
                temp_file_handle.close()

        # Determine if the lookup file exists, create it if it doesn't
        if resolved_file_path is None:
            self.logger.debug(
                'Creating a new lookup file, user=%s, namespace=%s, lookup_file=%s, path="%s"',
                owner, namespace, lookup_file, temp_file_name)

            lookupfiles.create_lookup_table(filename=temp_file_name,
                                            lookup_file=lookup_file,
                                            namespace=namespace,
                                            owner=owner,
                                            key=session_key)

            self.logger.info(
                'Lookup created successfully, user=%s, namespace=%s, lookup_file=%s, path="%s"',
                user, namespace, lookup_file, destination_lookup_full_path)

        # Edit the existing lookup otherwise
        else:

            if not is_lookup_in_users_path(
                    resolved_file_path) or owner == 'nobody':
                lookupfiles.update_lookup_table(filename=temp_file_name,
                                                lookup_file=lookup_file,
                                                namespace=namespace,
                                                owner="nobody",
                                                key=session_key)
            else:
                lookupfiles.update_lookup_table(filename=temp_file_name,
                                                lookup_file=lookup_file,
                                                namespace=namespace,
                                                owner=owner,
                                                key=session_key)

            self.logger.info(
                'Lookup edited successfully, user=%s, namespace=%s, lookup_file=%s',
                user, namespace, lookup_file)

        # Tell the SHC environment to replicate the file
        try:
            self.force_lookup_replication(namespace, lookup_file, session_key)
        except ResourceNotFound:
            self.logger.info(
                "Unable to force replication of the lookup file to other search heads; upgrade Splunk to 6.2 or later in order to support CSV file replication"
            )
        except AuthorizationFailed:
            self.logger.warn(
                "Unable to force replication of the lookup file (not authorized), user=%s, namespace=%s, lookup_file=%s",
                user, namespace, lookup_file)
        except:
            self.logger.exception(
                "Unable to force replication of the lookup file, user=%s, namespace=%s, lookup_file=%s",
                user, namespace, lookup_file)

        return resolved_file_path
Exemplo n.º 2
0
    def update(self, contents=None, lookup_file=None, namespace="lookup_editor", owner=None,
               session_key=None, user=None):
        """
        Update the given lookup file with the provided contents.
        """

        if owner is None:
            owner = "nobody"

        if namespace is None:
            namespace = "lookup_editor"

        # Check capabilities
        #LookupEditor.check_capabilities(lookup_file, request_info.user, request_info.session_key)

        # Ensure that the file name is valid
        if not is_file_name_valid(lookup_file):
            raise LookupNameInvalidException("The lookup filename contains disallowed characters")

        # Determine the final path of the file
        resolved_file_path = self.resolve_lookup_filename(lookup_file,
                                                          namespace,
                                                          owner,
                                                          session_key=session_key,
                                                          throw_not_found=False)

        # Parse the JSON
        parsed_contents = json.loads(contents, object_pairs_hook=OrderedDict)

        # Create the temporary file
        temp_file_handle = lookupfiles.get_temporary_lookup_file()

        # This is a full path already; no need to call make_splunkhome_path().
        temp_file_name = temp_file_handle.name

        # Make the lookups directory if it does not exist
        destination_lookup_full_path = make_lookup_filename(lookup_file, namespace, owner)
        self.logger.debug("destination_lookup_full_path=%s", destination_lookup_full_path)

        destination_lookup_path_only, _ = os.path.split(destination_lookup_full_path)

        try:
            os.makedirs(destination_lookup_path_only, 0755)
            os.chmod(destination_lookup_path_only, 0755)
        except OSError:
            # The directory already existed, no need to create it
            self.logger.debug("Destination path of lookup already existed, no need to create it; destination_lookup_path=%s", destination_lookup_path_only)

        # Write out the new file to a temporary location
        try:
            if temp_file_handle is not None and os.path.isfile(temp_file_name):

                csv_writer = csv.writer(temp_file_handle, lineterminator='\n')

                for row in parsed_contents:

                    if not self.is_empty(row): # Prune empty rows
                        csv_writer.writerow(row)

        finally:
            if temp_file_handle is not None:
                temp_file_handle.close()

        # Determine if the lookup file exists, create it if it doesn't
        if resolved_file_path is None:
            self.logger.debug('Creating a new lookup file, user=%s, namespace=%s, lookup_file=%s, path="%s"', owner, namespace, lookup_file, temp_file_name)
            
            lookupfiles.create_lookup_table(filename=temp_file_name,
                                            lookup_file=lookup_file,
                                            namespace=namespace,
                                            owner=owner,
                                            key=session_key)

            self.logger.info('Lookup created successfully, user=%s, namespace=%s, lookup_file=%s, path="%s"', user, namespace, lookup_file, destination_lookup_full_path)

        # Edit the existing lookup otherwise
        else:

            if not is_lookup_in_users_path(resolved_file_path) or owner == 'nobody':
                lookupfiles.update_lookup_table(filename=temp_file_name,
                                                lookup_file=lookup_file,
                                                namespace=namespace,
                                                owner="nobody",
                                                key=session_key)
            else:
                lookupfiles.update_lookup_table(filename=temp_file_name,
                                                lookup_file=lookup_file,
                                                namespace=namespace,
                                                owner=owner,
                                                key=session_key)

            self.logger.info('Lookup edited successfully, user=%s, namespace=%s, lookup_file=%s',
                             user, namespace, lookup_file)

        # Tell the SHC environment to replicate the file
        try:
            self.force_lookup_replication(namespace, lookup_file, session_key)
        except ResourceNotFound:
            self.logger.info("Unable to force replication of the lookup file to other search heads; upgrade Splunk to 6.2 or later in order to support CSV file replication")
        except AuthorizationFailed:
            self.logger.warn("Unable to force replication of the lookup file (not authorized), user=%s, namespace=%s, lookup_file=%s",
                             user, namespace, lookup_file)
        except:
            self.logger.exception("Unable to force replication of the lookup file, user=%s, namespace=%s, lookup_file=%s",
                                  user, namespace, lookup_file)

        return resolved_file_path
Exemplo n.º 3
0
    def save(self, lookup_file, contents, namespace=None, owner=None, **kwargs):
        """
        Save the contents of a lookup file
        """

        logger.info("Saving lookup contents...")

        try:

            user = cherrypy.session['user']['name']
            session_key = cherrypy.session.get('sessionKey')

            if owner is None:
                owner = "nobody"

            if namespace is None:
                namespace = "lookup_editor"

            # Check capabilities
            LookupEditor.check_capabilities(lookup_file, user, session_key)

            # Ensure that the file name is valid
            if not self.is_file_name_valid(lookup_file):
                cherrypy.response.status = 400
                return self.render_error_json("The lookup filename contains disallowed characters")

            # Determine the final path of the file
            resolved_file_path = self.resolve_lookup_filename(lookup_file, namespace, owner,
                                                              throw_not_found=False)

            # Make a backup
            self.backupLookupFile(lookup_file, namespace, owner)

            # Parse the JSON
            parsed_contents = json.loads(contents)

            # Create the temporary file
            temp_file_handle = lookupfiles.get_temporary_lookup_file()

            # This is a full path already; no need to call make_splunkhome_path().
            temp_file_name = temp_file_handle.name

            # Make the lookups directory if it does not exist
            destination_lookup_full_path = self.makeLookupFilename(lookup_file, namespace, owner)
            logger.debug("destination_lookup_full_path=%s", destination_lookup_full_path)
            destination_lookup_path_only, _ = os.path.split(destination_lookup_full_path)

            try:
                os.makedirs(destination_lookup_path_only, 0755)
                os.chmod(destination_lookup_path_only, 0755)
            except OSError:
                # The directory already existed, no need to create it
                logger.debug("Destination path of lookup already existed, no need to create it; destination_lookup_path=%s", destination_lookup_path_only)

            # Write out the new file to a temporary location
            try:
                if temp_file_handle is not None and os.path.isfile(temp_file_name):

                    csv_writer = csv.writer(temp_file_handle, lineterminator='\n')

                    for row in parsed_contents:

                        if not isEmpty(row): # Prune empty rows
                            csv_writer.writerow(row)

            finally:
                if temp_file_handle is not None:
                    temp_file_handle.close()

            # Determine if the lookup file exists, create it if it doesn't
            if resolved_file_path is None:
                shutil.move(temp_file_name, destination_lookup_full_path)
                logger.info('Lookup created successfully, user=%s, namespace=%s, lookup_file=%s, path="%s"', user, namespace, lookup_file, destination_lookup_full_path)

                # If the file is new, then make sure that the list is reloaded so that the editors
                # notice the change
                lookupfiles.SplunkLookupTableFile.reload(session_key=session_key)

            # Edit the existing lookup otherwise
            else:

                try:

                    if not self.isLookupInUsersPath(resolved_file_path) or owner == 'nobody':
                        lookupfiles.update_lookup_table(filename=temp_file_name,
                                                        lookup_file=lookup_file,
                                                        namespace=namespace,
                                                        owner="nobody",
                                                        key=session_key)
                    else:
                        lookupfiles.update_lookup_table(filename=temp_file_name,
                                                        lookup_file=lookup_file,
                                                        namespace=namespace,
                                                        owner=owner,
                                                        key=session_key)

                except AuthorizationFailed as e:
                    cherrypy.response.status = 403
                    return self.render_error_json(str(e))

                logger.info('Lookup edited successfully, user=%s, namespace=%s, lookup_file=%s',
                            user, namespace, lookup_file)

            # Tell the SHC environment to replicate the file
            try:
                force_lookup_replication(namespace, lookup_file, session_key)
            except ResourceNotFound:
                logger.info("Unable to force replication of the lookup file to other search heads; upgrade Splunk to 6.2 or later in order to support CSV file replication")

        except:
            logger.exception("Unable to save the lookup")
            cherrypy.response.status = 500
            return self.render_error_json("Unable to save the lookup")