diff --git a/README.md b/README.md
index 4118d999..48e7bd73 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ Github issues and feature requests welcomed.
| Logging | sentryio |
| MacOS | airport
macchanger
wdutil |
| Python | logging
requests |
-| SOAR | swimlane
splunk soar |
+| SOAR | swimlane
splunk soar
xsoar |
| Recon | nmap |
| Test Automation | selenium |
diff --git a/automon/integrations/xsoar/__init__.py b/automon/integrations/xsoar/__init__.py
new file mode 100644
index 00000000..6a965d12
--- /dev/null
+++ b/automon/integrations/xsoar/__init__.py
@@ -0,0 +1,2 @@
+from .client import XSOARClient
+from .config import XSOARConfig
diff --git a/automon/integrations/xsoar/client.py b/automon/integrations/xsoar/client.py
new file mode 100644
index 00000000..878be7dc
--- /dev/null
+++ b/automon/integrations/xsoar/client.py
@@ -0,0 +1,52 @@
+from automon.log import logging
+from automon.integrations.requestsWrapper import RequestsClient
+
+from .config import XSOARConfig
+from .endpoints import v1
+
+logger = logging.getLogger(__name__)
+logger.setLevel(level=logging.DEBUG)
+
+
+class XSOARClient(object):
+ """XSOAR REST API client
+
+ referenc: https://cortex-panw.stoplight.io/docs/cortex-xsoar-8/kjn2q21a7yrbm-get-started-with-cortex-xsoar-8-ap-is
+ """
+
+ def __init__(
+ self,
+ host: str = None,
+ api_key: str = None,
+ api_key_id: str = None,
+ config: XSOARConfig = None
+ ):
+ self.config = config or XSOARConfig(host=host, api_key=api_key, api_key_id=api_key_id)
+ self._requests = RequestsClient()
+
+ async def is_ready(self):
+ if self.config.is_ready():
+ return True
+ return False
+
+ async def auth(self):
+ return
+
+ async def get(self, endpoint: str):
+ logger.info(dict(
+ endpoint=f'{self.config.host}/{endpoint}'
+ ))
+ return await self._requests.get(url=f'{self.config.host}/{endpoint}', headers=self.config.headers)
+
+ async def post(self, endpoint: str):
+ logger.info(dict(
+ endpoint=f'{self.config.host}/{endpoint}'
+ ))
+ return self._requests.post(url=f'{self.config.host}/{endpoint}', headers=self.config.headers)
+
+ async def reports(self):
+ reports = await self.get(endpoint=v1.Reports.reports)
+ logger.info(dict(
+ reports=self._requests.content
+ ))
+ return reports
diff --git a/automon/integrations/xsoar/config.py b/automon/integrations/xsoar/config.py
new file mode 100644
index 00000000..57c6b1a7
--- /dev/null
+++ b/automon/integrations/xsoar/config.py
@@ -0,0 +1,41 @@
+from automon import environ
+from automon.log import logging
+
+logger = logging.getLogger(__name__)
+logger.setLevel(level=logging.DEBUG)
+
+
+class XSOARConfig(object):
+ """XSOAR REST API client config"""
+
+ def __init__(
+ self,
+ host: str = None,
+ api_key: str = None,
+ api_key_id: str = None
+ ):
+ self.host = host or environ('XSOAR_FQDN')
+ self.api_key = api_key or environ('XSOAR_API_KEY')
+ self.api_key_id = api_key_id or environ('XSOAR_API_KEY_ID')
+
+ def is_ready(self) -> bool:
+ if not self.host:
+ logger.error(f'missing XSOAR_FQDN')
+
+ if not self.api_key:
+ logger.error(f'missing XSOAR_API_KEY')
+
+ if not self.api_key_id:
+ logger.error(f'missing XSOAR_API_KEY_ID')
+
+ if self.host and self.api_key and self.api_key_id:
+ return True
+ return False
+
+ @property
+ def headers(self):
+ return {
+ 'Authorization': f'{self.api_key}',
+ 'x-xdr-auth-id': f'{self.api_key_id}',
+ "Content-Type": "application/json"
+ }
diff --git a/automon/integrations/xsoar/endpoints/__init__.py b/automon/integrations/xsoar/endpoints/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/automon/integrations/xsoar/endpoints/v1.py b/automon/integrations/xsoar/endpoints/v1.py
new file mode 100644
index 00000000..3ccb9458
--- /dev/null
+++ b/automon/integrations/xsoar/endpoints/v1.py
@@ -0,0 +1,9 @@
+class V1:
+ xsoar: str = 'xsoar'
+ public: str = f'{xsoar}/public'
+ v1: str = f'{public}/v1'
+
+
+class Reports:
+ """xsoar/public/v1/reports"""
+ reports: str = f'{V1.v1}/reports'
diff --git a/automon/integrations/xsoar/tests/__init__.py b/automon/integrations/xsoar/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/automon/integrations/xsoar/tests/test_client_auth.py b/automon/integrations/xsoar/tests/test_client_auth.py
new file mode 100644
index 00000000..520ed624
--- /dev/null
+++ b/automon/integrations/xsoar/tests/test_client_auth.py
@@ -0,0 +1,17 @@
+import asyncio
+import unittest
+
+from automon.integrations.xsoar import XSOARClient
+
+
+class MyTestCase(unittest.TestCase):
+ test = XSOARClient()
+
+ if asyncio.run(test.is_ready()):
+ def test_auth(self):
+ result = asyncio.run(self.test.reports())
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/automon/integrations/xsoar/tests/test_config.py b/automon/integrations/xsoar/tests/test_config.py
new file mode 100644
index 00000000..e496be05
--- /dev/null
+++ b/automon/integrations/xsoar/tests/test_config.py
@@ -0,0 +1,15 @@
+import unittest
+
+from automon.integrations.xsoar import XSOARConfig
+
+
+class MyTestCase(unittest.TestCase):
+ test = XSOARConfig()
+
+ if test.is_ready():
+ def test_config(self):
+ self.assertTrue(self.test.is_ready())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/env-example.sh b/env-example.sh
index 0be017cb..fb6ec32d 100644
--- a/env-example.sh
+++ b/env-example.sh
@@ -147,3 +147,8 @@ VDS_PASSWORD=
# Wdutil
WDUTIL_PASSWORD=
+
+# XSOAR
+XSOAR_FQDN=
+XSOAR_API_KEY=
+XSOAR_API_KEY_ID=