regscale-cli 6.16.0.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.

Potentially problematic release.


This version of regscale-cli might be problematic. Click here for more details.

Files changed (481) hide show
  1. regscale/__init__.py +1 -0
  2. regscale/airflow/__init__.py +9 -0
  3. regscale/airflow/azure/__init__.py +9 -0
  4. regscale/airflow/azure/cli.py +89 -0
  5. regscale/airflow/azure/upload_dags.py +116 -0
  6. regscale/airflow/click_dags.py +127 -0
  7. regscale/airflow/click_mixins.py +82 -0
  8. regscale/airflow/config.py +25 -0
  9. regscale/airflow/factories/__init__.py +0 -0
  10. regscale/airflow/factories/connections.py +58 -0
  11. regscale/airflow/factories/workflows.py +78 -0
  12. regscale/airflow/hierarchy.py +88 -0
  13. regscale/airflow/operators/__init__.py +0 -0
  14. regscale/airflow/operators/click.py +36 -0
  15. regscale/airflow/sensors/__init__.py +0 -0
  16. regscale/airflow/sensors/sql.py +107 -0
  17. regscale/airflow/sessions/__init__.py +0 -0
  18. regscale/airflow/sessions/sql/__init__.py +3 -0
  19. regscale/airflow/sessions/sql/queries.py +64 -0
  20. regscale/airflow/sessions/sql/sql_server_queries.py +248 -0
  21. regscale/airflow/tasks/__init__.py +0 -0
  22. regscale/airflow/tasks/branches.py +22 -0
  23. regscale/airflow/tasks/cli.py +116 -0
  24. regscale/airflow/tasks/click.py +73 -0
  25. regscale/airflow/tasks/debugging.py +9 -0
  26. regscale/airflow/tasks/groups.py +116 -0
  27. regscale/airflow/tasks/init.py +60 -0
  28. regscale/airflow/tasks/states.py +47 -0
  29. regscale/airflow/tasks/workflows.py +36 -0
  30. regscale/ansible/__init__.py +9 -0
  31. regscale/core/__init__.py +0 -0
  32. regscale/core/app/__init__.py +3 -0
  33. regscale/core/app/api.py +571 -0
  34. regscale/core/app/application.py +665 -0
  35. regscale/core/app/internal/__init__.py +136 -0
  36. regscale/core/app/internal/admin_actions.py +230 -0
  37. regscale/core/app/internal/assessments_editor.py +873 -0
  38. regscale/core/app/internal/catalog.py +316 -0
  39. regscale/core/app/internal/comparison.py +459 -0
  40. regscale/core/app/internal/control_editor.py +571 -0
  41. regscale/core/app/internal/encrypt.py +79 -0
  42. regscale/core/app/internal/evidence.py +1240 -0
  43. regscale/core/app/internal/file_uploads.py +151 -0
  44. regscale/core/app/internal/healthcheck.py +66 -0
  45. regscale/core/app/internal/login.py +305 -0
  46. regscale/core/app/internal/migrations.py +240 -0
  47. regscale/core/app/internal/model_editor.py +1701 -0
  48. regscale/core/app/internal/poam_editor.py +632 -0
  49. regscale/core/app/internal/workflow.py +105 -0
  50. regscale/core/app/logz.py +74 -0
  51. regscale/core/app/utils/XMLIR.py +258 -0
  52. regscale/core/app/utils/__init__.py +0 -0
  53. regscale/core/app/utils/api_handler.py +358 -0
  54. regscale/core/app/utils/app_utils.py +1110 -0
  55. regscale/core/app/utils/catalog_utils/__init__.py +0 -0
  56. regscale/core/app/utils/catalog_utils/common.py +91 -0
  57. regscale/core/app/utils/catalog_utils/compare_catalog.py +193 -0
  58. regscale/core/app/utils/catalog_utils/diagnostic_catalog.py +97 -0
  59. regscale/core/app/utils/catalog_utils/download_catalog.py +103 -0
  60. regscale/core/app/utils/catalog_utils/update_catalog.py +718 -0
  61. regscale/core/app/utils/catalog_utils/update_catalog_v2.py +1378 -0
  62. regscale/core/app/utils/catalog_utils/update_catalog_v3.py +1272 -0
  63. regscale/core/app/utils/catalog_utils/update_plans.py +334 -0
  64. regscale/core/app/utils/file_utils.py +238 -0
  65. regscale/core/app/utils/parser_utils.py +81 -0
  66. regscale/core/app/utils/pickle_file_handler.py +57 -0
  67. regscale/core/app/utils/regscale_utils.py +319 -0
  68. regscale/core/app/utils/report_utils.py +119 -0
  69. regscale/core/app/utils/variables.py +226 -0
  70. regscale/core/decorators.py +31 -0
  71. regscale/core/lazy_group.py +65 -0
  72. regscale/core/login.py +63 -0
  73. regscale/core/server/__init__.py +0 -0
  74. regscale/core/server/flask_api.py +473 -0
  75. regscale/core/server/helpers.py +373 -0
  76. regscale/core/server/rest.py +64 -0
  77. regscale/core/server/static/css/bootstrap.css +6030 -0
  78. regscale/core/server/static/css/bootstrap.min.css +6 -0
  79. regscale/core/server/static/css/main.css +176 -0
  80. regscale/core/server/static/images/regscale-cli.svg +49 -0
  81. regscale/core/server/static/images/regscale.svg +38 -0
  82. regscale/core/server/templates/base.html +74 -0
  83. regscale/core/server/templates/index.html +43 -0
  84. regscale/core/server/templates/login.html +28 -0
  85. regscale/core/server/templates/make_base64.html +22 -0
  86. regscale/core/server/templates/upload_STIG.html +109 -0
  87. regscale/core/server/templates/upload_STIG_result.html +26 -0
  88. regscale/core/server/templates/upload_ssp.html +144 -0
  89. regscale/core/server/templates/upload_ssp_result.html +128 -0
  90. regscale/core/static/__init__.py +0 -0
  91. regscale/core/static/regex.py +14 -0
  92. regscale/core/utils/__init__.py +117 -0
  93. regscale/core/utils/click_utils.py +13 -0
  94. regscale/core/utils/date.py +238 -0
  95. regscale/core/utils/graphql.py +254 -0
  96. regscale/core/utils/urls.py +23 -0
  97. regscale/dev/__init__.py +6 -0
  98. regscale/dev/analysis.py +454 -0
  99. regscale/dev/cli.py +235 -0
  100. regscale/dev/code_gen.py +492 -0
  101. regscale/dev/dirs.py +69 -0
  102. regscale/dev/docs.py +384 -0
  103. regscale/dev/monitoring.py +26 -0
  104. regscale/dev/profiling.py +216 -0
  105. regscale/exceptions/__init__.py +4 -0
  106. regscale/exceptions/license_exception.py +7 -0
  107. regscale/exceptions/validation_exception.py +9 -0
  108. regscale/integrations/__init__.py +1 -0
  109. regscale/integrations/commercial/__init__.py +486 -0
  110. regscale/integrations/commercial/ad.py +433 -0
  111. regscale/integrations/commercial/amazon/__init__.py +0 -0
  112. regscale/integrations/commercial/amazon/common.py +106 -0
  113. regscale/integrations/commercial/aqua/__init__.py +0 -0
  114. regscale/integrations/commercial/aqua/aqua.py +91 -0
  115. regscale/integrations/commercial/aws/__init__.py +6 -0
  116. regscale/integrations/commercial/aws/cli.py +322 -0
  117. regscale/integrations/commercial/aws/inventory/__init__.py +110 -0
  118. regscale/integrations/commercial/aws/inventory/base.py +64 -0
  119. regscale/integrations/commercial/aws/inventory/resources/__init__.py +19 -0
  120. regscale/integrations/commercial/aws/inventory/resources/compute.py +234 -0
  121. regscale/integrations/commercial/aws/inventory/resources/containers.py +113 -0
  122. regscale/integrations/commercial/aws/inventory/resources/database.py +101 -0
  123. regscale/integrations/commercial/aws/inventory/resources/integration.py +237 -0
  124. regscale/integrations/commercial/aws/inventory/resources/networking.py +253 -0
  125. regscale/integrations/commercial/aws/inventory/resources/security.py +240 -0
  126. regscale/integrations/commercial/aws/inventory/resources/storage.py +91 -0
  127. regscale/integrations/commercial/aws/scanner.py +823 -0
  128. regscale/integrations/commercial/azure/__init__.py +0 -0
  129. regscale/integrations/commercial/azure/common.py +32 -0
  130. regscale/integrations/commercial/azure/intune.py +488 -0
  131. regscale/integrations/commercial/azure/scanner.py +49 -0
  132. regscale/integrations/commercial/burp.py +78 -0
  133. regscale/integrations/commercial/cpe.py +144 -0
  134. regscale/integrations/commercial/crowdstrike.py +1117 -0
  135. regscale/integrations/commercial/defender.py +1511 -0
  136. regscale/integrations/commercial/dependabot.py +210 -0
  137. regscale/integrations/commercial/durosuite/__init__.py +0 -0
  138. regscale/integrations/commercial/durosuite/api.py +1546 -0
  139. regscale/integrations/commercial/durosuite/process_devices.py +101 -0
  140. regscale/integrations/commercial/durosuite/scanner.py +637 -0
  141. regscale/integrations/commercial/durosuite/variables.py +21 -0
  142. regscale/integrations/commercial/ecr.py +90 -0
  143. regscale/integrations/commercial/gcp/__init__.py +237 -0
  144. regscale/integrations/commercial/gcp/auth.py +96 -0
  145. regscale/integrations/commercial/gcp/control_tests.py +238 -0
  146. regscale/integrations/commercial/gcp/variables.py +18 -0
  147. regscale/integrations/commercial/gitlab.py +332 -0
  148. regscale/integrations/commercial/grype.py +165 -0
  149. regscale/integrations/commercial/ibm.py +90 -0
  150. regscale/integrations/commercial/import_all/__init__.py +0 -0
  151. regscale/integrations/commercial/import_all/import_all_cmd.py +467 -0
  152. regscale/integrations/commercial/import_all/scan_file_fingerprints.json +27 -0
  153. regscale/integrations/commercial/jira.py +1046 -0
  154. regscale/integrations/commercial/mappings/__init__.py +0 -0
  155. regscale/integrations/commercial/mappings/csf_controls.json +713 -0
  156. regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json +1516 -0
  157. regscale/integrations/commercial/nessus/__init__.py +0 -0
  158. regscale/integrations/commercial/nessus/nessus_utils.py +429 -0
  159. regscale/integrations/commercial/nessus/scanner.py +416 -0
  160. regscale/integrations/commercial/nexpose.py +90 -0
  161. regscale/integrations/commercial/okta.py +798 -0
  162. regscale/integrations/commercial/opentext/__init__.py +0 -0
  163. regscale/integrations/commercial/opentext/click.py +99 -0
  164. regscale/integrations/commercial/opentext/scanner.py +143 -0
  165. regscale/integrations/commercial/prisma.py +91 -0
  166. regscale/integrations/commercial/qualys.py +1462 -0
  167. regscale/integrations/commercial/salesforce.py +980 -0
  168. regscale/integrations/commercial/sap/__init__.py +0 -0
  169. regscale/integrations/commercial/sap/click.py +31 -0
  170. regscale/integrations/commercial/sap/sysdig/__init__.py +0 -0
  171. regscale/integrations/commercial/sap/sysdig/click.py +57 -0
  172. regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py +190 -0
  173. regscale/integrations/commercial/sap/tenable/__init__.py +0 -0
  174. regscale/integrations/commercial/sap/tenable/click.py +49 -0
  175. regscale/integrations/commercial/sap/tenable/scanner.py +196 -0
  176. regscale/integrations/commercial/servicenow.py +1756 -0
  177. regscale/integrations/commercial/sicura/__init__.py +0 -0
  178. regscale/integrations/commercial/sicura/api.py +855 -0
  179. regscale/integrations/commercial/sicura/commands.py +73 -0
  180. regscale/integrations/commercial/sicura/scanner.py +481 -0
  181. regscale/integrations/commercial/sicura/variables.py +16 -0
  182. regscale/integrations/commercial/snyk.py +90 -0
  183. regscale/integrations/commercial/sonarcloud.py +260 -0
  184. regscale/integrations/commercial/sqlserver.py +369 -0
  185. regscale/integrations/commercial/stig_mapper_integration/__init__.py +0 -0
  186. regscale/integrations/commercial/stig_mapper_integration/click_commands.py +38 -0
  187. regscale/integrations/commercial/stig_mapper_integration/mapping_engine.py +353 -0
  188. regscale/integrations/commercial/stigv2/__init__.py +0 -0
  189. regscale/integrations/commercial/stigv2/ckl_parser.py +349 -0
  190. regscale/integrations/commercial/stigv2/click_commands.py +95 -0
  191. regscale/integrations/commercial/stigv2/stig_integration.py +202 -0
  192. regscale/integrations/commercial/synqly/__init__.py +0 -0
  193. regscale/integrations/commercial/synqly/assets.py +46 -0
  194. regscale/integrations/commercial/synqly/ticketing.py +132 -0
  195. regscale/integrations/commercial/synqly/vulnerabilities.py +223 -0
  196. regscale/integrations/commercial/synqly_jira.py +840 -0
  197. regscale/integrations/commercial/tenablev2/__init__.py +0 -0
  198. regscale/integrations/commercial/tenablev2/authenticate.py +31 -0
  199. regscale/integrations/commercial/tenablev2/click.py +1584 -0
  200. regscale/integrations/commercial/tenablev2/scanner.py +504 -0
  201. regscale/integrations/commercial/tenablev2/stig_parsers.py +140 -0
  202. regscale/integrations/commercial/tenablev2/utils.py +78 -0
  203. regscale/integrations/commercial/tenablev2/variables.py +17 -0
  204. regscale/integrations/commercial/trivy.py +162 -0
  205. regscale/integrations/commercial/veracode.py +96 -0
  206. regscale/integrations/commercial/wizv2/WizDataMixin.py +97 -0
  207. regscale/integrations/commercial/wizv2/__init__.py +0 -0
  208. regscale/integrations/commercial/wizv2/click.py +429 -0
  209. regscale/integrations/commercial/wizv2/constants.py +1001 -0
  210. regscale/integrations/commercial/wizv2/issue.py +361 -0
  211. regscale/integrations/commercial/wizv2/models.py +112 -0
  212. regscale/integrations/commercial/wizv2/parsers.py +339 -0
  213. regscale/integrations/commercial/wizv2/sbom.py +115 -0
  214. regscale/integrations/commercial/wizv2/scanner.py +416 -0
  215. regscale/integrations/commercial/wizv2/utils.py +796 -0
  216. regscale/integrations/commercial/wizv2/variables.py +39 -0
  217. regscale/integrations/commercial/wizv2/wiz_auth.py +159 -0
  218. regscale/integrations/commercial/xray.py +91 -0
  219. regscale/integrations/integration/__init__.py +2 -0
  220. regscale/integrations/integration/integration.py +26 -0
  221. regscale/integrations/integration/inventory.py +17 -0
  222. regscale/integrations/integration/issue.py +100 -0
  223. regscale/integrations/integration_override.py +149 -0
  224. regscale/integrations/public/__init__.py +103 -0
  225. regscale/integrations/public/cisa.py +641 -0
  226. regscale/integrations/public/criticality_updater.py +70 -0
  227. regscale/integrations/public/emass.py +411 -0
  228. regscale/integrations/public/emass_slcm_import.py +697 -0
  229. regscale/integrations/public/fedramp/__init__.py +0 -0
  230. regscale/integrations/public/fedramp/appendix_parser.py +548 -0
  231. regscale/integrations/public/fedramp/click.py +479 -0
  232. regscale/integrations/public/fedramp/components.py +714 -0
  233. regscale/integrations/public/fedramp/docx_parser.py +259 -0
  234. regscale/integrations/public/fedramp/fedramp_cis_crm.py +1124 -0
  235. regscale/integrations/public/fedramp/fedramp_common.py +3181 -0
  236. regscale/integrations/public/fedramp/fedramp_docx.py +388 -0
  237. regscale/integrations/public/fedramp/fedramp_five.py +2343 -0
  238. regscale/integrations/public/fedramp/fedramp_traversal.py +138 -0
  239. regscale/integrations/public/fedramp/import_fedramp_r4_ssp.py +279 -0
  240. regscale/integrations/public/fedramp/import_workbook.py +495 -0
  241. regscale/integrations/public/fedramp/inventory_items.py +244 -0
  242. regscale/integrations/public/fedramp/mappings/__init__.py +0 -0
  243. regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +7388 -0
  244. regscale/integrations/public/fedramp/mappings/fedramp_r5_params.json +8636 -0
  245. regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +9605 -0
  246. regscale/integrations/public/fedramp/mappings/system_roles.py +34 -0
  247. regscale/integrations/public/fedramp/mappings/user.py +175 -0
  248. regscale/integrations/public/fedramp/mappings/values.py +141 -0
  249. regscale/integrations/public/fedramp/markdown_parser.py +150 -0
  250. regscale/integrations/public/fedramp/metadata.py +689 -0
  251. regscale/integrations/public/fedramp/models/__init__.py +59 -0
  252. regscale/integrations/public/fedramp/models/leveraged_auth_new.py +168 -0
  253. regscale/integrations/public/fedramp/models/poam_importer.py +522 -0
  254. regscale/integrations/public/fedramp/parts_mapper.py +107 -0
  255. regscale/integrations/public/fedramp/poam/__init__.py +0 -0
  256. regscale/integrations/public/fedramp/poam/scanner.py +851 -0
  257. regscale/integrations/public/fedramp/properties.py +201 -0
  258. regscale/integrations/public/fedramp/reporting.py +84 -0
  259. regscale/integrations/public/fedramp/resources.py +496 -0
  260. regscale/integrations/public/fedramp/rosetta.py +110 -0
  261. regscale/integrations/public/fedramp/ssp_logger.py +87 -0
  262. regscale/integrations/public/fedramp/system_characteristics.py +922 -0
  263. regscale/integrations/public/fedramp/system_control_implementations.py +582 -0
  264. regscale/integrations/public/fedramp/system_implementation.py +190 -0
  265. regscale/integrations/public/fedramp/xml_utils.py +87 -0
  266. regscale/integrations/public/nist_catalog.py +275 -0
  267. regscale/integrations/public/oscal.py +1946 -0
  268. regscale/integrations/public/otx.py +169 -0
  269. regscale/integrations/scanner_integration.py +2692 -0
  270. regscale/integrations/variables.py +25 -0
  271. regscale/models/__init__.py +7 -0
  272. regscale/models/app_models/__init__.py +5 -0
  273. regscale/models/app_models/catalog_compare.py +213 -0
  274. regscale/models/app_models/click.py +252 -0
  275. regscale/models/app_models/datetime_encoder.py +21 -0
  276. regscale/models/app_models/import_validater.py +321 -0
  277. regscale/models/app_models/mapping.py +260 -0
  278. regscale/models/app_models/pipeline.py +37 -0
  279. regscale/models/click_models.py +413 -0
  280. regscale/models/config.py +154 -0
  281. regscale/models/email_style.css +67 -0
  282. regscale/models/hierarchy.py +8 -0
  283. regscale/models/inspect_models.py +79 -0
  284. regscale/models/integration_models/__init__.py +0 -0
  285. regscale/models/integration_models/amazon_models/__init__.py +0 -0
  286. regscale/models/integration_models/amazon_models/inspector.py +262 -0
  287. regscale/models/integration_models/amazon_models/inspector_scan.py +206 -0
  288. regscale/models/integration_models/aqua.py +247 -0
  289. regscale/models/integration_models/azure_alerts.py +255 -0
  290. regscale/models/integration_models/base64.py +23 -0
  291. regscale/models/integration_models/burp.py +433 -0
  292. regscale/models/integration_models/burp_models.py +128 -0
  293. regscale/models/integration_models/cisa_kev_data.json +19333 -0
  294. regscale/models/integration_models/defender_data.py +93 -0
  295. regscale/models/integration_models/defenderimport.py +143 -0
  296. regscale/models/integration_models/drf.py +443 -0
  297. regscale/models/integration_models/ecr_models/__init__.py +0 -0
  298. regscale/models/integration_models/ecr_models/data.py +69 -0
  299. regscale/models/integration_models/ecr_models/ecr.py +239 -0
  300. regscale/models/integration_models/flat_file_importer.py +1079 -0
  301. regscale/models/integration_models/grype_import.py +247 -0
  302. regscale/models/integration_models/ibm.py +126 -0
  303. regscale/models/integration_models/implementation_results.py +85 -0
  304. regscale/models/integration_models/nexpose.py +140 -0
  305. regscale/models/integration_models/prisma.py +202 -0
  306. regscale/models/integration_models/qualys.py +720 -0
  307. regscale/models/integration_models/qualys_scanner.py +160 -0
  308. regscale/models/integration_models/sbom/__init__.py +0 -0
  309. regscale/models/integration_models/sbom/cyclone_dx.py +139 -0
  310. regscale/models/integration_models/send_reminders.py +620 -0
  311. regscale/models/integration_models/snyk.py +155 -0
  312. regscale/models/integration_models/synqly_models/__init__.py +0 -0
  313. regscale/models/integration_models/synqly_models/capabilities.json +1 -0
  314. regscale/models/integration_models/synqly_models/connector_types.py +22 -0
  315. regscale/models/integration_models/synqly_models/connectors/__init__.py +7 -0
  316. regscale/models/integration_models/synqly_models/connectors/assets.py +97 -0
  317. regscale/models/integration_models/synqly_models/connectors/ticketing.py +583 -0
  318. regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +169 -0
  319. regscale/models/integration_models/synqly_models/ocsf_mapper.py +331 -0
  320. regscale/models/integration_models/synqly_models/param.py +72 -0
  321. regscale/models/integration_models/synqly_models/synqly_model.py +733 -0
  322. regscale/models/integration_models/synqly_models/tenants.py +39 -0
  323. regscale/models/integration_models/tenable_models/__init__.py +0 -0
  324. regscale/models/integration_models/tenable_models/integration.py +187 -0
  325. regscale/models/integration_models/tenable_models/models.py +513 -0
  326. regscale/models/integration_models/trivy_import.py +231 -0
  327. regscale/models/integration_models/veracode.py +217 -0
  328. regscale/models/integration_models/xray.py +135 -0
  329. regscale/models/locking.py +100 -0
  330. regscale/models/platform.py +110 -0
  331. regscale/models/regscale_models/__init__.py +67 -0
  332. regscale/models/regscale_models/assessment.py +570 -0
  333. regscale/models/regscale_models/assessment_plan.py +52 -0
  334. regscale/models/regscale_models/asset.py +567 -0
  335. regscale/models/regscale_models/asset_mapping.py +190 -0
  336. regscale/models/regscale_models/case.py +42 -0
  337. regscale/models/regscale_models/catalog.py +261 -0
  338. regscale/models/regscale_models/cci.py +46 -0
  339. regscale/models/regscale_models/change.py +167 -0
  340. regscale/models/regscale_models/checklist.py +372 -0
  341. regscale/models/regscale_models/comment.py +49 -0
  342. regscale/models/regscale_models/compliance_settings.py +112 -0
  343. regscale/models/regscale_models/component.py +412 -0
  344. regscale/models/regscale_models/component_mapping.py +65 -0
  345. regscale/models/regscale_models/control.py +38 -0
  346. regscale/models/regscale_models/control_implementation.py +1128 -0
  347. regscale/models/regscale_models/control_objective.py +261 -0
  348. regscale/models/regscale_models/control_parameter.py +100 -0
  349. regscale/models/regscale_models/control_test.py +34 -0
  350. regscale/models/regscale_models/control_test_plan.py +75 -0
  351. regscale/models/regscale_models/control_test_result.py +52 -0
  352. regscale/models/regscale_models/custom_field.py +245 -0
  353. regscale/models/regscale_models/data.py +109 -0
  354. regscale/models/regscale_models/data_center.py +40 -0
  355. regscale/models/regscale_models/deviation.py +203 -0
  356. regscale/models/regscale_models/email.py +97 -0
  357. regscale/models/regscale_models/evidence.py +47 -0
  358. regscale/models/regscale_models/evidence_mapping.py +40 -0
  359. regscale/models/regscale_models/facility.py +59 -0
  360. regscale/models/regscale_models/file.py +382 -0
  361. regscale/models/regscale_models/filetag.py +37 -0
  362. regscale/models/regscale_models/form_field_value.py +94 -0
  363. regscale/models/regscale_models/group.py +169 -0
  364. regscale/models/regscale_models/implementation_objective.py +335 -0
  365. regscale/models/regscale_models/implementation_option.py +275 -0
  366. regscale/models/regscale_models/implementation_role.py +33 -0
  367. regscale/models/regscale_models/incident.py +177 -0
  368. regscale/models/regscale_models/interconnection.py +43 -0
  369. regscale/models/regscale_models/issue.py +1176 -0
  370. regscale/models/regscale_models/leveraged_authorization.py +125 -0
  371. regscale/models/regscale_models/line_of_inquiry.py +52 -0
  372. regscale/models/regscale_models/link.py +205 -0
  373. regscale/models/regscale_models/meta_data.py +64 -0
  374. regscale/models/regscale_models/mixins/__init__.py +0 -0
  375. regscale/models/regscale_models/mixins/parent_cache.py +124 -0
  376. regscale/models/regscale_models/module.py +224 -0
  377. regscale/models/regscale_models/modules.py +191 -0
  378. regscale/models/regscale_models/objective.py +14 -0
  379. regscale/models/regscale_models/parameter.py +87 -0
  380. regscale/models/regscale_models/ports_protocol.py +81 -0
  381. regscale/models/regscale_models/privacy.py +89 -0
  382. regscale/models/regscale_models/profile.py +50 -0
  383. regscale/models/regscale_models/profile_link.py +68 -0
  384. regscale/models/regscale_models/profile_mapping.py +124 -0
  385. regscale/models/regscale_models/project.py +63 -0
  386. regscale/models/regscale_models/property.py +278 -0
  387. regscale/models/regscale_models/question.py +85 -0
  388. regscale/models/regscale_models/questionnaire.py +87 -0
  389. regscale/models/regscale_models/questionnaire_instance.py +177 -0
  390. regscale/models/regscale_models/rbac.py +132 -0
  391. regscale/models/regscale_models/reference.py +86 -0
  392. regscale/models/regscale_models/regscale_model.py +1643 -0
  393. regscale/models/regscale_models/requirement.py +29 -0
  394. regscale/models/regscale_models/risk.py +274 -0
  395. regscale/models/regscale_models/sbom.py +54 -0
  396. regscale/models/regscale_models/scan_history.py +436 -0
  397. regscale/models/regscale_models/search.py +53 -0
  398. regscale/models/regscale_models/security_control.py +132 -0
  399. regscale/models/regscale_models/security_plan.py +204 -0
  400. regscale/models/regscale_models/software_inventory.py +159 -0
  401. regscale/models/regscale_models/stake_holder.py +64 -0
  402. regscale/models/regscale_models/stig.py +647 -0
  403. regscale/models/regscale_models/supply_chain.py +152 -0
  404. regscale/models/regscale_models/system_role.py +188 -0
  405. regscale/models/regscale_models/system_role_external_assignment.py +40 -0
  406. regscale/models/regscale_models/tag.py +37 -0
  407. regscale/models/regscale_models/tag_mapping.py +19 -0
  408. regscale/models/regscale_models/task.py +133 -0
  409. regscale/models/regscale_models/threat.py +196 -0
  410. regscale/models/regscale_models/user.py +175 -0
  411. regscale/models/regscale_models/user_group.py +55 -0
  412. regscale/models/regscale_models/vulnerability.py +242 -0
  413. regscale/models/regscale_models/vulnerability_mapping.py +162 -0
  414. regscale/models/regscale_models/workflow.py +55 -0
  415. regscale/models/regscale_models/workflow_action.py +34 -0
  416. regscale/models/regscale_models/workflow_instance.py +269 -0
  417. regscale/models/regscale_models/workflow_instance_step.py +114 -0
  418. regscale/models/regscale_models/workflow_template.py +58 -0
  419. regscale/models/regscale_models/workflow_template_step.py +45 -0
  420. regscale/regscale.py +815 -0
  421. regscale/utils/__init__.py +7 -0
  422. regscale/utils/b64conversion.py +14 -0
  423. regscale/utils/click_utils.py +118 -0
  424. regscale/utils/decorators.py +48 -0
  425. regscale/utils/dict_utils.py +59 -0
  426. regscale/utils/files.py +79 -0
  427. regscale/utils/fxns.py +30 -0
  428. regscale/utils/graphql_client.py +113 -0
  429. regscale/utils/lists.py +16 -0
  430. regscale/utils/numbers.py +12 -0
  431. regscale/utils/shell.py +148 -0
  432. regscale/utils/string.py +121 -0
  433. regscale/utils/synqly_utils.py +165 -0
  434. regscale/utils/threading/__init__.py +8 -0
  435. regscale/utils/threading/threadhandler.py +131 -0
  436. regscale/utils/threading/threadsafe_counter.py +47 -0
  437. regscale/utils/threading/threadsafe_dict.py +242 -0
  438. regscale/utils/threading/threadsafe_list.py +83 -0
  439. regscale/utils/version.py +104 -0
  440. regscale/validation/__init__.py +0 -0
  441. regscale/validation/address.py +37 -0
  442. regscale/validation/record.py +48 -0
  443. regscale/visualization/__init__.py +5 -0
  444. regscale/visualization/click.py +34 -0
  445. regscale_cli-6.16.0.0.dist-info/LICENSE +21 -0
  446. regscale_cli-6.16.0.0.dist-info/METADATA +659 -0
  447. regscale_cli-6.16.0.0.dist-info/RECORD +481 -0
  448. regscale_cli-6.16.0.0.dist-info/WHEEL +5 -0
  449. regscale_cli-6.16.0.0.dist-info/entry_points.txt +6 -0
  450. regscale_cli-6.16.0.0.dist-info/top_level.txt +2 -0
  451. tests/fixtures/__init__.py +2 -0
  452. tests/fixtures/api.py +87 -0
  453. tests/fixtures/models.py +91 -0
  454. tests/fixtures/test_fixture.py +144 -0
  455. tests/mocks/__init__.py +0 -0
  456. tests/mocks/objects.py +3 -0
  457. tests/mocks/response.py +32 -0
  458. tests/mocks/xml.py +13 -0
  459. tests/regscale/__init__.py +0 -0
  460. tests/regscale/core/__init__.py +0 -0
  461. tests/regscale/core/test_api.py +232 -0
  462. tests/regscale/core/test_app.py +406 -0
  463. tests/regscale/core/test_login.py +37 -0
  464. tests/regscale/core/test_logz.py +66 -0
  465. tests/regscale/core/test_sbom_generator.py +87 -0
  466. tests/regscale/core/test_validation_utils.py +163 -0
  467. tests/regscale/core/test_version.py +78 -0
  468. tests/regscale/models/__init__.py +0 -0
  469. tests/regscale/models/test_asset.py +71 -0
  470. tests/regscale/models/test_config.py +26 -0
  471. tests/regscale/models/test_control_implementation.py +27 -0
  472. tests/regscale/models/test_import.py +97 -0
  473. tests/regscale/models/test_issue.py +36 -0
  474. tests/regscale/models/test_mapping.py +52 -0
  475. tests/regscale/models/test_platform.py +31 -0
  476. tests/regscale/models/test_regscale_model.py +346 -0
  477. tests/regscale/models/test_report.py +32 -0
  478. tests/regscale/models/test_tenable_integrations.py +118 -0
  479. tests/regscale/models/test_user_model.py +121 -0
  480. tests/regscale/test_about.py +19 -0
  481. tests/regscale/test_authorization.py +65 -0
@@ -0,0 +1,247 @@
1
+ """
2
+ Aqua Scan information
3
+ """
4
+
5
+ from itertools import groupby
6
+ from operator import itemgetter
7
+ from typing import List, Optional
8
+
9
+ from regscale.core.app.application import Application
10
+ from regscale.core.app.logz import create_logger
11
+ from regscale.core.app.utils.app_utils import get_current_datetime, is_valid_fqdn
12
+ from regscale.core.utils.date import datetime_str
13
+ from regscale.models.app_models import ImportValidater
14
+ from regscale.models.integration_models.flat_file_importer import FlatFileImporter
15
+ from regscale.models.regscale_models.asset import Asset
16
+ from regscale.models.regscale_models.vulnerability import Vulnerability
17
+
18
+
19
+ class Aqua(FlatFileImporter):
20
+ """Aqua Scan information"""
21
+
22
+ def __init__(self, **kwargs):
23
+ from regscale.integrations.integration_override import IntegrationOverride
24
+
25
+ self.name = kwargs.get("name")
26
+ self.integration_mapping = IntegrationOverride(Application())
27
+ self.vuln_title = "Vulnerability Name"
28
+ self.fmt = "%m/%d/%Y"
29
+ self.dt_format = "%Y-%m-%d %H:%M:%S"
30
+ self.image_name = "Image Name"
31
+ self.OS = "OS"
32
+ self.description = "Description"
33
+ self.ffi = "First Found on Image"
34
+ self.last_image_scan = "Last Image Scan"
35
+ self.installed_version = "Installed Version"
36
+ self.vendor_cvss_v2_severity = "Vendor CVSS v2 Severity"
37
+ self.vendor_cvss_v3_severity = "Vendor CVSS v3 Severity"
38
+ self.vendor_cvss_v3_score = "Vendor CVSS v3 Score"
39
+ self.nvd_cvss_v2_severity = "NVD CVSS v2 Severity"
40
+ self.nvd_cvss_v3_severity = "NVD CVSS v3 Severity"
41
+ self.required_headers = [
42
+ self.image_name,
43
+ self.OS,
44
+ self.vuln_title,
45
+ self.description,
46
+ ]
47
+ self.mapping_file = kwargs.get("mappings_path")
48
+ self.disable_mapping = kwargs.get("disable_mapping")
49
+ self.validater = ImportValidater(
50
+ self.required_headers, kwargs.get("file_path"), self.mapping_file, self.disable_mapping
51
+ )
52
+ self.headers = self.validater.parsed_headers
53
+ self.mapping = self.validater.mapping
54
+ logger = create_logger()
55
+ self.logger = logger
56
+ super().__init__(
57
+ logger=logger,
58
+ headers=self.headers,
59
+ asset_func=self.create_asset,
60
+ vuln_func=self.create_vuln,
61
+ app=Application(),
62
+ ignore_validation=True,
63
+ **kwargs,
64
+ )
65
+
66
+ def create_asset(self, dat: Optional[dict] = None) -> Optional[Asset]:
67
+ """
68
+ Create an asset from a row in the Aqua file
69
+
70
+ :param Optional[dict] dat: Data row from CSV file, defaults to None
71
+ :return: RegScale Asset object or None
72
+ :rtype: Optional[Asset]
73
+ """
74
+ name = self.mapping.get_value(dat, self.image_name)
75
+ if not name:
76
+ return None
77
+ os = self.mapping.get_value(dat, self.OS)
78
+ return Asset(
79
+ **{
80
+ "id": 0,
81
+ "name": name,
82
+ "description": "",
83
+ "operatingSystem": Asset.find_os(os),
84
+ "operatingSystemVersion": os,
85
+ "ipAddress": "0.0.0.0",
86
+ "isPublic": True,
87
+ "status": "Active (On Network)",
88
+ "assetCategory": "Hardware",
89
+ "bLatestScan": True,
90
+ "bAuthenticatedScan": True,
91
+ "scanningTool": self.name,
92
+ "assetOwnerId": self.config["userId"],
93
+ "assetType": "Other",
94
+ "fqdn": name if is_valid_fqdn(name) else None,
95
+ "systemAdministratorId": self.config["userId"],
96
+ "parentId": self.attributes.parent_id,
97
+ "parentModule": self.attributes.parent_module,
98
+ "extra_data": {"software_inventory": self.generate_software_inventory(name)},
99
+ }
100
+ )
101
+
102
+ def generate_software_inventory(self, name: str) -> List[dict]:
103
+ """
104
+ Create and post a list of software inventory for a given asset
105
+
106
+ :param str name: The name of the asset
107
+ :return: List of software inventory
108
+ :rtype: List[dict]
109
+ """
110
+ inventory: List[dict] = []
111
+
112
+ image_group = {
113
+ k: list(g) for k, g in groupby(self.file_data, key=itemgetter(self.mapping.get_header(self.image_name)))
114
+ }
115
+
116
+ softwares = image_group[name]
117
+ for software in softwares:
118
+ if "Resource" not in software or self.installed_version not in software:
119
+ continue
120
+ inv = {
121
+ "name": software["Resource"],
122
+ "version": str(software[self.installed_version]),
123
+ }
124
+ if (inv.get("name"), inv.get("version")) not in {
125
+ (soft.get("name"), soft.get("version")) for soft in inventory
126
+ }:
127
+ inventory.append(inv)
128
+
129
+ return inventory
130
+
131
+ def current_datetime_w_log(self, field: str) -> str:
132
+ """
133
+ Get the current date and time with a log message
134
+
135
+ :param str field: The field that is missing the date
136
+ :return: The current date and time
137
+ :rtype: str
138
+ """
139
+ self.logger.info(f"Unable to determine date for the '{field}' field, falling back to current date and time.")
140
+ return get_current_datetime()
141
+
142
+ def create_vuln(self, dat: Optional[dict] = None, **kwargs: dict) -> Optional[Vulnerability]:
143
+ """
144
+ Create a vulnerability from a row in the Aqua csv file
145
+
146
+ :param Optional[dict] dat: Data row from CSV file, defaults to None
147
+ :param dict **kwargs: Additional keyword arguments
148
+ :return: RegScale Vulnerability object or None
149
+ :rtype: Optional[Vulnerability]
150
+ """
151
+
152
+ hostname = self.mapping.get_value(dat, self.image_name)
153
+
154
+ # Custom Integration Mapping fields
155
+ remediation = self.mapping.get_value(dat, self.integration_mapping.load("aqua", "remediation")) or (
156
+ self.mapping.get_value(dat, self.description) or "Upgrade affected package"
157
+ ) # OLDTODO: BMC would like this to use "Solution" column
158
+ description = self.mapping.get_value(dat, self.integration_mapping.load("aqua", "description")) or (
159
+ self.mapping.get_value(dat, self.description)
160
+ )
161
+ title = self.mapping.get_value(dat, self.integration_mapping.load("aqua", "title")) or (
162
+ description[:255] if description else f"Vulnerability on {hostname}"
163
+ ) # OLDTODO: BMC Would like the CVE here
164
+
165
+ regscale_vuln = None
166
+ severity = self.determine_cvss_severity(dat)
167
+ config = self.attributes.app.config
168
+ asset_match = [asset for asset in self.data["assets"] if asset.name == hostname]
169
+ asset = asset_match[0] if asset_match else None
170
+ if asset_match and self.validate(ix=kwargs.get("index"), dat=dat):
171
+ regscale_vuln = Vulnerability(
172
+ id=0,
173
+ scanId=0,
174
+ parentId=asset.id,
175
+ parentModule="assets",
176
+ ipAddress="0.0.0.0",
177
+ lastSeen=datetime_str(self.mapping.get_value(dat, self.last_image_scan))
178
+ or self.current_datetime_w_log(self.last_image_scan),
179
+ firstSeen=datetime_str(self.mapping.get_value(dat, self.ffi)) or self.current_datetime_w_log(self.ffi),
180
+ daysOpen=None,
181
+ dns=hostname,
182
+ mitigated=None,
183
+ operatingSystem=asset.operatingSystem,
184
+ severity=severity,
185
+ plugInName=description,
186
+ cve=self.mapping.get_value(dat, self.vuln_title),
187
+ cvsSv3BaseScore=self.mapping.get_value(dat, self.vendor_cvss_v3_score, 0.0),
188
+ tenantsId=0,
189
+ title=title,
190
+ description=description,
191
+ plugInText=self.mapping.get_value(dat, self.vuln_title),
192
+ createdById=config["userId"],
193
+ lastUpdatedById=config["userId"],
194
+ dateCreated=get_current_datetime(),
195
+ extra_data={"solution": remediation},
196
+ )
197
+ return regscale_vuln
198
+
199
+ def determine_cvss_severity(self, dat: dict) -> str:
200
+ """
201
+ Determine the CVSS severity of the vulnerability
202
+
203
+ :param dict dat: Data row from CSV file
204
+ :return: A severity derived from the CVSS scores
205
+ :rtype: str
206
+ """
207
+ precedence_order = [
208
+ self.nvd_cvss_v3_severity,
209
+ self.nvd_cvss_v2_severity,
210
+ self.vendor_cvss_v3_severity,
211
+ # This field may or may not be available in the file (Coalfire has it, BMC does not.)
212
+ (
213
+ self.vendor_cvss_v2_severity
214
+ if self.mapping.get_value(dat, self.vendor_cvss_v2_severity, warnings=False)
215
+ else None
216
+ ),
217
+ ]
218
+ severity = "info"
219
+ for key in precedence_order:
220
+ if key and self.mapping.get_value(dat, key):
221
+ severity = self.mapping.get_value(dat, key).lower()
222
+ break
223
+
224
+ return severity
225
+
226
+ def validate(self, ix: Optional[int], dat: dict) -> bool:
227
+ """
228
+ Validate the row of data, and populate with something if missing
229
+
230
+ :param Optional[int] ix: index
231
+ :param dict dat: Data row from CSV file
232
+ :return: True if the row is valid or has been updated with default value
233
+ :rtype: bool
234
+ """
235
+ required_keys = [self.description]
236
+ val = True
237
+ for key in required_keys:
238
+ if not dat.get(key):
239
+ default_val = f"No {key} available."
240
+ row_skip = (
241
+ f"Populating {key} for row #{ix + 1} with {default_val}"
242
+ if isinstance(ix, int)
243
+ else f"Populating {key} with {default_val}"
244
+ )
245
+ self.attributes.logger.warning(f"Missing value for required field: {key}, {row_skip}")
246
+ dat[key] = default_val
247
+ return val
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Dataclass for a Microsoft Defender for Cloud alerts"""
4
+
5
+ # standard python imports
6
+ from dataclasses import dataclass
7
+ from typing import Any, Optional
8
+ from typing import List
9
+
10
+
11
+ @dataclass
12
+ class Location:
13
+ countryCode: Optional[str] = None
14
+ countryName: Optional[str] = None
15
+ state: Optional[str] = None
16
+ city: Optional[str] = None
17
+ longitude: Optional[float] = None
18
+ latitude: Optional[float] = None
19
+ asn: Optional[int] = None
20
+ carrier: Optional[str] = None
21
+ organization: Optional[str] = None
22
+ organizationType: Optional[str] = None
23
+ cloudProvider: Optional[str] = None
24
+ systemService: Optional[str] = None
25
+
26
+ @staticmethod
27
+ def from_dict(obj: Any) -> "Location":
28
+ _countryCode = str(obj.get("countryCode"))
29
+ _countryName = str(obj.get("countryName"))
30
+ _state = str(obj.get("state"))
31
+ _city = str(obj.get("city"))
32
+ _longitude = float(obj.get("longitude"))
33
+ _latitude = float(obj.get("latitude"))
34
+ _asn = int(obj.get("asn"))
35
+ _carrier = str(obj.get("carrier"))
36
+ _organization = str(obj.get("organization"))
37
+ _organizationType = str(obj.get("organizationType"))
38
+ _cloudProvider = str(obj.get("cloudProvider"))
39
+ _systemService = str(obj.get("systemService"))
40
+ return Location(
41
+ _countryCode,
42
+ _countryName,
43
+ _state,
44
+ _city,
45
+ _longitude,
46
+ _latitude,
47
+ _asn,
48
+ _carrier,
49
+ _organization,
50
+ _organizationType,
51
+ _cloudProvider,
52
+ _systemService,
53
+ )
54
+
55
+
56
+ @dataclass
57
+ class SourceAddress:
58
+ ref: Optional[str] = None
59
+
60
+ @staticmethod
61
+ def from_dict(obj: Any) -> "SourceAddress":
62
+ _ref = str(obj.get("$ref"))
63
+ return SourceAddress(_ref)
64
+
65
+
66
+ @dataclass
67
+ class Host:
68
+ ref: Optional[str] = None
69
+
70
+ @staticmethod
71
+ def from_dict(obj: Any) -> "Host":
72
+ _ref = str(obj.get("$ref"))
73
+ return Host(_ref)
74
+
75
+
76
+ @dataclass
77
+ class Entity:
78
+ id: Optional[str] = None
79
+ resourceId: Optional[str] = None
80
+ type: Optional[str] = None
81
+ address: Optional[str] = None
82
+ location: Optional[str] = None
83
+ hostName: Optional[str] = None
84
+ sourceAddress: Optional[SourceAddress] = None
85
+ name: Optional[str] = None
86
+ host: Optional[Host] = None
87
+
88
+ @staticmethod
89
+ def from_dict(obj: Any) -> "Entity":
90
+ _id = str(obj.get("$id"))
91
+ _resourceId = str(obj.get("resourceId"))
92
+ _type = str(obj.get("type"))
93
+ _address = str(obj.get("address"))
94
+ _location = Location.from_dict(obj.get("location"))
95
+ _hostName = str(obj.get("hostName"))
96
+ _sourceAddress = SourceAddress.from_dict(obj.get("sourceAddress"))
97
+ _name = str(obj.get("name"))
98
+ _host = Host.from_dict(obj.get("host"))
99
+ return Entity(
100
+ _id,
101
+ _resourceId,
102
+ _type,
103
+ _address,
104
+ _location,
105
+ _hostName,
106
+ _sourceAddress,
107
+ _name,
108
+ _host,
109
+ )
110
+
111
+
112
+ @dataclass
113
+ class ExtendedProperties:
114
+ alertId: Optional[str] = None
115
+ compromisedEntity: Optional[str] = None
116
+ clientIpAddress: Optional[str] = None
117
+ clientPrincipalName: Optional[str] = None
118
+ clientApplication: Optional[str] = None
119
+ investigationSteps: Optional[str] = None
120
+ potentialCauses: Optional[str] = None
121
+ resourceType: Optional[str] = None
122
+ killChainIntent: Optional[str] = None
123
+
124
+ @staticmethod
125
+ def from_dict(obj: Any) -> "ExtendedProperties":
126
+ _alertId = str(obj.get("alert Id"))
127
+ _compromisedEntity = str(obj.get("compromised entity"))
128
+ _clientIpAddress = str(obj.get("client IP address"))
129
+ _clientPrincipalName = str(obj.get("client principal name"))
130
+ _clientApplication = str(obj.get("client application"))
131
+ _investigationSteps = str(obj.get("investigation steps"))
132
+ _potentialCauses = str(obj.get("potential causes"))
133
+ _resourceType = str(obj.get("resourceType"))
134
+ _killChainIntent = str(obj.get("killChainIntent"))
135
+ return ExtendedProperties(
136
+ _alertId,
137
+ _compromisedEntity,
138
+ _clientIpAddress,
139
+ _clientPrincipalName,
140
+ _clientApplication,
141
+ _investigationSteps,
142
+ _potentialCauses,
143
+ _resourceType,
144
+ _killChainIntent,
145
+ )
146
+
147
+
148
+ @dataclass
149
+ class ResourceIdentifier:
150
+ id: Optional[str] = None
151
+ azureResourceId: Optional[str] = None
152
+ type: Optional[str] = None
153
+ azureResourceTenantId: Optional[str] = None
154
+
155
+ @staticmethod
156
+ def from_dict(obj: Any) -> "ResourceIdentifier":
157
+ _id = str(obj.get("$id"))
158
+ _azureResourceId = str(obj.get("azureResourceId"))
159
+ _type = str(obj.get("type"))
160
+ _azureResourceTenantId = str(obj.get("azureResourceTenantId"))
161
+ return ResourceIdentifier(_id, _azureResourceId, _type, _azureResourceTenantId)
162
+
163
+
164
+ @dataclass
165
+ class Properties:
166
+ status: Optional[str] = None
167
+ timeGeneratedUtc: Optional[str] = None
168
+ processingEndTimeUtc: Optional[str] = None
169
+ version: Optional[str] = None
170
+ vendorName: Optional[str] = None
171
+ productName: Optional[str] = None
172
+ productComponentName: Optional[str] = None
173
+ alertType: Optional[str] = None
174
+ startTimeUtc: Optional[str] = None
175
+ endTimeUtc: Optional[str] = None
176
+ severity: Optional[str] = None
177
+ isIncident: Optional[str] = None
178
+ systemAlertId: Optional[str] = None
179
+ correlationKey: Optional[str] = None
180
+ intent: Optional[str] = None
181
+ resourceIdentifiers: Optional[List[ResourceIdentifier]] = None
182
+ compromisedEntity: Optional[str] = None
183
+ alertDisplayName: Optional[str] = None
184
+ description: Optional[str] = None
185
+ remediationSteps: Optional[List[str]] = None
186
+ extendedProperties: Optional[ExtendedProperties] = None
187
+ entities: Optional[List[Entity]] = None
188
+ alertUri: Optional[str] = None
189
+
190
+ @staticmethod
191
+ def from_dict(obj: Any) -> "Properties":
192
+ _status = str(obj.get("status"))
193
+ _timeGeneratedUtc = str(obj.get("timeGeneratedUtc"))
194
+ _processingEndTimeUtc = str(obj.get("processingEndTimeUtc"))
195
+ _version = str(obj.get("version"))
196
+ _vendorName = str(obj.get("vendorName"))
197
+ _productName = str(obj.get("productName"))
198
+ _productComponentName = str(obj.get("productComponentName"))
199
+ _alertType = str(obj.get("alertType"))
200
+ _startTimeUtc = str(obj.get("startTimeUtc"))
201
+ _endTimeUtc = str(obj.get("endTimeUtc"))
202
+ _severity = str(obj.get("severity"))
203
+ _isIncident = bool(obj.get("isIncident"))
204
+ _systemAlertId = str(obj.get("systemAlertId"))
205
+ _correlationKey = str(obj.get("correlationKey"))
206
+ _intent = str(obj.get("intent"))
207
+ _resourceIdentifiers = [ResourceIdentifier.from_dict(y) for y in obj.get("resourceIdentifiers")]
208
+ _compromisedEntity = str(obj.get("compromisedEntity"))
209
+ _alertDisplayName = str(obj.get("alertDisplayName"))
210
+ _description = str(obj.get("description"))
211
+ _remediationSteps = [obj.get("remediationSteps")]
212
+ _extended_properties = ExtendedProperties.from_dict(obj.get("extendedProperties"))
213
+ _entities = [Entity.from_dict(y) for y in obj.get("entities")]
214
+ _alertUri = str(obj.get("alertUri"))
215
+ return Properties(
216
+ _status,
217
+ _timeGeneratedUtc,
218
+ _processingEndTimeUtc,
219
+ _version,
220
+ _vendorName,
221
+ _productName,
222
+ _productComponentName,
223
+ _alertType,
224
+ _startTimeUtc,
225
+ _endTimeUtc,
226
+ _severity,
227
+ _isIncident,
228
+ _systemAlertId,
229
+ _correlationKey,
230
+ _intent,
231
+ _resourceIdentifiers,
232
+ _compromisedEntity,
233
+ _alertDisplayName,
234
+ _description,
235
+ _remediationSteps,
236
+ _extended_properties,
237
+ _entities,
238
+ _alertUri,
239
+ )
240
+
241
+
242
+ @dataclass
243
+ class Alert:
244
+ id: str
245
+ name: str
246
+ type: str
247
+ properties: Properties
248
+
249
+ @staticmethod
250
+ def from_dict(obj: Any) -> "Alert":
251
+ _id = str(obj.get("id"))
252
+ _name = str(obj.get("name"))
253
+ _type = str(obj.get("type"))
254
+ _properties = Properties.from_dict(obj.get("properties"))
255
+ return Alert(_id, _name, _type, _properties)
@@ -0,0 +1,23 @@
1
+ """Standard imports"""
2
+
3
+ import base64
4
+
5
+ from pydantic import ValidationError
6
+
7
+
8
+ class Base64String(str):
9
+ """Base64 String"""
10
+
11
+ @classmethod
12
+ def __get_validators__(cls):
13
+ """Get validators"""
14
+ yield cls.validate_base64_str
15
+
16
+ @classmethod
17
+ def validate_base64_str(cls, input_string: str, field: str):
18
+ """Validate base64 string"""
19
+ try:
20
+ base64.b64decode(input_string)
21
+ return input_string
22
+ except Exception as exc:
23
+ raise ValidationError(f"{field} is not a valid base64 string") from exc