regscale-cli 6.20.4.1__py3-none-any.whl → 6.20.6.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 (49) hide show
  1. regscale/__init__.py +1 -1
  2. regscale/_version.py +39 -0
  3. regscale/core/app/internal/__init__.py +13 -0
  4. regscale/core/app/internal/model_editor.py +3 -3
  5. regscale/core/app/internal/set_permissions.py +173 -0
  6. regscale/core/app/utils/file_utils.py +11 -1
  7. regscale/core/app/utils/regscale_utils.py +34 -129
  8. regscale/core/utils/date.py +86 -30
  9. regscale/integrations/commercial/defender.py +3 -0
  10. regscale/integrations/commercial/qualys/__init__.py +40 -14
  11. regscale/integrations/commercial/qualys/containers.py +324 -0
  12. regscale/integrations/commercial/qualys/scanner.py +203 -8
  13. regscale/integrations/commercial/synqly/edr.py +10 -0
  14. regscale/integrations/commercial/wizv2/click.py +11 -7
  15. regscale/integrations/commercial/wizv2/constants.py +28 -0
  16. regscale/integrations/commercial/wizv2/issue.py +3 -2
  17. regscale/integrations/commercial/wizv2/parsers.py +23 -0
  18. regscale/integrations/commercial/wizv2/scanner.py +89 -30
  19. regscale/integrations/commercial/wizv2/utils.py +208 -75
  20. regscale/integrations/commercial/wizv2/variables.py +2 -1
  21. regscale/integrations/commercial/wizv2/wiz_auth.py +3 -3
  22. regscale/integrations/public/fedramp/fedramp_cis_crm.py +98 -20
  23. regscale/integrations/public/fedramp/fedramp_docx.py +2 -3
  24. regscale/integrations/scanner_integration.py +7 -2
  25. regscale/models/integration_models/cisa_kev_data.json +187 -5
  26. regscale/models/integration_models/synqly_models/capabilities.json +1 -1
  27. regscale/models/regscale_models/__init__.py +2 -0
  28. regscale/models/regscale_models/asset.py +1 -1
  29. regscale/models/regscale_models/catalog.py +16 -0
  30. regscale/models/regscale_models/file.py +2 -1
  31. regscale/models/regscale_models/form_field_value.py +59 -1
  32. regscale/models/regscale_models/issue.py +47 -0
  33. regscale/models/regscale_models/modules.py +88 -1
  34. regscale/models/regscale_models/organization.py +30 -0
  35. regscale/models/regscale_models/regscale_model.py +20 -6
  36. regscale/models/regscale_models/security_control.py +47 -0
  37. regscale/models/regscale_models/security_plan.py +32 -0
  38. regscale/models/regscale_models/vulnerability.py +3 -3
  39. regscale/models/regscale_models/vulnerability_mapping.py +2 -2
  40. regscale/regscale.py +2 -0
  41. {regscale_cli-6.20.4.1.dist-info → regscale_cli-6.20.6.0.dist-info}/METADATA +1 -1
  42. {regscale_cli-6.20.4.1.dist-info → regscale_cli-6.20.6.0.dist-info}/RECORD +49 -44
  43. tests/fixtures/test_fixture.py +33 -4
  44. tests/regscale/core/test_app.py +53 -32
  45. tests/regscale/test_init.py +94 -0
  46. {regscale_cli-6.20.4.1.dist-info → regscale_cli-6.20.6.0.dist-info}/LICENSE +0 -0
  47. {regscale_cli-6.20.4.1.dist-info → regscale_cli-6.20.6.0.dist-info}/WHEEL +0 -0
  48. {regscale_cli-6.20.4.1.dist-info → regscale_cli-6.20.6.0.dist-info}/entry_points.txt +0 -0
  49. {regscale_cli-6.20.4.1.dist-info → regscale_cli-6.20.6.0.dist-info}/top_level.txt +0 -0
@@ -16,8 +16,10 @@ from zipfile import ZipFile
16
16
  import cachetools
17
17
  import requests
18
18
  from pydantic import ValidationError
19
+ from rich.progress import Progress, TaskID
19
20
 
20
21
  from regscale.core.app.api import Api
22
+ from regscale.core.app.application import Application
21
23
  from regscale.core.app.utils.app_utils import (
22
24
  error_and_exit,
23
25
  check_file_path,
@@ -27,19 +29,31 @@ from regscale.core.app.utils.app_utils import (
27
29
  )
28
30
  from regscale.core.utils.date import datetime_obj
29
31
  from regscale.integrations.commercial.wizv2.constants import (
30
- DOWNLOAD_QUERY,
31
32
  BEARER,
32
- REPORTS_QUERY,
33
+ CHECK_INTERVAL_FOR_DOWNLOAD_REPORT,
33
34
  CONTENT_TYPE,
34
- RATE_LIMIT_MSG,
35
35
  CREATE_REPORT_QUERY,
36
+ DOWNLOAD_QUERY,
36
37
  MAX_RETRIES,
37
- CHECK_INTERVAL_FOR_DOWNLOAD_REPORT,
38
+ RATE_LIMIT_MSG,
39
+ REPORTS_QUERY,
40
+ RERUN_REPORT_QUERY,
38
41
  )
39
42
  from regscale.integrations.commercial.wizv2.models import ComplianceReport, ComplianceCheckStatus
40
43
  from regscale.integrations.commercial.wizv2.variables import WizVariables
41
44
  from regscale.integrations.commercial.wizv2.wiz_auth import wiz_authenticate
42
- from regscale.models import File, Sbom, SecurityPlan, Catalog, ControlImplementation, Assessment, regscale_models
45
+ from regscale.models import (
46
+ File,
47
+ Sbom,
48
+ SecurityControl,
49
+ SecurityPlan,
50
+ Catalog,
51
+ ControlImplementation,
52
+ Assessment,
53
+ regscale_models,
54
+ ControlImplementationStatus,
55
+ ImplementationObjective,
56
+ )
43
57
  from regscale.utils import PaginatedGraphQLClient
44
58
  from regscale.utils.decorators import deprecated
45
59
 
@@ -47,6 +61,31 @@ logger = logging.getLogger("regscale")
47
61
  compliance_job_progress = create_progress_object()
48
62
 
49
63
 
64
+ def is_report_expired(report_run_at: str, max_age_days: int) -> bool:
65
+ """
66
+ Check if a report is expired based on its run date
67
+
68
+ :param str report_run_at: Report run date in ISO format
69
+ :param int max_age_days: Maximum age in days
70
+ :return: True if report is expired, False otherwise
71
+ :rtype: bool
72
+ """
73
+ try:
74
+ run_date = datetime_obj(report_run_at)
75
+ if not run_date:
76
+ return True
77
+
78
+ # Convert to naive datetime for comparison
79
+ run_date_naive = run_date.replace(tzinfo=None)
80
+ current_date = datetime.datetime.now()
81
+ age_in_days = (current_date - run_date_naive).days
82
+
83
+ return age_in_days >= max_age_days
84
+ except (ValueError, TypeError):
85
+ # If we can't parse the date, consider it expired
86
+ return True
87
+
88
+
50
89
  def get_notes_from_wiz_props(wiz_entity_properties: Dict, external_id: str) -> str:
51
90
  """
52
91
  Get notes from wiz properties
@@ -407,15 +446,28 @@ def get_or_create_report_id(
407
446
  :param target_framework: Target framework name with underscores
408
447
  :return: Single report ID
409
448
  """
449
+ app = Application()
450
+ report_age_days = app.config.get("wizReportAge", 15)
410
451
  report_name = f"{target_framework}_project_{project_id}"
411
452
 
412
453
  # Check for existing report with exact name
413
454
  for report in existing_reports:
414
455
  if report.get("name") == report_name:
415
456
  logger.info(f"Found existing report '{report_name}' with ID {report['id']}")
416
- return report["id"]
417
457
 
418
- # Create new report if no exact match found
458
+ # Check if report is expired based on wizReportAge
459
+ run_at = report.get("lastRun", {}).get("runAt")
460
+
461
+ if run_at and is_report_expired(run_at, report_age_days):
462
+ logger.info(
463
+ f"Report '{report_name}' is expired (older than {report_age_days} days), will create new report"
464
+ )
465
+ break
466
+ else:
467
+ logger.info(f"Report '{report_name}' is still valid, using existing report")
468
+ return report["id"]
469
+
470
+ # Create new report if no valid existing report found
419
471
  try:
420
472
  framework_index = frameworks.index(target_framework)
421
473
  framework_id = wiz_frameworks[framework_index].get("id")
@@ -439,13 +491,14 @@ def fetch_report_data(report_id: str) -> List[Dict]:
439
491
  """
440
492
  try:
441
493
  download_url = get_report_url_and_status(report_id)
442
- logger.info(f"Fetching report {report_id} from: {download_url}")
494
+ logger.debug(f"Fetching report {report_id} from: {download_url}")
443
495
 
444
496
  with closing(requests.get(url=download_url, stream=True, timeout=10)) as response:
445
497
  response.raise_for_status()
446
- logger.info(f"Streaming and parsing report {report_id}")
498
+ logger.info(f"Streaming and parsing report {report_id}...")
447
499
 
448
500
  reader = csv.DictReader(codecs.iterdecode(response.iter_lines(), encoding="utf-8"), delimiter=",")
501
+ logger.info(f"Report {report_id} fetched successfully.")
449
502
  return list(reader)
450
503
  except requests.RequestException as e:
451
504
  error_and_exit(f"Failed to fetch report {report_id}: {str(e)}")
@@ -586,7 +639,7 @@ def send_request(
586
639
  """
587
640
  logger.debug("Sending a request to Wiz API")
588
641
  api = Api()
589
- payload = dict({"query": query, "variables": variables})
642
+ payload = {"query": query, "variables": variables}
590
643
  if api_endpoint_url is None:
591
644
  api_endpoint_url = WizVariables.wizUrl
592
645
  if WizVariables.wizAccessToken:
@@ -650,8 +703,7 @@ def get_report_url_and_status(report_id: str) -> str:
650
703
  raise requests.RequestException("Failed to download report")
651
704
 
652
705
  response_json = response.json()
653
- errors = response_json.get("errors")
654
- if errors:
706
+ if errors := response_json.get("errors"):
655
707
  message = errors[0]["message"]
656
708
  if RATE_LIMIT_MSG in message:
657
709
  rate = errors[0]["extensions"]["retryAfter"]
@@ -664,6 +716,10 @@ def get_report_url_and_status(report_id: str) -> str:
664
716
  status = response_json.get("data", {}).get("report", {}).get("lastRun", {}).get("status")
665
717
  if status == "COMPLETED":
666
718
  return response_json["data"]["report"]["lastRun"]["url"]
719
+ elif status == "EXPIRED":
720
+ logger.warning("Report %s is expired, rerunning report...", report_id)
721
+ rerun_expired_report({"reportId": report_id})
722
+ return get_report_url_and_status(report_id)
667
723
 
668
724
  raise requests.RequestException("Download failed, exceeding the maximum number of retries")
669
725
 
@@ -680,13 +736,25 @@ def download_report(variables: Dict) -> requests.Response:
680
736
  return response
681
737
 
682
738
 
739
+ def rerun_expired_report(variables: Dict) -> requests.Response:
740
+ """
741
+ Rerun a report
742
+
743
+ :param Dict variables: Variables for Wiz request
744
+ :return: Response object from Wiz API
745
+ :rtype: requests.Response
746
+ """
747
+ response = send_request(RERUN_REPORT_QUERY, variables=variables)
748
+ return response
749
+
750
+
683
751
  def _sync_compliance(
684
752
  wiz_project_id: str,
685
753
  regscale_id: int,
686
754
  regscale_module: str,
687
755
  client_id: str,
688
756
  client_secret: str,
689
- catalog_id: int,
757
+ catalog_id: Optional[int] = None,
690
758
  framework: Optional[str] = "NIST800-53R5",
691
759
  ) -> List[ComplianceReport]:
692
760
  """
@@ -697,7 +765,7 @@ def _sync_compliance(
697
765
  :param str regscale_module: RegScale module
698
766
  :param str client_id: Wiz Client ID
699
767
  :param str client_secret: Wiz Client Secret
700
- :param int catalog_id: Catalog ID, defaults to None
768
+ :param Optional[int] catalog_id: Catalog ID, defaults to None
701
769
  :param Optional[str] framework: Framework, defaults to NIST800-53R5
702
770
  :return: List of ComplianceReport objects
703
771
  :rtype: List[ComplianceReport]
@@ -708,68 +776,84 @@ def _sync_compliance(
708
776
  client_id=client_id,
709
777
  client_secret=client_secret,
710
778
  )
711
- report_job = compliance_job_progress.add_task("[#f68d1f]Fetching Wiz compliance report...", total=1)
712
- fetch_regscale_data_job = compliance_job_progress.add_task(
713
- "[#f68d1f]Fetching RegScale Catalog info for framework...", total=1
714
- )
715
- logger.info("Fetching Wiz compliance report for project ID %s...", wiz_project_id)
716
- compliance_job_progress.update(report_job, completed=True, advance=1)
779
+ with compliance_job_progress:
780
+ report_job = compliance_job_progress.add_task("[#f68d1f]Fetching Wiz compliance report...", total=1)
781
+ fetch_regscale_data_job = compliance_job_progress.add_task(
782
+ "[#f68d1f]Fetching RegScale Catalog info for framework...", total=1
783
+ )
784
+ compliance_job_progress.update(report_job, completed=True, advance=1)
717
785
 
718
- framework_mapping = {
719
- "CSF": "NIST CSF v1.1",
720
- "NIST800-53R5": "NIST SP 800-53 Revision 5",
721
- "NIST800-53R4": "NIST SP 800-53 Revision 4",
722
- }
723
- sync_framework = framework_mapping.get(framework)
724
- snake_framework = sync_framework.replace(" ", "_")
725
- logger.debug(f"{snake_framework=}")
726
- logger.info("Fetching Wiz compliance report for project ID %s", wiz_project_id)
727
- report_data = fetch_framework_report(wiz_project_id, snake_framework)
728
- report_models = []
729
- compliance_job_progress.update(report_job, completed=True, advance=1)
730
-
731
- catalog = Catalog.get_with_all_details(catalog_id=catalog_id)
732
- controls = catalog.get("controls") if catalog else []
733
- passing_controls = {}
734
- failing_controls = {}
735
- controls_to_reports = {}
736
-
737
- compliance_job_progress.update(fetch_regscale_data_job, completed=True, advance=1)
738
- logger.info("Analyzing ComplianceReport for framework %s from Wiz" % sync_framework)
739
- running_compliance_job = compliance_job_progress.add_task(
740
- "[#f68d1f]Building compliance posture from wiz report...",
741
- total=len(report_data),
742
- )
743
- for row in report_data:
744
- try:
745
- cr = ComplianceReport(**row)
746
- if cr.framework == sync_framework:
747
- check_compliance(
748
- cr,
749
- controls,
750
- passing_controls,
751
- failing_controls,
752
- controls_to_reports,
753
- )
754
- report_models.append(cr)
786
+ framework_mapping = {
787
+ "CSF": "NIST CSF v1.1",
788
+ "NIST800-53R5": "NIST SP 800-53 Revision 5",
789
+ "NIST800-53R4": "NIST SP 800-53 Revision 4",
790
+ }
791
+ sync_framework = framework_mapping.get(framework)
792
+ snake_framework = sync_framework.replace(" ", "_")
793
+ logger.debug(f"{snake_framework=}")
794
+ logger.info("Fetching Wiz compliance report for project ID %s...", wiz_project_id)
795
+ report_data = fetch_framework_report(wiz_project_id, snake_framework)
796
+ report_models = []
797
+ compliance_job_progress.update(report_job, completed=True, advance=1)
798
+
799
+ if catalog_id:
800
+ logger.info("Fetching all Controls for catalog #%s...", catalog_id)
801
+ catalog = Catalog.get_with_all_details(catalog_id=catalog_id)
802
+ controls = catalog.get("controls") if catalog else []
803
+ else:
804
+ # get all of the ControlImplementations for the security plan and get the controls from them
805
+ logger.info("Fetching all Controls for %s #%d...", regscale_module, regscale_id)
806
+ controls = SecurityControl.get_controls_by_parent_id_and_module(
807
+ parent_module=regscale_module, parent_id=regscale_id, return_dicts=True
808
+ )
809
+ logger.info("Received %d control(s) from RegScale.", len(controls))
810
+
811
+ passing_controls = {}
812
+ failing_controls = {}
813
+ controls_to_reports = {}
814
+
815
+ compliance_job_progress.update(fetch_regscale_data_job, completed=True, advance=1)
816
+ logger.info("Analyzing ComplianceReport for framework %s from Wiz...", sync_framework)
817
+ running_compliance_job = compliance_job_progress.add_task(
818
+ "[#f68d1f]Building compliance posture from wiz report...",
819
+ total=len(report_data),
820
+ )
821
+ for row in report_data:
822
+ try:
823
+ cr = ComplianceReport(**row)
824
+ if cr.framework == sync_framework:
825
+ check_compliance(
826
+ cr,
827
+ controls,
828
+ passing_controls,
829
+ failing_controls,
830
+ controls_to_reports,
831
+ )
832
+ report_models.append(cr)
833
+ except ValidationError:
834
+ error_message = traceback.format_exc()
835
+ logger.error(f"Error creating ComplianceReport: {error_message}")
836
+ finally:
755
837
  compliance_job_progress.update(running_compliance_job, advance=1)
756
- except ValidationError:
838
+ try:
839
+ saving_regscale_data_job = compliance_job_progress.add_task(
840
+ "[#f68d1f]Saving RegScale data...", total=len(controls_to_reports)
841
+ )
842
+ create_assessment_from_compliance_report(
843
+ controls_to_reports=controls_to_reports,
844
+ regscale_id=regscale_id,
845
+ regscale_module=regscale_module,
846
+ controls=controls,
847
+ progress=compliance_job_progress,
848
+ task=saving_regscale_data_job,
849
+ )
850
+ logger.info("Completed saving RegScale data.")
851
+ except Exception:
757
852
  error_message = traceback.format_exc()
758
- logger.error(f"Error creating ComplianceReport: {error_message}")
759
- try:
760
- saving_regscale_data_job = compliance_job_progress.add_task("[#f68d1f]Saving RegScale data...", total=1)
761
- create_assessment_from_compliance_report(
762
- controls_to_reports=controls_to_reports,
763
- regscale_id=regscale_id,
764
- regscale_module=regscale_module,
765
- controls=controls,
766
- )
767
- compliance_job_progress.update(saving_regscale_data_job, completed=True, advance=1)
768
-
769
- except Exception:
770
- error_message = traceback.format_exc()
771
- logger.error(f"Error creating ControlImplementations from compliance report: {error_message}")
772
- return report_models
853
+ logger.error(f"Error creating ControlImplementations from compliance report: {error_message}")
854
+ finally:
855
+ compliance_job_progress.update(saving_regscale_data_job, completed=True, advance=len(controls_to_reports))
856
+ return report_models
773
857
 
774
858
 
775
859
  def check_compliance(
@@ -833,7 +917,7 @@ def _clean_passing_list(passing: Dict, failing: Dict) -> None:
833
917
 
834
918
 
835
919
  def create_assessment_from_compliance_report(
836
- controls_to_reports: Dict, regscale_id: int, regscale_module: str, controls: List
920
+ controls_to_reports: Dict, regscale_id: int, regscale_module: str, controls: List, progress: Progress, task: TaskID
837
921
  ) -> None:
838
922
  """
839
923
  Create assessment from compliance report
@@ -842,6 +926,8 @@ def create_assessment_from_compliance_report(
842
926
  :param int regscale_id: RegScale ID
843
927
  :param str regscale_module: RegScale module
844
928
  :param List controls: Controls
929
+ :param Progress progress: Progress object, used for progress bar updates
930
+ :param TaskID task: Task ID, used for progress bar updates
845
931
  :return: None
846
932
  :rtype: None
847
933
  """
@@ -854,6 +940,7 @@ def create_assessment_from_compliance_report(
854
940
  break
855
941
  filtered_results = [x for x in implementations if x.controlID == control_record_id]
856
942
  create_report_assessment(filtered_results, reports, control_id)
943
+ progress.update(task, advance=1)
857
944
 
858
945
 
859
946
  def create_report_assessment(filtered_results: List, reports: List, control_id: str) -> None:
@@ -870,7 +957,7 @@ def create_report_assessment(filtered_results: List, reports: List, control_id:
870
957
  for report in reports:
871
958
  html_summary = format_dict_to_html(report.dict())
872
959
  if implementation:
873
- Assessment(
960
+ a = Assessment(
874
961
  leadAssessorId=implementation.createdById,
875
962
  title=f"Wiz compliance report assessment for {control_id}",
876
963
  assessmentType="Control Testing",
@@ -884,3 +971,49 @@ def create_report_assessment(filtered_results: List, reports: List, control_id:
884
971
  parentModule="controls",
885
972
  isPublic=True,
886
973
  ).create()
974
+ update_implementation_status(
975
+ implementation=implementation,
976
+ result=report.result,
977
+ )
978
+ logger.info(f"Created report assessment for {control_id}: {a.id}")
979
+
980
+
981
+ def update_implementation_status(implementation: ControlImplementation, result: str) -> ControlImplementation:
982
+ """
983
+ Update implementation status based on the report result
984
+
985
+ :param ControlImplementation implementation: Control Implementation object
986
+ :param str result: Report result
987
+ :return: Updated Control Implementation object
988
+ :rtype: ControlImplementation
989
+ """
990
+ objectives = ImplementationObjective.get_all_by_parent(
991
+ parent_module=implementation.get_module_slug(),
992
+ parent_id=implementation.id,
993
+ )
994
+ if objectives:
995
+ for objective in objectives:
996
+ objective.status = report_result_to_implementation_status(result)
997
+ objective.save()
998
+ logger.debug(f"Updated status for {objective.id}: {objective.status}")
999
+ else:
1000
+ implementation.objectives = []
1001
+ implementation.status = report_result_to_implementation_status(result)
1002
+ implementation.save()
1003
+ logger.info(f"Updated implementation status for {implementation.id}: {implementation.status}")
1004
+
1005
+
1006
+ def report_result_to_implementation_status(result: str) -> str:
1007
+ """
1008
+ Convert report result to implementation status
1009
+
1010
+ :param str result: Report result
1011
+ :return: Implementation status
1012
+ :rtype: str
1013
+ """
1014
+ if result == ComplianceCheckStatus.PASS.value:
1015
+ return ControlImplementationStatus.Implemented.value
1016
+ elif result == ComplianceCheckStatus.FAIL.value:
1017
+ return ControlImplementationStatus.InRemediation.value
1018
+ else:
1019
+ return ControlImplementationStatus.NotImplemented.value
@@ -31,7 +31,7 @@ class WizVariables(metaclass=RsVariablesMeta):
31
31
  "PRIVATE_LINK", "RAW_ACCESS_POLICY", "REGISTERED_DOMAIN", "RESOURCE_GROUP", "SECRET",
32
32
  "SECRET_CONTAINER", "SERVERLESS", "SERVERLESS_PACKAGE", "SERVICE_ACCOUNT", "SERVICE_CONFIGURATION",
33
33
  "STORAGE_ACCOUNT", "SUBNET", "SUBSCRIPTION", "VIRTUAL_DESKTOP", "VIRTUAL_MACHINE",
34
- "VIRTUAL_MACHINE_IMAGE", "VIRTUAL_NETWORK", "VOLUME", "WEB_SERVICE" ] }""",
34
+ "VIRTUAL_MACHINE_IMAGE", "VIRTUAL_NETWORK", "VOLUME", "WEB_SERVICE", "NETWORK_ADDRESS"] }""",
35
35
  ) # type: ignore
36
36
  wizAccessToken: RsVariableType(str, "", sensitive=True, required=False) # type: ignore
37
37
  wizClientId: RsVariableType(str, "", sensitive=True) # type: ignore
@@ -44,3 +44,4 @@ class WizVariables(metaclass=RsVariablesMeta):
44
44
  default=["SERVER_APPLICATION", "CLIENT_APPLICATION", "VIRTUAL_APPLIANCE"],
45
45
  required=False,
46
46
  ) # type: ignore
47
+ wizReportAge: RsVariableType(int, "14", default=14, required=False) # type: ignore
@@ -49,10 +49,10 @@ def wiz_authenticate(client_id: Optional[str] = None, client_secret: Optional[st
49
49
  # get secrets
50
50
  client_id = WizVariables.wizClientId if client_id is None else client_id
51
51
  if not client_id:
52
- raise ValueError("No Wiz Client ID provided in system environment or CLI command.")
52
+ error_and_exit("No Wiz Client ID provided in system environment or CLI command.")
53
53
  client_secret = WizVariables.wizClientSecret if client_secret is None else client_secret
54
54
  if not client_secret:
55
- raise ValueError("No Wiz Client Secret provided in system environment or CLI command.")
55
+ error_and_exit("No Wiz Client Secret provided in system environment or CLI command.")
56
56
  wiz_auth_url = config.get("wizAuthUrl")
57
57
  if not wiz_auth_url:
58
58
  error_and_exit("No Wiz Authentication URL provided in the init.yaml file.")
@@ -100,7 +100,7 @@ def get_token(api: Api, client_id: str, client_secret: str, token_url: str) -> t
100
100
  )
101
101
  if response.ok:
102
102
  status_code = 200
103
- logger.debug(response.reason)
103
+ logger.info(response.reason)
104
104
  # If response is unauthorized, try the first cognito url
105
105
  if response.status_code == requests.codes.unauthorized:
106
106
  try: