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,242 @@
1
+ """
2
+ This module contains the ThreadSafeDict class, which is a thread-safe dictionary.
3
+ """
4
+
5
+ from threading import RLock
6
+ from typing import Optional, List, Callable, Iterator, TypeVar, Generic, Dict
7
+
8
+ KT = TypeVar("KT") # Key Type
9
+ VT = TypeVar("VT") # Value Type
10
+
11
+
12
+ class ThreadSafeDict(Generic[KT, VT]):
13
+ """
14
+ ThreadSafeDict class to create a thread-safe dictionary.
15
+ """
16
+
17
+ def __init__(self):
18
+ self._dict: Dict[KT, VT] = {}
19
+ self._lock = RLock()
20
+
21
+ def __getitem__(self, key: KT) -> VT:
22
+ """
23
+ Get a value from the thread-safe dictionary
24
+
25
+ :param KT key: Key to get the value for
26
+ :return: The value from the dictionary
27
+ :rtype: VT
28
+ """
29
+ with self._lock:
30
+ return self._dict[key]
31
+
32
+ def __setitem__(self, key: KT, value: VT) -> None:
33
+ """
34
+ Set a value in the thread-safe dictionary
35
+
36
+ :param KT key: Key to set the value for
37
+ :param VT value: Value to set
38
+ :rtype: None
39
+ """
40
+ with self._lock:
41
+ self._dict[key] = value
42
+
43
+ def __delitem__(self, key: KT) -> None:
44
+ """
45
+ Delete a key from the thread-safe dictionary
46
+
47
+ :param Any key: Key to delete
48
+ :rtype: None
49
+ """
50
+ with self._lock:
51
+ del self._dict[key]
52
+
53
+ def get(self, key: KT, default: Optional[VT] = None) -> Optional[VT]:
54
+ """
55
+ Get a value from the thread-safe dictionary
56
+
57
+ :param Any key: Key to get the value for
58
+ :param Optional[Any] default: Default value to return if the key is not in the dictionary, defaults to None
59
+ :return: The value from the dictionary, if found or the default value
60
+ :rtype: Optional[Any]
61
+ """
62
+ with self._lock:
63
+ return self._dict.get(key, default)
64
+
65
+ def pop(self, key: KT, default: Optional[VT] = None) -> Optional[VT]:
66
+ """
67
+ Pop a value from the thread-safe dictionary
68
+
69
+ :param Any key: Key to pop the value for
70
+ :param Optional[Any] default: Default value to return if the key is not in the dictionary, defaults to None
71
+ :return: The value from the dictionary, if found or the default value
72
+ :rtype: Optional[Any]
73
+ """
74
+ with self._lock:
75
+ return self._dict.pop(key, default)
76
+
77
+ def __contains__(self, key: KT) -> bool:
78
+ """
79
+ Check if a key is in the thread-safe dictionary
80
+
81
+ :param Any key: Key to check in the dictionary
82
+ :return: Whether the key is in the dictionary
83
+ :rtype: bool
84
+ """
85
+ with self._lock:
86
+ return key in self._dict
87
+
88
+ def keys(self) -> List[KT]:
89
+ """
90
+ Get a list of keys from the thread-safe dictionary
91
+
92
+ :return: A list of keys
93
+ :rtype: List[Any]
94
+ """
95
+ with self._lock:
96
+ return list(self._dict.keys())
97
+
98
+ def values(self) -> List[VT]:
99
+ """
100
+ Get a list of values from the thread-safe dictionary
101
+
102
+ :return: A list of values
103
+ :rtype: List[Any]
104
+ """
105
+ with self._lock:
106
+ return list(self._dict.values())
107
+
108
+ def items(self) -> List[tuple]:
109
+ """
110
+ Get a list of items from the thread-safe dictionary
111
+
112
+ :return: A list of items
113
+ :rtype: List[Any]
114
+ """
115
+ with self._lock:
116
+ return list(self._dict.items())
117
+
118
+ def clear(self) -> None:
119
+ """
120
+ Clear the thread-safe dictionary
121
+
122
+ :rtype: None
123
+ """
124
+ with self._lock:
125
+ self._dict.clear()
126
+
127
+ def update(self, other_dict: Dict[KT, VT]) -> None:
128
+ """
129
+ Update the thread-safe dictionary with another dictionary
130
+
131
+ :param dict other_dict: Dictionary to update the thread-safe dictionary with
132
+ :rtype: None
133
+ """
134
+ with self._lock:
135
+ self._dict.update(other_dict)
136
+
137
+ def __len__(self) -> int:
138
+ """
139
+ Get the length of the thread-safe dictionary
140
+
141
+ :return: The length of the dictionary
142
+ :rtype: int
143
+ """
144
+ with self._lock:
145
+ return len(self._dict)
146
+
147
+ def __iter__(self) -> Iterator[KT]:
148
+ """
149
+ Return an iterator over the keys of the dictionary.
150
+
151
+ :return: An iterator over the keys of the dictionary
152
+ :rtype: Iterator[Any]
153
+ """
154
+ with self._lock:
155
+ # Create a copy of the keys to prevent issues during iteration
156
+ return iter(self._dict.copy())
157
+
158
+ def setdefault(self, key: KT, default: VT = None) -> VT:
159
+ with self._lock:
160
+ return self._dict.setdefault(key, default)
161
+
162
+
163
+ class ThreadSafeDefaultDict(ThreadSafeDict):
164
+ """
165
+ ThreadSafeDefaultDict class to create a thread-safe defaultdict.
166
+ """
167
+
168
+ def __init__(self, default_factory: Optional[Callable[[], VT]] = None):
169
+ """
170
+ Initialize a ThreadSafeDefaultDict.
171
+
172
+ :param Optional[Callable[[], Any]] default_factory: A callable that returns the default value for missing keys
173
+ """
174
+ super().__init__()
175
+ if default_factory is not None and not callable(default_factory):
176
+ raise TypeError("default_factory must be callable")
177
+ self.default_factory: Optional[Callable[[], VT]] = default_factory
178
+
179
+ def __getitem__(self, key: KT) -> VT:
180
+ """
181
+ Get an item from the dictionary, using the default_factory if the key is missing.
182
+
183
+ :param Any key: The key to look up
184
+ :return: The value associated with the key or the default value
185
+ :rtype: Any
186
+ """
187
+ with self._lock:
188
+ try:
189
+ return self._dict[key]
190
+ except KeyError:
191
+ if self.default_factory is None:
192
+ raise
193
+ else:
194
+ value = self.default_factory()
195
+ self._dict[key] = value
196
+ return value
197
+
198
+ def get(self, key: KT, default: Optional[VT] = None) -> Optional[VT]:
199
+ """
200
+ Get an item from the dictionary, using the default_factory or provided default if the key is missing.
201
+
202
+ :param Any key: The key to look up
203
+ :param Optional[Any] default: The default value to return if the key is not found and default_factory is None
204
+ :return: The value associated with the key or the default value
205
+ :rtype: Optional[Any]
206
+ """
207
+ with self._lock:
208
+ if key in self._dict:
209
+ return self._dict[key]
210
+ elif self.default_factory is not None:
211
+ value = self.default_factory()
212
+ self._dict[key] = value
213
+ return value
214
+ else:
215
+ return default
216
+
217
+ def setdefault(self, key: KT, default: Optional[VT] = None) -> VT:
218
+ """
219
+ Insert key with a value of default if key is not in the dictionary.
220
+
221
+ :param Any key: The key to insert if it doesn't exist
222
+ :param Optional[Any] default: The value to set if the key doesn't exist
223
+ :return: The value for key if key is in the dictionary, else default
224
+ :rtype: Any
225
+ """
226
+ with self._lock:
227
+ if key in self._dict:
228
+ return self._dict[key]
229
+ else:
230
+ if default is None and self.default_factory is not None:
231
+ default = self.default_factory()
232
+ self._dict[key] = default
233
+ return default
234
+
235
+ def __repr__(self) -> str:
236
+ """
237
+ Return a string representation of the ThreadSafeDefaultDict.
238
+
239
+ :return: A string representation of the object
240
+ :rtype: str
241
+ """
242
+ return f"{self.__class__.__name__}({self.default_factory}, {self._dict})"
@@ -0,0 +1,83 @@
1
+ """
2
+ This module contains the ThreadSafeList class, which is a thread-safe list.
3
+ """
4
+
5
+ from threading import RLock
6
+ from typing import Generic, List, Optional, TypeVar
7
+
8
+ T = TypeVar("T") # Declare type variable
9
+
10
+
11
+ class ThreadSafeList(Generic[T]):
12
+ """
13
+ ThreadSafeList class to create a thread-safe list.
14
+ """
15
+
16
+ def __init__(self, initial_list: Optional[List[T]] = None):
17
+ """
18
+ Initialize a new ThreadSafeList
19
+
20
+ :param List[T]|None initial_list: Optional initial list to populate the ThreadSafeList
21
+ """
22
+ self._list: List[T] = list(initial_list) if initial_list is not None else []
23
+ self._lock = RLock()
24
+
25
+ def append(self, item: T) -> None:
26
+ """
27
+ Append an item to the list
28
+
29
+ :param T item: Item to append to the list
30
+ :rtype: None
31
+ """
32
+ with self._lock:
33
+ self._list.append(item)
34
+
35
+ def __getitem__(self, index: int) -> T:
36
+ """
37
+ Get an item from the list by index
38
+
39
+ :param int index: Index of the item to get
40
+ :return: The item at the specified index
41
+ :rtype: T
42
+ """
43
+ with self._lock:
44
+ return self._list[index]
45
+
46
+ def __len__(self) -> int:
47
+ """
48
+ Get the length of the list
49
+
50
+ :return: The length of the list
51
+ :rtype: int
52
+ """
53
+ with self._lock:
54
+ return len(self._list)
55
+
56
+ def __iter__(self):
57
+ """
58
+ Return an iterator over the list
59
+
60
+ :return: An iterator over the list
61
+ :rtype: Iterator[T]
62
+ """
63
+ with self._lock:
64
+ return iter(self._list.copy())
65
+
66
+ def remove(self, item: T) -> None:
67
+ """
68
+ Remove an item from the list
69
+
70
+ :param T item: Item to remove from the list
71
+ :rtype: None
72
+ """
73
+ with self._lock:
74
+ self._list.remove(item)
75
+
76
+ def clear(self) -> None:
77
+ """
78
+ Clear the list
79
+
80
+ :rtype: None
81
+ """
82
+ with self._lock:
83
+ self._list.clear()
@@ -0,0 +1,104 @@
1
+ """Version utility functions"""
2
+
3
+ import logging
4
+ import re
5
+ from typing import Optional
6
+ from functools import lru_cache
7
+
8
+ from packaging.version import Version
9
+
10
+ from regscale.core.app.utils.api_handler import APIHandler
11
+ from regscale.utils.decorators import classproperty
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class RegscaleVersion:
17
+ """Utility class for managing and comparing Rescale platform versions"""
18
+
19
+ def __init__(self):
20
+ """Initialize RegscaleVersion with current platform version"""
21
+ self.current_version = self.get_platform_version()
22
+
23
+ @staticmethod
24
+ @lru_cache(maxsize=1)
25
+ def get_platform_version() -> str:
26
+ """Fetch the current platform version from the API. Result is cached.
27
+
28
+ :return: Platform version string (e.g. "1.2.3") or special version ("dev", "localdev", "Unknown")
29
+ :rtype: str
30
+ """
31
+ logger.debug("Fetching platform version using API handler")
32
+ try:
33
+ api_handler = APIHandler()
34
+ response = api_handler.get("/assets/json/version.json")
35
+ if response.status_code == 200:
36
+ version_data = response.json()
37
+ return version_data.get("version", "Unknown")
38
+ else:
39
+ logger.error(f"Failed to fetch version. Status code: {response.status_code}")
40
+ return "dev"
41
+ except Exception as e:
42
+ logger.error(f"Error fetching version: {e}", exc_info=True)
43
+ return "dev"
44
+
45
+ @staticmethod
46
+ def is_valid_version(version: str) -> bool:
47
+ """Check if a version string matches semantic versioning format (X.Y.Z or X.Y.Z.W).
48
+
49
+ :param str version: Version string to validate
50
+ :return: True if version matches semantic versioning format
51
+ :rtype: bool
52
+
53
+ Examples:
54
+ >>> RegscaleVersion.is_valid_version("1.2.3") # Returns True
55
+ >>> RegscaleVersion.is_valid_version("1.2.3.4") # Returns True
56
+ >>> RegscaleVersion.is_valid_version("1.2") # Returns True
57
+ >>> RegscaleVersion.is_valid_version("1.2.3.4.5") # Returns False
58
+ >>> RegscaleVersion.is_valid_version("1.2.a") # Returns False
59
+ """
60
+ return bool(re.match(r"^\d+\.\d+(\.\d+)?(\.\d+)?$", version))
61
+
62
+ @staticmethod
63
+ def meets_minimum_version(minimum_version: str, dev_is_latest: bool = True) -> bool:
64
+ """Check if the given platform version meets or exceeds a minimum version requirement.
65
+
66
+ :param str minimum_version: The minimum version required (e.g. "1.2.3")
67
+ :param bool dev_is_latest: When True, dev is treated as newest version. When False, as oldest.
68
+ :return: True if current platform version is new enough
69
+ :rtype: bool
70
+
71
+ Examples:
72
+ >>> RegscaleVersion.meets_minimum_version("1.0.0") # Returns True if platform version >= 1.0.0
73
+ >>> RegscaleVersion.meets_minimum_version("2.0.0", dev_is_latest=False) # Dev version treated as oldest
74
+ """
75
+ current_version = RegscaleVersion.get_platform_version()
76
+ return RegscaleVersion.compare_versions(current_version, minimum_version, dev_is_latest)
77
+
78
+ @staticmethod
79
+ def compare_versions(version1: str, version2: str, dev_is_latest: bool = True) -> bool:
80
+ """Compare two version strings.
81
+
82
+ :param str version1: First version to compare
83
+ :param str version2: Second version to compare
84
+ :param bool dev_is_latest: When True, dev is treated as newest version. When False, as oldest.
85
+ :return: True if version1 >= version2
86
+ :rtype: bool
87
+ """
88
+ special_value = "9999.9999.9999.9999" if dev_is_latest else "0.0.0.0"
89
+ special_versions = dict.fromkeys(["dev", "localdev", "Unknown"], special_value)
90
+
91
+ # This handles if it is an epic/dev versions as they are normally in the format `BUILDNUMBER-YYYY-MM-DD`
92
+ if "-" in version1:
93
+ version1 = version1.split("-")[0]
94
+ if "-" in version2:
95
+ version2 = version2.split("-")[0]
96
+
97
+ v1 = special_versions.get(version1, version1)
98
+ v2 = special_versions.get(version2, version2)
99
+
100
+ if not RegscaleVersion.is_valid_version(v2):
101
+ logger.info(f"Invalid version {v2}, assuming dev")
102
+ return True
103
+
104
+ return Version(v1) >= Version(v2)
File without changes
@@ -0,0 +1,37 @@
1
+ import ipaddress
2
+ import re
3
+
4
+
5
+ def validate_ip_address(ip_str: str) -> bool:
6
+ """Validate IPv4 or IPv6 address
7
+
8
+ :param str ip_str: String to validate
9
+ :return: bool
10
+ :rtype: bool
11
+ """
12
+ try:
13
+ ipaddress.IPv4Address(ip_str)
14
+ return True
15
+ except ipaddress.AddressValueError:
16
+ try:
17
+ ipaddress.IPv6Address(ip_str)
18
+ return True
19
+ except ipaddress.AddressValueError:
20
+ return False
21
+
22
+
23
+ def validate_mac_address(mac_address: str) -> bool:
24
+ """
25
+ Simple validation of a mac address input
26
+ :param str mac_address: mac address
27
+ :return: Whether mac address is valid or not
28
+ :rtype: bool
29
+ """
30
+ if not mac_address:
31
+ return False
32
+ return bool(
33
+ re.match(
34
+ "[0-9a-f]{2}(:?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$",
35
+ mac_address.lower(),
36
+ )
37
+ )
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Rich Logging"""
4
+
5
+
6
+ from regscale.core.app.api import Api
7
+
8
+ # standard python imports
9
+ from regscale.core.utils.graphql import GraphQLQuery
10
+ from regscale.models.regscale_models.modules import Modules
11
+
12
+
13
+ def validate_regscale_object(parent_id: int, parent_module: str) -> bool:
14
+ """
15
+ Query regscale to confirm the object in question exists.
16
+
17
+ :param int parent_id: The RegScale id to query
18
+ :param str parent_module: The RegScale module to query
19
+ :return: Whether the object exists or not
20
+ :rtype: bool
21
+ """
22
+ import inflect # Optimize import performance
23
+
24
+ api = Api()
25
+ query = GraphQLQuery()
26
+ query.start_query()
27
+ result = False
28
+ mods = Modules()
29
+ p = inflect.engine()
30
+ for (
31
+ key,
32
+ val,
33
+ ) in mods.dict().items(): # for name, age in dictionary.iteritems(): (for Python 2.x)
34
+ if val.lower() == parent_module.lower():
35
+ mod_lookup = p.plural(key)
36
+ query.add_query(
37
+ entity=mod_lookup,
38
+ items=[
39
+ "id",
40
+ ],
41
+ where={"id": {"eq": parent_id}},
42
+ )
43
+ query.end_query()
44
+
45
+ dat = api.graph(query=query.build())
46
+ if mod_lookup.lower() in [k.lower() for k in dat.keys()] and dat[list(dat.keys())[0]]["totalCount"] > 0:
47
+ result = True
48
+ return result
@@ -0,0 +1,5 @@
1
+ try:
2
+ import matplotlib.pyplot as plt
3
+ import networkx as nx
4
+ except ImportError as exc:
5
+ raise ImportError("Install regscale[viz] to visualize regscale.") from exc
@@ -0,0 +1,34 @@
1
+ """Generate a click group object."""
2
+
3
+ import matplotlib.pyplot as plt
4
+ import networkx as nx
5
+
6
+ from regscale.models.click_models import ClickGroup, ClickCommand
7
+
8
+
9
+ def plot_click_group(group: ClickGroup):
10
+ G = nx.DiGraph()
11
+
12
+ def add_node(cmd, parent=None):
13
+ G.add_node(cmd.name)
14
+ if parent is not None:
15
+ G.add_edge(parent.name, cmd.name)
16
+ if isinstance(cmd, ClickCommand):
17
+ for param in cmd.params:
18
+ G.add_node(param.name)
19
+ G.add_edge(cmd.name, param.name)
20
+ elif isinstance(cmd, ClickGroup):
21
+ for subcmd in cmd.commands:
22
+ add_node(subcmd, cmd)
23
+
24
+ add_node(group)
25
+ nx.draw(G, with_labels=True)
26
+ plt.show()
27
+
28
+
29
+ if __name__ == "__main__":
30
+ from regscale.regscale import cli
31
+
32
+ click_group = ClickGroup.from_group(cli, include_callback=True)
33
+ print(click_group.json())
34
+ plot_click_group(click_group)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 RegScale Corporation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.