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,73 @@
1
+ """
2
+ This module contains the Click command group for Sicura.
3
+ """
4
+
5
+ import logging
6
+
7
+ import click
8
+ from rich.console import Console
9
+ from regscale.models import regscale_id
10
+
11
+ logger = logging.getLogger("regscale")
12
+ console = Console()
13
+
14
+
15
+ @click.group()
16
+ def sicura():
17
+ """
18
+ Sicura Integration
19
+
20
+ Commands for interacting with Sicura security scanning platform.
21
+ """
22
+
23
+
24
+ @sicura.command(name="sync_assets")
25
+ @regscale_id(help="RegScale will create and update assets as children of this record.")
26
+ def sync_assets(regscale_id):
27
+ """
28
+ Sync Sicura assets to RegScale.
29
+
30
+ Fetches all devices from Sicura and synchronizes them as assets into RegScale.
31
+ """
32
+ try:
33
+ from regscale.integrations.commercial.sicura.scanner import SicuraIntegration
34
+
35
+ integration = SicuraIntegration(
36
+ plan_id=regscale_id,
37
+ )
38
+
39
+ with console.status("[bold green]Syncing assets from Sicura to RegScale..."):
40
+ # Using import_assets method which handles the synchronization
41
+ integration.sync_assets(plan_id=regscale_id)
42
+
43
+ console.print("[bold green]Asset synchronization complete.")
44
+
45
+ except Exception as e:
46
+ logger.error(f"Error syncing assets: {e}", exc_info=True)
47
+ console.print(f"[bold red]Error syncing assets: {e}")
48
+
49
+
50
+ @sicura.command(name="sync_findings")
51
+ @regscale_id(help="RegScale will create and update findings as children of this record.")
52
+ def sync_findings(regscale_id):
53
+ """
54
+ Sync Sicura findings to RegScale.
55
+
56
+ Fetches all scan results from Sicura and synchronizes them as findings into RegScale.
57
+ """
58
+ try:
59
+ from regscale.integrations.commercial.sicura.scanner import SicuraIntegration
60
+
61
+ integration = SicuraIntegration(
62
+ plan_id=regscale_id,
63
+ )
64
+
65
+ with console.status("[bold green]Syncing findings from Sicura to RegScale..."):
66
+ # Using import_findings method which handles the synchronization
67
+ integration.sync_findings(plan_id=regscale_id)
68
+
69
+ console.print("[bold green]Finding synchronization complete.")
70
+
71
+ except Exception as e:
72
+ logger.error(f"Error syncing findings: {e}", exc_info=True)
73
+ console.print(f"[bold red]Error syncing findings: {e}")
@@ -0,0 +1,481 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ RegScale Sicura Integration
5
+ """
6
+ import datetime
7
+ from typing import Generator, Iterator, Any
8
+
9
+ from regscale.core.utils.date import date_str
10
+ from regscale.integrations.commercial.sicura.api import SicuraAPI, ScanReport, SicuraProfile, Device, ScanResult
11
+ from regscale.integrations.scanner_integration import (
12
+ logger,
13
+ IntegrationFinding,
14
+ ScannerIntegration,
15
+ IntegrationAsset,
16
+ ScannerIntegrationType,
17
+ issue_due_date,
18
+ )
19
+ from regscale.models import regscale_models
20
+ from regscale.models.regscale_models import AssetType
21
+
22
+
23
+ class SicuraIntegration(ScannerIntegration):
24
+ """
25
+ Sicura Integration for RegScale
26
+
27
+ This integration fetches assets and scan findings from Sicura
28
+ """
29
+
30
+ options_map_assets_to_components = True
31
+ import_closed_findings = False
32
+
33
+ title = "Sicura"
34
+ type = ScannerIntegrationType.CHECKLIST
35
+
36
+ # Map Sicura scan result states to RegScale checklist statuses
37
+ checklist_status_map = {
38
+ "pass": regscale_models.ChecklistStatus.PASS,
39
+ "fail": regscale_models.ChecklistStatus.FAIL,
40
+ }
41
+
42
+ # Map severity levels
43
+ finding_severity_map = {
44
+ "high": regscale_models.IssueSeverity.High,
45
+ "medium": regscale_models.IssueSeverity.Moderate,
46
+ "low": regscale_models.IssueSeverity.Low,
47
+ }
48
+
49
+ def __init__(self, *args, **kwargs):
50
+ """
51
+ Initialize the Sicura Integration
52
+
53
+ :param args: Arguments to pass to the parent class
54
+ :param kwargs: Keyword arguments to pass to the parent class
55
+ """
56
+ super().__init__(*args, **kwargs)
57
+ self.api = SicuraAPI()
58
+
59
+ def fetch_findings(self, **kwargs) -> Generator[IntegrationFinding, None, None]:
60
+ """
61
+ Fetches findings from Sicura API
62
+
63
+ :param kwargs: Additional arguments
64
+ :yields: IntegrationFinding objects
65
+ :return: Generator of IntegrationFinding objects
66
+ :rtype: Generator[IntegrationFinding, None, None]
67
+ """
68
+ logger.info("Fetching findings from Sicura...")
69
+
70
+ # Get all devices
71
+ devices = kwargs.get("devices", self.api.get_devices())
72
+
73
+ if not devices:
74
+ logger.warning("No devices found in Sicura")
75
+ return
76
+
77
+ self.num_findings_to_process = 0
78
+ findings_count = 0
79
+
80
+ # Process each device
81
+ for device in devices:
82
+ for finding in self._process_device_findings(device):
83
+ findings_count += 1
84
+ yield finding
85
+
86
+ self.num_findings_to_process = findings_count
87
+
88
+ def _process_device_findings(self, device: Device) -> Generator[IntegrationFinding, None, None]:
89
+ """
90
+ Process findings for a single device
91
+
92
+ :param Device device: The device to process
93
+ :yield: IntegrationFinding objects
94
+ :rtype: Generator[IntegrationFinding, None, None]
95
+ """
96
+ logger.info(f"Fetching scan results for device: {device.fqdn}")
97
+ if not device.fqdn:
98
+ logger.warning(f"Device {device.name} has no FQDN, skipping")
99
+ return
100
+
101
+ # Profiles to scan
102
+ profiles = [SicuraProfile.I_MISSION_CRITICAL_CLASSIFIED, SicuraProfile.LEVEL_1_SERVER]
103
+
104
+ for profile in profiles:
105
+ yield from self._process_profile_findings(device, profile)
106
+
107
+ def _process_profile_findings(
108
+ self, device: Device, profile: SicuraProfile
109
+ ) -> Generator[IntegrationFinding, None, None]:
110
+ """
111
+ Process findings for a device with a specific profile
112
+
113
+ :param Device device: The device to process
114
+ :param SicuraProfile profile: The profile to process
115
+ :yield: IntegrationFinding objects
116
+ :rtype: Generator[IntegrationFinding, None, None]
117
+ """
118
+ scan_report = self.api.get_scan_results(fqdn=device.fqdn, profile=profile)
119
+
120
+ if not scan_report:
121
+ logger.warning(f"No scan results found for device: {device.fqdn} with profile: {profile}")
122
+ return
123
+
124
+ # Process scan results based on the report type
125
+ if isinstance(scan_report, ScanReport):
126
+ yield from self._process_scan_report_findings(device, scan_report.scans)
127
+ elif isinstance(scan_report, dict) and scan_report.get("scans"):
128
+ yield from self._process_scan_report_findings(device, scan_report.get("scans", []))
129
+
130
+ def _process_scan_report_findings(self, device: Device, scans: list) -> Generator[IntegrationFinding, None, None]:
131
+ """
132
+ Process findings from a scan report
133
+
134
+ :param Device device: The device being scanned
135
+ :param list scans: The list of scans to process
136
+ :yield: IntegrationFinding objects
137
+ :rtype: Generator[IntegrationFinding, None, None]
138
+ """
139
+ for scan in scans:
140
+ yield from self.parse_finding(device, scan)
141
+
142
+ def parse_finding(
143
+ self,
144
+ device: Device,
145
+ scan: Any,
146
+ ) -> Generator[IntegrationFinding, None, None]:
147
+ """
148
+ Creates and yields IntegrationFinding objects from Sicura scan results, one per CCI reference
149
+
150
+ :param Device device: The device object
151
+ :param Any scan: The scan data
152
+ :yield: IntegrationFinding objects
153
+ :rtype: Generator[IntegrationFinding, None, None]
154
+ """
155
+ # Extract basic information from device and scan
156
+ asset_identifier = device.fqdn
157
+ platform = device.platforms
158
+
159
+ # Extract scan data
160
+ scan_data = self._extract_scan_data(scan)
161
+ title = scan_data["title"]
162
+ ce_name = scan_data["ce_name"]
163
+ result = scan_data["result"]
164
+ description = scan_data["description"]
165
+ state = scan_data["state"]
166
+ state_reason = scan_data["state_reason"]
167
+ controls = scan_data["controls"]
168
+
169
+ # Extract control references
170
+ cci_refs, srg_refs = self._extract_control_refs(controls)
171
+
172
+ # Determine severity and due date
173
+ severity = self._determine_severity(title)
174
+ created_date = date_str(datetime.datetime.now())
175
+ due_date = issue_due_date(severity, created_date, title=self.title)
176
+
177
+ # Common mitigation recommendation
178
+ mitigation = f"Fix the issues identified: {', '.join(state_reason) if state_reason else 'See description'}"
179
+
180
+ # If no CCI references, use empty string as the only CCI ref
181
+ if not cci_refs:
182
+ cci_refs = [""]
183
+
184
+ # Create a finding for each CCI reference
185
+ for cci_ref in cci_refs:
186
+ # Create a ScanResult object to hold the scan data
187
+ scan_result = ScanResult(
188
+ title=title,
189
+ ce_name=ce_name,
190
+ result=result,
191
+ description=description,
192
+ state=state,
193
+ state_reason=state_reason,
194
+ controls=controls,
195
+ )
196
+
197
+ yield from self._create_finding_for_cci(
198
+ asset_identifier=asset_identifier,
199
+ platform=platform,
200
+ cci_ref=cci_ref,
201
+ scan_result=scan_result,
202
+ srg_refs=srg_refs,
203
+ severity=severity,
204
+ created_date=created_date,
205
+ due_date=due_date,
206
+ mitigation=mitigation,
207
+ )
208
+
209
+ def _extract_scan_data(self, scan: Any) -> dict:
210
+ """
211
+ Extract scan data from the scan object
212
+
213
+ :param Any scan: The scan object
214
+ :return: Dictionary with scan data
215
+ :rtype: dict
216
+ """
217
+ if isinstance(scan, dict):
218
+ return {
219
+ "title": scan.get("title", ""),
220
+ "ce_name": scan.get("ce_name", ""),
221
+ "result": scan.get("result", ""),
222
+ "description": scan.get("description", ""),
223
+ "state": scan.get("state", ""),
224
+ "state_reason": scan.get("state_reason", []),
225
+ "controls": scan.get("controls", {}),
226
+ }
227
+ else:
228
+ return {
229
+ "title": scan.title,
230
+ "ce_name": scan.ce_name,
231
+ "result": scan.result,
232
+ "description": scan.description,
233
+ "state": scan.state,
234
+ "state_reason": scan.state_reason,
235
+ "controls": scan.controls if hasattr(scan, "controls") else {},
236
+ }
237
+
238
+ def _extract_control_refs(self, controls: dict) -> tuple:
239
+ """
240
+ Extract CCI and SRG references from controls
241
+
242
+ :param dict controls: The controls dictionary
243
+ :return: Tuple of (cci_refs, srg_refs)
244
+ :rtype: tuple
245
+ """
246
+ cci_refs = []
247
+ srg_refs = []
248
+
249
+ for control_key, control_value in controls.items():
250
+ if control_key.startswith("cci:"):
251
+ # Extract CCI number (e.g., "cci:CCI-000366" -> "CCI-000366")
252
+ cci_ref = control_key.split(":", 1)[1] if ":" in control_key else control_key
253
+ cci_refs.append(cci_ref)
254
+ elif control_key.startswith("SRG-"):
255
+ srg_refs.append(control_key)
256
+
257
+ return cci_refs, srg_refs
258
+
259
+ def _determine_severity(self, title: str) -> regscale_models.IssueSeverity:
260
+ """
261
+ Determine severity based on title
262
+
263
+ :param str title: The finding title
264
+ :return: Severity enum value
265
+ :rtype: regscale_models.IssueSeverity
266
+ """
267
+ severity_text = "medium"
268
+ if "critical" in title.lower() or "cat i" in title.lower():
269
+ severity_text = "high"
270
+ elif "low" in title.lower() or "cat iii" in title.lower():
271
+ severity_text = "low"
272
+
273
+ return self.get_finding_severity(severity_text)
274
+
275
+ def _create_finding_for_cci(
276
+ self,
277
+ asset_identifier,
278
+ platform,
279
+ cci_ref,
280
+ scan_result: ScanResult,
281
+ srg_refs,
282
+ severity,
283
+ created_date,
284
+ due_date,
285
+ mitigation,
286
+ ) -> Generator[IntegrationFinding, None, None]:
287
+ """
288
+ Create a finding for a single CCI reference
289
+
290
+ :param str asset_identifier: The asset identifier
291
+ :param str platform: The platform
292
+ :param str cci_ref: The CCI reference
293
+ :param ScanResult scan_result: The scan result data
294
+ :param list srg_refs: The SRG references
295
+ :param regscale_models.IssueSeverity severity: The severity
296
+ :param str created_date: The created date
297
+ :param str due_date: The due date
298
+ :param str mitigation: The mitigation
299
+ :yield: IntegrationFinding objects
300
+ :rtype: Generator[IntegrationFinding, None, None]
301
+ """
302
+ # Determine if this is a CCI finding or a regular finding
303
+ is_cci_finding = cci_ref != ""
304
+
305
+ # Extract values from scan_result
306
+ title = scan_result.title
307
+ ce_name = scan_result.ce_name
308
+ result = scan_result.result
309
+ description = scan_result.description
310
+ state = scan_result.state
311
+ state_reason = scan_result.state_reason
312
+
313
+ # Set title based on whether it's a CCI finding
314
+ finding_title = title if not is_cci_finding else f"{title} (CCI: {cci_ref})"
315
+
316
+ # Create results text
317
+ results = self._create_results_text(
318
+ title, ce_name, result, description, state, state_reason, cci_ref, srg_refs, is_cci_finding
319
+ )
320
+
321
+ # Create external ID
322
+ external_id = (
323
+ f"{ce_name}:{asset_identifier}" if not is_cci_finding else f"{ce_name}:{cci_ref}:{asset_identifier}"
324
+ )
325
+
326
+ # Create and yield the finding
327
+ yield IntegrationFinding(
328
+ asset_identifier=asset_identifier,
329
+ control_labels=[], # Empty list as controls will be mapped via other mechanisms
330
+ title=finding_title,
331
+ issue_title=finding_title,
332
+ category=ce_name,
333
+ severity=severity,
334
+ description=description,
335
+ status=regscale_models.IssueStatus.Open if result == "fail" else regscale_models.IssueStatus.Closed,
336
+ checklist_status=self.get_checklist_status(result),
337
+ external_id=external_id,
338
+ vulnerability_number=ce_name,
339
+ cci_ref=cci_ref,
340
+ rule_id=ce_name,
341
+ rule_version="1.0",
342
+ results=results,
343
+ recommendation_for_mitigation=mitigation,
344
+ comments="",
345
+ poam_comments="",
346
+ date_created=created_date,
347
+ due_date=due_date,
348
+ plugin_name=ce_name,
349
+ observations=f"Result: {result}, State: {state}",
350
+ gaps=description,
351
+ evidence=f"State reasons: {', '.join(state_reason) if state_reason else 'N/A'}",
352
+ impact="Security compliance impact",
353
+ baseline=platform,
354
+ )
355
+
356
+ def _create_results_text(
357
+ self, title, ce_name, result, description, state, state_reason, cci_ref, srg_refs, is_cci_finding
358
+ ) -> str:
359
+ """
360
+ Create the results text for a finding
361
+
362
+ :param str title: The finding title
363
+ :param str ce_name: The CE name
364
+ :param str result: The result
365
+ :param str description: The description
366
+ :param str state: The state
367
+ :param list state_reason: The state reason
368
+ :param str cci_ref: The CCI reference
369
+ :param list srg_refs: The SRG references
370
+ :param bool is_cci_finding: Whether this is a CCI finding
371
+ :return: The results text
372
+ :rtype: str
373
+ """
374
+ # Create the results text with conditional CCI reference section
375
+ results_parts = [
376
+ f"Title: {title}",
377
+ f"Check: {ce_name}",
378
+ f"Result: {result}",
379
+ f"Description: {description}",
380
+ f"State: {state}",
381
+ f"State Reason: {', '.join(state_reason) if state_reason else 'N/A'}",
382
+ ]
383
+
384
+ # Add CCI reference only if it exists
385
+ if is_cci_finding:
386
+ results_parts.append(f"CCI Reference: {cci_ref}")
387
+
388
+ # Always add SRG references
389
+ results_parts.append(f"SRG References: {', '.join(srg_refs)}")
390
+
391
+ # Join all parts with newlines
392
+ return "\n".join(results_parts)
393
+
394
+ def fetch_assets(self, **kwargs) -> Iterator[IntegrationAsset]:
395
+ """
396
+ Fetches assets from Sicura API
397
+
398
+ :param kwargs: Additional arguments
399
+ :yield: IntegrationAsset objects
400
+ :return: Iterator of IntegrationAsset objects
401
+ :rtype: Iterator[IntegrationAsset]
402
+ """
403
+ logger.info("Fetching assets from Sicura...")
404
+
405
+ # Get all devices
406
+ pending_devices = self.api.get_pending_devices()
407
+ for pending_device in pending_devices:
408
+ print(f"Pending device: {pending_device}")
409
+ self.api.accept_pending_device(pending_device.id)
410
+ task_id = self.api.create_scan_task(
411
+ device_id=pending_device.id,
412
+ platform=pending_device.platform,
413
+ profile=SicuraProfile.I_MISSION_CRITICAL_CLASSIFIED,
414
+ )
415
+ if task_id:
416
+ self.api.wait_for_scan_results(
417
+ task_id=task_id,
418
+ fqdn=pending_device.fqdn,
419
+ platform=pending_device.platform,
420
+ profile=SicuraProfile.I_MISSION_CRITICAL_CLASSIFIED,
421
+ )
422
+ else:
423
+ logger.warning(f"Failed to create scan task for device {pending_device.fqdn}")
424
+ continue # Continue to next device if creating scan task failed
425
+
426
+ task_id = self.api.create_scan_task(
427
+ device_id=pending_device.id, platform=pending_device.platform, profile=SicuraProfile.LEVEL_1_SERVER
428
+ )
429
+ if task_id:
430
+ self.api.wait_for_scan_results(
431
+ task_id=task_id,
432
+ fqdn=pending_device.fqdn,
433
+ platform=pending_device.platform,
434
+ profile=SicuraProfile.LEVEL_1_SERVER,
435
+ )
436
+ else:
437
+ logger.warning(f"Failed to create scan task for device {pending_device.fqdn}")
438
+ # No continue needed here as we're at the end of the loop iteration
439
+
440
+ devices = self.api.get_devices()
441
+
442
+ if not devices:
443
+ logger.warning("No devices found in Sicura")
444
+ return
445
+
446
+ self.num_assets_to_process = len(devices)
447
+
448
+ loading_devices = self.asset_progress.add_task(
449
+ f"[#f8b737]Loading {len(devices)} Sicura devices.",
450
+ total=len(devices),
451
+ )
452
+
453
+ for device in devices:
454
+ # Skip devices without an FQDN
455
+ if not device.fqdn:
456
+ logger.warning(f"Device {device.name} has no FQDN, skipping")
457
+ self.asset_progress.update(loading_devices, advance=1)
458
+ continue
459
+
460
+ # Extract platform as the component name if available
461
+ component_names = []
462
+ if device.platforms:
463
+ component_names.append(device.platforms)
464
+
465
+ # Create an asset from the device information
466
+ yield IntegrationAsset(
467
+ name=device.name,
468
+ identifier=device.fqdn,
469
+ asset_type=AssetType.VM, # Default to server type
470
+ ip_address=device.ip_address,
471
+ fqdn=device.fqdn,
472
+ asset_owner_id=self.assessor_id,
473
+ parent_id=self.plan_id,
474
+ parent_module=regscale_models.SecurityPlan.get_module_slug(),
475
+ asset_category=regscale_models.AssetCategory.Hardware,
476
+ component_names=component_names,
477
+ component_type=regscale_models.ComponentType.Hardware,
478
+ external_id=str(device.id) if device.id else None,
479
+ )
480
+
481
+ self.asset_progress.update(loading_devices, advance=1)
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """DuroSuite Variables"""
4
+
5
+ from regscale.core.app.utils.variables import RsVariableType, RsVariablesMeta
6
+
7
+
8
+ class SicuraVariables(metaclass=RsVariablesMeta):
9
+ """
10
+ Sicura Variables class to define class-level attributes with type annotations and examples
11
+ """
12
+
13
+ # Define class-level attributes with type annotations and examples
14
+ sicuraEnabled: RsVariableType(bool, "True", default=False) # type: ignore # noqa: F722,F821
15
+ sicuraURL: RsVariableType(str, "https://sicura.mydomain.com") # type: ignore # noqa: F722,F821
16
+ sicuraToken: RsVariableType(str, "your-sicura-token") # type: ignore # noqa: F722,F821
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Snyk RegScale integration"""
4
+ from datetime import datetime
5
+ from os import PathLike
6
+ from typing import Optional
7
+
8
+ import click
9
+
10
+ from regscale.models.integration_models.flat_file_importer import FlatFileImporter
11
+ from regscale.models.integration_models.snyk import Snyk
12
+
13
+
14
+ @click.group()
15
+ def snyk():
16
+ """Performs actions on Snyk export files."""
17
+
18
+
19
+ @snyk.command(name="import_snyk")
20
+ @FlatFileImporter.common_scanner_options(
21
+ message="File path to the folder containing Snyk .xlsx files to process to RegScale.",
22
+ prompt="File path for Snyk files",
23
+ import_name="snyk",
24
+ )
25
+ def import_snyk(
26
+ folder_path: PathLike[str],
27
+ regscale_ssp_id: int,
28
+ scan_date: datetime,
29
+ mappings_path: PathLike[str],
30
+ disable_mapping: bool,
31
+ s3_bucket: str,
32
+ s3_prefix: str,
33
+ aws_profile: str,
34
+ upload_file: bool,
35
+ ):
36
+ """
37
+ Import scans, vulnerabilities and assets to RegScale from Snyk export files
38
+ """
39
+ import_synk_files(
40
+ folder_path=folder_path,
41
+ regscale_ssp_id=regscale_ssp_id,
42
+ scan_date=scan_date,
43
+ mappings_path=mappings_path,
44
+ disable_mapping=disable_mapping,
45
+ s3_bucket=s3_bucket,
46
+ s3_prefix=s3_prefix,
47
+ aws_profile=aws_profile,
48
+ upload_file=upload_file,
49
+ )
50
+
51
+
52
+ def import_synk_files(
53
+ folder_path: PathLike[str],
54
+ regscale_ssp_id: int,
55
+ scan_date: datetime,
56
+ mappings_path: PathLike[str],
57
+ disable_mapping: bool,
58
+ s3_bucket: str,
59
+ s3_prefix: str,
60
+ aws_profile: str,
61
+ upload_file: Optional[bool] = True,
62
+ ) -> None:
63
+ """
64
+ Import Snyk scans, vulnerabilities and assets to RegScale from Snyk files
65
+
66
+ :param PathLike[str] folder_path: File path to the folder containing Snyk .xlsx files to process to RegScale
67
+ :param int regscale_ssp_id: The RegScale SSP ID
68
+ :param datetime scan_date: The date of the scan
69
+ :param PathLike[str] mappings_path: The path to the mappings file
70
+ :param bool disable_mapping: Whether to disable custom mappings
71
+ :param str s3_bucket: The S3 bucket to download the files from
72
+ :param str s3_prefix: The S3 prefix to download the files from
73
+ :param str aws_profile: The AWS profile to use for S3 access
74
+ :param Optional[bool] upload_file: Whether to upload the file to RegScale after processing, defaults to True
75
+ :rtype: None
76
+ """
77
+ FlatFileImporter.import_files(
78
+ import_type=Snyk,
79
+ import_name="Snyk",
80
+ file_types=".xlsx",
81
+ folder_path=folder_path,
82
+ regscale_ssp_id=regscale_ssp_id,
83
+ scan_date=scan_date,
84
+ mappings_path=mappings_path,
85
+ disable_mapping=disable_mapping,
86
+ s3_bucket=s3_bucket,
87
+ s3_prefix=s3_prefix,
88
+ aws_profile=aws_profile,
89
+ upload_file=upload_file,
90
+ )