regscale-cli 6.19.0.1__py3-none-any.whl → 6.19.2.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.
- regscale/__init__.py +1 -1
- regscale/core/app/utils/app_utils.py +1 -1
- regscale/integrations/commercial/amazon/common.py +5 -4
- regscale/integrations/commercial/aws/scanner.py +3 -2
- regscale/integrations/commercial/synqly/assets.py +10 -0
- regscale/integrations/commercial/synqly/ticketing.py +25 -0
- regscale/integrations/commercial/tenablev2/commands.py +34 -4
- regscale/integrations/commercial/tenablev2/sync_compliance.py +550 -0
- regscale/integrations/commercial/wizv2/click.py +3 -3
- regscale/integrations/scanner_integration.py +3 -2
- regscale/models/app_models/import_validater.py +2 -0
- regscale/models/integration_models/cisa_kev_data.json +188 -10
- regscale/models/integration_models/flat_file_importer/__init__.py +26 -9
- regscale/models/integration_models/synqly_models/capabilities.json +1 -1
- regscale/models/regscale_models/assessment_plan.py +1 -1
- regscale/models/regscale_models/assessment_result.py +39 -0
- regscale/models/regscale_models/line_of_inquiry.py +2 -2
- regscale/models/regscale_models/regscale_model.py +16 -15
- regscale/models/regscale_models/software_inventory.py +1 -1
- regscale/models/regscale_models/supply_chain.py +4 -4
- regscale/models/regscale_models/user.py +11 -0
- regscale/utils/graphql_client.py +2 -1
- {regscale_cli-6.19.0.1.dist-info → regscale_cli-6.19.2.0.dist-info}/METADATA +45 -45
- {regscale_cli-6.19.0.1.dist-info → regscale_cli-6.19.2.0.dist-info}/RECORD +28 -26
- {regscale_cli-6.19.0.1.dist-info → regscale_cli-6.19.2.0.dist-info}/LICENSE +0 -0
- {regscale_cli-6.19.0.1.dist-info → regscale_cli-6.19.2.0.dist-info}/WHEEL +0 -0
- {regscale_cli-6.19.0.1.dist-info → regscale_cli-6.19.2.0.dist-info}/entry_points.txt +0 -0
- {regscale_cli-6.19.0.1.dist-info → regscale_cli-6.19.2.0.dist-info}/top_level.txt +0 -0
regscale/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "6.19.0
|
|
1
|
+
__version__ = "6.19.2.0"
|
|
@@ -642,7 +642,7 @@ def save_to_json(file: Path, data: Any, output_log: bool) -> None:
|
|
|
642
642
|
with open(file, "w", encoding="utf-8") as outfile:
|
|
643
643
|
outfile.write(str(data))
|
|
644
644
|
if output_log:
|
|
645
|
-
logger.info("Data successfully saved to %s", file.
|
|
645
|
+
logger.info("Data successfully saved to %s", file.name)
|
|
646
646
|
|
|
647
647
|
|
|
648
648
|
def save_data_to(file: Path, data: Any, output_log: bool = True, transpose_data: bool = True) -> None:
|
|
@@ -56,17 +56,18 @@ def determine_status_and_results(finding: Any) -> Tuple[str, Optional[str]]:
|
|
|
56
56
|
results = None
|
|
57
57
|
if "Compliance" in finding.keys():
|
|
58
58
|
status = "Fail" if finding["Compliance"]["Status"] == "FAILED" else "Pass"
|
|
59
|
-
results = ", ".join(finding
|
|
59
|
+
results = ", ".join(finding.get("Compliance", {}).get("RelatedRequirements", [])) or "N/A"
|
|
60
60
|
if "FindingProviderFields" in finding.keys():
|
|
61
61
|
status = (
|
|
62
62
|
"Fail"
|
|
63
|
-
if finding
|
|
63
|
+
if finding.get("FindingProviderFields", {}).get("Severity", {}).get("Label", "")
|
|
64
|
+
in ["CRITICAL", "HIGH", "MEDIUM", "LOW"]
|
|
64
65
|
else "Pass"
|
|
65
66
|
)
|
|
66
67
|
if "PatchSummary" in finding.keys() and not results:
|
|
67
68
|
results = (
|
|
68
|
-
f"{finding
|
|
69
|
-
"{finding
|
|
69
|
+
f"{finding.get('PatchSummary', {}).get('MissingCount', 0)} Missing Patch(s) of "
|
|
70
|
+
"{finding.get('PatchSummary', {}).get('InstalledCount', 0)}"
|
|
70
71
|
)
|
|
71
72
|
return status, results
|
|
72
73
|
|
|
@@ -711,12 +711,13 @@ Description: {description if isinstance(description, str) else ''}"""
|
|
|
711
711
|
)
|
|
712
712
|
if not region:
|
|
713
713
|
logger.warning("AWS region not provided. Defaulting to 'us-east-1'.")
|
|
714
|
-
|
|
715
|
-
"securityhub",
|
|
714
|
+
session = boto3.Session(
|
|
716
715
|
region_name=kwargs.get(region, "us-east-1"),
|
|
717
716
|
aws_access_key_id=aws_secret_key_id,
|
|
718
717
|
aws_secret_access_key=aws_secret_access_key,
|
|
718
|
+
aws_session_token=kwargs.get("aws_session_token"),
|
|
719
719
|
)
|
|
720
|
+
client = session.client("securityhub")
|
|
720
721
|
aws_findings = fetch_aws_findings(aws_client=client)
|
|
721
722
|
self.num_findings_to_process = len(aws_findings)
|
|
722
723
|
for finding in aws_findings:
|
|
@@ -33,6 +33,16 @@ def sync_nozomi_vantage(regscale_ssp_id: int) -> None:
|
|
|
33
33
|
assets_nozomi_vantage.run_sync(regscale_ssp_id=regscale_ssp_id)
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
@assets.command(name="sync_qualys_cloud")
|
|
37
|
+
@regscale_ssp_id()
|
|
38
|
+
def sync_qualys_cloud(regscale_ssp_id: int) -> None:
|
|
39
|
+
"""Sync Assets from Qualys Cloud to RegScale."""
|
|
40
|
+
from regscale.models.integration_models.synqly_models.connectors import Assets
|
|
41
|
+
|
|
42
|
+
assets_qualys_cloud = Assets("qualys_cloud")
|
|
43
|
+
assets_qualys_cloud.run_sync(regscale_ssp_id=regscale_ssp_id)
|
|
44
|
+
|
|
45
|
+
|
|
36
46
|
@assets.command(name="sync_servicenow")
|
|
37
47
|
@regscale_ssp_id()
|
|
38
48
|
def sync_servicenow(regscale_ssp_id: int) -> None:
|
|
@@ -158,4 +158,29 @@ def sync_torq(regscale_id: int, regscale_module: str, name: str) -> None:
|
|
|
158
158
|
ticketing_torq.run_sync(regscale_id=regscale_id, regscale_module=regscale_module, name=name)
|
|
159
159
|
|
|
160
160
|
|
|
161
|
+
@ticketing.command(name="sync_zendesk")
|
|
162
|
+
@regscale_id()
|
|
163
|
+
@regscale_module()
|
|
164
|
+
@click.option(
|
|
165
|
+
"--name",
|
|
166
|
+
type=click.STRING,
|
|
167
|
+
help="zendesk name",
|
|
168
|
+
required=True,
|
|
169
|
+
prompt="zendesk name",
|
|
170
|
+
)
|
|
171
|
+
@click.option(
|
|
172
|
+
"--subject",
|
|
173
|
+
type=click.STRING,
|
|
174
|
+
help="zendesk subject",
|
|
175
|
+
required=True,
|
|
176
|
+
prompt="zendesk subject",
|
|
177
|
+
)
|
|
178
|
+
def sync_zendesk(regscale_id: int, regscale_module: str, name: str, subject: str) -> None:
|
|
179
|
+
"""Sync Ticketing data between Zendesk and RegScale."""
|
|
180
|
+
from regscale.models.integration_models.synqly_models.connectors import Ticketing
|
|
181
|
+
|
|
182
|
+
ticketing_zendesk = Ticketing("zendesk")
|
|
183
|
+
ticketing_zendesk.run_sync(regscale_id=regscale_id, regscale_module=regscale_module, name=name, subject=subject)
|
|
184
|
+
|
|
185
|
+
|
|
161
186
|
# pylint: enable=line-too-long
|
|
@@ -30,12 +30,17 @@ from regscale.integrations.commercial.tenablev2.jsonl_scanner import TenableSCJs
|
|
|
30
30
|
from regscale.integrations.commercial.tenablev2.sc_scanner import SCIntegration
|
|
31
31
|
from regscale.integrations.commercial.tenablev2.variables import TenableVariables
|
|
32
32
|
from regscale.models import regscale_id, regscale_ssp_id
|
|
33
|
-
from regscale.models.app_models.click import
|
|
34
|
-
from regscale.models.regscale_models
|
|
33
|
+
from regscale.models.app_models.click import file_types, hidden_file_path, save_output_to
|
|
34
|
+
from regscale.models.regscale_models import SecurityPlan
|
|
35
35
|
|
|
36
36
|
logger = logging.getLogger("regscale")
|
|
37
37
|
console = Console()
|
|
38
38
|
artifacts_dir = "./artifacts"
|
|
39
|
+
REGSCALE_INC = "RegScale, Inc."
|
|
40
|
+
REGSCALE_CLI = "RegScale CLI"
|
|
41
|
+
FULLY_IMPLEMENTED = "Fully Implemented"
|
|
42
|
+
NOT_IMPLEMENTED = "Not Implemented"
|
|
43
|
+
IN_REMEDIATION = "In Remediation"
|
|
39
44
|
|
|
40
45
|
|
|
41
46
|
# Define a helper function for gen_client to replace the original one
|
|
@@ -146,7 +151,7 @@ def io_sync_assets(regscale_ssp_id: int, tags: List[Tuple[str, str]] = None):
|
|
|
146
151
|
from regscale.integrations.commercial.tenablev2.scanner import TenableIntegration
|
|
147
152
|
|
|
148
153
|
integration = TenableIntegration(plan_id=regscale_ssp_id, tags=tags)
|
|
149
|
-
integration.sync_assets()
|
|
154
|
+
integration.sync_assets(plan_id=regscale_ssp_id)
|
|
150
155
|
|
|
151
156
|
console.print("[bold green]Tenable.io asset synchronization complete.[/bold green]")
|
|
152
157
|
except Exception as e:
|
|
@@ -185,7 +190,7 @@ def io_sync_findings(
|
|
|
185
190
|
from regscale.integrations.commercial.tenablev2.scanner import TenableIntegration
|
|
186
191
|
|
|
187
192
|
integration = TenableIntegration(plan_id=regscale_ssp_id, tags=tags, scan_date=scan_date)
|
|
188
|
-
integration.sync_findings(severity=severity)
|
|
193
|
+
integration.sync_findings(plan_id=regscale_ssp_id, severity=severity)
|
|
189
194
|
|
|
190
195
|
console.print("[bold green]Tenable.io finding synchronization complete.[/bold green]")
|
|
191
196
|
except Exception as e:
|
|
@@ -768,6 +773,31 @@ def sync_jsonl(
|
|
|
768
773
|
logger.error(f"Error in Tenable SC JSONL sync: {str(e)}", exc_info=True)
|
|
769
774
|
|
|
770
775
|
|
|
776
|
+
@io.command(name="sync_compliance_controls")
|
|
777
|
+
@regscale_ssp_id()
|
|
778
|
+
@click.option(
|
|
779
|
+
"--catalog_id",
|
|
780
|
+
type=click.INT,
|
|
781
|
+
help="The ID number from RegScale Catalog that the System Security Plan's controls belong to",
|
|
782
|
+
prompt="Enter RegScale Catalog ID",
|
|
783
|
+
required=True,
|
|
784
|
+
)
|
|
785
|
+
@click.option(
|
|
786
|
+
"--framework",
|
|
787
|
+
required=True,
|
|
788
|
+
type=click.Choice(["800-53", "800-53r5", "CSF", "800-171"], case_sensitive=True),
|
|
789
|
+
help="The framework to use. from Tenable.io frameworks MUST be the same RegScale Catalog of controls",
|
|
790
|
+
)
|
|
791
|
+
@hidden_file_path(help="The file path to load control data instead of fetching from Tenable.io")
|
|
792
|
+
def sync_compliance_data(regscale_ssp_id: int, catalog_id: int, framework: str, offline: Optional[Path] = None):
|
|
793
|
+
"""
|
|
794
|
+
Sync the compliance data from Tenable.io to create control implementations for controls in frameworks.
|
|
795
|
+
"""
|
|
796
|
+
from regscale.integrations.commercial.tenablev2.sync_compliance import sync_compliance_data
|
|
797
|
+
|
|
798
|
+
sync_compliance_data(ssp_id=regscale_ssp_id, catalog_id=catalog_id, framework=framework, offline=offline)
|
|
799
|
+
|
|
800
|
+
|
|
771
801
|
# Add import_nessus to __all__ exports at the end of the file
|
|
772
802
|
__all__ = [
|
|
773
803
|
"tenable",
|