def test_make_lookup_filename_invalid(self): """ Test the creation of a lookup file via make_lookup_filename() when the path includes disallowed characters. """ # Invalid characters self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("../test.csv")), "/etc/apps/lookup_editor/lookups/test.csv") self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv", namespace="../some_app")), "/etc/apps/some_app/lookups/test.csv") self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv", owner="../some_user")), "/etc/users/some_user/lookup_editor/lookups/test.csv")
def test_make_lookup_filename_invalid(self): """ Test the creation of a lookup file via make_lookup_filename() when the path includes disallowed characters. """ # Invalid characters self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("../test.csv")), "/etc/apps/lookup_editor/lookups/test.csv") self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("test.csv", namespace="../some_app")), "/etc/apps/some_app/lookups/test.csv") self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("test.csv", owner="../some_user")), "/etc/users/some_user/lookup_editor/lookups/test.csv")
def test_make_lookup_filename_valid(self): """ Test the make_lookup_filename() functions ability to create a lookup file path. """ # Global lookup self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv", namespace="some_app")), "/etc/apps/some_app/lookups/test.csv") self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv")), "/etc/apps/lookup_editor/lookups/test.csv") # User lookup self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv", owner='some_user')), "/etc/users/some_user/lookup_editor/lookups/test.csv") self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv", namespace="some_app", owner='some_user')), "/etc/users/some_user/some_app/lookups/test.csv") # A user of nobody self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv", owner='nobody')), "/etc/apps/lookup_editor/lookups/test.csv") # A user of blank self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv", owner='')), "/etc/apps/lookup_editor/lookups/test.csv") self.assertEquals(self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv", owner=' ')), "/etc/apps/lookup_editor/lookups/test.csv")
def test_make_lookup_filename_valid(self): """ Test the make_lookup_filename() functions ability to create a lookup file path. """ # Global lookup self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("test.csv", namespace="some_app")), "/etc/apps/some_app/lookups/test.csv") self.assertEquals( self.strip_splunk_path(shortcuts.make_lookup_filename("test.csv")), "/etc/apps/lookup_editor/lookups/test.csv") # User lookup self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("test.csv", owner='some_user')), "/etc/users/some_user/lookup_editor/lookups/test.csv") self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("test.csv", namespace="some_app", owner='some_user')), "/etc/users/some_user/some_app/lookups/test.csv") # A user of nobody self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("test.csv", owner='nobody')), "/etc/apps/lookup_editor/lookups/test.csv") # A user of blank self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("test.csv", owner='')), "/etc/apps/lookup_editor/lookups/test.csv") self.assertEquals( self.strip_splunk_path( shortcuts.make_lookup_filename("test.csv", owner=' ')), "/etc/apps/lookup_editor/lookups/test.csv")
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
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