def main(): global USERNAME, PASSWORD, ACCOUNT_EMAIL USERNAME = demisto.params()['credentials']['identifier'] PASSWORD = demisto.params()['credentials']['password'] ACCOUNT_EMAIL = demisto.params().get('mailbox', None) if not ACCOUNT_EMAIL: if "@" in USERNAME: ACCOUNT_EMAIL = USERNAME if ACCOUNT_EMAIL is None: raise Exception("Provide a valid email address in the mailbox field") global config config = prepare() args = prepare_args(demisto.args()) try: if demisto.command() == 'test-module': test_module() elif demisto.command() == 'send-mail': demisto.results(send_email(**args)) try: # we don't want to leave cached connection arround as EWS limits the number of connections # in a very aggressive way. 12 seems to be the default limit # see: https://blogs.msdn.microsoft.com/webdav_101/2018/06/02/you-are-doing-too-much-at-one-time-ewsmaxconcurrency-too-many-concurrent-connections-opened/ # noqa close_connections() except Exception as ex: demisto.info( "Failed close_connections (shouldn't happen). Ignoring exception: {}" .format(ex)) except Exception as e: import time time.sleep(2) debug_log = log_stream.getvalue() error_message = "" if "Status code: 401" in debug_log: error_message = ("Got unauthorized from the server. " "Check credentials are correct and authentication" " method are supported. ") error_message += ( "You can try using 'domain\\username' as username for authentication. " if AUTH_METHOD_STR.lower() == 'ntlm' else '') if "Status code: 503" in debug_log: error_message = "Got timeout from the server. " \ "Probably the server is not reachable with the current settings. " \ "Check proxy parameter. If you are using server URL - change to server IP address. " error_message = error_message + "\n" + str(e) stacktrace = traceback.format_exc() if stacktrace: debug_log += "\nFull stacktrace:\n" + stacktrace demisto.error("EWS Mail Sender failed {}. Error: {}. Debug: {}".format( demisto.command(), error_message, debug_log)) if IS_TEST_MODULE: demisto.results(error_message) else: return_error(error_message + '\n' + debug_log)
def exchangelib_cleanup(): key_protocols = exchangelib.protocol.CachingProtocol._protocol_cache.items() try: exchangelib.close_connections() except Exception as ex: demisto.error("Error was found in exchangelib cleanup, ignoring: {}".format(ex)) for key, protocol in key_protocols: try: if "thread_pool" in protocol.__dict__: demisto.debug('terminating thread pool key{} id: {}'.format(key, id(protocol.thread_pool))) protocol.thread_pool.terminate() del protocol.__dict__["thread_pool"] else: demisto.info('Thread pool not found (ignoring terminate) in protcol dict: {}'.format(dir(protocol.__dict__))) except Exception as ex: demisto.error("Error with thread_pool.terminate, ignoring: {}".format(ex))
def test_close_connections_helper(self): # Just test that it doesn't break close_connections()