contentctl 4.4.7__py3-none-any.whl → 5.0.0a0__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.
Files changed (69) hide show
  1. contentctl/actions/build.py +39 -27
  2. contentctl/actions/detection_testing/DetectionTestingManager.py +0 -1
  3. contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructure.py +32 -26
  4. contentctl/actions/detection_testing/progress_bar.py +6 -6
  5. contentctl/actions/detection_testing/views/DetectionTestingView.py +4 -4
  6. contentctl/actions/new_content.py +98 -81
  7. contentctl/actions/test.py +4 -5
  8. contentctl/actions/validate.py +2 -1
  9. contentctl/contentctl.py +114 -79
  10. contentctl/helper/utils.py +0 -14
  11. contentctl/input/director.py +5 -5
  12. contentctl/input/new_content_questions.py +2 -2
  13. contentctl/input/yml_reader.py +11 -6
  14. contentctl/objects/abstract_security_content_objects/detection_abstract.py +228 -120
  15. contentctl/objects/abstract_security_content_objects/security_content_object_abstract.py +5 -7
  16. contentctl/objects/alert_action.py +2 -1
  17. contentctl/objects/atomic.py +1 -0
  18. contentctl/objects/base_test.py +4 -3
  19. contentctl/objects/base_test_result.py +3 -3
  20. contentctl/objects/baseline.py +26 -6
  21. contentctl/objects/baseline_tags.py +2 -3
  22. contentctl/objects/config.py +26 -45
  23. contentctl/objects/constants.py +4 -1
  24. contentctl/objects/correlation_search.py +89 -95
  25. contentctl/objects/data_source.py +5 -6
  26. contentctl/objects/deployment.py +2 -10
  27. contentctl/objects/deployment_email.py +2 -1
  28. contentctl/objects/deployment_notable.py +2 -1
  29. contentctl/objects/deployment_phantom.py +2 -1
  30. contentctl/objects/deployment_rba.py +2 -1
  31. contentctl/objects/deployment_scheduling.py +2 -1
  32. contentctl/objects/deployment_slack.py +2 -1
  33. contentctl/objects/detection_tags.py +7 -42
  34. contentctl/objects/drilldown.py +1 -0
  35. contentctl/objects/enums.py +21 -58
  36. contentctl/objects/investigation.py +6 -5
  37. contentctl/objects/investigation_tags.py +2 -3
  38. contentctl/objects/lookup.py +145 -63
  39. contentctl/objects/macro.py +2 -3
  40. contentctl/objects/mitre_attack_enrichment.py +2 -2
  41. contentctl/objects/observable.py +3 -1
  42. contentctl/objects/playbook_tags.py +5 -1
  43. contentctl/objects/rba.py +90 -0
  44. contentctl/objects/risk_event.py +87 -144
  45. contentctl/objects/story_tags.py +1 -2
  46. contentctl/objects/test_attack_data.py +2 -1
  47. contentctl/objects/unit_test_baseline.py +2 -1
  48. contentctl/output/api_json_output.py +233 -220
  49. contentctl/output/conf_output.py +51 -44
  50. contentctl/output/conf_writer.py +201 -125
  51. contentctl/output/data_source_writer.py +0 -1
  52. contentctl/output/json_writer.py +2 -4
  53. contentctl/output/svg_output.py +1 -1
  54. contentctl/output/templates/analyticstories_detections.j2 +1 -1
  55. contentctl/output/templates/collections.j2 +1 -1
  56. contentctl/output/templates/doc_detections.j2 +0 -5
  57. contentctl/output/templates/savedsearches_detections.j2 +8 -3
  58. contentctl/output/templates/transforms.j2 +4 -4
  59. contentctl/output/yml_writer.py +15 -0
  60. contentctl/templates/detections/endpoint/anomalous_usage_of_7zip.yml +16 -34
  61. {contentctl-4.4.7.dist-info → contentctl-5.0.0a0.dist-info}/METADATA +5 -4
  62. {contentctl-4.4.7.dist-info → contentctl-5.0.0a0.dist-info}/RECORD +65 -68
  63. {contentctl-4.4.7.dist-info → contentctl-5.0.0a0.dist-info}/WHEEL +1 -1
  64. contentctl/objects/event_source.py +0 -11
  65. contentctl/output/detection_writer.py +0 -28
  66. contentctl/output/new_content_yml_output.py +0 -56
  67. contentctl/output/yml_output.py +0 -66
  68. {contentctl-4.4.7.dist-info → contentctl-5.0.0a0.dist-info}/LICENSE.md +0 -0
  69. {contentctl-4.4.7.dist-info → contentctl-5.0.0a0.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  from typing import Union, Any
2
- from enum import Enum
2
+ from enum import StrEnum
3
3
 
4
4
  from pydantic import ConfigDict, BaseModel
5
5
  from splunklib.data import Record # type: ignore
@@ -10,7 +10,7 @@ from contentctl.helper.utils import Utils
10
10
  # TODO (#267): Align test reporting more closely w/ status enums (as it relates to "untested")
11
11
  # TODO (PEX-432): add status "UNSET" so that we can make sure the result is always of this enum
12
12
  # type; remove mypy ignores associated w/ these typing issues once we do
13
- class TestResultStatus(str, Enum):
13
+ class TestResultStatus(StrEnum):
14
14
  """Enum for test status (e.g. pass/fail)"""
15
15
  # Test failed (detection did NOT fire appropriately)
16
16
  FAIL = "fail"
@@ -113,7 +113,7 @@ class BaseTestResult(BaseModel):
113
113
  # Exceptions and enums cannot be serialized, so convert to str
114
114
  if isinstance(getattr(self, field), Exception):
115
115
  summary_dict[field] = str(getattr(self, field))
116
- elif isinstance(getattr(self, field), Enum):
116
+ elif isinstance(getattr(self, field), StrEnum):
117
117
  summary_dict[field] = str(getattr(self, field))
118
118
  else:
119
119
  summary_dict[field] = getattr(self, field)
@@ -1,7 +1,10 @@
1
1
 
2
2
  from __future__ import annotations
3
- from typing import Annotated, Optional, List,Any
4
- from pydantic import field_validator, ValidationInfo, Field, model_serializer
3
+ from typing import Annotated, List,Any, TYPE_CHECKING
4
+ if TYPE_CHECKING:
5
+ from contentctl.input.director import DirectorOutputDto
6
+
7
+ from pydantic import field_validator, ValidationInfo, Field, model_serializer, computed_field
5
8
  from contentctl.objects.deployment import Deployment
6
9
  from contentctl.objects.security_content_object import SecurityContentObject
7
10
  from contentctl.objects.enums import DataModel
@@ -9,21 +12,34 @@ from contentctl.objects.baseline_tags import BaselineTags
9
12
 
10
13
  from contentctl.objects.config import CustomApp
11
14
 
12
-
15
+ from contentctl.objects.lookup import Lookup
13
16
  from contentctl.objects.constants import CONTENTCTL_MAX_SEARCH_NAME_LENGTH,CONTENTCTL_BASELINE_STANZA_NAME_FORMAT_TEMPLATE
14
17
 
15
18
  class Baseline(SecurityContentObject):
16
19
  name:str = Field(...,max_length=CONTENTCTL_MAX_SEARCH_NAME_LENGTH)
17
20
  type: Annotated[str,Field(pattern="^Baseline$")] = Field(...)
18
- datamodel: Optional[List[DataModel]] = None
19
21
  search: str = Field(..., min_length=4)
20
22
  how_to_implement: str = Field(..., min_length=4)
21
23
  known_false_positives: str = Field(..., min_length=4)
22
24
  tags: BaselineTags = Field(...)
23
-
25
+ lookups: list[Lookup] = Field([], validate_default=True)
24
26
  # enrichment
25
27
  deployment: Deployment = Field({})
26
-
28
+
29
+
30
+ @field_validator('lookups', mode="before")
31
+ @classmethod
32
+ def getBaselineLookups(cls, v:list[str], info:ValidationInfo) -> list[Lookup]:
33
+ '''
34
+ This function has been copied and renamed from the Detection_Abstract class
35
+ '''
36
+ director:DirectorOutputDto = info.context.get("output_dto",None)
37
+ search: str | None = info.data.get("search",None)
38
+ if search is None:
39
+ raise ValueError("Search was None - is this file missing the search field?")
40
+
41
+ lookups = Lookup.get_lookups(search, director)
42
+ return lookups
27
43
 
28
44
  def get_conf_stanza_name(self, app:CustomApp)->str:
29
45
  stanza_name = CONTENTCTL_BASELINE_STANZA_NAME_FORMAT_TEMPLATE.format(app_label=app.label, detection_name=self.name)
@@ -34,6 +50,10 @@ class Baseline(SecurityContentObject):
34
50
  def getDeployment(cls, v:Any, info:ValidationInfo)->Deployment:
35
51
  return Deployment.getDeployment(v,info)
36
52
 
53
+ @computed_field
54
+ @property
55
+ def datamodel(self) -> List[DataModel]:
56
+ return [dm for dm in DataModel if dm in self.search]
37
57
 
38
58
  @model_serializer
39
59
  def serialize_model(self):
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from pydantic import BaseModel, Field, field_validator, ValidationInfo, model_serializer
2
+ from pydantic import BaseModel, Field, field_validator, ValidationInfo, model_serializer, ConfigDict
3
3
  from typing import List, Any, Union
4
4
 
5
5
  from contentctl.objects.story import Story
@@ -12,12 +12,12 @@ from contentctl.objects.enums import SecurityDomain
12
12
 
13
13
 
14
14
  class BaselineTags(BaseModel):
15
+ model_config = ConfigDict(extra="forbid")
15
16
  analytic_story: list[Story] = Field(...)
16
17
  #deployment: Deployment = Field('SET_IN_GET_DEPLOYMENT_FUNCTION')
17
18
  # TODO (#223): can we remove str from the possible types here?
18
19
  detections: List[Union[Detection,str]] = Field(...)
19
20
  product: List[SecurityContentProductName] = Field(...,min_length=1)
20
- required_fields: List[str] = Field(...,min_length=1)
21
21
  security_domain: SecurityDomain = Field(...)
22
22
 
23
23
 
@@ -33,7 +33,6 @@ class BaselineTags(BaseModel):
33
33
  "analytic_story": [story.name for story in self.analytic_story],
34
34
  "detections": [detection.name for detection in self.detections if isinstance(detection,Detection)],
35
35
  "product": self.product,
36
- "required_fields":self.required_fields,
37
36
  "security_domain":self.security_domain,
38
37
  "deployments": None
39
38
  }
@@ -33,9 +33,9 @@ COMMON_INFORMATION_MODEL_UID = 1621
33
33
  SPLUNKBASE_URL = "https://splunkbase.splunk.com/app/{uid}/release/{version}/download"
34
34
 
35
35
 
36
- # TODO (#266): disable the use_enum_values configuration
37
36
  class App_Base(BaseModel,ABC):
38
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
37
+
38
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True, extra='forbid')
39
39
  uid: Optional[int] = Field(default=None)
40
40
  title: str = Field(description="Human-readable name used by the app. This can have special characters.")
41
41
  appid: Optional[APPID_TYPE]= Field(default=None,description="Internal name used by your app. "
@@ -59,9 +59,8 @@ class App_Base(BaseModel,ABC):
59
59
  config.getLocalAppDir().mkdir(parents=True)
60
60
 
61
61
 
62
- # TODO (#266): disable the use_enum_values configuration
63
62
  class TestApp(App_Base):
64
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
63
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
65
64
  hardcoded_path: Optional[Union[FilePath,HttpUrl]] = Field(default=None, description="This may be a relative or absolute link to a file OR an HTTP URL linking to your app.")
66
65
 
67
66
 
@@ -99,9 +98,8 @@ class TestApp(App_Base):
99
98
  return str(destination)
100
99
 
101
100
 
102
- # TODO (#266): disable the use_enum_values configuration
103
101
  class CustomApp(App_Base):
104
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
102
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
105
103
  # Fields required for app.conf based on
106
104
  # https://docs.splunk.com/Documentation/Splunk/9.0.4/Admin/Appconf
107
105
  uid: int = Field(ge=2, lt=100000, default_factory=lambda:random.randint(20000,100000))
@@ -159,9 +157,8 @@ class CustomApp(App_Base):
159
157
  verbose_print=True)
160
158
  return str(destination)
161
159
 
162
- # TODO (#266): disable the use_enum_values configuration
163
160
  class Config_Base(BaseModel):
164
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
161
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
165
162
 
166
163
  path: DirectoryPath = Field(default=DirectoryPath("."), description="The root of your app.")
167
164
  app:CustomApp = Field(default_factory=CustomApp)
@@ -175,7 +172,7 @@ class Config_Base(BaseModel):
175
172
  return str(path)
176
173
 
177
174
  class init(Config_Base):
178
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
175
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
179
176
  bare: bool = Field(default=False, description="contentctl normally provides some some example content "
180
177
  "(macros, stories, data_sources, and/or analytic stories). This option disables "
181
178
  "initialization with that additional contnet. Note that even if --bare is used, it "
@@ -184,9 +181,8 @@ class init(Config_Base):
184
181
  "the deployment/ directory (since it is not yet easily customizable).")
185
182
 
186
183
 
187
- # TODO (#266): disable the use_enum_values configuration
188
184
  class validate(Config_Base):
189
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
185
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
190
186
  enrichments: bool = Field(default=False, description="Enable MITRE, APP, and CVE Enrichments. "\
191
187
  "This is useful when outputting a release build "\
192
188
  "and validating these values, but should otherwise "\
@@ -241,9 +237,8 @@ class report(validate):
241
237
  return self.path/"reporting/"
242
238
 
243
239
 
244
- # TODO (#266): disable the use_enum_values configuration
245
240
  class build(validate):
246
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
241
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
247
242
  build_path: DirectoryPath = Field(default=DirectoryPath("dist/"), title="Target path for all build outputs")
248
243
 
249
244
  @field_serializer('build_path',when_used='always')
@@ -395,17 +390,15 @@ class new(Config_Base):
395
390
  type: NewContentType = Field(default=NewContentType.detection, description="Specify the type of content you would like to create.")
396
391
 
397
392
 
398
- # TODO (#266): disable the use_enum_values configuration
399
393
  class deploy_acs(inspect):
400
- model_config = ConfigDict(use_enum_values=True,validate_default=False, arbitrary_types_allowed=True)
394
+ model_config = ConfigDict(validate_default=False, arbitrary_types_allowed=True)
401
395
  #ignore linter error
402
396
  splunk_cloud_jwt_token: str = Field(exclude=True, description="Splunk JWT used for performing ACS operations on a Splunk Cloud Instance")
403
397
  splunk_cloud_stack: str = Field(description="The name of your Splunk Cloud Stack")
404
398
 
405
399
 
406
- # TODO (#266): disable the use_enum_values configuration
407
400
  class Infrastructure(BaseModel):
408
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
401
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
409
402
  splunk_app_username:str = Field(default="admin", description="Username for logging in to your Splunk Server")
410
403
  splunk_app_password:str = Field(exclude=True, default="password", description="Password for logging in to your Splunk Server.")
411
404
  instance_address:str = Field(..., description="Address of your splunk server.")
@@ -415,15 +408,13 @@ class Infrastructure(BaseModel):
415
408
  instance_name: str = Field(...)
416
409
 
417
410
 
418
- # TODO (#266): disable the use_enum_values configuration
419
411
  class Container(Infrastructure):
420
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
412
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
421
413
  instance_address:str = Field(default="localhost", description="Address of your splunk server.")
422
414
 
423
415
 
424
- # TODO (#266): disable the use_enum_values configuration
425
416
  class ContainerSettings(BaseModel):
426
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
417
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
427
418
  leave_running: bool = Field(default=True, description="Leave container running after it is first "
428
419
  "set up to speed up subsequent test runs.")
429
420
  num_containers: PositiveInt = Field(default=1, description="Number of containers to start in parallel. "
@@ -444,18 +435,19 @@ class ContainerSettings(BaseModel):
444
435
 
445
436
  class All(BaseModel):
446
437
  #Doesn't need any extra logic
438
+ mode_name:str = "All"
447
439
  pass
448
440
 
449
441
 
450
- # TODO (#266): disable the use_enum_values configuration
451
442
  class Changes(BaseModel):
452
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
443
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
444
+ mode_name: str = "Changes"
453
445
  target_branch:str = Field(...,description="The target branch to diff against. Note that this includes uncommitted changes in the working directory as well.")
454
446
 
455
447
 
456
- # TODO (#266): disable the use_enum_values configuration
457
448
  class Selected(BaseModel):
458
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
449
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
450
+ mode_name:str = "Selected"
459
451
  files:List[FilePath] = Field(...,description="List of detection files to test, separated by spaces.")
460
452
 
461
453
  @field_serializer('files',when_used='always')
@@ -684,12 +676,12 @@ DEFAULT_APPS:List[TestApp] = [
684
676
  class test_common(build):
685
677
  mode:Union[Changes, Selected, All] = Field(All(), union_mode='left_to_right')
686
678
  post_test_behavior: PostTestBehavior = Field(default=PostTestBehavior.pause_on_failure, description="Controls what to do when a test completes.\n\n"
687
- f"'{PostTestBehavior.always_pause.value}' - the state of "
679
+ f"'{PostTestBehavior.always_pause}' - the state of "
688
680
  "the test will always pause after a test, allowing the user to log into the "
689
681
  "server and experiment with the search and data before it is removed.\n\n"
690
- f"'{PostTestBehavior.pause_on_failure.value}' - pause execution ONLY when a test fails. The user may press ENTER in the terminal "
682
+ f"'{PostTestBehavior.pause_on_failure}' - pause execution ONLY when a test fails. The user may press ENTER in the terminal "
691
683
  "running the test to move on to the next test.\n\n"
692
- f"'{PostTestBehavior.never_pause.value}' - never stop testing, even if a test fails.\n\n"
684
+ f"'{PostTestBehavior.never_pause}' - never stop testing, even if a test fails.\n\n"
693
685
  "***SPECIAL NOTE FOR CI/CD*** 'never_pause' MUST be used for a test to "
694
686
  "run in an unattended manner or in a CI/CD system - otherwise a single failed test "
695
687
  "will result in the testing never finishing as the tool waits for input.")
@@ -706,7 +698,7 @@ class test_common(build):
706
698
  " interactive command line workflow that can display progress bars and status information frequently. "
707
699
  "Unfortunately it is incompatible with, or may cause poorly formatted logs, in many CI/CD systems or other unattended environments. "
708
700
  "If you are running contentctl in CI/CD, then please set this argument to True. Note that if you are running in a CI/CD context, "
709
- f"you also MUST set post_test_behavior to {PostTestBehavior.never_pause.value}. Otherwiser, a failed detection will cause"
701
+ f"you also MUST set post_test_behavior to {PostTestBehavior.never_pause}. Otherwiser, a failed detection will cause"
710
702
  "the CI/CD running to pause indefinitely.")
711
703
 
712
704
  apps: List[TestApp] = Field(default=DEFAULT_APPS, exclude=False, description="List of apps to install in test environment")
@@ -715,7 +707,7 @@ class test_common(build):
715
707
  def dumpCICDPlanAndQuit(self, githash: str, detections:List[Detection]):
716
708
  output_file = self.path / "test_plan.yml"
717
709
  self.mode = Selected(files=sorted([detection.file_path for detection in detections], key=lambda path: str(path)))
718
- self.post_test_behavior = PostTestBehavior.never_pause.value
710
+ self.post_test_behavior = PostTestBehavior.never_pause
719
711
  #required so that CI/CD does not get too much output or hang
720
712
  self.disable_tqdm = True
721
713
 
@@ -782,12 +774,12 @@ class test_common(build):
782
774
  def suppressTQDM(self)->Self:
783
775
  if self.disable_tqdm:
784
776
  tqdm.tqdm.__init__ = partialmethod(tqdm.tqdm.__init__, disable=True)
785
- if self.post_test_behavior != PostTestBehavior.never_pause.value:
777
+ if self.post_test_behavior != PostTestBehavior.never_pause:
786
778
  raise ValueError(f"You have disabled tqdm, presumably because you are "
787
779
  f"running in CI/CD or another unattended context.\n"
788
780
  f"However, post_test_behavior is set to [{self.post_test_behavior}].\n"
789
781
  f"If that is the case, then you MUST set post_test_behavior "
790
- f"to [{PostTestBehavior.never_pause.value}].\n"
782
+ f"to [{PostTestBehavior.never_pause}].\n"
791
783
  "Otherwise, if a detection fails in CI/CD, your CI/CD runner will hang forever.")
792
784
  return self
793
785
 
@@ -817,18 +809,8 @@ class test_common(build):
817
809
  return self
818
810
 
819
811
 
820
- def getModeName(self)->str:
821
- if isinstance(self.mode, All):
822
- return DetectionTestingMode.all.value
823
- elif isinstance(self.mode, Changes):
824
- return DetectionTestingMode.changes.value
825
- else:
826
- return DetectionTestingMode.selected.value
827
-
828
-
829
- # TODO (#266): disable the use_enum_values configuration
830
812
  class test(test_common):
831
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
813
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
832
814
  container_settings:ContainerSettings = ContainerSettings()
833
815
  test_instances: List[Container] = Field([], exclude = True, validate_default=True)
834
816
  splunk_api_username: Optional[str] = Field(default=None, exclude = True,description="Splunk API username used for running appinspect or installating apps from Splunkbase")
@@ -893,9 +875,8 @@ class test(test_common):
893
875
  TEST_ARGS_ENV = "CONTENTCTL_TEST_INFRASTRUCTURES"
894
876
 
895
877
 
896
- # TODO (#266): disable the use_enum_values configuration
897
878
  class test_servers(test_common):
898
- model_config = ConfigDict(use_enum_values=True,validate_default=True, arbitrary_types_allowed=True)
879
+ model_config = ConfigDict(validate_default=True, arbitrary_types_allowed=True)
899
880
  test_instances:List[Infrastructure] = Field([],description="Test against one or more preconfigured servers.", validate_default=True)
900
881
  server_info:Optional[str] = Field(None, validate_default=True, description='String of pre-configured servers to use for testing. The list MUST be in the format:\n'
901
882
  'address,username,web_ui_port,hec_port,api_port;address_2,username_2,web_ui_port_2,hec_port_2,api_port_2'
@@ -79,6 +79,7 @@ SES_KILL_CHAIN_MAPPINGS = {
79
79
  "Actions on Objectives": 7
80
80
  }
81
81
 
82
+ # TODO (cmcginley): @ljstella should this be removed? also referenced in new_content.py
82
83
  SES_OBSERVABLE_ROLE_MAPPING = {
83
84
  "Other": -1,
84
85
  "Unknown": 0,
@@ -93,6 +94,7 @@ SES_OBSERVABLE_ROLE_MAPPING = {
93
94
  "Observer": 9
94
95
  }
95
96
 
97
+ # TODO (cmcginley): @ljstella should this be removed? also referenced in new_content.py
96
98
  SES_OBSERVABLE_TYPE_MAPPING = {
97
99
  "Unknown": 0,
98
100
  "Hostname": 1,
@@ -135,6 +137,7 @@ SES_ATTACK_TACTICS_ID_MAPPING = {
135
137
  "Impact": "TA0040"
136
138
  }
137
139
 
140
+ # TODO (cmcginley): is this just for the transition testing?
138
141
  RBA_OBSERVABLE_ROLE_MAPPING = {
139
142
  "Attacker": 0,
140
143
  "Victim": 1
@@ -149,7 +152,7 @@ DOWNLOADS_DIRECTORY = "downloads"
149
152
  # errors, if its name is longer than 99 characters.
150
153
  # When an saved search is cloned in Enterprise Security User Interface,
151
154
  # it is wrapped in the following:
152
- # {Detection.tags.security_domain.value} - {SEARCH_STANZA_NAME} - Rule
155
+ # {Detection.tags.security_domain} - {SEARCH_STANZA_NAME} - Rule
153
156
  # Similarly, when we generate the search stanza name in contentctl, it
154
157
  # is app.label - detection.name - Rule
155
158
  # However, in product the search name is: