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,25 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Scanner Variables"""
4
+
5
+ from regscale.core.app.utils.variables import RsVariablesMeta, RsVariableType
6
+
7
+
8
+ class ScannerVariables(metaclass=RsVariablesMeta):
9
+ """
10
+ Scanner 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
+ issueCreation: RsVariableType(str, "PerAsset|Consolidated", default="Consolidated", required=False) # type: ignore # noqa: F722,F821
15
+ vulnerabilityCreation: RsVariableType(str, "NoIssue|IssueCreation|PoamCreation", default="PoamCreation", required=False) # type: ignore # noqa: F722,F821
16
+ userId: RsVariableType(str, "00000000-0000-0000-0000-000000000000") # type: ignore # noqa: F722,F821
17
+ poamTitleType: RsVariableType(str, "Cve|PluginId", default="Cve", required=False) # type: ignore # noqa: F722,F821
18
+ tenableGroupByPlugin: RsVariableType(bool, "true|false", default=False, required=False) # type: ignore # noqa: F722,F821
19
+ threadMaxWorkers: RsVariableType(int, "1-8", default=4, required=False) # type: ignore # noqa: F722,F821
20
+ stigMapperFile: RsVariableType(str, "stig_mapper.json", default="stig_mapper_rules.json", required=False) # type: ignore # noqa: F722,F821
21
+ ingestClosedIssues: RsVariableType(bool, "true|false", default=False, required=False) # type: ignore # noqa: F722,F821
22
+ # Increment the POAM identifier by 1 for each new POAM created in the format of V-0001
23
+ incrementPoamIdentifier: RsVariableType(bool, "true|false", default=False, required=False) # type: ignore # noqa: F722,F821
24
+ sslVerify: RsVariableType(bool, "true|false", default=True, required=False) # type: ignore # noqa: F722,F821
25
+ issueDueDates: RsVariableType(dict, "dueDates", default="{'high': 60, 'moderate': 120, 'low': 364}", required=False) # type: ignore # noqa: F722,F821
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """standard python imports"""
4
+ from regscale.models.app_models.click import regscale_id, regscale_module, regscale_ssp_id
5
+ from .regscale_models import *
6
+ from .integration_models import *
7
+ from .app_models import *
@@ -0,0 +1,5 @@
1
+ """App models for RegScale CLI"""
2
+
3
+ from .mapping import Mapping
4
+ from .import_validater import ImportValidater
5
+ from .datetime_encoder import DateTimeEncoder
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Dataclass for a RegScale Assessment"""
4
+ import re
5
+ import sys
6
+ from dataclasses import asdict, dataclass
7
+ from typing import Any, Optional
8
+
9
+ from regscale.core.app.api import Api
10
+ from regscale.core.app.logz import create_logger
11
+
12
+
13
+ @dataclass
14
+ class CatalogCompare:
15
+ """Catalog comparison Model"""
16
+
17
+ title: Optional[str] = None
18
+ uuid: Optional[str] = None
19
+ keywords: Optional[list] = None
20
+ cci_count: int = 0
21
+ objective_count: int = 0
22
+ parameter_count: int = 0
23
+ security_control_count: int = 0
24
+ test_count: int = 0
25
+
26
+ def __getitem__(self, key: Any) -> Any:
27
+ """
28
+ Get attribute from CatalogCompare
29
+
30
+ :param Any key: Key to get value from
31
+ :return: value of provided key
32
+ :rtype: Any
33
+ """
34
+ return getattr(self, key)
35
+
36
+ def __setitem__(self, key: Any, value: Any) -> None:
37
+ """
38
+ Set attribute in CatalogCompare with provided key
39
+
40
+ :param Any key: Key to change to provided value
41
+ :param Any value: New value for provided Key
42
+ :rtype: None
43
+ """
44
+ return setattr(self, key, value)
45
+
46
+ def dict(self) -> dict:
47
+ """
48
+ Create a dictionary from the CatalogCompare dataclass
49
+
50
+ :return: Dictionary of CatalogCompare
51
+ :rtype: dict
52
+ """
53
+ return {k: v for k, v in asdict(self).items()}
54
+
55
+ @staticmethod
56
+ def from_new_catalog_dict(obj: dict, keywords: list = None) -> "CatalogCompare":
57
+ """
58
+ Create CatalogCompare object from dict
59
+
60
+ :param dict obj: dictionary of a newly formatted catalog
61
+ :param list keywords: list of keywords for the catalog
62
+ :return: CatalogCompare class
63
+ :rtype: CatalogCompare
64
+ """
65
+ _title = str(obj["catalog"].get("title", "")) or None
66
+ _uuid = str(obj["catalog"].get("uuid", "")) or None
67
+ _keywords = keywords
68
+ _cci_count = 0
69
+ _objective_count = 0
70
+ _parameter_count = 0
71
+ _test_count = 0
72
+ _security_control_count = 0
73
+ for control in obj["catalog"].get("securityControls", []):
74
+ _objective_count += len(control.get("objectives", []))
75
+ _cci_count += len(control.get("cci", []))
76
+ _parameter_count += len(control.get("parameters", []))
77
+ _test_count += len(control.get("tests", []))
78
+ _security_control_count += 1
79
+
80
+ return CatalogCompare(
81
+ title=_title,
82
+ uuid=_uuid,
83
+ keywords=_keywords,
84
+ cci_count=_cci_count,
85
+ objective_count=_objective_count,
86
+ parameter_count=_parameter_count,
87
+ security_control_count=_security_control_count,
88
+ test_count=_test_count,
89
+ )
90
+
91
+ @staticmethod
92
+ def from_old_catalog_dict(obj: dict, keywords: list = None) -> "CatalogCompare":
93
+ """
94
+ Create CatalogCompare object from dict
95
+
96
+ :param dict obj: dictionary of an old formatted catalog
97
+ :param list keywords: list of keywords for the catalog
98
+ :return: CatalogCompare class
99
+ :rtype: CatalogCompare
100
+ """
101
+ _title = str(obj.get("title", "")) or None
102
+ _uuid = str(obj.get("uuid", "")) or None
103
+ _keywords = keywords
104
+ _cci_count = int(obj.get("cci", 0)) or 0
105
+ _objective_count = int(obj.get("objectives", 0)) or 0
106
+ _parameter_count = int(obj.get("parameters", 0)) or 0
107
+ _security_control_count = int(obj.get("securityControls", 0)) or 0
108
+ _test_count = int(obj.get("tests", 0)) or 0
109
+
110
+ return CatalogCompare(
111
+ title=_title,
112
+ uuid=_uuid,
113
+ keywords=_keywords,
114
+ cci_count=_cci_count,
115
+ objective_count=_objective_count,
116
+ parameter_count=_parameter_count,
117
+ security_control_count=_security_control_count,
118
+ test_count=_test_count,
119
+ )
120
+
121
+ @staticmethod
122
+ def run_new_diagnostics(
123
+ new_diagnose_cat: dict,
124
+ ) -> "CatalogCompare":
125
+ """
126
+ Run diagnostics on new catalog
127
+
128
+ :param dict new_diagnose_cat: dictionary of the new catalog
129
+ :return: CatalogCompare class
130
+ :rtype: CatalogCompare
131
+ """
132
+ new_list = []
133
+ # get keywords list from catalog
134
+ # https://stackoverflow.com/questions/4998629/split-string-with-multiple-delimiters-in-python
135
+ keywords_list = re.split(r"; |, |\*|\n", new_diagnose_cat.get("keywords", ""))
136
+ for keyword in keywords_list:
137
+ new_key = keyword.replace("<p>", "").replace("</p>", "").lstrip()
138
+ new_list.append(new_key)
139
+
140
+ return CatalogCompare().from_new_catalog_dict(new_diagnose_cat, new_list)
141
+
142
+ @staticmethod
143
+ def run_old_diagnostics(
144
+ old_diagnose_cat: dict,
145
+ ) -> "CatalogCompare":
146
+ """
147
+ Function to run diagnostics on the old catalog
148
+
149
+ :param dict old_diagnose_cat: dictionary of the old catalog
150
+ :return: CatalogCompare object
151
+ :rtype: CatalogCompare
152
+ """
153
+ # set variables for catalog section
154
+ cci_count = 0
155
+ objective_count = 0
156
+ parameter_count = 0
157
+ test_count = 0
158
+ new_list = []
159
+ # get keywords list from catalog
160
+ # https://stackoverflow.com/questions/4998629/split-string-with-multiple-delimiters-in-python
161
+ keywords_list = re.split(r"; |, |\*|\n", old_diagnose_cat.get("keywords", ""))
162
+ for keyword in keywords_list:
163
+ new_key = keyword.replace("<p>", "").replace("</p>", "").lstrip()
164
+ new_list.append(new_key)
165
+ # loop through security controls
166
+ for control in old_diagnose_cat["securityControls"]:
167
+ # count objectives in security controls
168
+ for objectives in control["objectives"]:
169
+ if objectives.get("uuid"):
170
+ objective_count += 1
171
+ # count parametes in security controls
172
+ for parameters in control["parameters"]:
173
+ if parameters.get("uuid"):
174
+ parameter_count += 1
175
+ # count ccis in security controls
176
+ for ccis in control["cci"]:
177
+ if ccis.get("uuid"):
178
+ cci_count += 1
179
+ # count tests in security controls
180
+ for tests in control["tests"]:
181
+ if tests.get("uuid"):
182
+ test_count += 1
183
+ return CatalogCompare(
184
+ title=old_diagnose_cat.get("title", ""),
185
+ uuid=old_diagnose_cat.get("uuid", ""),
186
+ keywords=new_list,
187
+ cci_count=cci_count,
188
+ objective_count=objective_count,
189
+ parameter_count=parameter_count,
190
+ security_control_count=len(old_diagnose_cat.get("securityControls", 0)),
191
+ test_count=test_count,
192
+ )
193
+
194
+ @staticmethod
195
+ def get_master_catalogs(api: Api) -> dict:
196
+ """
197
+ Get list of master catalogs via API
198
+
199
+ :param Api api: API object
200
+ :return: master catalog list
201
+ :rtype: dict
202
+ """
203
+ catalog_url = "https://regscaleblob.blob.core.windows.net/catalogs/catalog_registry.json"
204
+ response = api.get(url=catalog_url, headers={})
205
+ try:
206
+ master_list = response.json()
207
+ except Exception:
208
+ logger = create_logger()
209
+ logger.error("Unable to retrieve master catalogs.")
210
+ sys.exit(1)
211
+ # Filter out catalogs without downloadURL
212
+ master_list["catalogs"] = [cat for cat in master_list.get("catalogs") if cat.get("downloadURL")]
213
+ return master_list
@@ -0,0 +1,252 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Module to allow dynamic click arguments and store commonly used click commands"""
4
+
5
+ from typing import Tuple, Any, Optional
6
+
7
+ import click
8
+ from pathlib import Path
9
+
10
+
11
+ class NotRequiredIf(click.Option):
12
+ """
13
+ NotRequiredIf class for dynamic click options Updates the help command to let the user know if a
14
+ command is exclusive or not
15
+
16
+ :param Tuple *args: List of arguments
17
+ :param **kwargs: Dictionary of keyword arguments
18
+ """
19
+
20
+ def __init__(self, *args: Tuple, **kwargs):
21
+ self.not_required_if: list = kwargs.pop("not_required_if")
22
+
23
+ assert self.not_required_if, "'not_required_if' parameter required"
24
+ kwargs["help"] = (
25
+ kwargs.get("help", "") + "Option is mutually exclusive with " + ", ".join(self.not_required_if) + "."
26
+ ).strip()
27
+ super(NotRequiredIf, self).__init__(*args, **kwargs)
28
+
29
+ def handle_parse_result(self, ctx: Any, opts: Any, args: Any) -> Any:
30
+ """
31
+ Function to handle the click arguments and whether a parameter is required
32
+
33
+ :param Any ctx: Any context
34
+ :param Any opts: Any options
35
+ :param Any args: Any arguments
36
+ :raises click.UsageError: Raises a UsageError if the option is mutually exclusive
37
+ :return: Returns the click option
38
+ :rtype: Any
39
+ """
40
+ current_opt: bool = self.name in opts
41
+ for mutex_opt in self.not_required_if:
42
+ if mutex_opt in opts:
43
+ if current_opt:
44
+ raise click.UsageError(
45
+ "Illegal usage: '" + str(self.name) + "' is mutually exclusive with " + str(mutex_opt) + "."
46
+ )
47
+ else:
48
+ self.prompt = None
49
+ return super(NotRequiredIf, self).handle_parse_result(ctx, opts, args)
50
+
51
+
52
+ def save_output_to(exists: bool = False, dir_okay: bool = True, file_okay: bool = False) -> click.option:
53
+ """
54
+ Function to return a click.option for saving data to a directory
55
+
56
+ :param bool exists: Whether the directory has to exist, default False
57
+ :param bool dir_okay: Whether to accept a directory, default True
58
+ :param bool file_okay: Whether a file path will be accepted, default False
59
+ :return: click.option with the provided parameters
60
+ :rtype: click.option
61
+ """
62
+ return click.option(
63
+ "--save_output_to",
64
+ type=click.Path(
65
+ exists=exists,
66
+ dir_okay=dir_okay,
67
+ file_okay=file_okay,
68
+ path_type=Path,
69
+ ),
70
+ help="Provide the path where you would like to save the output to.",
71
+ prompt="Enter directory for file output",
72
+ required=True,
73
+ )
74
+
75
+
76
+ def file_types(accepted_files: list) -> click.option:
77
+ """
78
+ Function to return click.option for accepted file types
79
+
80
+ :param list accepted_files: list of file extensions
81
+ :return: click.option with provided file list
82
+ :rtype: click.option
83
+ """
84
+ return click.option(
85
+ "--file_type",
86
+ type=click.Choice(accepted_files, case_sensitive=False),
87
+ help="Select a file type to save the output as.",
88
+ prompt="Enter desired file type",
89
+ required=True,
90
+ )
91
+
92
+
93
+ def regscale_ssp_id(
94
+ help: str = "The ID number from RegScale of the System Security Plan",
95
+ required: bool = True,
96
+ **kwargs: dict,
97
+ ) -> click.option:
98
+ """
99
+ Function to return click.option for RegScale SSP ID
100
+
101
+ :param str help: String to display when user enters --help
102
+ :param bool required: Whether input is required, defaults to True
103
+ :param dict **kwargs: kwargs to pass to click.option
104
+ :return: click.option for RegScale SSP ID
105
+ :rtype: click.option
106
+ """
107
+ if "prompt" not in kwargs:
108
+ return click.option(
109
+ "--regscale_ssp_id",
110
+ "-id",
111
+ "--id",
112
+ "--regscale_id",
113
+ type=click.INT,
114
+ help=help,
115
+ required=required,
116
+ prompt="Enter the RegScale System Security Plan ID",
117
+ **kwargs,
118
+ )
119
+ return click.option(
120
+ "--regscale_id",
121
+ "-id",
122
+ "--id",
123
+ "--regscale_id",
124
+ type=click.INT,
125
+ help=help,
126
+ required=required,
127
+ **kwargs,
128
+ )
129
+
130
+
131
+ def regscale_id(
132
+ help: str = "Enter the desired ID # from RegScale.",
133
+ required: bool = True,
134
+ **kwargs,
135
+ ) -> click.option:
136
+ """
137
+ Function to return click.option for RegScale parent ID
138
+
139
+ :param str help: String to display when user enters --help
140
+ :param bool required: Whether input is required, defaults to True
141
+ :param **kwargs: kwargs to pass to click.option
142
+ :return: click.option for RegScale parent ID
143
+ :rtype: click.option
144
+ """
145
+ if kwargs.get("prompt") is None:
146
+ return click.option(
147
+ "--regscale_id",
148
+ "-id",
149
+ "--id",
150
+ type=click.INT,
151
+ help=help,
152
+ prompt="Enter the RegScale Record ID",
153
+ required=required,
154
+ **kwargs,
155
+ )
156
+ return click.option(
157
+ "--regscale_id",
158
+ "-id",
159
+ "--id",
160
+ type=click.INT,
161
+ help=help,
162
+ required=required,
163
+ **kwargs,
164
+ )
165
+
166
+
167
+ def regscale_module(required: bool = True, **kwargs) -> click.option:
168
+ """
169
+ Function to return click.option for RegScale modules
170
+
171
+ :param bool required: Whether input is required, defaults to True
172
+ :param **kwargs: kwargs to pass to click.option
173
+ :return: click.option for RegScale modules
174
+ :rtype: click.option
175
+ """
176
+ from regscale.models.regscale_models.modules import Modules
177
+
178
+ if kwargs.get("prompt") is None:
179
+ return click.option(
180
+ "--regscale_module",
181
+ "-m",
182
+ type=click.STRING,
183
+ help=f"Enter the RegScale module name.\n\n{Modules().to_str_table()}",
184
+ prompt="Enter the RegScale Module name",
185
+ required=required,
186
+ **kwargs,
187
+ )
188
+ return click.option(
189
+ "--regscale_module",
190
+ "-m",
191
+ type=click.STRING,
192
+ help=f"Enter the RegScale module name.\n\n{Modules().to_str_table()}",
193
+ required=required,
194
+ **kwargs,
195
+ )
196
+
197
+
198
+ def hidden_file_path(**kwargs) -> click.option:
199
+ """
200
+ Function to return a hidden click.option for file path
201
+ """
202
+ return click.option(
203
+ "--offline",
204
+ type=click.Path(exists=True, file_okay=True, dir_okay=False, path_type=Path, resolve_path=True),
205
+ help=kwargs.pop("help") if kwargs.get("help") else "Enter the file path",
206
+ hidden=True,
207
+ default=kwargs.get("default"),
208
+ **kwargs,
209
+ )
210
+
211
+
212
+ def show_mapping(group: click.Group, import_name: str, file_type: Optional[str] = None) -> click.Command:
213
+ """
214
+ Show the mapping for the given import_name
215
+
216
+ :param click.Group group: The click group to register the command with
217
+ :param str import_name: The name of the import function
218
+ :param Optional[str] file_type: The file type of the import, defaults to None
219
+ :return: The decorated function.
220
+ :rtype: Callable[[Callable], click.option]
221
+ """
222
+ import os
223
+
224
+ # Define default path based on import_name and file_type
225
+ default = os.path.join("./", "mappings", import_name, f"{file_type}_mapping.json") if file_type else None
226
+
227
+ @click.command(help=f"Show the mapping file used during {import_name} imports.")
228
+ @click.option(
229
+ "--file_path",
230
+ "-f",
231
+ help="File path to the mapping file to display",
232
+ type=click.Path(exists=True, dir_okay=False, file_okay=True, resolve_path=True),
233
+ required=True,
234
+ default=default if default else None,
235
+ )
236
+ # Define the desired function behavior
237
+ def wrapped_func(file_path: str) -> None:
238
+ """
239
+ Show the mapping file used during imports
240
+ """
241
+ import json
242
+ from rich.console import Console
243
+
244
+ console = Console()
245
+ with open(file_path, "r", encoding="utf-8") as file:
246
+ mapping = json.load(file)
247
+ dat = json.dumps(mapping, indent=4)
248
+ console.print(f"{file_path} mapping:")
249
+ console.print(dat)
250
+
251
+ # Register the decorated function with the given click group
252
+ group.add_command(wrapped_func, name="show_mapping")
@@ -0,0 +1,21 @@
1
+ """
2
+ This module provides a custom JSON encoder for handling datetime objects.
3
+ """
4
+
5
+ import datetime
6
+ import json
7
+ from typing import Any
8
+
9
+
10
+ class DateTimeEncoder(json.JSONEncoder):
11
+ """
12
+ Custom JSON encoder that converts datetime objects to ISO format strings.
13
+ """
14
+
15
+ def default(self, obj: Any) -> Any:
16
+ """
17
+ Override the default method to handle datetime objects.
18
+ """
19
+ if isinstance(obj, datetime.datetime):
20
+ return obj.isoformat()
21
+ return super().default(obj)