Skip to content

Commit

Permalink
Merge branch 'releases/0.9.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
t0mz06 committed Oct 29, 2024
2 parents 0cf8416 + aed5973 commit dc7ba00
Show file tree
Hide file tree
Showing 12 changed files with 638 additions and 203 deletions.
166 changes: 87 additions & 79 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/pytmv1/__about__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.8.9"
__version__ = "0.9.0"
18 changes: 14 additions & 4 deletions src/pytmv1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
OatEvent,
OatFilter,
OatObject,
OatPackage,
OatPipeline,
SaeAlert,
SaeIndicator,
SandboxSuspiciousObject,
Expand All @@ -45,8 +47,6 @@
ApiStatus,
DetectionType,
EntityType,
EventID,
EventSubID,
Iam,
IntegrityLevel,
InvestigationResult,
Expand Down Expand Up @@ -99,6 +99,8 @@
GetApiKeyResp,
GetEmailActivitiesCountResp,
GetEndpointActivitiesCountResp,
GetOatPackageResp,
GetPipelineResp,
ListAlertNoteResp,
ListAlertsResp,
ListApiKeyResp,
Expand All @@ -107,13 +109,16 @@
ListEndpointActivityResp,
ListEndpointDataResp,
ListExceptionsResp,
ListOatPackagesResp,
ListOatPipelinesResp,
ListOatsResp,
ListSandboxSuspiciousResp,
ListSuspiciousResp,
MultiApiKeyResp,
MultiResp,
MultiUrlResp,
NoContentResp,
OatPipelineResp,
SandboxAnalysisResultResp,
SandboxSubmissionStatusResp,
SandboxSubmitUrlTaskResp,
Expand Down Expand Up @@ -162,15 +167,15 @@
"Entity",
"EntityType",
"Error",
"EventID",
"EventSubID",
"ExceptionObject",
"ScriptType",
"GetAlertResp",
"GetAlertNoteResp",
"GetApiKeyResp",
"GetEmailActivitiesCountResp",
"GetEndpointActivitiesCountResp",
"GetOatPackageResp",
"GetPipelineResp",
"HostInfo",
"Iam",
"ImpactScope",
Expand All @@ -187,6 +192,8 @@
"ListEndpointDataResp",
"ListExceptionsResp",
"ListOatsResp",
"ListOatPackagesResp",
"ListOatPipelinesResp",
"ListSandboxSuspiciousResp",
"ListSuspiciousResp",
"MatchedEvent",
Expand All @@ -208,6 +215,9 @@
"OatEvent",
"OatFilter",
"OatObject",
"OatPackage",
"OatPipeline",
"OatPipelineResp",
"OatRiskLevel",
"DetectionType",
"ObjectRequest",
Expand Down
8 changes: 8 additions & 0 deletions src/pytmv1/api/alert.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ def consume(
consumer: Callable[[Union[SaeAlert, TiAlert]], None],
start_time: Optional[str] = None,
end_time: Optional[str] = None,
op: QueryOp = QueryOp.AND,
**fields: str,
) -> Result[ConsumeLinkableResp]:
"""Retrieves and consume workbench alerts.
Expand All @@ -134,6 +136,11 @@ def consume(
time range (yyyy-MM-ddThh:mm:ssZ).
Defaults to the time the request is made.
:type end_time: Optional[str]
:param op: Operator to apply between fields (ie: ... OR ...).
:type op: QueryOp
:param fields: Field/value used to filter result (i.e:fileName="1.sh"),
check Vision One API documentation for full list of supported fields.
:type fields: Dict[str, str]
:rtype: Result[ConsumeLinkableResp]:
"""
return self._core.send_linkable(
Expand All @@ -147,4 +154,5 @@ def consume(
"orderBy": "createdDateTime desc",
}
),
headers=utils.tmv1_filter(op, fields),
)
214 changes: 207 additions & 7 deletions src/pytmv1/api/oat.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
from typing import Callable, Optional
from typing import Callable, List, Optional

from .. import utils
from ..core import Core
from ..model.common import OatEvent
from ..model.enum import Api, QueryOp
from ..model.response import ListOatsResp
from ..result import Result
from ..model.common import OatEvent, OatPackage
from ..model.enum import Api, HttpMethod, OatRiskLevel, QueryOp
from ..model.response import (
ConsumeLinkableResp,
GetOatPackageResp,
GetPipelineResp,
ListOatPackagesResp,
ListOatPipelinesResp,
ListOatsResp,
MultiResp,
NoContentResp,
OatPipelineResp,
)
from ..result import MultiResult, Result


class Oat:
Expand Down Expand Up @@ -74,7 +84,7 @@ def consume(
top: int = 50,
op: QueryOp = QueryOp.AND,
**fields: str,
) -> Result[ListOatsResp]:
) -> Result[ConsumeLinkableResp]:
"""Retrieves and consume OAT events.
:param consumer: Function which will consume every record in result.
Expand All @@ -100,7 +110,7 @@ def consume(
:param fields: Field/value used to filter result (i.e:uuid="123"),
check Vision One API documentation for full list of supported fields.
:type fields: Dict[str, str]
:rtype: Result[ListOatsResp]
:rtype: Result[ConsumeLinkableResp]
"""
return self._core.send_linkable(
ListOatsResp,
Expand All @@ -117,3 +127,193 @@ def consume(
),
headers=utils.tmv1_filter(op, fields),
)

def create_pipeline(
self,
has_detail: bool,
risk_levels: List[OatRiskLevel],
description: Optional[str] = None,
) -> Result[OatPipelineResp]:
"""Registers a customer
to the Observed Attack Techniques data pipeline.
:param has_detail: Retrieve detailed logs from the OAT data pipeline.
:type has_detail: bool
:param risk_levels: Risk levels to include in the results,
requests must include at least one risk level.
:type risk_levels: List[OatRiskLevel]
:param description: Notes or comments about the pipeline.
:type description: Optional[str]
:return: Result[PipelineResp]
"""
return self._core.send(
OatPipelineResp,
Api.CREATE_OAT_PIPELINE,
HttpMethod.POST,
json=utils.filter_none(
{
"hasDetail": has_detail,
"riskLevels": risk_levels,
"description": description,
}
),
)

def get_pipeline(self, pipeline_id: str) -> Result[GetPipelineResp]:
"""Displays the settings of the specified data pipeline.
:param pipeline_id: Pipeline ID.
:type pipeline_id: str
:return: Result[GetPipelineResp]
"""
return self._core.send(
GetPipelineResp, Api.GET_OAT_PIPELINE.value.format(pipeline_id)
)

def update_pipeline(
self,
pipeline_id: str,
etag: str,
has_detail: Optional[bool] = None,
risk_levels: Optional[List[OatRiskLevel]] = None,
description: Optional[str] = None,
) -> Result[NoContentResp]:
"""Modifies the settings of the specified data pipeline.
:param pipeline_id: Pipeline ID.
:type pipeline_id: str
:param etag: ETag of the resource you want to update.
:type etag: str
:param has_detail: Retrieve detailed logs from the OAT data pipeline.
:type has_detail: Optional[bool]
:param risk_levels: Risk levels to include in the results,
requests must include at least one risk level.
:type risk_levels: Optional[List[OatRiskLevel]]
:param description: Notes or comments about the pipeline.
:type description: Optional[str]
:return: Result[NoContentResp]
"""
return self._core.send(
NoContentResp,
Api.UPDATE_OAT_PIPELINE.value.format(pipeline_id),
HttpMethod.PATCH,
json=utils.filter_none(
{
"hasDetail": has_detail,
"riskLevels": risk_levels,
"description": description,
}
),
headers={
"If-Match": (etag[1:-1] if etag.startswith('"') else etag)
},
)

def delete_pipelines(self, *pipeline_ids: str) -> MultiResult[MultiResp]:
"""Unregisters a customer
from the Observed Attack Techniques data pipeline(s).
:param pipeline_ids: Pipeline IDs.
:type pipeline_ids: List[str]
:return: MultiResult[MultiResp]
"""
return self._core.send_multi(
MultiResp,
Api.DELETE_OAT_PIPELINE,
json=[{"id": pipeline_id} for pipeline_id in pipeline_ids],
)

def list_pipelines(self) -> Result[ListOatPipelinesResp]:
"""Displays all data pipelines that have registered users.
:return: Result[ListOatPipelineResp]
"""
return self._core.send(ListOatPipelinesResp, Api.LIST_OAT_PIPELINE)

def get_package(
self, pipeline_id: str, package_id: str
) -> Result[GetOatPackageResp]:
"""Retrieves the specified Observed Attack Techniques package.
:param pipeline_id: Pipeline ID.
:type pipeline_id: str
:param package_id: Package ID.
:type package_id: str
:return: Result[GetOatPackageResp]
"""
return self._core.send(
GetOatPackageResp,
Api.DOWNLOAD_OAT_PACKAGE.value.format(pipeline_id, package_id),
)

def list_packages(
self,
pipeline_id: str,
start_date_time: Optional[str] = None,
end_date_time: Optional[str] = None,
top: int = 500,
) -> Result[ListOatPackagesResp]:
"""Displays all the available packages from a data pipeline
in a paginated list.
:param pipeline_id: Pipeline ID.
:type pipeline_id: str
:param start_date_time: Date that indicates the start of
the data retrieval time range. (yyyy-MM-ddThh:mm:ssZ).
:type start_date_time: Optional[str]
:param end_date_time: Date that indicates the end of
the data retrieval time range. (yyyy-MM-ddThh:mm:ssZ).
:type end_date_time: Optional[str]
:param top: Number of records displayed on a page.
:type top: int
:return: Result[ListOatPackagesResp]
"""
return self._core.send(
ListOatPackagesResp,
Api.LIST_OAT_PACKAGE.value.format(pipeline_id),
params=utils.filter_none(
{
"startDateTime": start_date_time,
"endDateTime": end_date_time,
"top": top,
}
),
)

def consume_packages(
self,
pipeline_id: str,
consumer: Callable[[OatPackage], None],
start_date_time: Optional[str] = None,
end_date_time: Optional[str] = None,
top: int = 500,
) -> Result[ConsumeLinkableResp]:
"""Displays and consume all the available packages from a data pipeline
in a paginated list.
:param pipeline_id: Pipeline ID.
:type pipeline_id: str
:param consumer: Function which will consume every record in result.
:type consumer: Callable[[OatPackage], None]
:param start_date_time: Date that indicates the start of
the data retrieval time range. (yyyy-MM-ddThh:mm:ssZ).
:type start_date_time: Optional[str]
:param end_date_time: Date that indicates the end of
the data retrieval time range. (yyyy-MM-ddThh:mm:ssZ).
:type end_date_time: Optional[str]
:param top: Number of records displayed on a page.
:type top: int
:return: Result[ConsumeLinkableResp]
"""
return self._core.send_linkable(
ListOatPackagesResp,
Api.LIST_OAT_PACKAGE.value.format(pipeline_id),
consumer,
params=utils.filter_none(
{
"startDateTime": start_date_time,
"endDateTime": end_date_time,
"top": top,
}
),
)
Loading

0 comments on commit dc7ba00

Please sign in to comment.