splunk-soar-sdk 3.1.0__py3-none-any.whl → 3.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- soar_sdk/actions_manager.py +7 -0
- soar_sdk/app.py +26 -0
- soar_sdk/code_renderers/action_renderer.py +56 -0
- soar_sdk/code_renderers/app_renderer.py +11 -0
- soar_sdk/decorators/__init__.py +2 -0
- soar_sdk/decorators/on_es_poll.py +218 -0
- soar_sdk/models/__init__.py +15 -0
- soar_sdk/models/attachment_input.py +27 -0
- soar_sdk/models/container.py +1 -0
- soar_sdk/params.py +19 -0
- {splunk_soar_sdk-3.1.0.dist-info → splunk_soar_sdk-3.2.0.dist-info}/METADATA +1 -1
- {splunk_soar_sdk-3.1.0.dist-info → splunk_soar_sdk-3.2.0.dist-info}/RECORD +15 -13
- {splunk_soar_sdk-3.1.0.dist-info → splunk_soar_sdk-3.2.0.dist-info}/WHEEL +0 -0
- {splunk_soar_sdk-3.1.0.dist-info → splunk_soar_sdk-3.2.0.dist-info}/entry_points.txt +0 -0
- {splunk_soar_sdk-3.1.0.dist-info → splunk_soar_sdk-3.2.0.dist-info}/licenses/LICENSE +0 -0
soar_sdk/actions_manager.py
CHANGED
|
@@ -154,6 +154,13 @@ class ActionsManager(BaseConnector):
|
|
|
154
154
|
# For non-broker just proceed as we did before
|
|
155
155
|
return super().get_app_dir()
|
|
156
156
|
|
|
157
|
+
def send_finding_to_es(self, finding: dict[str, Any]) -> str:
|
|
158
|
+
"""Send finding to ES.
|
|
159
|
+
|
|
160
|
+
Returns finding_id: ID for the finding in ES.
|
|
161
|
+
"""
|
|
162
|
+
return ""
|
|
163
|
+
|
|
157
164
|
@classmethod
|
|
158
165
|
def get_soar_base_url(cls) -> str:
|
|
159
166
|
"""Get the base URL of the Splunk SOAR instance this app is running on."""
|
soar_sdk/app.py
CHANGED
|
@@ -38,6 +38,7 @@ from soar_sdk.decorators import (
|
|
|
38
38
|
ActionDecorator,
|
|
39
39
|
ViewHandlerDecorator,
|
|
40
40
|
OnPollDecorator,
|
|
41
|
+
OnESPollDecorator,
|
|
41
42
|
WebhookDecorator,
|
|
42
43
|
MakeRequestDecorator,
|
|
43
44
|
)
|
|
@@ -495,6 +496,31 @@ class App:
|
|
|
495
496
|
"""
|
|
496
497
|
return OnPollDecorator(self)
|
|
497
498
|
|
|
499
|
+
def on_es_poll(self) -> OnESPollDecorator:
|
|
500
|
+
"""Decorator for the on_es_poll action.
|
|
501
|
+
|
|
502
|
+
The decorated function must be a generator (using yield) or return an Iterator that yields tuples of (Finding, list[AttachmentInput]). Only one on_es_poll action is allowed per app.
|
|
503
|
+
|
|
504
|
+
Example:
|
|
505
|
+
>>> @app.on_es_poll()
|
|
506
|
+
... def on_es_poll(
|
|
507
|
+
... params: OnESPollParams, soar: SOARClient, asset: Asset
|
|
508
|
+
... ) -> Iterator[tuple[Finding, list[AttachmentInput]]]:
|
|
509
|
+
... yield (
|
|
510
|
+
... Finding(
|
|
511
|
+
... rule_title="Risk threshold exceeded for user",
|
|
512
|
+
... rule_description="Risk Threshold Exceeded for an object over a 24 hour period",
|
|
513
|
+
... security_domain="threat",
|
|
514
|
+
... risk_object="bad_user@splunk.com",
|
|
515
|
+
... risk_object_type="user",
|
|
516
|
+
... risk_score=100.0,
|
|
517
|
+
... status="New",
|
|
518
|
+
... ),
|
|
519
|
+
... [],
|
|
520
|
+
... )
|
|
521
|
+
"""
|
|
522
|
+
return OnESPollDecorator(self)
|
|
523
|
+
|
|
498
524
|
def view_handler(
|
|
499
525
|
self,
|
|
500
526
|
*,
|
|
@@ -103,6 +103,62 @@ class ActionRenderer(AstRenderer[ActionMeta]):
|
|
|
103
103
|
ctx=ast.Load(),
|
|
104
104
|
),
|
|
105
105
|
),
|
|
106
|
+
"on es poll": ast.FunctionDef(
|
|
107
|
+
name="on_es_poll",
|
|
108
|
+
args=ast.arguments(
|
|
109
|
+
posonlyargs=[],
|
|
110
|
+
args=[
|
|
111
|
+
ast.arg(
|
|
112
|
+
arg="soar", annotation=ast.Name(id="SOARClient", ctx=ast.Load())
|
|
113
|
+
),
|
|
114
|
+
ast.arg(
|
|
115
|
+
arg="asset", annotation=ast.Name(id="Asset", ctx=ast.Load())
|
|
116
|
+
),
|
|
117
|
+
ast.arg(
|
|
118
|
+
arg="params",
|
|
119
|
+
annotation=ast.Name(id="OnESPollParams", ctx=ast.Load()),
|
|
120
|
+
),
|
|
121
|
+
],
|
|
122
|
+
vararg=None,
|
|
123
|
+
kwonlyargs=[],
|
|
124
|
+
kw_defaults=[],
|
|
125
|
+
kwarg=None,
|
|
126
|
+
defaults=[],
|
|
127
|
+
),
|
|
128
|
+
body=[
|
|
129
|
+
ast.Raise(
|
|
130
|
+
ast.Call(
|
|
131
|
+
func=ast.Name(id="NotImplementedError"), args=[], keywords=[]
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
],
|
|
135
|
+
decorator_list=[
|
|
136
|
+
ast.Call(
|
|
137
|
+
func=ast.Name(id="app.on_es_poll", ctx=ast.Load()),
|
|
138
|
+
args=[],
|
|
139
|
+
keywords=[],
|
|
140
|
+
)
|
|
141
|
+
],
|
|
142
|
+
returns=ast.Subscript(
|
|
143
|
+
value=ast.Name(id="Iterator", ctx=ast.Load()),
|
|
144
|
+
slice=ast.Subscript(
|
|
145
|
+
value=ast.Name(id="tuple", ctx=ast.Load()),
|
|
146
|
+
slice=ast.Tuple(
|
|
147
|
+
elts=[
|
|
148
|
+
ast.Name(id="Finding", ctx=ast.Load()),
|
|
149
|
+
ast.Subscript(
|
|
150
|
+
value=ast.Name(id="list", ctx=ast.Load()),
|
|
151
|
+
slice=ast.Name(id="AttachmentInput", ctx=ast.Load()),
|
|
152
|
+
ctx=ast.Load(),
|
|
153
|
+
),
|
|
154
|
+
],
|
|
155
|
+
ctx=ast.Load(),
|
|
156
|
+
),
|
|
157
|
+
ctx=ast.Load(),
|
|
158
|
+
),
|
|
159
|
+
ctx=ast.Load(),
|
|
160
|
+
),
|
|
161
|
+
),
|
|
106
162
|
}
|
|
107
163
|
|
|
108
164
|
@property
|
|
@@ -80,6 +80,7 @@ class AppRenderer:
|
|
|
80
80
|
ast.alias(name="Param", asname=None),
|
|
81
81
|
ast.alias(name="Params", asname=None),
|
|
82
82
|
ast.alias(name="OnPollParams", asname=None),
|
|
83
|
+
ast.alias(name="OnESPollParams", asname=None),
|
|
83
84
|
],
|
|
84
85
|
level=0,
|
|
85
86
|
)
|
|
@@ -114,6 +115,16 @@ class AppRenderer:
|
|
|
114
115
|
names=[ast.alias(name="Artifact", asname=None)],
|
|
115
116
|
level=0,
|
|
116
117
|
)
|
|
118
|
+
yield ast.ImportFrom(
|
|
119
|
+
module="soar_sdk.models.finding",
|
|
120
|
+
names=[ast.alias(name="Finding", asname=None)],
|
|
121
|
+
level=0,
|
|
122
|
+
)
|
|
123
|
+
yield ast.ImportFrom(
|
|
124
|
+
module="soar_sdk.models.attachment_input",
|
|
125
|
+
names=[ast.alias(name="AttachmentInput", asname=None)],
|
|
126
|
+
level=0,
|
|
127
|
+
)
|
|
117
128
|
|
|
118
129
|
def create_app_constructor(self) -> ast.Assign:
|
|
119
130
|
"""Create the App class constructor.
|
soar_sdk/decorators/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@ from .action import ActionDecorator
|
|
|
4
4
|
from .test_connectivity import ConnectivityTestDecorator
|
|
5
5
|
from .view_handler import ViewHandlerDecorator
|
|
6
6
|
from .on_poll import OnPollDecorator
|
|
7
|
+
from .on_es_poll import OnESPollDecorator
|
|
7
8
|
from .webhook import WebhookDecorator
|
|
8
9
|
from .make_request import MakeRequestDecorator
|
|
9
10
|
|
|
@@ -11,6 +12,7 @@ __all__ = [
|
|
|
11
12
|
"ActionDecorator",
|
|
12
13
|
"ConnectivityTestDecorator",
|
|
13
14
|
"MakeRequestDecorator",
|
|
15
|
+
"OnESPollDecorator",
|
|
14
16
|
"OnPollDecorator",
|
|
15
17
|
"ViewHandlerDecorator",
|
|
16
18
|
"WebhookDecorator",
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from functools import wraps
|
|
3
|
+
from typing import Any
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from collections.abc import Iterator
|
|
6
|
+
|
|
7
|
+
from soar_sdk.abstract import SOARClient
|
|
8
|
+
from soar_sdk.action_results import ActionResult
|
|
9
|
+
from soar_sdk.params import OnESPollParams
|
|
10
|
+
from soar_sdk.meta.actions import ActionMeta
|
|
11
|
+
from soar_sdk.types import Action, action_protocol
|
|
12
|
+
from soar_sdk.exceptions import ActionFailure
|
|
13
|
+
from soar_sdk.async_utils import run_async_if_needed
|
|
14
|
+
from soar_sdk.logging import getLogger
|
|
15
|
+
from soar_sdk.models.finding import Finding
|
|
16
|
+
from soar_sdk.models.attachment_input import AttachmentInput
|
|
17
|
+
from soar_sdk.models.container import Container
|
|
18
|
+
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from soar_sdk.app import App
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class OnESPollDecorator:
|
|
26
|
+
"""Class-based decorator for tagging a function as the special 'on es poll' action."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, app: "App") -> None:
|
|
29
|
+
self.app = app
|
|
30
|
+
|
|
31
|
+
def __call__(self, function: Callable) -> Action:
|
|
32
|
+
"""Decorator for the 'on es poll' action.
|
|
33
|
+
|
|
34
|
+
The decorated function must be a generator (using yield) or return an Iterator that yields tuples of (Finding, list[AttachmentInput]). Only one on_es_poll action is allowed per app.
|
|
35
|
+
|
|
36
|
+
Usage:
|
|
37
|
+
Each yielded tuple creates a Container from the Finding metadata. All AttachmentInput items in the list are added as vault attachments to that container.
|
|
38
|
+
"""
|
|
39
|
+
if self.app.actions_manager.get_action("on_es_poll"):
|
|
40
|
+
raise TypeError(
|
|
41
|
+
"The 'on_es_poll' decorator can only be used once per App instance."
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
is_generator = inspect.isgeneratorfunction(function)
|
|
45
|
+
is_async_generator = inspect.isasyncgenfunction(function)
|
|
46
|
+
signature = inspect.signature(function)
|
|
47
|
+
|
|
48
|
+
has_iterator_return = (
|
|
49
|
+
signature.return_annotation != inspect.Signature.empty
|
|
50
|
+
and getattr(signature.return_annotation, "__origin__", None) is Iterator
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if not (is_generator or is_async_generator or has_iterator_return):
|
|
54
|
+
raise TypeError(
|
|
55
|
+
"The on_es_poll function must be a generator (use 'yield') or return an Iterator."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
action_identifier = "on_es_poll"
|
|
59
|
+
action_name = "on es poll"
|
|
60
|
+
|
|
61
|
+
validated_params_class = OnESPollParams
|
|
62
|
+
logger = getLogger()
|
|
63
|
+
|
|
64
|
+
@action_protocol
|
|
65
|
+
@wraps(function)
|
|
66
|
+
def inner(
|
|
67
|
+
params: OnESPollParams,
|
|
68
|
+
soar: SOARClient = self.app.soar_client,
|
|
69
|
+
*args: Any, # noqa: ANN401
|
|
70
|
+
**kwargs: Any, # noqa: ANN401
|
|
71
|
+
) -> bool:
|
|
72
|
+
try:
|
|
73
|
+
try:
|
|
74
|
+
action_params = validated_params_class.parse_obj(params)
|
|
75
|
+
except Exception as e:
|
|
76
|
+
logger.info(f"Parameter validation error: {e!s}")
|
|
77
|
+
return self.app._adapt_action_result(
|
|
78
|
+
ActionResult(
|
|
79
|
+
status=False, message=f"Invalid parameters: {e!s}"
|
|
80
|
+
),
|
|
81
|
+
self.app.actions_manager,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
kwargs = self.app._build_magic_args(function, soar=soar, **kwargs)
|
|
85
|
+
|
|
86
|
+
result = function(action_params, *args, **kwargs)
|
|
87
|
+
result = run_async_if_needed(result)
|
|
88
|
+
|
|
89
|
+
for item in result:
|
|
90
|
+
if not isinstance(item, tuple) or len(item) != 2:
|
|
91
|
+
logger.info(
|
|
92
|
+
f"Warning: Expected tuple of (Finding, list[AttachmentInput]), got: {type(item)}"
|
|
93
|
+
)
|
|
94
|
+
continue
|
|
95
|
+
|
|
96
|
+
finding, attachments = item
|
|
97
|
+
|
|
98
|
+
if not isinstance(finding, Finding):
|
|
99
|
+
logger.info(
|
|
100
|
+
f"Warning: First element must be Finding, got: {type(finding)}"
|
|
101
|
+
)
|
|
102
|
+
continue
|
|
103
|
+
|
|
104
|
+
if not isinstance(attachments, list):
|
|
105
|
+
logger.info(
|
|
106
|
+
f"Warning: Second element must be list[AttachmentInput], got: {type(attachments)}"
|
|
107
|
+
)
|
|
108
|
+
continue
|
|
109
|
+
|
|
110
|
+
for attachment in attachments:
|
|
111
|
+
if not isinstance(attachment, AttachmentInput):
|
|
112
|
+
logger.info(
|
|
113
|
+
f"Warning: Attachment must be AttachmentInput, got: {type(attachment)}"
|
|
114
|
+
)
|
|
115
|
+
break
|
|
116
|
+
else:
|
|
117
|
+
finding_dict = finding.to_dict()
|
|
118
|
+
logger.info(
|
|
119
|
+
f"Processing finding: {finding_dict.get('rule_title', 'Unnamed finding')}"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Send finding to ES and get finding_id back
|
|
123
|
+
finding_id = self.app.actions_manager.send_finding_to_es(
|
|
124
|
+
finding_dict
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
container = Container(
|
|
128
|
+
name=finding.rule_title,
|
|
129
|
+
description=finding.rule_description,
|
|
130
|
+
severity=finding.urgency or "medium",
|
|
131
|
+
status=finding.status,
|
|
132
|
+
owner_id=finding.owner,
|
|
133
|
+
sensitivity=finding.disposition,
|
|
134
|
+
tags=finding.source,
|
|
135
|
+
external_id=finding_id,
|
|
136
|
+
data={
|
|
137
|
+
"security_domain": finding.security_domain,
|
|
138
|
+
"risk_score": finding.risk_score,
|
|
139
|
+
"risk_object": finding.risk_object,
|
|
140
|
+
"risk_object_type": finding.risk_object_type,
|
|
141
|
+
},
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
ret_val, message, container_id = (
|
|
145
|
+
self.app.actions_manager.save_container(container.to_dict())
|
|
146
|
+
)
|
|
147
|
+
logger.info(
|
|
148
|
+
f"Creating container for finding: {finding.rule_title}"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
if not ret_val:
|
|
152
|
+
logger.info(f"Failed to create container: {message}")
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
for attachment in attachments:
|
|
156
|
+
try:
|
|
157
|
+
if attachment.file_content is not None:
|
|
158
|
+
vault_id = soar.vault.create_attachment(
|
|
159
|
+
container_id=container_id,
|
|
160
|
+
file_content=attachment.file_content,
|
|
161
|
+
file_name=attachment.file_name,
|
|
162
|
+
metadata=attachment.metadata,
|
|
163
|
+
)
|
|
164
|
+
else:
|
|
165
|
+
vault_id = soar.vault.add_attachment(
|
|
166
|
+
container_id=container_id,
|
|
167
|
+
file_location=attachment.file_location,
|
|
168
|
+
file_name=attachment.file_name,
|
|
169
|
+
metadata=attachment.metadata,
|
|
170
|
+
)
|
|
171
|
+
logger.info(
|
|
172
|
+
f"Added attachment {attachment.file_name} with vault_id: {vault_id}"
|
|
173
|
+
)
|
|
174
|
+
except Exception as e:
|
|
175
|
+
logger.info(
|
|
176
|
+
f"Failed to add attachment {attachment.file_name}: {e!s}"
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
return self.app._adapt_action_result(
|
|
180
|
+
ActionResult(status=True, message="Finding processing complete"),
|
|
181
|
+
self.app.actions_manager,
|
|
182
|
+
)
|
|
183
|
+
except ActionFailure as e:
|
|
184
|
+
e.set_action_name(action_name)
|
|
185
|
+
return self.app._adapt_action_result(
|
|
186
|
+
ActionResult(status=False, message=str(e)),
|
|
187
|
+
self.app.actions_manager,
|
|
188
|
+
)
|
|
189
|
+
except Exception as e:
|
|
190
|
+
self.app.actions_manager.add_exception(e)
|
|
191
|
+
logger.info(f"Error during finding processing: {e!s}")
|
|
192
|
+
return self.app._adapt_action_result(
|
|
193
|
+
ActionResult(status=False, message=str(e)),
|
|
194
|
+
self.app.actions_manager,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
inner.params_class = validated_params_class
|
|
198
|
+
|
|
199
|
+
class OnESPollActionMeta(ActionMeta):
|
|
200
|
+
def model_dump(self, *args: object, **kwargs: object) -> dict[str, Any]:
|
|
201
|
+
data = super().model_dump(*args, **kwargs)
|
|
202
|
+
data["output"] = []
|
|
203
|
+
return data
|
|
204
|
+
|
|
205
|
+
inner.meta = OnESPollActionMeta(
|
|
206
|
+
action=action_name,
|
|
207
|
+
identifier=action_identifier,
|
|
208
|
+
description=inspect.getdoc(function) or action_name,
|
|
209
|
+
verbose="Callback action for the on_es_poll ingest functionality",
|
|
210
|
+
type="ingest",
|
|
211
|
+
read_only=True,
|
|
212
|
+
parameters=validated_params_class,
|
|
213
|
+
versions="EQ(*)",
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
self.app.actions_manager.set_action(action_identifier, inner)
|
|
217
|
+
self.app._dev_skip_in_pytest(function, inner)
|
|
218
|
+
return inner
|
soar_sdk/models/__init__.py
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .artifact import Artifact
|
|
2
|
+
from .attachment_input import AttachmentInput
|
|
3
|
+
from .container import Container
|
|
4
|
+
from .finding import Finding, DrilldownSearch, DrilldownDashboard
|
|
5
|
+
from .vault_attachment import VaultAttachment
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"Artifact",
|
|
9
|
+
"AttachmentInput",
|
|
10
|
+
"Container",
|
|
11
|
+
"DrilldownDashboard",
|
|
12
|
+
"DrilldownSearch",
|
|
13
|
+
"Finding",
|
|
14
|
+
"VaultAttachment",
|
|
15
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from pydantic import BaseModel, field_validator, ConfigDict
|
|
2
|
+
from pydantic_core.core_schema import ValidationInfo
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AttachmentInput(BaseModel):
|
|
6
|
+
"""Represents a vault attachment to be created during on_es_poll.
|
|
7
|
+
|
|
8
|
+
Specify either file_content OR file_location, not both.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
model_config = ConfigDict(extra="forbid")
|
|
12
|
+
|
|
13
|
+
file_content: str | bytes | None = None
|
|
14
|
+
file_location: str | None = None
|
|
15
|
+
file_name: str
|
|
16
|
+
metadata: dict[str, str] | None = None
|
|
17
|
+
|
|
18
|
+
@field_validator("file_location")
|
|
19
|
+
@classmethod
|
|
20
|
+
def validate_one_source(cls, v: str | None, info: ValidationInfo) -> str | None:
|
|
21
|
+
"""Validate that exactly one of file_content or file_location is provided."""
|
|
22
|
+
file_content = info.data.get("file_content")
|
|
23
|
+
if v is None and file_content is None:
|
|
24
|
+
raise ValueError("Must provide either file_content or file_location")
|
|
25
|
+
if v is not None and file_content is not None:
|
|
26
|
+
raise ValueError("Cannot provide both file_content and file_location")
|
|
27
|
+
return v
|
soar_sdk/models/container.py
CHANGED
|
@@ -14,6 +14,7 @@ class Container(BaseModel):
|
|
|
14
14
|
label: str | None = None
|
|
15
15
|
description: str | None = None
|
|
16
16
|
source_data_identifier: str | None = None
|
|
17
|
+
external_id: str | None = None
|
|
17
18
|
severity: str | None = None
|
|
18
19
|
status: str | None = None
|
|
19
20
|
tags: list[str] | str | None = None
|
soar_sdk/params.py
CHANGED
|
@@ -193,6 +193,25 @@ class OnPollParams(Params):
|
|
|
193
193
|
)
|
|
194
194
|
|
|
195
195
|
|
|
196
|
+
class OnESPollParams(Params):
|
|
197
|
+
"""Canonical parameters for the special 'on es poll' action."""
|
|
198
|
+
|
|
199
|
+
start_time: int = Param(
|
|
200
|
+
description="Start of time range, in epoch time (milliseconds).",
|
|
201
|
+
required=False,
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
end_time: int = Param(
|
|
205
|
+
description="End of time range, in epoch time (milliseconds).",
|
|
206
|
+
required=False,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
container_count: int = Param(
|
|
210
|
+
description="Maximum number of container records to query for.",
|
|
211
|
+
required=False,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
196
215
|
class MakeRequestParams(Params):
|
|
197
216
|
"""Canonical parameters for the special make request action."""
|
|
198
217
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: splunk-soar-sdk
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: The official framework for developing and testing Splunk SOAR Apps
|
|
5
5
|
Project-URL: Homepage, https://github.com/phantomcyber/splunk-soar-sdk
|
|
6
6
|
Project-URL: Documentation, https://github.com/phantomcyber/splunk-soar-sdk
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
soar_sdk/__init__.py,sha256=RzAng-ARqpK01SY82lNy4uYJFVG0yW6Q3CccEqbToJ4,726
|
|
2
2
|
soar_sdk/abstract.py,sha256=3oJvWljqDTr2nucf-9IdBRMDJwRnDe6nISYKyGuLMxw,7752
|
|
3
3
|
soar_sdk/action_results.py,sha256=ajlsed6ZkCyOTra4SFy31iYZO2a6mlvBK2-zIyO09q4,11928
|
|
4
|
-
soar_sdk/actions_manager.py,sha256=
|
|
5
|
-
soar_sdk/app.py,sha256=
|
|
4
|
+
soar_sdk/actions_manager.py,sha256=Ce4zU06QJlbTP3TONfxsS4CWuykcZpQ0mw3ir8ThLsw,6663
|
|
5
|
+
soar_sdk/app.py,sha256=xCdBHQgzdIwfyYRHSGFRYpEu8nKPMsULZCrdm5CbRrY,34512
|
|
6
6
|
soar_sdk/app_cli_runner.py,sha256=tdglXCIRZS3dc3P18Tha7yUJQX9zIDxJFdST02LL9xY,11644
|
|
7
7
|
soar_sdk/app_client.py,sha256=p5dsgxmMK61qLFIn7pATEQkVWldTtQhJPcMs4Idv2Lw,6197
|
|
8
8
|
soar_sdk/asset.py,sha256=b4-f7r3JSfR-nUzalpgJnoXAIEHQ34yvIuoyoAFvye0,11055
|
|
@@ -14,7 +14,7 @@ soar_sdk/exceptions.py,sha256=bzydqdpzwG5VaVkZBiUEcf9Wp0clMdzqdUBZHzpfqT0,1830
|
|
|
14
14
|
soar_sdk/field_utils.py,sha256=Jb0HteUPd-CtuDM7rNXVLy4uRxl419zeDxY_oOpU8GM,287
|
|
15
15
|
soar_sdk/input_spec.py,sha256=79MFGF2IkAAoWpHmZYP0VqUBu10SkvmF_RPmXkf8bQ4,4677
|
|
16
16
|
soar_sdk/logging.py,sha256=30cUxU7Tjf_OY4rUOrvjDoqPH7pcFydrdDbcG4ppY_s,11424
|
|
17
|
-
soar_sdk/params.py,sha256=
|
|
17
|
+
soar_sdk/params.py,sha256=I-XL_5b7XEZEpnqAG05dll7rdscRnzbBInypO8miD_U,10308
|
|
18
18
|
soar_sdk/paths.py,sha256=XhpanQCAiTXaulRx440oKu36mnll7P05TethHXgMpgQ,239
|
|
19
19
|
soar_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
soar_sdk/types.py,sha256=-mOu8_sphcgJictMTn4Dl_6ijd2elLAlU2nuXF74zQc,616
|
|
@@ -43,15 +43,16 @@ soar_sdk/cli/manifests/serializers.py,sha256=hSfOcBNhv7s437A7t5BM1NXG5dfjKmh_xbH
|
|
|
43
43
|
soar_sdk/cli/package/cli.py,sha256=8AWItAAXzfjJMRLwDIRbrN9cQhy7clBX7WrOmdcGClw,9499
|
|
44
44
|
soar_sdk/cli/package/utils.py,sha256=zZmpWg76Vb3rtGn28aPhPHt1JUWR6eIByU6DTTRC3ng,1584
|
|
45
45
|
soar_sdk/code_renderers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
-
soar_sdk/code_renderers/action_renderer.py,sha256=
|
|
47
|
-
soar_sdk/code_renderers/app_renderer.py,sha256=
|
|
46
|
+
soar_sdk/code_renderers/action_renderer.py,sha256=nPbB3SJLm4VDu_zuwY6vO_LgVg1tvW5ZTrzeS7JdyF8,16489
|
|
47
|
+
soar_sdk/code_renderers/app_renderer.py,sha256=OCNNhXc36Amcg1kUUayyyzWx_M2RY8W8wvy0ppujLaE,7791
|
|
48
48
|
soar_sdk/code_renderers/asset_renderer.py,sha256=eZS-VaV6wn_zgKth4Sieqo2fyPLF1o-k3qN7UjNUycE,3833
|
|
49
49
|
soar_sdk/code_renderers/renderer.py,sha256=82FP89024ZP-J_Ebzsvrso1hlCFSLllR1U9GR-wB_Pc,1229
|
|
50
50
|
soar_sdk/code_renderers/toml_renderer.py,sha256=-zP8UzlYMCVVA5ex9slaNLeFTu4xLjkv88YLmRNLrTM,1505
|
|
51
51
|
soar_sdk/code_renderers/templates/pyproject.toml.jinja,sha256=uH7SJhFD9_-kYzGHobwv04aV4Nfru1bquL30GoOirfg,3918
|
|
52
|
-
soar_sdk/decorators/__init__.py,sha256
|
|
52
|
+
soar_sdk/decorators/__init__.py,sha256=-eM9ueHvdOq8Vd2C7Y0H3EJajVdV_sVfFJGQngbGRhg,580
|
|
53
53
|
soar_sdk/decorators/action.py,sha256=als7cKWozZnobylBXsY5aQ2Y4js_2Y4n8UmxI-pKy1w,6642
|
|
54
54
|
soar_sdk/decorators/make_request.py,sha256=NWPI5NhmvnI7VMKI-tmhsQ34kegGxWyXC9_PVW49EJc,5978
|
|
55
|
+
soar_sdk/decorators/on_es_poll.py,sha256=5wiAcboG45ut7dLr0ZRcKOU01yIBfBrq00laGtv1k84,9437
|
|
55
56
|
soar_sdk/decorators/on_poll.py,sha256=H_aijFWKeZKwiS72Vsa9uolmj8sziGW2lZF6EhjEDjs,8276
|
|
56
57
|
soar_sdk/decorators/test_connectivity.py,sha256=tZt7w-BnZUpxCyixblXts4tsUp8z-Kmz-JGJ5i5LQs8,3564
|
|
57
58
|
soar_sdk/decorators/view_handler.py,sha256=_qjfk2nQxPwraldjRIl4DWdW-tvANJfdVDU_lLA3UvE,7075
|
|
@@ -63,9 +64,10 @@ soar_sdk/meta/app.py,sha256=eZlM8GIY1B_o-RzJrRNCNVEQSx0sFupxZqCM7sIWGv4,2777
|
|
|
63
64
|
soar_sdk/meta/datatypes.py,sha256=piR-oBVAATiRciXSdVE7XaqjUZTgSaOvTEqcOcNvCS0,795
|
|
64
65
|
soar_sdk/meta/dependencies.py,sha256=DZr38K_1rKh7OzlIb5nLbdDH8xOHArr48H8Ra6rcB4k,18259
|
|
65
66
|
soar_sdk/meta/webhooks.py,sha256=E5pdoD9j7FDeM2DBTO2h9Yw6-5flzp-NfhM_M1oPAUU,1216
|
|
66
|
-
soar_sdk/models/__init__.py,sha256=
|
|
67
|
+
soar_sdk/models/__init__.py,sha256=ql7RRFAxmSdzU-IsoU1OFQ53E6WxZJ7YQQAhHl4Ssbk,380
|
|
67
68
|
soar_sdk/models/artifact.py,sha256=OlYp150sf9sYvTz6tC7PaYV1qbBvQYrz1bXmC2xNj8Q,1086
|
|
68
|
-
soar_sdk/models/
|
|
69
|
+
soar_sdk/models/attachment_input.py,sha256=dE0Z8CaKSYkNP1-NvOWz4O044-UKtqRoxdJhc471M5k,1043
|
|
70
|
+
soar_sdk/models/container.py,sha256=2uLwFDDcsJ7cURYsd6Vt3mtbqEszlIHXshYL-BUGUEA,1527
|
|
69
71
|
soar_sdk/models/finding.py,sha256=Yhw4mOJLeZj7ylDgxbjJs9wm_xzK6Sbkr4r3XOtL0PM,1414
|
|
70
72
|
soar_sdk/models/vault_attachment.py,sha256=IQPX239OFClVfOKr9nHIu9Is55cXWBaOgM2lG5Lt-b4,1072
|
|
71
73
|
soar_sdk/models/view.py,sha256=frfbNdWfzc0XjiU3CY79zBJxvzUsgLdFmphVeZ6QqTc,777
|
|
@@ -98,8 +100,8 @@ soar_sdk/views/components/pie_chart.py,sha256=LVTeHVJN6nf2vjUs9y7PDBhS0U1fKW750l
|
|
|
98
100
|
soar_sdk/webhooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
99
101
|
soar_sdk/webhooks/models.py,sha256=PG9SDs5xXqtFndm5C8AsJOTYXU5v_UTY7SpYosWT_CA,4542
|
|
100
102
|
soar_sdk/webhooks/routing.py,sha256=MnzbnIDy2uG_5mJzsTeX-NsE6QYvzyqEGbHmEFj-DG8,6900
|
|
101
|
-
splunk_soar_sdk-3.
|
|
102
|
-
splunk_soar_sdk-3.
|
|
103
|
-
splunk_soar_sdk-3.
|
|
104
|
-
splunk_soar_sdk-3.
|
|
105
|
-
splunk_soar_sdk-3.
|
|
103
|
+
splunk_soar_sdk-3.2.0.dist-info/METADATA,sha256=sL-PyINCXBsGJ-bPeHqiXCshp4IeLhs4HGHT171Uucs,7334
|
|
104
|
+
splunk_soar_sdk-3.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
105
|
+
splunk_soar_sdk-3.2.0.dist-info/entry_points.txt,sha256=CgBjo2ZWpYNkt9TgvToL26h2Tg1yt8FbvYTb5NVgNuc,51
|
|
106
|
+
splunk_soar_sdk-3.2.0.dist-info/licenses/LICENSE,sha256=gNCGrGhrSQb1PUzBOByVUN1tvaliwLZfna-QU2r2hQ8,11345
|
|
107
|
+
splunk_soar_sdk-3.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|