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,79 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Click BaseModels."""
4
+ from collections import OrderedDict
5
+ from inspect import Parameter, Signature, signature
6
+ from types import MappingProxyType
7
+ from typing import Any, Dict, List, Optional, Union, Callable
8
+
9
+ import click
10
+ import click.core
11
+ from pydantic import BaseModel, validator, ConfigDict, field_validator
12
+
13
+
14
+ # A Pydantic model to represent a parameter in a function signature
15
+ class ParameterModel(BaseModel):
16
+ model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True)
17
+ name: str
18
+ kind: str
19
+ default: Optional[Any] = None
20
+ annotation: Union[str, None]
21
+
22
+ # Validators to convert Parameter.kind and Parameter.annotation to string
23
+ @field_validator("kind", mode="before")
24
+ def _get_kind_str(cls, v):
25
+ return str(v)
26
+
27
+ @field_validator("annotation", mode="before")
28
+ def _get_annotation_str(cls, v):
29
+ if v is Parameter.empty:
30
+ return None
31
+ return str(v)
32
+
33
+
34
+ class SignatureModel(BaseModel):
35
+ """Signature Model"""
36
+
37
+ model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True)
38
+
39
+ name: Optional[str] = None
40
+ signature: Optional[Union[Signature, dict, str]] = None
41
+ # parameters: Optional[OrderedDict] = None
42
+ parameters: Dict[str, ParameterModel]
43
+
44
+ @field_validator("signature", mode="before")
45
+ def _check_signature(cls, var):
46
+ """Validate a click.Command"""
47
+ if not isinstance(var, (Signature, str, dict)):
48
+ print(f"signature must be a (Signature, str, dict) not {type(var)}")
49
+ return var
50
+
51
+ @classmethod
52
+ def from_callable(cls, command: str, fn: Callable):
53
+ sig = signature(fn)
54
+ params = {
55
+ name: ParameterModel(
56
+ name=command,
57
+ kind=param.kind,
58
+ default=param.default if param.default is not Parameter.empty else None,
59
+ annotation=param.annotation,
60
+ )
61
+ for name, param in sig.parameters.items()
62
+ }
63
+ return cls(name=command, parameters=params, signature=sig)
64
+
65
+ def to_dict(self):
66
+ return {name: param.dict() for name, param in self.parameters.items()}
67
+
68
+ def to_string(self):
69
+ return ", ".join(
70
+ [f"{param.name}: {param.annotation}={repr(param.default)}" for param in self.parameters.values()]
71
+ )
72
+
73
+
74
+ if __name__ == "__main__":
75
+ from regscale.models.hierarchy import REGSCALE_CLI
76
+
77
+ call = REGSCALE_CLI["login"].callback
78
+ b = SignatureModel.from_callable(command="login", fn=call)
79
+ b
File without changes
@@ -0,0 +1,262 @@
1
+ """
2
+ AWS Inspector Model
3
+ """
4
+
5
+ import csv
6
+ import json
7
+ from typing import List, Optional, TYPE_CHECKING, Tuple, Union
8
+
9
+ if TYPE_CHECKING:
10
+ from regscale.models import Mapping
11
+
12
+ from pathlib import Path
13
+ from pydantic import BaseModel
14
+
15
+ from regscale.core.app.utils.app_utils import error_and_exit
16
+
17
+
18
+ class InspectorRecord(BaseModel):
19
+ """
20
+ AWS Inspector Record
21
+ """
22
+
23
+ aws_account_id: str
24
+ severity: Optional[str] = None
25
+ fix_available: Optional[str] = None
26
+ finding_type: Optional[str] = None
27
+ title: Optional[str] = None
28
+ description: Optional[str] = None
29
+ finding_arn: Optional[str] = None
30
+ first_seen: Optional[str] = None
31
+ last_seen: Optional[str] = None
32
+ last_updated: Optional[str] = None
33
+ resource_id: Optional[str] = None
34
+ container_image_tags: Optional[str] = None
35
+ region: Optional[str] = None
36
+ platform: Optional[str] = None
37
+ resource_tags: Optional[str] = None
38
+ affected_packages: Optional[str] = None
39
+ package_installed_version: Optional[str] = None
40
+ fixed_in_version: Optional[str] = None
41
+ package_remediation: Optional[str] = None
42
+ file_path: Optional[str] = None
43
+ network_paths: Optional[str] = None
44
+ age_days: Optional[str] = None
45
+ remediation: Optional[str] = None
46
+ inspector_score: Optional[str] = None
47
+ inspector_score_vector: Optional[str] = None
48
+ status: Optional[str] = None
49
+ vulnerability_id: Optional[str] = None
50
+ vendor: Optional[str] = None
51
+ vendor_severity: Optional[str] = None
52
+ vendor_advisory: Optional[str] = None
53
+ vendor_advisory_published: Optional[str] = None
54
+ nvd_cvss3_score: Optional[str] = None
55
+ nvd_cvss3_vector: Optional[str] = None
56
+ nvd_cvss2_score: Optional[str] = None
57
+ nvd_cvss2_vector: Optional[str] = None
58
+ vendor_cvss3_score: Optional[str] = None
59
+ vendor_cvss3_vector: Optional[str] = None
60
+ vendor_cvss2_score: Optional[str] = None
61
+ vendor_cvss2_vector: Optional[str] = None
62
+ resource_type: Optional[str] = None
63
+ ami: Optional[str] = None
64
+ resource_public_ipv4: Optional[str] = None
65
+ resource_private_ipv4: Optional[str] = None
66
+ resource_ipv6: Optional[str] = None
67
+ resource_vpc: Optional[str] = None
68
+ port_range: Optional[str] = None
69
+ epss_score: Optional[str] = None
70
+ exploit_available: Optional[str] = None
71
+ last_exploited_at: Optional[str] = None
72
+ lambda_layers: Optional[str] = None
73
+ lambda_package_type: Optional[str] = None
74
+ lambda_last_updated_at: Optional[str] = None
75
+ reference_urls: Optional[str] = None
76
+ detector_name: Optional[str] = None
77
+ package_manager: Optional[str] = None
78
+
79
+ @classmethod
80
+ def process_csv(cls, file_path: Union[str, Path], mapping: "Mapping") -> Tuple[dict, List["InspectorRecord"]]:
81
+ """
82
+ Process CSV file
83
+
84
+ :param Union[str, Path] file_path: File path
85
+ :param Mapping mapping: Mapping object for different headers
86
+ :return: A header dict and a list of InspectorRecord objects
87
+ :rtype: Tuple[dict, List["InspectorRecord"]]
88
+ """
89
+
90
+ with open(file=file_path, mode="r", encoding="utf-8") as f:
91
+ res = []
92
+ reader = csv.DictReader(f)
93
+ header = reader.fieldnames
94
+ header_mapping = {name: name for name in header}
95
+ for row in reader:
96
+ new_row = {header_mapping[key]: value for key, value in row.items()}
97
+ res.append(cls.create_inspector_record_from_csv_data(new_row, mapping))
98
+ return header, res
99
+
100
+ @classmethod
101
+ def process_json(cls, file_path: Union[str, Path], mapping: "Mapping") -> Tuple[dict, List["InspectorRecord"]]:
102
+ """
103
+ Process JSON file
104
+
105
+ :param Union[str, Path] file_path: File path
106
+ :param Mapping mapping: Mapping object for different headers
107
+ :rtype: Tuple[dict, List["InspectorRecord"]]
108
+ :return: An empty dict and a list of InspectorRecord objects
109
+ """
110
+ with open(file=file_path, mode="r", encoding="utf-8") as file_object:
111
+ dat = json.load(file_object)
112
+ if not dat.get("findings"):
113
+ error_and_exit("No findings in JSON file, check the file format and try again.")
114
+ return {}, [cls.create_inspector_record_from_json_data(finding, mapping) for finding in dat.get("findings", [])]
115
+
116
+ @classmethod
117
+ def create_inspector_record_from_json_data(cls, finding: dict, mapping: "Mapping") -> "InspectorRecord":
118
+ """
119
+ Create an InspectorRecord from a csv row of data
120
+
121
+ :param dict finding: The finding data
122
+ :param Mapping mapping: Mapping object for different headers
123
+ :return: An InspectorRecord object
124
+ :rtype: InspectorRecord
125
+ """
126
+ resource = cls.get_resource(finding, mapping)
127
+ details = resource.get("details", {})
128
+ vulnerabilities = mapping.get_value(finding, "packageVulnerabilityDetails", {})
129
+ platform_key = list(details.keys())[0] if details.keys() else None
130
+
131
+ return InspectorRecord(
132
+ aws_account_id=mapping.get_value(finding, "awsAccountId", "", warnings=False),
133
+ description=mapping.get_value(finding, "description", warnings=False),
134
+ exploit_available=mapping.get_value(finding, "exploitAvailable", warnings=False),
135
+ finding_arn=mapping.get_value(finding, "findingArn", warnings=False),
136
+ first_seen=mapping.get_value(finding, "firstObservedAt", warnings=False),
137
+ fix_available=mapping.get_value(finding, "fixAvailable", warnings=False),
138
+ last_seen=mapping.get_value(finding, "lastObservedAt", warnings=False),
139
+ remediation=mapping.get_value(finding, "remediation", {}).get("recommendation", {}).get("text", ""),
140
+ severity=mapping.get_value(finding, "Severity", warnings=False),
141
+ status=mapping.get_value(finding, "status", warnings=False),
142
+ title=mapping.get_value(finding, "title", warnings=False),
143
+ resource_type=resource.get("type"),
144
+ resource_id=resource.get("id"),
145
+ region=resource.get("region"),
146
+ last_updated=mapping.get_value(finding, "updatedAt", warnings=False),
147
+ platform=resource.get("details", {}).get(platform_key, {}).get("platform", ""),
148
+ resource_tags=" ,".join(resource.get("details", {}).get(platform_key, {}).get("imageTags", "")),
149
+ affected_packages=cls.get_vulnerable_package_info(vulnerabilities, "name"),
150
+ package_installed_version=cls.get_vulnerable_package_info(vulnerabilities, "version"),
151
+ fixed_in_version=cls.get_vulnerable_package_info(vulnerabilities, "fixedInVersion"),
152
+ package_remediation=cls.get_vulnerable_package_info(vulnerabilities, "remediation"),
153
+ vulnerability_id=vulnerabilities.get("vulnerabilityId") if vulnerabilities else None,
154
+ vendor=vulnerabilities.get("source") if vulnerabilities else None,
155
+ vendor_severity=mapping.get_value(finding, "severity", warnings=False),
156
+ vendor_advisory=vulnerabilities.get("sourceUrl") if vulnerabilities else None,
157
+ vendor_advisory_published=vulnerabilities.get("vendorCreatedAt") if vulnerabilities else None,
158
+ package_manager=cls.get_vulnerable_package_info(
159
+ mapping.get_value(finding, "packageVulnerabilityDetails", {}, warnings=False), "packageManager"
160
+ ),
161
+ file_path=cls.get_vulnerable_package_info(
162
+ mapping.get_value(finding, "packageVulnerabilityDetails", {}, warnings=False), "filePath"
163
+ ),
164
+ reference_urls=mapping.get_value(finding, "packageVulnerabilityDetails", {}, warnings=False).get(
165
+ "sourceUrl"
166
+ ),
167
+ )
168
+
169
+ @classmethod
170
+ def create_inspector_record_from_csv_data(cls, finding: dict, mapping: "Mapping") -> "InspectorRecord":
171
+ """
172
+ Create an InspectorRecord from a finding
173
+
174
+ :param dict finding: The finding data
175
+ :param Mapping mapping: Mapping object for different headers
176
+ :return: An InspectorRecord object
177
+ :rtype: InspectorRecord
178
+ """
179
+ return InspectorRecord(
180
+ aws_account_id=mapping.get_value(finding, "AWS Account Id"),
181
+ severity=mapping.get_value(finding, "Severity"),
182
+ fix_available=mapping.get_value(finding, "Fix Available"),
183
+ finding_type=mapping.get_value(finding, "Finding Type"),
184
+ title=mapping.get_value(finding, "Title"),
185
+ description=mapping.get_value(finding, "Description"),
186
+ finding_arn=mapping.get_value(finding, "Finding ARN"),
187
+ first_seen=mapping.get_value(finding, "First Seen"),
188
+ last_seen=mapping.get_value(finding, "Last Seen"),
189
+ last_updated=mapping.get_value(finding, "Last Updated"),
190
+ resource_id=mapping.get_value(finding, "Resource ID"),
191
+ container_image_tags=mapping.get_value(finding, "Container Image Tags"),
192
+ region=mapping.get_value(finding, "Region"),
193
+ platform=mapping.get_value(finding, "Platform"),
194
+ resource_tags=mapping.get_value(finding, "Resource Tags"),
195
+ affected_packages=mapping.get_value(finding, "Affected Packages"),
196
+ package_installed_version=mapping.get_value(finding, "Package Installed Version"),
197
+ fixed_in_version=mapping.get_value(finding, "Fixed in Version"),
198
+ package_remediation=mapping.get_value(finding, "Package Remediation"),
199
+ file_path=mapping.get_value(finding, "File Path"),
200
+ network_paths=mapping.get_value(finding, "Network Paths"),
201
+ age_days=mapping.get_value(finding, "Age (Days)"),
202
+ remediation=mapping.get_value(finding, "Remediation"),
203
+ inspector_score=mapping.get_value(finding, "Inspector Score"),
204
+ inspector_score_vector=mapping.get_value(finding, "Inspector Score Vector"),
205
+ status=mapping.get_value(finding, "Status"),
206
+ vulnerability_id=mapping.get_value(finding, "Vulnerability Id"),
207
+ vendor=mapping.get_value(finding, "Vendor"),
208
+ vendor_severity=mapping.get_value(finding, "Vendor Severity"),
209
+ vendor_advisory=mapping.get_value(finding, "Vendor Advisory"),
210
+ vendor_advisory_published=mapping.get_value(finding, "Vendor Advisory Published"),
211
+ nvd_cvss3_score=mapping.get_value(finding, "NVD CVSS3 Score"),
212
+ nvd_cvss3_vector=mapping.get_value(finding, "NVD CVSS3 Vector"),
213
+ nvd_cvss2_score=mapping.get_value(finding, "NVD CVSS2 Score"),
214
+ nvd_cvss2_vector=mapping.get_value(finding, "NVD CVSS2 Vector"),
215
+ vendor_cvss3_score=mapping.get_value(finding, "Vendor CVSS3 Score"),
216
+ vendor_cvss3_vector=mapping.get_value(finding, "Vendor CVSS3 Vector"),
217
+ vendor_cvss2_score=mapping.get_value(finding, "Vendor CVSS2 Score"),
218
+ vendor_cvss2_vector=mapping.get_value(finding, "Vendor CVSS2 Vector"),
219
+ resource_type=mapping.get_value(finding, "Resource Type"),
220
+ ami=mapping.get_value(finding, "Ami"),
221
+ resource_public_ipv4=mapping.get_value(finding, "Resource Public Ipv4"),
222
+ resource_private_ipv4=mapping.get_value(finding, "Resource Private Ipv4"),
223
+ resource_ipv6=mapping.get_value(finding, "Resource Ipv6"),
224
+ resource_vpc=mapping.get_value(finding, "Resource Vpc"),
225
+ port_range=mapping.get_value(finding, "Port Range"),
226
+ epss_score=mapping.get_value(finding, "Epss Score"),
227
+ exploit_available=mapping.get_value(finding, "Exploit Available"),
228
+ last_exploited_at=mapping.get_value(finding, "Last Exploited At"),
229
+ lambda_layers=mapping.get_value(finding, "Lambda Layers"),
230
+ lambda_package_type=mapping.get_value(finding, "Lambda Package Type"),
231
+ lambda_last_updated_at=mapping.get_value(finding, "Lambda Last Updated At"),
232
+ reference_urls=mapping.get_value(finding, "Reference Urls"),
233
+ detector_name=mapping.get_value(finding, "Detector Name"),
234
+ package_manager=mapping.get_value(finding, "Package Manager"),
235
+ )
236
+
237
+ @staticmethod
238
+ def get_resource(finding: dict, mapping: "Mapping") -> dict:
239
+ """
240
+ Get the resource from a finding
241
+
242
+ :param dict finding: The finding data
243
+ :param Mapping mapping: Mapping object for different headers
244
+ :return: The resource data
245
+ :rtype: dict
246
+ """
247
+ resources = mapping.get_value(finding, "resources", [])
248
+ resource = resources.pop() if resources else {}
249
+ return resource
250
+
251
+ @staticmethod
252
+ def get_vulnerable_package_info(vulnerabilities: dict, key: str) -> Optional[str]:
253
+ """
254
+ Get information from a vulnerable package
255
+
256
+ :param dict vulnerabilities: The vulnerabilities data
257
+ :param str key: The key of the information to get
258
+ :return: The information or None if not found
259
+ :rtype: Optional[str]
260
+ """
261
+ vulnerable_packages = vulnerabilities.get("vulnerablePackages", [])
262
+ return vulnerable_packages[0].get(key) if vulnerabilities and vulnerable_packages else None
@@ -0,0 +1,206 @@
1
+ """
2
+ AWS Inspector Scan information
3
+ """
4
+
5
+ import re
6
+ from typing import List, Optional, Tuple
7
+
8
+ from pathlib import Path
9
+
10
+ from regscale.core.app.application import Application
11
+ from regscale.core.app.logz import create_logger
12
+ from regscale.core.app.utils.app_utils import get_current_datetime, is_valid_fqdn
13
+ from regscale.models import ImportValidater
14
+ from regscale.models.integration_models.amazon_models.inspector import InspectorRecord
15
+ from regscale.models.integration_models.flat_file_importer import FlatFileImporter
16
+ from regscale.models.regscale_models.asset import Asset
17
+ from regscale.models.regscale_models.vulnerability import Vulnerability
18
+
19
+
20
+ class InspectorScan(FlatFileImporter):
21
+ """
22
+ AWS Inspector Scan
23
+ """
24
+
25
+ def __init__(self, **kwargs: dict):
26
+ self.name = "amazon"
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.ffi = "First Found on Image"
32
+ json_headers = [
33
+ "awsAccountId",
34
+ "resources",
35
+ "packageVulnerabilityDetails",
36
+ "title",
37
+ "description",
38
+ ]
39
+ csv_headers = [
40
+ "AWS Account Id",
41
+ "Resource ID",
42
+ "Title",
43
+ "Description",
44
+ ]
45
+ file_type = kwargs.get("file_type")
46
+ if file_type == ".json":
47
+ self.required_headers = json_headers
48
+ key = "findings"
49
+ elif file_type == ".csv":
50
+ self.required_headers = csv_headers
51
+ key = None
52
+ else:
53
+ from regscale.exceptions import ValidationException
54
+
55
+ raise ValidationException(f"Unsupported file format: {file_type}, must be .json or .csv.")
56
+ self.mappings_path = kwargs.get("mappings_path")
57
+ self.disable_mapping = kwargs.get("disable_mapping")
58
+ self.validater = ImportValidater(
59
+ self.required_headers, kwargs.get("file_path"), self.mappings_path, self.disable_mapping, key=key
60
+ )
61
+ self.headers = self.validater.parsed_headers
62
+ self.mapping = self.validater.mapping
63
+ logger = create_logger()
64
+ super().__init__(
65
+ logger=logger,
66
+ app=Application(),
67
+ headers=self.headers,
68
+ asset_func=self.create_asset,
69
+ vuln_func=self.create_vuln,
70
+ **kwargs,
71
+ )
72
+
73
+ def file_to_list_of_dicts(self) -> Tuple[dict, List[InspectorRecord]]:
74
+ """
75
+ Override the base class method to handle the AWS Inspector CSV or JSON file format
76
+
77
+ :raises ValueError: If the file format is not supported
78
+ :return: Tuple of a header and a list of inspector objects
79
+ :rtype: Tuple[dict, List[InspectorRecord]]
80
+ """
81
+ file_path = Path(self.attributes.file_path)
82
+ file_ext = file_path.suffix
83
+ if file_ext == ".csv":
84
+ header, res = InspectorRecord.process_csv(file_path, self.mapping)
85
+ elif file_ext == ".json":
86
+ header, res = InspectorRecord.process_json(file_path, self.mapping)
87
+ else:
88
+ raise ValueError(f"Unsupported file format: {file_ext}")
89
+ return header, res
90
+
91
+ def create_asset(self, dat: Optional[InspectorRecord] = None) -> Asset:
92
+ """
93
+ Create an asset from a row in an Inspector Record
94
+
95
+ :param Optional[InspectorRecord] dat: Data row from an Inspector Record, defaults to None
96
+ :return: RegScale Asset object
97
+ :rtype: Asset
98
+ """
99
+ hostname = dat.resource_id
100
+ distro = dat.platform
101
+ # Container Image, Virtual Machine (VM), etc.
102
+ asset_type = self.amazon_type_map().get(dat.resource_type, "Other")
103
+
104
+ return Asset(
105
+ **{
106
+ "id": 0,
107
+ "name": hostname,
108
+ "awsIdentifier": hostname,
109
+ "ipAddress": "",
110
+ "isPublic": True,
111
+ "status": "Active (On Network)",
112
+ "assetCategory": "Hardware",
113
+ "bLatestScan": True,
114
+ "bAuthenticatedScan": True,
115
+ "scanningTool": self.name,
116
+ "assetOwnerId": self.config["userId"],
117
+ "assetType": asset_type,
118
+ "fqdn": hostname if is_valid_fqdn(hostname) else None,
119
+ "operatingSystem": Asset.find_os(distro),
120
+ "systemAdministratorId": self.config["userId"],
121
+ "parentId": self.attributes.parent_id,
122
+ "parentModule": self.attributes.parent_module,
123
+ }
124
+ )
125
+
126
+ def create_vuln(self, dat: Optional[InspectorRecord] = None, **kwargs) -> Optional[Vulnerability]:
127
+ """
128
+ Create a vulnerability from an Inspector Record
129
+
130
+ :param Optional[InspectorRecord] dat: Data row an Inspector Record, defaults to None
131
+ :return: RegScale Vulnerability object or None
132
+ :rtype: Optional[Vulnerability]
133
+ """
134
+ hostname = dat.resource_id
135
+ distro = dat.platform
136
+ cve: str = dat.vulnerability_id
137
+ description: str = dat.description
138
+ title = dat.title if dat.title else dat.description
139
+ aws_severity = dat.severity
140
+ severity = self.severity_mapper(aws_severity)
141
+ config = self.attributes.app.config
142
+ asset_match = [asset for asset in self.data["assets"] if asset.name == hostname]
143
+ asset = asset_match[0] if asset_match else None
144
+ if dat and asset_match:
145
+ return Vulnerability(
146
+ id=0,
147
+ scanId=0, # set later
148
+ parentId=asset.id,
149
+ parentModule="assets",
150
+ ipAddress="0.0.0.0", # No ip address available
151
+ lastSeen=dat.last_seen,
152
+ firstSeen=dat.first_seen,
153
+ daysOpen=None,
154
+ dns=hostname,
155
+ mitigated=None,
156
+ operatingSystem=(Asset.find_os(distro) if Asset.find_os(distro) else None),
157
+ severity=severity,
158
+ plugInName=dat.title,
159
+ plugInId=self.convert_cve_string_to_int(dat.vulnerability_id),
160
+ cve=cve,
161
+ vprScore=None,
162
+ tenantsId=0,
163
+ title=f"{description} on asset {asset.name}",
164
+ description=description,
165
+ plugInText=title,
166
+ createdById=config["userId"],
167
+ lastUpdatedById=config["userId"],
168
+ dateCreated=get_current_datetime(),
169
+ extra_data={
170
+ "solution": dat.remediation,
171
+ "proof": dat.finding_arn,
172
+ },
173
+ )
174
+ return None
175
+
176
+ @staticmethod
177
+ def amazon_type_map() -> dict:
178
+ """
179
+ Map Amazon Inspector resource types to RegScale asset types
180
+ """
181
+ return {
182
+ "AWS_EC2_INSTANCE": "Virtual Machine (VM)",
183
+ "AWS_ECR_CONTAINER_IMAGE": "Container Image",
184
+ }
185
+
186
+ @staticmethod
187
+ def severity_mapper(aws_severity):
188
+ """
189
+ Map AWS Inspector severity to RegScale severity
190
+ """
191
+
192
+ severity_map = {"CRITICAL": "high", "HIGH": "high", "LOW": "low", "MEDIUM": "medium", "UNTRIAGED": "high"}
193
+ return severity_map.get(aws_severity, "low")
194
+
195
+ @staticmethod
196
+ def convert_cve_string_to_int(s: str) -> int:
197
+ """
198
+ Convert a CVE string to an integer
199
+
200
+ :param str s: CVE string
201
+ :return: CVE integer
202
+ :rtype: int
203
+ """
204
+ numbers = re.findall(r"\d+", s)
205
+ # merge numbers to string
206
+ return int("".join(numbers))