contentctl 5.5.6__py3-none-any.whl → 5.5.8__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 (65) hide show
  1. contentctl/actions/deploy_acs.py +5 -3
  2. contentctl/actions/detection_testing/DetectionTestingManager.py +3 -3
  3. contentctl/actions/detection_testing/GitService.py +4 -4
  4. contentctl/actions/detection_testing/generate_detection_coverage_badge.py +3 -3
  5. contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructure.py +15 -17
  6. contentctl/actions/detection_testing/infrastructures/DetectionTestingInfrastructureContainer.py +9 -8
  7. contentctl/actions/detection_testing/progress_bar.py +2 -1
  8. contentctl/actions/detection_testing/views/DetectionTestingViewCLI.py +4 -3
  9. contentctl/actions/detection_testing/views/DetectionTestingViewFile.py +4 -2
  10. contentctl/actions/detection_testing/views/DetectionTestingViewWeb.py +7 -7
  11. contentctl/actions/doc_gen.py +1 -2
  12. contentctl/actions/release_notes.py +2 -2
  13. contentctl/actions/reporting.py +3 -3
  14. contentctl/actions/test.py +2 -3
  15. contentctl/actions/validate.py +1 -1
  16. contentctl/api.py +7 -6
  17. contentctl/contentctl.py +1 -1
  18. contentctl/enrichments/attack_enrichment.py +1 -1
  19. contentctl/enrichments/cve_enrichment.py +9 -6
  20. contentctl/enrichments/splunk_app_enrichment.py +5 -4
  21. contentctl/helper/link_validator.py +7 -7
  22. contentctl/helper/splunk_app.py +6 -6
  23. contentctl/helper/utils.py +8 -8
  24. contentctl/input/director.py +3 -2
  25. contentctl/input/new_content_questions.py +1 -0
  26. contentctl/input/yml_reader.py +2 -2
  27. contentctl/objects/abstract_security_content_objects/detection_abstract.py +1 -1
  28. contentctl/objects/alert_action.py +4 -2
  29. contentctl/objects/atomic.py +8 -5
  30. contentctl/objects/base_test.py +1 -1
  31. contentctl/objects/base_test_result.py +2 -2
  32. contentctl/objects/baseline_tags.py +7 -6
  33. contentctl/objects/config.py +5 -5
  34. contentctl/objects/correlation_search.py +156 -139
  35. contentctl/objects/dashboard.py +1 -1
  36. contentctl/objects/deployment_email.py +1 -0
  37. contentctl/objects/deployment_notable.py +3 -1
  38. contentctl/objects/deployment_phantom.py +1 -0
  39. contentctl/objects/deployment_rba.py +1 -0
  40. contentctl/objects/deployment_scheduling.py +1 -0
  41. contentctl/objects/deployment_slack.py +1 -0
  42. contentctl/objects/detection_stanza.py +1 -1
  43. contentctl/objects/integration_test.py +2 -2
  44. contentctl/objects/investigation_tags.py +6 -3
  45. contentctl/objects/manual_test.py +2 -2
  46. contentctl/objects/playbook_tags.py +247 -10
  47. contentctl/objects/risk_analysis_action.py +1 -1
  48. contentctl/objects/savedsearches_conf.py +3 -3
  49. contentctl/objects/story_tags.py +1 -1
  50. contentctl/objects/test_group.py +2 -2
  51. contentctl/objects/throttling.py +2 -1
  52. contentctl/objects/unit_test.py +2 -2
  53. contentctl/objects/unit_test_baseline.py +2 -1
  54. contentctl/objects/unit_test_result.py +4 -2
  55. contentctl/output/conf_output.py +2 -2
  56. contentctl/output/conf_writer.py +5 -5
  57. contentctl/output/doc_md_output.py +0 -1
  58. contentctl/output/jinja_writer.py +1 -0
  59. contentctl/output/json_writer.py +1 -1
  60. contentctl/output/yml_writer.py +3 -2
  61. {contentctl-5.5.6.dist-info → contentctl-5.5.8.dist-info}/METADATA +3 -3
  62. {contentctl-5.5.6.dist-info → contentctl-5.5.8.dist-info}/RECORD +65 -65
  63. {contentctl-5.5.6.dist-info → contentctl-5.5.8.dist-info}/LICENSE.md +0 -0
  64. {contentctl-5.5.6.dist-info → contentctl-5.5.8.dist-info}/WHEEL +0 -0
  65. {contentctl-5.5.6.dist-info → contentctl-5.5.8.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,10 @@
1
1
  from __future__ import annotations
2
- from typing import Optional, List
3
- from pydantic import BaseModel, Field, ConfigDict
2
+
4
3
  import enum
4
+ from typing import List, Optional
5
+
6
+ from pydantic import BaseModel, ConfigDict, Field
7
+
5
8
  from contentctl.objects.detection import Detection
6
9
 
7
10
 
@@ -10,9 +13,13 @@ class PlaybookProduct(str, enum.Enum):
10
13
 
11
14
 
12
15
  class PlaybookUseCase(str, enum.Enum):
13
- PHISHING = "Phishing"
16
+ COLLECTION = "Collection"
14
17
  ENDPOINT = "Endpoint"
15
18
  ENRICHMENT = "Enrichment"
19
+ MALWARE = "Malware"
20
+ PHISHING = "Phishing"
21
+ RESPONSE = "Response"
22
+ UTILITY = "Utility"
16
23
 
17
24
 
18
25
  class PlaybookType(str, enum.Enum):
@@ -26,20 +33,250 @@ class VpeType(str, enum.Enum):
26
33
 
27
34
 
28
35
  class DefendTechnique(str, enum.Enum):
36
+ D3_AA = "D3-AA"
37
+ D3_ABPI = "D3-ABPI"
38
+ D3_ACA = "D3-ACA"
39
+ D3_ACH = "D3-ACH"
40
+ D3_AH = "D3-AH"
41
+ D3_AI = "D3-AI"
29
42
  D3_AL = "D3-AL"
30
- D3_DNSDL = "D3-DNSDL"
43
+ D3_ALLM = "D3-ALLM"
44
+ D3_AM = "D3-AM"
45
+ D3_AMED = "D3-AMED"
46
+ D3_ANAA = "D3-ANAA"
47
+ D3_ANCI = "D3-ANCI"
48
+ D3_ANET = "D3-ANET"
49
+ D3_APA = "D3-APA"
50
+ D3_APLM = "D3-APLM"
51
+ D3_AVE = "D3-AVE"
52
+ D3_AZET = "D3-AZET"
53
+ D3_BA = "D3-BA"
54
+ D3_BAN = "D3-BAN"
55
+ D3_BDI = "D3-BDI"
56
+ D3_BSE = "D3-BSE"
57
+ D3_CA = "D3-CA"
58
+ D3_CAA = "D3-CAA"
59
+ D3_CBAN = "D3-CBAN"
60
+ D3_CCSA = "D3-CCSA"
61
+ D3_CE = "D3-CE"
62
+ D3_CERO = "D3-CERO"
63
+ D3_CF = "D3-CF"
64
+ D3_CFC = "D3-CFC"
65
+ D3_CH = "D3-CH"
66
+ D3_CHN = "D3-CHN"
67
+ D3_CI = "D3-CI"
68
+ D3_CIA = "D3-CIA"
69
+ D3_CM = "D3-CM"
70
+ D3_CNE = "D3-CNE"
71
+ D3_CNR = "D3-CNR"
72
+ D3_CNS = "D3-CNS"
73
+ D3_CP = "D3-CP"
74
+ D3_CQ = "D3-CQ"
75
+ D3_CR = "D3-CR"
76
+ D3_CRO = "D3-CRO"
77
+ D3_CS = "D3-CS"
78
+ D3_CSPP = "D3-CSPP"
79
+ D3_CTS = "D3-CTS"
80
+ D3_CV = "D3-CV"
31
81
  D3_DA = "D3-DA"
82
+ D3_DAM = "D3-DAM"
83
+ D3_DCE = "D3-DCE"
84
+ D3_DE = "D3-DE"
85
+ D3_DEM = "D3-DEM"
86
+ D3_DENCR = "D3-DENCR"
87
+ D3_DF = "D3-DF"
88
+ D3_DI = "D3-DI"
89
+ D3_DKE = "D3-DKE"
90
+ D3_DKF = "D3-DKF"
91
+ D3_DKP = "D3-DKP"
92
+ D3_DLIC = "D3-DLIC"
93
+ D3_DNR = "D3-DNR"
94
+ D3_DNRA = "D3-DNRA"
95
+ D3_DNSAL = "D3-DNSAL"
96
+ D3_DNSCE = "D3-DNSCE"
97
+ D3_DNSDL = "D3-DNSDL"
98
+ D3_DNSTA = "D3-DNSTA"
99
+ D3_DO = "D3-DO"
100
+ D3_DP = "D3-DP"
101
+ D3_DPLM = "D3-DPLM"
102
+ D3_DPR = "D3-DPR"
103
+ D3_DQSA = "D3-DQSA"
104
+ D3_DRT = "D3-DRT"
105
+ D3_DST = "D3-DST"
106
+ D3_DTP = "D3-DTP"
107
+ D3_DUC = "D3-DUC"
108
+ D3_EAL = "D3-EAL"
109
+ D3_EBWSAM = "D3-EBWSAM"
110
+ D3_EDL = "D3-EDL"
111
+ D3_EF = "D3-EF"
112
+ D3_EFA = "D3-EFA"
113
+ D3_EHB = "D3-EHB"
114
+ D3_EHPV = "D3-EHPV"
115
+ D3_EI = "D3-EI"
116
+ D3_ER = "D3-ER"
117
+ D3_ET = "D3-ET"
118
+ D3_FA = "D3-FA"
119
+ D3_FAPA = "D3-FAPA"
120
+ D3_FBA = "D3-FBA"
121
+ D3_FC = "D3-FC"
122
+ D3_FCA = "D3-FCA"
123
+ D3_FCDC = "D3-FCDC"
124
+ D3_FCOA = "D3-FCOA"
125
+ D3_FCR = "D3-FCR"
126
+ D3_FE = "D3-FE"
127
+ D3_FEMC = "D3-FEMC"
128
+ D3_FEV = "D3-FEV"
129
+ D3_FFV = "D3-FFV"
130
+ D3_FH = "D3-FH"
131
+ D3_FHRA = "D3-FHRA"
132
+ D3_FIM = "D3-FIM"
133
+ D3_FISV = "D3-FISV"
134
+ D3_FMBV = "D3-FMBV"
135
+ D3_FMCV = "D3-FMCV"
136
+ D3_FMVV = "D3-FMVV"
137
+ D3_FRDDL = "D3-FRDDL"
138
+ D3_FRIDL = "D3-FRIDL"
139
+ D3_FV = "D3-FV"
140
+ D3_HBPI = "D3-HBPI"
141
+ D3_HCI = "D3-HCI"
142
+ D3_HD = "D3-HD"
143
+ D3_HDDL = "D3-HDDL"
144
+ D3_HDL = "D3-HDL"
145
+ D3_HR = "D3-HR"
146
+ D3_HS = "D3-HS"
32
147
  D3_IAA = "D3-IAA"
148
+ D3_IBCA = "D3-IBCA"
149
+ D3_ID = "D3-ID"
150
+ D3_IDA = "D3-IDA"
151
+ D3_IHN = "D3-IHN"
152
+ D3_IOPR = "D3-IOPR"
153
+ D3_IPCTA = "D3-IPCTA"
154
+ D3_IPRA = "D3-IPRA"
33
155
  D3_IRA = "D3-IRA"
156
+ D3_IRV = "D3-IRV"
157
+ D3_ISVA = "D3-ISVA"
158
+ D3_ITF = "D3-ITF"
159
+ D3_JFAPA = "D3-JFAPA"
160
+ D3_KBPI = "D3-KBPI"
161
+ D3_LAM = "D3-LAM"
162
+ D3_LAMED = "D3-LAMED"
163
+ D3_LFAM = "D3-LFAM"
164
+ D3_LFP = "D3-LFP"
165
+ D3_LLM = "D3-LLM"
166
+ D3_MA = "D3-MA"
167
+ D3_MAN = "D3-MAN"
168
+ D3_MBSV = "D3-MBSV"
169
+ D3_MBT = "D3-MBT"
170
+ D3_MENCR = "D3-MENCR"
171
+ D3_MFA = "D3-MFA"
172
+ D3_MH = "D3-MH"
173
+ D3_NAM = "D3-NAM"
174
+ D3_NI = "D3-NI"
175
+ D3_NM = "D3-NM"
176
+ D3_NNI = "D3-NNI"
177
+ D3_NPC = "D3-NPC"
178
+ D3_NRAM = "D3-NRAM"
179
+ D3_NTA = "D3-NTA"
180
+ D3_NTCD = "D3-NTCD"
181
+ D3_NTF = "D3-NTF"
182
+ D3_NTPM = "D3-NTPM"
183
+ D3_NTSA = "D3-NTSA"
184
+ D3_NVA = "D3-NVA"
185
+ D3_OAM = "D3-OAM"
186
+ D3_ODM = "D3-ODM"
187
+ D3_OE = "D3-OE"
188
+ D3_OM = "D3-OM"
189
+ D3_ORA = "D3-ORA"
190
+ D3_OSM = "D3-OSM"
34
191
  D3_OTF = "D3-OTF"
35
- D3_ER = "D3-ER"
192
+ D3_OTP = "D3-OTP"
193
+ D3_PA = "D3-PA"
194
+ D3_PAM = "D3-PAM"
195
+ D3_PAN = "D3-PAN"
196
+ D3_PBWSAM = "D3-PBWSAM"
197
+ D3_PCA = "D3-PCA"
198
+ D3_PCSV = "D3-PCSV"
199
+ D3_PE = "D3-PE"
200
+ D3_PFV = "D3-PFV"
201
+ D3_PH = "D3-PH"
202
+ D3_PHDURA = "D3-PHDURA"
203
+ D3_PLA = "D3-PLA"
204
+ D3_PLLM = "D3-PLLM"
205
+ D3_PLM = "D3-PLM"
206
+ D3_PM = "D3-PM"
207
+ D3_PMAD = "D3-PMAD"
208
+ D3_PR = "D3-PR"
209
+ D3_PS = "D3-PS"
210
+ D3_PSA = "D3-PSA"
211
+ D3_PSEP = "D3-PSEP"
212
+ D3_PSMD = "D3-PSMD"
213
+ D3_PT = "D3-PT"
214
+ D3_PV = "D3-PV"
215
+ D3_PWA = "D3-PWA"
216
+ D3_RA = "D3-RA"
217
+ D3_RAM = "D3-RAM"
218
+ D3_RAPA = "D3-RAPA"
219
+ D3_RC = "D3-RC"
220
+ D3_RD = "D3-RD"
221
+ D3_RDI = "D3-RDI"
36
222
  D3_RE = "D3-RE"
37
- D3_URA = "D3-URA"
38
- D3_DNRA = "D3-DNRA"
39
- D3_IPRA = "D3-IPRA"
40
- D3_FHRA = "D3-FHRA"
41
- D3_SRA = "D3-SRA"
223
+ D3_RF = "D3-RF"
224
+ D3_RFAM = "D3-RFAM"
225
+ D3_RFS = "D3-RFS"
226
+ D3_RIC = "D3-RIC"
227
+ D3_RKD = "D3-RKD"
228
+ D3_RN = "D3-RN"
229
+ D3_RNA = "D3-RNA"
230
+ D3_RO = "D3-RO"
231
+ D3_RPA = "D3-RPA"
232
+ D3_RRID = "D3-RRID"
233
+ D3_RS = "D3-RS"
234
+ D3_RTA = "D3-RTA"
235
+ D3_RTSD = "D3-RTSD"
42
236
  D3_RUAA = "D3-RUAA"
237
+ D3_SAOR = "D3-SAOR"
238
+ D3_SBV = "D3-SBV"
239
+ D3_SCA = "D3-SCA"
240
+ D3_SCF = "D3-SCF"
241
+ D3_SCH = "D3-SCH"
242
+ D3_SCP = "D3-SCP"
243
+ D3_SDA = "D3-SDA"
244
+ D3_SDM = "D3-SDM"
245
+ D3_SEA = "D3-SEA"
246
+ D3_SFA = "D3-SFA"
247
+ D3_SFCV = "D3-SFCV"
248
+ D3_SFV = "D3-SFV"
249
+ D3_SHN = "D3-SHN"
250
+ D3_SICA = "D3-SICA"
251
+ D3_SJA = "D3-SJA"
252
+ D3_SMRA = "D3-SMRA"
253
+ D3_SPP = "D3-SPP"
254
+ D3_SRA = "D3-SRA"
255
+ D3_SSC = "D3-SSC"
256
+ D3_ST = "D3-ST"
257
+ D3_SU = "D3-SU"
258
+ D3_SVCDM = "D3-SVCDM"
259
+ D3_SWI = "D3-SWI"
260
+ D3_SYSDM = "D3-SYSDM"
261
+ D3_SYSM = "D3-SYSM"
262
+ D3_SYSVA = "D3-SYSVA"
263
+ D3_TAAN = "D3-TAAN"
264
+ D3_TB = "D3-TB"
265
+ D3_TBA = "D3-TBA"
266
+ D3_TBI = "D3-TBI"
267
+ D3_TL = "D3-TL"
268
+ D3_UA = "D3-UA"
269
+ D3_UAP = "D3-UAP"
270
+ D3_UBA = "D3-UBA"
271
+ D3_UDTA = "D3-UDTA"
272
+ D3_UGLPA = "D3-UGLPA"
273
+ D3_ULA = "D3-ULA"
274
+ D3_URA = "D3-URA"
275
+ D3_USICA = "D3-USICA"
276
+ D3_VI = "D3-VI"
277
+ D3_VTV = "D3-VTV"
278
+ D3_WSAA = "D3-WSAA"
279
+ D3_WSAM = "D3-WSAM"
43
280
 
44
281
 
45
282
  class PlaybookTag(BaseModel):
@@ -1,5 +1,5 @@
1
- from typing import Any
2
1
  import json
2
+ from typing import Any
3
3
 
4
4
  from pydantic import BaseModel, field_validator
5
5
 
@@ -1,8 +1,8 @@
1
- from pathlib import Path
2
- from typing import Any, ClassVar
3
1
  import re
4
- import tempfile
5
2
  import tarfile
3
+ import tempfile
4
+ from pathlib import Path
5
+ from typing import Any, ClassVar
6
6
 
7
7
  from pydantic import BaseModel, Field, PrivateAttr
8
8
 
@@ -45,7 +45,7 @@ class StoryTags(BaseModel):
45
45
  def getCategory_conf(self) -> str:
46
46
  # if len(self.category) > 1:
47
47
  # print("Story with more than 1 category. We can only have 1 category, fix it!")
48
- return list(self.category)[0]
48
+ return next(iter(self.category))
49
49
 
50
50
  @model_serializer
51
51
  def serialize_model(self):
@@ -1,9 +1,9 @@
1
1
  from pydantic import BaseModel
2
2
 
3
- from contentctl.objects.unit_test import UnitTest
3
+ from contentctl.objects.base_test_result import TestResultStatus
4
4
  from contentctl.objects.integration_test import IntegrationTest
5
5
  from contentctl.objects.test_attack_data import TestAttackData
6
- from contentctl.objects.base_test_result import TestResultStatus
6
+ from contentctl.objects.unit_test import UnitTest
7
7
 
8
8
 
9
9
  class TestGroup(BaseModel):
@@ -1,6 +1,7 @@
1
- from pydantic import BaseModel, Field, field_validator
2
1
  from typing import Annotated
3
2
 
3
+ from pydantic import BaseModel, Field, field_validator
4
+
4
5
 
5
6
  # Alert Suppression/Throttling settings have been taken from
6
7
  # https://docs.splunk.com/Documentation/Splunk/9.2.2/Admin/Savedsearchesconf
@@ -2,10 +2,10 @@ from __future__ import annotations
2
2
 
3
3
  from pydantic import Field
4
4
 
5
- from contentctl.objects.test_attack_data import TestAttackData
6
- from contentctl.objects.unit_test_result import UnitTestResult
7
5
  from contentctl.objects.base_test import BaseTest, TestType
8
6
  from contentctl.objects.base_test_result import TestResultStatus
7
+ from contentctl.objects.test_attack_data import TestAttackData
8
+ from contentctl.objects.unit_test_result import UnitTestResult
9
9
 
10
10
 
11
11
  class UnitTest(BaseTest):
@@ -1,6 +1,7 @@
1
- from pydantic import BaseModel, ConfigDict
2
1
  from typing import Union
3
2
 
3
+ from pydantic import BaseModel, ConfigDict
4
+
4
5
 
5
6
  class UnitTestBaseline(BaseModel):
6
7
  model_config = ConfigDict(extra="forbid")
@@ -1,7 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Union, TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Union
4
+
4
5
  from splunklib.data import Record
6
+
5
7
  from contentctl.objects.base_test_result import BaseTestResult, TestResultStatus
6
8
 
7
9
  if TYPE_CHECKING:
@@ -70,7 +72,7 @@ class UnitTestResult(BaseTestResult):
70
72
  elif content is None:
71
73
  self.status = TestResultStatus.ERROR
72
74
  if self.exception is not None:
73
- self.message = f"EXCEPTION: {str(self.exception)}"
75
+ self.message = f"EXCEPTION: {self.exception!s}"
74
76
  else:
75
77
  self.message = "ERROR with no more specific message available."
76
78
  self.sid_link = NO_SID
@@ -270,7 +270,7 @@ class ConfOutput:
270
270
  output_dir=pathlib.Path(self.config.getBuildDir()),
271
271
  )
272
272
  except SystemExit as e:
273
- raise Exception(f"Error building package with slim: {str(e)}")
273
+ raise Exception(f"Error building package with slim: {e!s}")
274
274
 
275
275
  except Exception as e:
276
276
  print(
@@ -278,7 +278,7 @@ class ConfOutput:
278
278
  "Packaging app with tar instead. This should still work, but appinspect may catch "
279
279
  "errors that otherwise would have been flagged by slim."
280
280
  )
281
- raise Exception(f"slim (splunk packaging toolkit) not installed: {str(e)}")
281
+ raise Exception(f"slim (splunk packaging toolkit) not installed: {e!s}")
282
282
 
283
283
  def packageApp(self, method: Callable[[ConfOutput], None] = packageAppTar) -> None:
284
284
  return method(self)
@@ -339,7 +339,7 @@ class ConfWriter:
339
339
  f"Name:{obj.name if not isinstance(obj, CustomApp) else obj.title}\n"
340
340
  f"Type {type(obj)}: \n"
341
341
  f"Output File: {app_output_path}\n"
342
- f"Error: {str(e)}\n"
342
+ f"Error: {e!s}\n"
343
343
  )
344
344
 
345
345
  output_path.parent.mkdir(parents=True, exist_ok=True)
@@ -376,7 +376,7 @@ class ConfWriter:
376
376
  try:
377
377
  _ = configparser.RawConfigParser().read(path)
378
378
  except Exception as e:
379
- raise Exception(f"Failed to validate .conf file {str(path)}: {str(e)}")
379
+ raise Exception(f"Failed to validate .conf file {path!s}: {e!s}")
380
380
 
381
381
  @staticmethod
382
382
  def validateXmlFile(path: pathlib.Path):
@@ -390,7 +390,7 @@ class ConfWriter:
390
390
  with open(path, "r") as xmlFile:
391
391
  _ = ET.fromstring(xmlFile.read())
392
392
  except Exception as e:
393
- raise Exception(f"Failed to validate .xml file {str(path)}: {str(e)}")
393
+ raise Exception(f"Failed to validate .xml file {path!s}: {e!s}")
394
394
 
395
395
  @staticmethod
396
396
  def validateManifestFile(path: pathlib.Path):
@@ -405,9 +405,9 @@ class ConfWriter:
405
405
  _ = json.load(manifestFile)
406
406
  except Exception as e:
407
407
  raise Exception(
408
- f"Failed to validate .manifest file {str(path)} (Note that .manifest files should contain only valid JSON-formatted data): {str(e)}"
408
+ f"Failed to validate .manifest file {path!s} (Note that .manifest files should contain only valid JSON-formatted data): {e!s}"
409
409
  )
410
410
  except Exception as e:
411
411
  raise Exception(
412
- f"Failed to validate .manifest file {str(path)} (Note that .manifest files should contain only valid JSON-formatted data): {str(e)}"
412
+ f"Failed to validate .manifest file {path!s} (Note that .manifest files should contain only valid JSON-formatted data): {e!s}"
413
413
  )
@@ -1,6 +1,5 @@
1
1
  import os
2
2
  import sys
3
-
4
3
  from pathlib import Path
5
4
 
6
5
  from contentctl.output.jinja_writer import JinjaWriter
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  from typing import Any
3
+
3
4
  from jinja2 import Environment, FileSystemLoader
4
5
 
5
6
 
@@ -27,5 +27,5 @@ class JsonWriter:
27
27
 
28
28
  except Exception as e:
29
29
  raise Exception(
30
- f"Error serializing object to Json File '{file_path}': {str(e)}"
30
+ f"Error serializing object to Json File '{file_path}': {e!s}"
31
31
  )
@@ -1,6 +1,7 @@
1
- import yaml
1
+ from enum import IntEnum, StrEnum
2
2
  from typing import Any
3
- from enum import StrEnum, IntEnum
3
+
4
+ import yaml
4
5
 
5
6
  # Set the following so that we can write StrEnum and IntEnum
6
7
  # to files. Otherwise, we will get the following errors when trying
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: contentctl
3
- Version: 5.5.6
3
+ Version: 5.5.8
4
4
  Summary: Splunk Content Control Tool
5
5
  License: Apache 2.0
6
6
  Author: STRT
@@ -21,10 +21,10 @@ Requires-Dist: pycvesearch (>=1.2,<2.0)
21
21
  Requires-Dist: pydantic (>=2.9.2,<2.10.0)
22
22
  Requires-Dist: pygit2 (>=1.15.1,<2.0.0)
23
23
  Requires-Dist: questionary (>=2.0.1,<3.0.0)
24
- Requires-Dist: requests (>=2.32.3,<2.33.0)
24
+ Requires-Dist: requests (>=2.32.4)
25
25
  Requires-Dist: rich (>=14.0.0,<15.0.0)
26
26
  Requires-Dist: semantic-version (>=2.10.0,<3.0.0)
27
- Requires-Dist: setuptools (>=69.5.1,<81.0.0)
27
+ Requires-Dist: setuptools (>=80.9.0)
28
28
  Requires-Dist: splunk-sdk (>=2.0.2,<3.0.0)
29
29
  Requires-Dist: tqdm (>=4.66.5,<5.0.0)
30
30
  Requires-Dist: tyro (>=0.9.2,<0.9.23)