def post_data(self, item): """ Method to post the data. Args: item: item to be sent """ row_id = item.get( 'row_id' ) #sqlite row_id used to delete the row once it has been sent status = api.session.post_data(item['activity'], item['data']) if status == api.Status.MISMATCH: #a mismatch status indicates that we missed a config update event, so we are doing it now api.session.get_config() #delete from offline store if data was sent; we consider it is sent if api session is connected and is not unauthorized. #no need to check for any other status code. if api.is_not_connected( status) == False and status != api.Status.UNAUTHORIZED: self.del_rows.append(row_id) else: Sender.store_available( True ) #if sending failed, we need to mark offline store as available
def handle_response(self, status): """ Method to handle the api session response. Args: status: status of the request to be handled Returns: True if the response is ok, else False """ _log.debug('Handling response status %d' % status) if status == api.Status.SUCCESS: #all good return True elif api.is_not_connected(status): _log.info('Failed to establish connection') elif status == api.Status.NOT_FOUND: #uninstall if the agent is not found in the organization try: _log.info('Uninstalling agent') subprocess.Popen([self.univ.exe_path + '/uninstall.sh'], close_fds=True) except Exception as e: _log.error('Failed to open uninstall script; %s' % unicode(e)) elif status == api.Status.UNAUTHORIZED: _log.error('Agent unauthorized to connect') elif status == api.Status.BAD_REQUEST: _log.error('Server marked the request as bad') elif status == api.Status.SESSION_CONFLICT: _log.error('Agent session conflict') return False
def handle_response(self, status): """ Method to handle the api session response. Args: status: status of the request to be handled Returns: True if the response is ok, else False """ _log.debug('Handling response status %d' % status) if status == api.Status.SUCCESS: #all good return True elif api.is_not_connected(status): _log.info('Failed to establish connection') elif status == api.Status.NOT_FOUND: #uninstall if the agent is not found in the organization try: _log.info('Uninstalling agent') subprocess.Popen([self.univ.exe_path + 'uninstall.sh']) except Exception as e: _log.error('Failed to open uninstall script; %s' % unicode(e)) elif status == api.Status.UNAUTHORIZED: _log.error('Agent unauthorized to connect') elif status == api.Status.BAD_REQUEST: _log.error('Server marked the request as bad') elif status == api.Status.SESSION_CONFLICT: _log.error('Agent session conflict') return False
def post_data(self, item): """ Method to post the data. Args: item: item to be sent """ Storage.get_data( item['data'] ) #get the data. read get_data doc to know why this is required #update the timestamp limit for selecting rows to the last real time data retreived. #this will prevent any data sent to offline store due to queue overflow being sent before real time queue clears up self.off_store.select_timestamp = item['data']['timestamp'] status = api.session.post_data(item['activity'], item['data']) if status == api.Status.MISMATCH: #a mismatch status indicates that we missed a config update event, so we are doing it now api.session.get_config() elif api.is_not_connected( status ) == True or status == api.Status.UNAUTHORIZED: #save to offline store if the api session is not connected or unauthorized self.off_store.put(item['activity'], item['data'], Sender.store_put_callback)
def connect(self): """ Public method to authenticate the api session. The method tries auth for three times before giving it to the background thread in case of connection issues. Returns: status of auth """ #if the session is not authorized or another thread is performing auth, then we return if api.session.auth_status( ) != api.AuthStatus.UNAUTHORIZED or not api.session.auth_status( api.AuthStatus.AUTHENTICATING): return api.Status.UNKNOWN status = self.attempt(retry_count=2) #attempt to auth #if api sesssion cannot connect to server and we have the activities available, we can run them offline if api.is_not_connected(status) and self.univ.config.agent.get([ 'config', 'activities' ]) and self.univ.config.agent.get(['config', 'org']): self.start() status = api.Status.SUCCESS #modify the status so that caller can continue return status
def send_crash_dumps(self): """ Method to send all crash dumps to server. This method runs in a seperate thread. """ import api univ = Universal() #get Universal #how much time the crash dump sender wait before start sending. #this is required not to affect crash loop detection, since crash loop detection is done by checking number crash dumps generated in a span of time crash_dump_timeout = (self.crash_loop_count * self.monit_interval) + 10 #get the agent version regex to differentiate dumps from any other file agent_version_regex = univ.config.agent.schema['agentVersion'].get('regex', '.*') agent_version_regex = re.sub('^\^?([^\$]+)\$?$', '\g<1>', agent_version_regex) _log.debug('CrashDumpSender waiting for stop event for %d seconds' % crash_dump_timeout) univ.stop_event.wait(crash_dump_timeout) try: for file in os.listdir(self.crash_dump_path): #loop though files in the crash dump directory file_name = self.crash_dump_path + file #is this a valid crash dump filename if os.path.isfile(file_name) and re.match('^sealion-%s-[0-9]+\.dmp$' % agent_version_regex, file) != None: report = None while 1: if univ.stop_event.is_set(): #do we need to stop now _log.debug('CrashDumpSender received stop event') return #read the report from the dump, or retry the report report = report if report != None else self.read_dump(file_name) if report == None or api.is_not_connected(api.unauth_session.send_crash_report(report)) == False: #send the dump break _log.debug('CrashDumpSender waiting for stop event for 10 seconds') univ.stop_event.wait(10) #on failure, wait for some time try: os.remove(file_name) #remove the dump as we sent it _log.info('Removed dump %s' % file_name) except Exception as e: _log.error('Failed to remove dump %s; %s' % (file_name, unicode(e))) if univ.stop_event.is_set(): #do we need to stop now _log.debug('CrashDumpSender received stop event') return except: pass
def post_data(self, item): """ Method to post the data. Args: item: item to be sent """ row_id = item.get('row_id') #sqlite row_id used to delete the row once it has been sent status = api.session.post_data(item['activity'], item['data']) if status == api.Status.MISMATCH: #a mismatch status indicates that we missed a config update event, so we are doing it now api.session.get_config() #delete from offline store if data was sent; we consider it is sent if api session is connected and is not unauthorized. #no need to check for any other status code. if api.is_not_connected(status) == False and status != api.Status.UNAUTHORIZED: self.del_rows.append(row_id) else: Sender.store_available(True) #if sending failed, we need to mark offline store as available
def post_data(self, item): """ Method to post the data. Args: item: item to be sent """ Storage.get_data(item['data']) #get the data. read get_data doc to know why this is required #update the timestamp limit for selecting rows to the last real time data retreived. #this will prevent any data sent to offline store due to queue overflow being sent before real time queue clears up self.off_store.select_timestamp = item['data']['timestamp'] status = api.session.post_data(item['activity'], item['data']) if status == api.Status.MISMATCH: #a mismatch status indicates that we missed a config update event, so we are doing it now api.session.get_config() elif api.is_not_connected(status) == True or status == api.Status.UNAUTHORIZED: #save to offline store if the api session is not connected or unauthorized self.off_store.put(item['activity'], item['data'], Sender.store_put_callback)
def connect(self): """ Public method to authenticate the api session. The method tries auth for three times before giving it to the background thread in case of connection issues. Returns: status of auth """ #if the session is not authorized or another thread is performing auth, then we return if api.session.auth_status() != api.AuthStatus.UNAUTHORIZED or not api.session.auth_status(api.AuthStatus.AUTHENTICATING): return api.Status.UNKNOWN status = self.attempt(retry_count = 2) #attempt to auth #if api sesssion cannot connect to server and we have the activities available, we can run them offline if api.is_not_connected(status) and hasattr(self.univ.config.agent, 'activities') and hasattr(self.univ.config.agent, 'org'): self.start() status = api.Status.SUCCESS #modify the status so that caller can continue return status
#get the exe path, which is the absolute path to the parent directory of the module's direcotry exe_path = os.path.dirname(os.path.abspath(__file__)) exe_path = exe_path[:-1] if exe_path[len(exe_path) - 1] == '/' else exe_path exe_path = exe_path[:exe_path.rfind('/') + 1] #add module lookup paths to sys.path so that import can find them #we are inserting at the begining of sys.path so that we can be sure that we are importing the right module sys.path.insert(0, exe_path + 'lib/websocket_client') sys.path.insert(0, exe_path + 'src') sys.path.insert(0, exe_path + 'lib') #to avoid the bug reported at http://bugs.python.org/issue13684 we use a stable httplib version available with CPython 2.7.3 and 3.2.3 #since httplib has been renamed to http, we have to add that also in the path so that import can find it if sys.version_info[0] == 3: sys.path.insert(0, exe_path + 'lib/httplib') import exit_status try: #it is possible that the agent was removed from the UI, in that case it already had removed config files. so import api can raise an exception import api api.create_session() except: sys.exit(exit_status.AGENT_ERR_SUCCESS ) #any exception should be considered as success api.session.ping( ) #required to set the post event, as the post event is set only after auth status = api.session.unregister() #unregister the agent sys.exit(exit_status.AGENT_ERR_SUCCESS if api.is_not_connected(status) == False else exit_status.AGENT_ERR_FAILED_CONNECT)
def send_crash_dumps(self): """ Method to send all crash dumps to server. This method runs in a seperate thread. """ import api univ = universal.Universal() #get Universal #how much time the crash dump sender wait before start sending. #this is required not to affect crash loop detection, since crash loop detection is done by checking number crash dumps generated in a span of time crash_dump_timeout = (self.crash_loop_count * self.crash_loop_timeout) + 10 _log.debug('CrashDumpSender waiting for stop event for %d seconds' % crash_dump_timeout) univ.stop_event.wait(crash_dump_timeout) try: for file in os.listdir( self.crash_dump_path ): #loop though files in the crash dump directory file_name = self.crash_dump_path + file #is this a valid crash dump filename if os.path.isfile(file_name) and re.match( self.crash_dump_pattern % self.agent_version_regex, file) != None: report = None while 1: if univ.stop_event.is_set(): #do we need to stop now _log.debug('CrashDumpSender received stop event') return #read the report from the dump, or retry the report report = report if report != None else self.read_dump( file_name) if report == None or api.is_not_connected( api.unauth_session.send_crash_report( report)) == False: #send the dump break _log.debug( 'CrashDumpSender waiting for stop event for 10 seconds' ) univ.stop_event.wait( 10) #on failure, wait for some time try: os.remove(file_name) #remove the dump as we sent it _log.info('Removed dump %s' % file_name) except Exception as e: _log.error('Failed to remove dump %s; %s' % (file_name, unicode(e))) if univ.stop_event.is_set(): #do we need to stop now _log.debug('CrashDumpSender received stop event') return except: pass
import sys #get the exe path, which is the absolute path to the parent directory of the module's direcotry exe_path = os.path.dirname(os.path.abspath(__file__)) exe_path = exe_path[:-1] if exe_path[len(exe_path) - 1] == '/' else exe_path exe_path = exe_path[:exe_path.rfind('/') + 1] #add module lookup paths to sys.path so that import can find them #we are inserting at the begining of sys.path so that we can be sure that we are importing the right module sys.path.insert(0, exe_path + 'lib/websocket_client') sys.path.insert(0, exe_path + 'src') sys.path.insert(0, exe_path + 'lib') #to avoid the bug reported at http://bugs.python.org/issue13684 we use a stable httplib version available with CPython 2.7.3 and 3.2.3 #since httplib has been renamed to http, we have to add that also in the path so that import can find it if sys.version_info[0] == 3: sys.path.insert(0, exe_path + 'lib/httplib') import exit_status try: #it is possible that the agent was removed from the UI, in that case it already had removed config files. so import api can raise an exception import api api.create_session() except: sys.exit(exit_status.AGENT_ERR_SUCCESS) #any exception should be considered as success api.session.ping() #required to set the post event, as the post event is set only after auth status = api.session.unregister() #unregister the agent sys.exit(exit_status.AGENT_ERR_SUCCESS if api.is_not_connected(status) == False else exit_status.AGENT_ERR_FAILED_CONNECT)