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
regscale/regscale.py ADDED
@@ -0,0 +1,815 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Main script for starting RegScale CLI application"""
4
+ # standard python imports
5
+ import logging
6
+ import os
7
+ import sys
8
+
9
+ # Initialize config from AWS Secrets Manager if running in container
10
+ secret_name = os.getenv("SECRET_NAME")
11
+ if os.getenv("REGSCALE_CONTAINER") == "Yes" and secret_name:
12
+ try:
13
+ import boto3
14
+
15
+ session = boto3.session.Session()
16
+ client = session.client("secretsmanager")
17
+ response = client.get_secret_value(SecretId=secret_name)
18
+ secret = response["SecretString"]
19
+
20
+ # Write the secret to init.yaml
21
+ config_path = "/tmp/init.yaml"
22
+ with open(config_path, "w") as f:
23
+ f.write(secret)
24
+
25
+ # Set the config path environment variable
26
+ os.environ["REGSCALE_CONFIG"] = config_path
27
+
28
+ logging.info(f"Loaded configuration from AWS Secrets Manager: {secret_name}")
29
+ except Exception as e:
30
+ logging.error(f"Failed to load secret from AWS Secrets Manager: {str(e)}")
31
+ sys.exit(1)
32
+
33
+ # flake8: noqa: E402
34
+ import time
35
+ from getpass import getpass
36
+ from typing import Any, Optional
37
+ from urllib.parse import urlparse
38
+
39
+ import click
40
+ import psutil
41
+ from rich.console import Console
42
+
43
+ from regscale.models.app_models.click import NotRequiredIf, regscale_id, regscale_module
44
+
45
+ if working_dir := os.getenv("REGSCALE_WORKDIR"):
46
+ os.chdir(working_dir)
47
+
48
+ start_time = time.time() # noqa
49
+ import importlib
50
+
51
+ ############################################################
52
+ # Internal Integrations
53
+ ############################################################
54
+ import regscale.core.app.internal.healthcheck as hc
55
+ import regscale.core.app.internal.login as lg
56
+
57
+ ############################################################
58
+ # Versioning
59
+ ############################################################
60
+ from regscale import __version__
61
+ from regscale.core.app import create_logger
62
+
63
+ logger = create_logger()
64
+
65
+
66
+ def import_command_with_timing(
67
+ module_name: str, command_name: str, warning_time_threshold: int = 0.02, warning_memory_threshold: int = 10.0
68
+ ) -> Any:
69
+ """
70
+ Import a command from a module and log a warning if the import takes longer than the threshold
71
+
72
+ :param str module_name: The name of the module to import the command from
73
+ :param str command_name: The name of the command to import
74
+ :param int warning_time_threshold: The threshold in seconds for logging a warning if the import takes longer, default is 0.02 seconds
75
+ :param int warning_memory_threshold: The threshold in MB for logging a warning if the memory increase is greater than the threshold, default is 10.0 MB :return: The command object imported from the module
76
+ :raises ImportError: If the command is not found in the module
77
+ :return: The command object imported from the module
78
+ :rtype: Any
79
+ """
80
+ if logger.getEffectiveLevel() == logging.DEBUG:
81
+ before_import = set(sys.modules.keys())
82
+ memory_before = psutil.Process().memory_info().rss / (1024 * 1024) # Memory in MB
83
+
84
+ start_time = time.time()
85
+ module = importlib.import_module(module_name)
86
+ command = getattr(module, command_name, None)
87
+ elapsed_time = time.time() - start_time
88
+
89
+ after_import = set(sys.modules.keys())
90
+ new_modules = after_import - before_import
91
+ memory_after = psutil.Process().memory_info().rss / (1024 * 1024) # Memory in MB
92
+
93
+ if elapsed_time > warning_time_threshold or memory_after - memory_before > warning_memory_threshold:
94
+ logger.debug(f"Warning: Importing {command_name} from {module_name} took {elapsed_time} seconds to import!")
95
+ logger.debug(f"New modules loaded during import: {new_modules}")
96
+ logger.debug(f"Memory used after import: {memory_after:.2f} MB")
97
+ logger.debug(f"Memory increase: {(memory_after - memory_before):.2f} MB")
98
+ logger.debug("--------------------------------------------------")
99
+ else:
100
+ start_time = time.time()
101
+ module = importlib.import_module(module_name)
102
+ command = getattr(module, command_name, None)
103
+ elapsed_time = time.time() - start_time
104
+ if elapsed_time > 0.01 and logger.level >= logging.DEBUG:
105
+ logger.debug(f"Warning: Importing {command_name} from {module_name} took {elapsed_time} seconds to import!")
106
+
107
+ if command is None:
108
+ raise ImportError(f"No command named '{command_name}' found in '{module_name}'.")
109
+ return command
110
+
111
+
112
+ ############################################################
113
+ # Application Integrations
114
+ ############################################################
115
+ ENCRYPT = "regscale.core.app.internal.encrypt"
116
+ INTERNAL = "regscale.core.app.internal"
117
+ actions = import_command_with_timing(INTERNAL, "admin_actions")
118
+ assessments = import_command_with_timing(INTERNAL, "assessments")
119
+ catalog = import_command_with_timing(INTERNAL, "catalog")
120
+ compare = import_command_with_timing(INTERNAL, "compare")
121
+ control_editor = import_command_with_timing(INTERNAL, "control_editor")
122
+ IOA21H98 = import_command_with_timing(ENCRYPT, "IOA21H98")
123
+ JH0847 = import_command_with_timing(ENCRYPT, "JH0847")
124
+ YO9322 = import_command_with_timing(ENCRYPT, "YO9322")
125
+ evidence = import_command_with_timing(INTERNAL, "evidence")
126
+ file_upload = import_command_with_timing("regscale.core.app.internal.file_uploads", "file_upload")
127
+ migrations = import_command_with_timing(INTERNAL, "migrations")
128
+ model = import_command_with_timing(INTERNAL, "model")
129
+ issues = import_command_with_timing(INTERNAL, "issues")
130
+
131
+ ############################################################
132
+ # Public Integrations
133
+ ############################################################
134
+ PUBLIC = "regscale.integrations.public"
135
+ alienvault = import_command_with_timing(PUBLIC, "alienvault")
136
+ cisa = import_command_with_timing(PUBLIC, "cisa")
137
+ emass = import_command_with_timing(PUBLIC, "emass")
138
+ fedramp = import_command_with_timing(PUBLIC, "fedramp")
139
+ nist = import_command_with_timing(PUBLIC, "nist")
140
+ oscal = import_command_with_timing(PUBLIC, "oscal")
141
+ criticality_updater = import_command_with_timing(PUBLIC, "criticality_updater")
142
+
143
+ ############################################################
144
+ # Commercial Integrations
145
+ ############################################################
146
+ COMMERCIAL = "regscale.integrations.commercial"
147
+ ad = import_command_with_timing(COMMERCIAL, "ad")
148
+ aqua = import_command_with_timing(COMMERCIAL, "aqua")
149
+ awsv2 = import_command_with_timing(COMMERCIAL, "aws")
150
+ azure = import_command_with_timing(COMMERCIAL, "azure")
151
+ burp = import_command_with_timing(COMMERCIAL, "burp")
152
+ assets = import_command_with_timing("regscale.integrations.commercial.synqly.assets", "assets")
153
+ vulnerabilities = import_command_with_timing(
154
+ "regscale.integrations.commercial.synqly.vulnerabilities", "vulnerabilities"
155
+ )
156
+ ticketing = import_command_with_timing("regscale.integrations.commercial.synqly.ticketing", "ticketing")
157
+ crowdstrike = import_command_with_timing(COMMERCIAL, "crowdstrike")
158
+ defender = import_command_with_timing(COMMERCIAL, "defender")
159
+ dependabot = import_command_with_timing(COMMERCIAL, "dependabot")
160
+ durosuite = import_command_with_timing(COMMERCIAL + ".durosuite.scanner", "durosuite")
161
+ ecr = import_command_with_timing(COMMERCIAL, "ecr")
162
+ gcp = import_command_with_timing(COMMERCIAL, "gcp")
163
+ gitlab = import_command_with_timing(COMMERCIAL, "gitlab")
164
+ ibm = import_command_with_timing(COMMERCIAL, "ibm")
165
+ import_all = import_command_with_timing(COMMERCIAL, "import_all")
166
+ jira = import_command_with_timing(COMMERCIAL, "jira")
167
+ nexpose = import_command_with_timing(COMMERCIAL, "nexpose")
168
+ okta = import_command_with_timing(COMMERCIAL, "okta")
169
+ prisma = import_command_with_timing(COMMERCIAL, "prisma")
170
+ qualys = import_command_with_timing(COMMERCIAL, "qualys")
171
+ salesforce = import_command_with_timing(COMMERCIAL, "salesforce")
172
+ sap = import_command_with_timing("regscale.integrations.commercial.sap.click", "sap")
173
+ sysdig = import_command_with_timing("regscale.integrations.commercial.sap.sysdig.click", "sysdig")
174
+ servicenow = import_command_with_timing(COMMERCIAL, "servicenow")
175
+ sicura = import_command_with_timing(COMMERCIAL, "sicura")
176
+ stig_mapper = import_command_with_timing(COMMERCIAL, "stig_mapper")
177
+ stig = import_command_with_timing(COMMERCIAL, "stig")
178
+ snyk = import_command_with_timing(COMMERCIAL, "snyk")
179
+ sonarcloud = import_command_with_timing(COMMERCIAL, "sonarcloud")
180
+ tenable = import_command_with_timing(COMMERCIAL, "tenable")
181
+ trivy = import_command_with_timing(COMMERCIAL, "trivy")
182
+ grype = import_command_with_timing(COMMERCIAL, "grype")
183
+ tenable_flat = import_command_with_timing("regscale.integrations.commercial.sap.tenable.click", "tenable")
184
+ veracode = import_command_with_timing(COMMERCIAL, "veracode")
185
+ wiz = import_command_with_timing(COMMERCIAL, "wiz")
186
+ xray = import_command_with_timing(COMMERCIAL, "xray")
187
+ fortify = import_command_with_timing(COMMERCIAL, "fortify")
188
+
189
+ logger = logging.getLogger("regscale")
190
+
191
+
192
+ @click.group()
193
+ @click.option(
194
+ "--config",
195
+ type=click.STRING,
196
+ help="Config to use for the CLI. Can be a JSON string or a path to a YAML/JSON file",
197
+ default=None,
198
+ hidden=True,
199
+ )
200
+ @click.option("--debug", is_flag=True, help="Enable debug mode")
201
+ @click.version_option(
202
+ __version__,
203
+ "--version",
204
+ "-V",
205
+ prog_name="RegScale CLI",
206
+ )
207
+ @click.pass_context
208
+ def cli(ctx, config, debug) -> click.Group:
209
+ """
210
+ Welcome to the RegScale CLI client app!
211
+ """
212
+ # Ensure that ctx.obj exists and is a dict (in case further commands need to pass more data)
213
+ ctx.ensure_object(dict)
214
+ ctx.obj["DEBUG"] = debug
215
+
216
+ if config:
217
+ import json
218
+ import yaml
219
+ from regscale.core.app.application import Application
220
+
221
+ try:
222
+ try:
223
+ # First try to parse as JSON string
224
+ ctx.obj["CONFIG"] = json.loads(config)
225
+ except json.JSONDecodeError:
226
+ # If not JSON, try as file path
227
+ if os.path.isfile(config):
228
+ with open(config, "r") as f:
229
+ if config.endswith(".json"):
230
+ ctx.obj["CONFIG"] = json.load(f)
231
+ else:
232
+ ctx.obj["CONFIG"] = yaml.safe_load(f)
233
+ else:
234
+ logger.error(f"Config must be valid JSON string or path to JSON/YAML file path: {config}")
235
+ ctx.obj["CONFIG"] = {}
236
+ except Exception as e:
237
+ logger.error(f"Error loading config: {str(e)}, using default config.")
238
+ ctx.obj["CONFIG"] = {}
239
+
240
+ if debug:
241
+ logger.setLevel("DEBUG")
242
+
243
+
244
+ # About function
245
+ @cli.command()
246
+ def about():
247
+ """Provides information about the CLI and its current version."""
248
+ banner()
249
+ about_display()
250
+
251
+
252
+ @cli.command(hidden=True)
253
+ def import_time():
254
+ """Displays the total import time for the CLI."""
255
+ end_time = time.time()
256
+ console = Console()
257
+ console.print(f"Total Import Time: {end_time - start_time} seconds")
258
+
259
+
260
+ def about_display():
261
+ """Provides information about the CLI and its current version."""
262
+ console = Console()
263
+ console.print(f"[red]RegScale[/red] CLI Version: {__version__}")
264
+ console.print("Author: J. Travis Howerton (thowerton@regscale.com)")
265
+ console.print("Copyright: RegScale Incorporated")
266
+ console.print("Pre-Requisite: Python 3.9, 3.10, 3.11, 3.12, or 3.13")
267
+ console.print("Website: https://www.regscale.com")
268
+ console.print("Read the CLI Docs: https://regscale.readme.io/docs/overview")
269
+ console.print(
270
+ "\n[red]DISCLAIMER: RegScale does not conduct any form of security scanning for data imported by the customer. "
271
+ + "It is the customer's responsibility to ensure that data imported into the platform using "
272
+ + "the Command Line Interface meets industry standard, minimum security screening requirements. "
273
+ + "RegScale has no liability for failing to scan any such data or for any data imported by "
274
+ + "the customer that fails to meet such requirements.[red]\n"
275
+ )
276
+
277
+
278
+ def banner():
279
+ """RegScale logo banner"""
280
+ txt = """
281
+ \t[#10c4d3] .';;;;;;;;;;;;;[#14bfc7];;;;;;;;;;;;,'..
282
+ \t[#10c4d3].:llllllllllllll[#14bfc7]lllllllllllllllc:'.
283
+ \t[#10c4d3].cliclicliclicli[#14bfc7]clicliclicliclooool;.
284
+ \t[#10c4d3].cliclic###################;:looooooc'
285
+ \t[#05d1b7].clicli, [#15cfec].;loooool'
286
+ \t[#05d1b7].clicli, [#18a8e9].:oolloc.
287
+ \t[#05d1b7].clicli, [#ef7f2e].,cli,. [#18a8e9].clllll,
288
+ \t[#05d1b7].clicli. [#ef7f2e].,oxxxxd; [#158fd0].:lllll;
289
+ \t[#05d1b7] ..cli. [#f68d1f]';cdxxxxxo, [#18a8e9].cllllc,
290
+ \t [#f68d1f].:odddddddc. [#1b97d5] .;ccccc:.
291
+ \t[#ffc42a] ..'. [#f68d1f].;ldddddddl' [#0c8cd7].':ccccc:.
292
+ \t[#ffc42a] ;xOOkl. [#e9512b]'coddddddl,. [#0c8cd7].;::::::;.
293
+ \t[#ffc42a]'x0000O: [#e9512b].:oooooool;. [#0c8cd7].,::::::;'.
294
+ \t[#ffc42a]'xO00OO: [#e9512b].;loooooo:,. [#0c8cd7].';::;::;'.
295
+ \t[#ff9d20]'xOOOOOc[#ba1d49].'cllllllc' [#0c83c8].,;;;;;;,.
296
+ \t[#ff9d20]'xOOOOOo[#ba1d49]:clllllc'. [#0c83c8]';;;;;;'.
297
+ \t[#ff9d20]'xOOOOOd[#ba1d49]ccccc:,. [#1a4ea4].',,,,'''.
298
+ \t[#ff9d20]'dOOOOkd[#ba1d49]c:::,. [#1a4ea4]..''''''..
299
+ \t[#f68d1f]'dkkkkko[#ba1d49]:;,. [#1a4ea4].''''','..
300
+ \t[#f68d1f]'dkkkkkl[#ba1d49],. [#0866b4].''',,,'.
301
+ \t[#f68d1f].lkkkkx;[#ba1d49]. [#0866b4]..',,,,.
302
+ \t[#f68d1f] .;cc:' [#0866b4].....
303
+ """
304
+ console = Console()
305
+ console.print(txt)
306
+
307
+
308
+ @cli.command("version")
309
+ @click.option("--server", is_flag=True, help="Display the version information from the server and exit.")
310
+ def version(server: bool = False) -> None:
311
+ """
312
+ Display the CLI or RegScale application version and exit.
313
+ """
314
+ if server:
315
+ from urllib.parse import urljoin
316
+
317
+ from regscale.core.app.api import Api
318
+
319
+ api = Api()
320
+ res = api.get(urljoin(api.app.config["domain"], "/assets/json/version.json"))
321
+ if res and res.ok:
322
+ try:
323
+ print(res.json()["version"])
324
+ except ValueError:
325
+ print("Unable to get version from server.")
326
+ else:
327
+ print("Unable to get version from server.")
328
+ sys.exit(0)
329
+ print(__version__)
330
+
331
+
332
+ @cli.command(name="change_passkey")
333
+ def change_passkey():
334
+ """Change your encryption/decryption passkey."""
335
+ YO9322()
336
+ sys.exit()
337
+
338
+
339
+ @cli.command()
340
+ @click.option("--file", hide_input=False, help="File to encrypt.", prompt=True, required=True)
341
+ def encrypt(file):
342
+ """Encrypts .txt, .yaml, .json, & .csv files."""
343
+ if file:
344
+ JH0847(file)
345
+ sys.exit()
346
+
347
+
348
+ @cli.command()
349
+ @click.option("--file", hide_input=False, help="File to decrypt.", prompt=True, required=True)
350
+ def decrypt(file):
351
+ """Decrypts .txt, .yaml, .json, & .csv files."""
352
+ if file:
353
+ IOA21H98(file)
354
+ sys.exit()
355
+
356
+
357
+ # Update config parameter
358
+ @cli.command()
359
+ @click.option(
360
+ "--param",
361
+ hide_input=False,
362
+ help="CLI config parameter name.",
363
+ prompt=True,
364
+ required=True,
365
+ type=click.STRING,
366
+ )
367
+ @click.option(
368
+ "--val",
369
+ hide_input=True,
370
+ help="CLI config parameter value.",
371
+ type=click.STRING, # default is string even if entering an integer
372
+ prompt=True,
373
+ required=True,
374
+ )
375
+ def config(param, val):
376
+ """Updates init.yaml config parameter with value"""
377
+ # check if key provided exists in init.yaml or the app.template before adding it
378
+ from regscale.core.app.application import Application
379
+
380
+ app = Application()
381
+ from regscale.core.app.utils.regscale_utils import update_regscale_config
382
+
383
+ if param in app.config or param in app.template:
384
+ # check the datatype provided vs what is expected
385
+ if isinstance(val, (type(app.config[param]), type(app.template.get(param)))):
386
+ # update init file from login
387
+ result_msg = update_regscale_config(param, val, app=app)
388
+ # print the result
389
+ logger.info(result_msg)
390
+ else:
391
+ # try to convert val entry to an int
392
+ try:
393
+ int_val = int(val)
394
+ # update init file from login
395
+ result_msg = update_regscale_config(param, int_val, app=app)
396
+ # print the result
397
+ logger.info(result_msg)
398
+ except ValueError:
399
+ logger.error(
400
+ "%s needs a %s value, but a %s was provided.",
401
+ param,
402
+ type(app.template[param]),
403
+ type(val),
404
+ )
405
+ sys.exit(1)
406
+ else:
407
+ message = f"{param} is not required for RegScale CLI and was not added to init.yaml."
408
+ message += "If you believe this is incorrect, please add the key and value to init.yaml manually."
409
+ logger.error(message)
410
+
411
+
412
+ # Log into RegScale to get a token
413
+ @cli.command(name="validate_token")
414
+ def validate_token():
415
+ """Check to see if token is valid."""
416
+ from regscale.core.app.application import Application
417
+
418
+ app = Application()
419
+ if lg.is_valid(app=app):
420
+ logger.info("RegScale token is valid.")
421
+ sys.exit(0)
422
+ else:
423
+ logger.warning("RegScale token is invalid, please login.")
424
+ sys.exit(1)
425
+
426
+
427
+ @cli.command()
428
+ @click.option(
429
+ "--username",
430
+ hide_input=False,
431
+ help="RegScale User Name.",
432
+ type=click.STRING,
433
+ default=os.getenv("REGSCALE_USER"),
434
+ cls=NotRequiredIf,
435
+ not_required_if=["token"],
436
+ )
437
+ @click.option(
438
+ "--password",
439
+ hide_input=True,
440
+ help="RegScale password.",
441
+ default=os.getenv("REGSCALE_PASSWORD"),
442
+ cls=NotRequiredIf,
443
+ not_required_if=["token"],
444
+ )
445
+ @click.option(
446
+ "--token",
447
+ hide_input=True,
448
+ help="RegScale JWT Token.",
449
+ prompt=False,
450
+ default=None,
451
+ type=click.STRING,
452
+ cls=NotRequiredIf,
453
+ not_required_if=["username", "password", "mfa_token"],
454
+ )
455
+ @click.option(
456
+ "--domain",
457
+ hide_input=True,
458
+ help="RegScale Domain (e.g. https://regscale.yourcompany.com)",
459
+ prompt=False,
460
+ required=False,
461
+ default=os.getenv("REGSCALE_DOMAIN"),
462
+ type=click.STRING,
463
+ )
464
+ @click.option(
465
+ "--mfa_token",
466
+ hide_input=True,
467
+ help="RegScale MFA Token.",
468
+ type=click.STRING,
469
+ cls=NotRequiredIf,
470
+ not_required_if=["token"],
471
+ )
472
+ def login(
473
+ username: Optional[str],
474
+ password: Optional[str],
475
+ token: Optional[str] = None,
476
+ domain: Optional[str] = None,
477
+ mfa_token: Optional[str] = None,
478
+ ):
479
+ """Logs the user into their RegScale instance."""
480
+ from regscale.core.app.application import Application
481
+
482
+ app = Application()
483
+ if token:
484
+ lg.login(token=token, host=domain, app=app)
485
+ sys.exit(0)
486
+ if not username:
487
+ username = click.prompt("Username", type=str)
488
+ if not password:
489
+ password = click.prompt("Password", type=str, hide_input=True)
490
+ if mfa_token:
491
+ lg.login(
492
+ str_user=username,
493
+ str_password=password,
494
+ mfa_token=mfa_token,
495
+ app=app,
496
+ host=domain,
497
+ )
498
+ else:
499
+ lg.login(str_user=username, str_password=password, app=app, host=domain)
500
+
501
+
502
+ # Check the health of the RegScale Application
503
+ @cli.command()
504
+ def healthcheck():
505
+ """Monitoring tool to check the health of the RegScale instance."""
506
+ hc.status()
507
+
508
+
509
+ @cli.command()
510
+ @click.option(
511
+ "--domain",
512
+ type=click.STRING,
513
+ help="RegScale domain URL to skip domain prompt.",
514
+ prompt=False,
515
+ default=os.getenv("REGSCALE_DOMAIN"),
516
+ required=False,
517
+ )
518
+ @click.option(
519
+ "--username",
520
+ type=click.STRING,
521
+ help="RegScale User Name to skip login prompt.",
522
+ hide_input=False,
523
+ prompt=False,
524
+ required=False,
525
+ default=os.getenv("REGSCALE_USER"),
526
+ )
527
+ @click.option(
528
+ "--password",
529
+ type=click.STRING,
530
+ help="RegScale password to skip login prompt.",
531
+ hide_input=True,
532
+ default=os.getenv("REGSCALE_PASSWORD"),
533
+ prompt=False,
534
+ required=False,
535
+ )
536
+ @click.option(
537
+ "--mfa_token",
538
+ type=click.STRING,
539
+ help="MFA Token used to log into RegScale.",
540
+ default="",
541
+ prompt=False,
542
+ required=False,
543
+ )
544
+ @click.option(
545
+ "--user_id",
546
+ type=click.STRING,
547
+ help="RegScale User ID to skip login prompt.",
548
+ hide_input=False,
549
+ prompt=False,
550
+ required=False,
551
+ default=os.getenv("REGSCALE_USER_ID"),
552
+ )
553
+ @click.option(
554
+ "--token",
555
+ type=click.STRING,
556
+ help="RegScale JWT Token to skip login prompt.",
557
+ hide_input=True,
558
+ prompt=False,
559
+ required=False,
560
+ default=os.getenv("REGSCALE_TOKEN"),
561
+ )
562
+ @click.option(
563
+ "--skip-prompts",
564
+ is_flag=True,
565
+ help="Skip domain and login prompts.",
566
+ )
567
+ def init(
568
+ domain: str = None,
569
+ username: str = None,
570
+ password: str = None,
571
+ user_id: str = None,
572
+ token: str = None,
573
+ mfa_token: Optional[str] = "",
574
+ skip_prompts: Optional[bool] = False,
575
+ ):
576
+ """Initialize RegScale CLI environment"""
577
+ console = Console()
578
+ from regscale.core.app.application import Application
579
+
580
+ app = Application()
581
+ console.print("Initializing your RegScale CLI environment...")
582
+ # skip prompts when no-prompts flag sent
583
+ if skip_prompts:
584
+ os.remove("init.yaml")
585
+ Application()
586
+ domain_to_use = domain or os.getenv("REGSCALE_DOMAIN")
587
+ if not domain_to_use:
588
+ console.print("[red]You must pass a domain or set the REGSCALE_DOMAIN environment variable")
589
+ sys.exit(1)
590
+ app.config["domain"] = domain_to_use
591
+ if user_id:
592
+ app.config["userId"] = user_id
593
+ if token:
594
+ app.config["token"] = token
595
+ app.save_config(conf=app.config)
596
+ banner()
597
+ about_display()
598
+ console.print(f'Successfully initialized with Domain [green]{app.config["domain"]}.')
599
+ console.print("logging in . . .")
600
+ lg.login(token=token, host=domain_to_use, app=app)
601
+ console.print("Logged in successfully.")
602
+ return None
603
+
604
+ domain_prompt = "n"
605
+ # see if user used the --domain flag
606
+ if not domain:
607
+ domain_prompt = (
608
+ input(f"Would you like to change your RegScale domain from {app.config['domain']}? (Y/n): ") or "y"
609
+ )
610
+
611
+ # if the user used --domain or entered y to change their domain when prompted
612
+ if domain or domain_prompt[0].lower() == "y":
613
+ # make sure --domain wasn't used & input yes to change their domain
614
+ if not skip_prompts and not domain and domain_prompt[0].lower() == "y":
615
+ # prompt user for the new domain
616
+ domain = input("\nPlease enter your RegScale domain.\nExample: https://mydomain.regscale.com/\nDomain: ")
617
+
618
+ # parse the domain entry for a URL
619
+ result = urlparse(domain)
620
+
621
+ # check if the domain provided is a valid URL
622
+ if all([result.scheme, result.netloc]):
623
+ from regscale.core.app.utils.regscale_utils import update_regscale_config
624
+
625
+ # update the domain in init.yaml with the user's provided domain
626
+ update_regscale_config(str_param="domain", val=domain, app=app)
627
+ logger.info("Valid URL provided, init.yaml has been updated.")
628
+ else:
629
+ logger.error("Invalid URL provided, init.yaml was not updated.")
630
+ # make sure --username and --password weren't used before asking if user wants to log in
631
+ login_prompt = "n"
632
+ if not username and not password:
633
+ # prompt the user if they would like to log in to their RegScale instance
634
+ login_prompt = input("Would you like to log in to your RegScale instance? (Y/n): ") or "y"
635
+ # see if user used --username, --password or entered yes to log in to RegScale
636
+ if username or password or login_prompt[0].lower() == "y":
637
+ # if no username was provided, ask for one
638
+ if not username:
639
+ username = input("Please enter your username: ")
640
+ # if no password was provided, ask for one
641
+ if not password:
642
+ # hide the password entry with getpass()
643
+ password = getpass("Please enter your password: ")
644
+ # try to log in with provided username and password
645
+ lg.login(username, password, host=domain, app=app, mfa_token=mfa_token)
646
+ banner()
647
+ about_display()
648
+
649
+
650
+ @cli.command(name="upload_file")
651
+ @regscale_id()
652
+ @regscale_module()
653
+ @click.option(
654
+ "--file_path",
655
+ "-f",
656
+ type=click.Path(exists=True),
657
+ help="The path to the file to upload to RegScale.",
658
+ prompt="File to upload to RegScale.",
659
+ required=True,
660
+ )
661
+ def upload_file(regscale_id, regscale_module, file_path): # noqa
662
+ """Upload a file from your local machine to a record in RegScale."""
663
+ file_upload(regscale_id, regscale_module, file_path)
664
+
665
+
666
+ @cli.command(name="env_info")
667
+ def env_info():
668
+ """
669
+ Display information about the current working environment.
670
+ """
671
+ import platform
672
+ import subprocess
673
+
674
+ import psutil
675
+
676
+ # check if the file system is case-sensitive
677
+ case_sensitive = False
678
+ with open("tempfile.txt", "w") as f:
679
+ f.write("test")
680
+ try:
681
+ with open("TempFile.txt", "x") as f:
682
+ f.write("test")
683
+ case_sensitive = True
684
+ except FileExistsError:
685
+ case_sensitive = False
686
+ finally:
687
+ os.remove("tempfile.txt")
688
+ if case_sensitive:
689
+ os.remove("TempFile.txt")
690
+
691
+ from regscale.core.app.utils.app_utils import detect_shell
692
+
693
+ shell = detect_shell() or "Unable to determine"
694
+
695
+ # determine pip version
696
+ try:
697
+ result = subprocess.run(["pip", "--version"], capture_output=True, text=True, check=True)
698
+ pip_version = result.stdout.strip()
699
+ except subprocess.SubprocessError:
700
+ pip_version = "Pip version not available"
701
+ user_name = None
702
+ print(f"Operating System: {platform.system()} {platform.release()}")
703
+ if "linux" in platform.system().lower():
704
+ import distro
705
+
706
+ print(f"Distribution: {distro.name()} {distro.version()}")
707
+ import grp
708
+ import pwd
709
+
710
+ user_name = pwd.getpwuid(os.getuid()).pw_name
711
+ user_id = pwd.getpwuid(os.getuid()).pw_uid
712
+ group_id = grp.getgrgid(user_id).gr_gid
713
+ group = grp.getgrgid(group_id).gr_name
714
+ elif "darwin" in platform.system().lower():
715
+ import grp
716
+ import pwd
717
+
718
+ user_name = pwd.getpwuid(os.getuid()).pw_name
719
+ user_id = pwd.getpwuid(os.getuid()).pw_uid
720
+ group_id = os.getgid()
721
+ group = grp.getgrgid(group_id).gr_name
722
+ elif "windows" in platform.system().lower():
723
+ group = "Not applicable on Windows"
724
+ user_id = group
725
+ group_id = group
726
+ else:
727
+ group = "Unable to determine on this OS"
728
+ user_id = group
729
+ group_id = group
730
+ print(f"Version: {platform.version()}")
731
+ print(f"Total Available Ram: {psutil.virtual_memory().total / (1024**3):.2f} GB")
732
+ print(f"Terminal: {os.getenv('TERM')}")
733
+ print(f"Shell: {shell}")
734
+ print(f"Python Version: {sys.version}")
735
+ print(f"Pip Version: {pip_version}")
736
+ print(f"RegScale CLI Version: {__version__}")
737
+ print(f"Running in a virtual environment: {sys.prefix != sys.base_prefix}")
738
+ print(f"Read & Write Permissions: {os.access('.', os.R_OK) and os.access('.', os.W_OK)}")
739
+ print(f"Current Working Directory: {os.getcwd()}")
740
+ print(f"Username: {user_name if user_name else os.getlogin()}")
741
+ print(f"User's Group: {group}")
742
+ print(f"User's ID: {user_id}")
743
+ print(f"User's Group ID: {group_id}")
744
+ print(f"File System Case Sensitive: {case_sensitive}")
745
+ print(f"Running in an official RegScale container: {os.getenv('REGSCALE_CONTAINER', 'No')}")
746
+
747
+
748
+ ############################################################
749
+ # Add Application Integrations
750
+ ############################################################
751
+ cli.add_command(actions) # add Reminder Functionality
752
+ cli.add_command(assessments) # add Assessments Editor Feature
753
+ cli.add_command(catalog) # add Catalog Management Feature
754
+ cli.add_command(compare) # add Comparison support
755
+ cli.add_command(control_editor) # add Control Editor Feature
756
+ cli.add_command(evidence) # add Evidence Feature
757
+ cli.add_command(migrations) # add data migration support
758
+ cli.add_command(issues) # add POAM(Issues) Editor Feature
759
+ cli.add_command(model) # add POAM(Issues) Editor Feature
760
+
761
+ ############################################################
762
+ # Add Commercial Integrations
763
+ ############################################################
764
+ cli.add_command(ad) # add Azure Active Directory (AD) support
765
+ cli.add_command(aqua) # Add Aqua ECR support
766
+ cli.add_command(awsv2) # add AWS support
767
+ cli.add_command(azure) # add Azure Integration
768
+ cli.add_command(burp) # add Burp File Integration
769
+ cli.add_command(assets) # add Assets connector
770
+ cli.add_command(vulnerabilities) # add Vulnerabilities connector
771
+ cli.add_command(ticketing) # add Ticketing connector
772
+ cli.add_command(crowdstrike) # add CrowdStrike support
773
+ cli.add_command(defender) # add Microsoft Defender Functionality
774
+ cli.add_command(dependabot) # add Dependabot Integration
775
+ cli.add_command(durosuite) # add DuroSuite Integration
776
+ cli.add_command(ecr) # add ECR Flat File Integration
777
+ cli.add_command(gcp) # add GCP Integration
778
+ cli.add_command(gitlab) # add GitLab
779
+ cli.add_command(grype) # add Grype support
780
+ cli.add_command(ibm) # add IBM AppScan support
781
+ cli.add_command(import_all) # add import_all support
782
+ cli.add_command(jira) # add JIRA support
783
+ cli.add_command(nexpose) # add Nexpose support
784
+ cli.add_command(fortify) # add NS2 support
785
+ cli.add_command(okta) # add Okta Support
786
+ cli.add_command(prisma) # add Prisma support
787
+ cli.add_command(qualys) # add Qualys Functionality
788
+ cli.add_command(salesforce) # add Salesforce support
789
+ cli.add_command(sap) # add SAP Concur support
790
+ cli.add_command(servicenow) # add ServiceNow support
791
+ cli.add_command(sicura) # add Sicura Integration
792
+ cli.add_command(snyk) # add Snyk support
793
+ cli.add_command(veracode) # add Veracode Integration
794
+ cli.add_command(sonarcloud) # add SonarCloud Integration
795
+ cli.add_command(stig) # add STIGv2 support
796
+ cli.add_command(stig_mapper) # add STIG Mapper support
797
+ cli.add_command(tenable) # add Tenable support
798
+ cli.add_command(trivy) # add Trivy support
799
+ cli.add_command(wiz) # add Wiz support
800
+ cli.add_command(xray) # add JFrog Xray support
801
+
802
+ ############################################################
803
+ # Add Public Integrations
804
+ ############################################################
805
+ cli.add_command(alienvault) # add Alienvault OTX integration
806
+ cli.add_command(cisa) # add CISA support
807
+ cli.add_command(emass) # add eMASS support
808
+ cli.add_command(fedramp) # add FedRAMP support
809
+ cli.add_command(nist) # add Nist_Catalog support
810
+ cli.add_command(oscal) # add OSCAL support
811
+ cli.add_command(criticality_updater) # add Criticality Updater support
812
+
813
+ # start function for the CLI
814
+ if __name__ == "__main__":
815
+ cli()