regscale-cli 6.20.1.1__py3-none-any.whl → 6.20.3.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/variables.py +5 -3
- regscale/integrations/commercial/__init__.py +15 -0
- regscale/integrations/commercial/axonius/__init__.py +0 -0
- regscale/integrations/commercial/axonius/axonius_integration.py +70 -0
- regscale/integrations/commercial/burp.py +14 -0
- regscale/integrations/commercial/grype/commands.py +8 -1
- regscale/integrations/commercial/grype/scanner.py +2 -1
- regscale/integrations/commercial/jira.py +288 -137
- regscale/integrations/commercial/opentext/commands.py +14 -5
- regscale/integrations/commercial/opentext/scanner.py +3 -2
- regscale/integrations/commercial/qualys/__init__.py +3 -3
- regscale/integrations/commercial/stigv2/click_commands.py +6 -37
- regscale/integrations/commercial/synqly/assets.py +10 -0
- regscale/integrations/commercial/tenablev2/commands.py +12 -4
- regscale/integrations/commercial/tenablev2/sc_scanner.py +21 -1
- regscale/integrations/commercial/tenablev2/sync_compliance.py +3 -0
- regscale/integrations/commercial/trivy/commands.py +11 -4
- regscale/integrations/commercial/trivy/scanner.py +2 -1
- regscale/integrations/commercial/wizv2/constants.py +4 -0
- regscale/integrations/commercial/wizv2/scanner.py +67 -14
- regscale/integrations/commercial/wizv2/utils.py +24 -10
- regscale/integrations/commercial/wizv2/variables.py +7 -0
- regscale/integrations/jsonl_scanner_integration.py +8 -1
- regscale/integrations/public/cisa.py +58 -63
- regscale/integrations/public/fedramp/fedramp_cis_crm.py +153 -104
- regscale/integrations/scanner_integration.py +30 -8
- regscale/integrations/variables.py +1 -0
- regscale/models/app_models/click.py +49 -1
- regscale/models/app_models/import_validater.py +3 -1
- regscale/models/integration_models/axonius_models/__init__.py +0 -0
- regscale/models/integration_models/axonius_models/connectors/__init__.py +3 -0
- regscale/models/integration_models/axonius_models/connectors/assets.py +111 -0
- regscale/models/integration_models/burp.py +11 -8
- regscale/models/integration_models/cisa_kev_data.json +204 -23
- regscale/models/integration_models/flat_file_importer/__init__.py +36 -176
- regscale/models/integration_models/jira_task_sync.py +27 -0
- regscale/models/integration_models/qualys.py +6 -7
- regscale/models/integration_models/synqly_models/capabilities.json +1 -1
- regscale/models/regscale_models/__init__.py +2 -1
- regscale/models/regscale_models/control_implementation.py +39 -2
- regscale/models/regscale_models/issue.py +1 -0
- regscale/models/regscale_models/regscale_model.py +49 -1
- regscale/models/regscale_models/risk_issue_mapping.py +61 -0
- regscale/models/regscale_models/task.py +1 -0
- regscale/regscale.py +1 -4
- regscale/utils/graphql_client.py +4 -4
- regscale/utils/string.py +13 -0
- {regscale_cli-6.20.1.1.dist-info → regscale_cli-6.20.3.0.dist-info}/METADATA +1 -1
- {regscale_cli-6.20.1.1.dist-info → regscale_cli-6.20.3.0.dist-info}/RECORD +54 -48
- regscale/integrations/commercial/synqly_jira.py +0 -840
- {regscale_cli-6.20.1.1.dist-info → regscale_cli-6.20.3.0.dist-info}/LICENSE +0 -0
- {regscale_cli-6.20.1.1.dist-info → regscale_cli-6.20.3.0.dist-info}/WHEEL +0 -0
- {regscale_cli-6.20.1.1.dist-info → regscale_cli-6.20.3.0.dist-info}/entry_points.txt +0 -0
- {regscale_cli-6.20.1.1.dist-info → regscale_cli-6.20.3.0.dist-info}/top_level.txt +0 -0
regscale/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "6.20.
|
|
1
|
+
__version__ = "6.20.3.0"
|
|
@@ -193,10 +193,12 @@ class RsVariablesMeta(type):
|
|
|
193
193
|
logger.debug(f"Using default value for '{attr_name}': {processed_value}")
|
|
194
194
|
try:
|
|
195
195
|
if config_type.type == dict:
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
if isinstance(processed_value, str):
|
|
197
|
+
import ast
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
typed_value = ast.literal_eval(processed_value) if processed_value else {}
|
|
200
|
+
else:
|
|
201
|
+
typed_value = processed_value if processed_value else {}
|
|
200
202
|
elif config_type.type == bool:
|
|
201
203
|
if isinstance(processed_value, str):
|
|
202
204
|
typed_value = processed_value.lower() in ["true", "1", "yes"]
|
|
@@ -57,6 +57,19 @@ def aws():
|
|
|
57
57
|
show_mapping(aws, "aws_inspector")
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
@click.group(
|
|
61
|
+
cls=LazyGroup,
|
|
62
|
+
lazy_subcommands={
|
|
63
|
+
"sync_assets": "regscale.integrations.commercial.axonius.axonius_integration.sync_assets",
|
|
64
|
+
"sync_findings": "regscale.integrations.commercial.axonius.axonius_integration.sync_findings",
|
|
65
|
+
},
|
|
66
|
+
name="axonius",
|
|
67
|
+
)
|
|
68
|
+
def axonius():
|
|
69
|
+
"""Axonius Integration"""
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
|
|
60
73
|
@click.group(
|
|
61
74
|
cls=LazyGroup,
|
|
62
75
|
lazy_subcommands={
|
|
@@ -430,6 +443,8 @@ def stig():
|
|
|
430
443
|
"io": "regscale.integrations.commercial.tenablev2.commands.io",
|
|
431
444
|
"sc": "regscale.integrations.commercial.tenablev2.commands.sc",
|
|
432
445
|
"nessus": "regscale.integrations.commercial.tenablev2.commands.nessus",
|
|
446
|
+
"sync_jsonl": "regscale.integrations.commercial.tenablev2.commands.sync_jsonl",
|
|
447
|
+
"sync_vulns": "regscale.integrations.commercial.tenablev2.commands.sync_vulns",
|
|
433
448
|
},
|
|
434
449
|
name="tenable",
|
|
435
450
|
)
|
|
File without changes
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Axonius integration for RegScale CLI to sync assets"""
|
|
4
|
+
|
|
5
|
+
# Standard python imports
|
|
6
|
+
import click
|
|
7
|
+
from regscale.core.app.utils.parser_utils import safe_datetime_str
|
|
8
|
+
from regscale.core.app.api import Api
|
|
9
|
+
from regscale.core.app.logz import create_logger
|
|
10
|
+
from regscale.core.app.utils.app_utils import (
|
|
11
|
+
check_file_path,
|
|
12
|
+
check_license,
|
|
13
|
+
compute_hashes_in_directory,
|
|
14
|
+
convert_datetime_to_regscale_string,
|
|
15
|
+
create_progress_object,
|
|
16
|
+
error_and_exit,
|
|
17
|
+
get_current_datetime,
|
|
18
|
+
save_data_to,
|
|
19
|
+
)
|
|
20
|
+
from regscale.core.app.utils.regscale_utils import verify_provided_module
|
|
21
|
+
from regscale.models import regscale_id, regscale_module
|
|
22
|
+
from regscale.models.regscale_models.file import File
|
|
23
|
+
from regscale.models.regscale_models.issue import Issue
|
|
24
|
+
from regscale.models.regscale_models.task import Task
|
|
25
|
+
from regscale.utils.threading.threadhandler import create_threads, thread_assignment
|
|
26
|
+
from regscale.models import regscale_ssp_id
|
|
27
|
+
|
|
28
|
+
import pandas as pd
|
|
29
|
+
import requests
|
|
30
|
+
import datetime
|
|
31
|
+
from datetime import date
|
|
32
|
+
import warnings
|
|
33
|
+
import json
|
|
34
|
+
from urllib.parse import urljoin
|
|
35
|
+
|
|
36
|
+
warnings.filterwarnings("ignore")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
####################################################################################################
|
|
40
|
+
#
|
|
41
|
+
# SYNC ASSETS WITH AXONIUS
|
|
42
|
+
# AXONIUS API Docs: https://developer.axonius.com/docs/overview
|
|
43
|
+
#
|
|
44
|
+
####################################################################################################
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# Create group to handle Axonius integration
|
|
48
|
+
@click.group()
|
|
49
|
+
def axonius():
|
|
50
|
+
"""Sync assets between Axonius and RegScale."""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@axonius.command(name="sync_assets")
|
|
54
|
+
@regscale_ssp_id()
|
|
55
|
+
def sync_assets(regscale_ssp_id: int) -> None:
|
|
56
|
+
"""Sync Assets from Axonius into RegScale."""
|
|
57
|
+
from regscale.models.integration_models.axonius_models.connectors.assets import AxoniusIntegration
|
|
58
|
+
|
|
59
|
+
scanner = AxoniusIntegration(plan_id=regscale_ssp_id)
|
|
60
|
+
scanner.sync_assets(plan_id=regscale_ssp_id)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@axonius.command(name="sync_findings")
|
|
64
|
+
@regscale_ssp_id()
|
|
65
|
+
def sync_findings(regscale_ssp_id: int) -> None:
|
|
66
|
+
"""Sync Assets from Axonius into RegScale."""
|
|
67
|
+
from regscale.models.integration_models.axonius_models.connectors.assets import AxoniusIntegration
|
|
68
|
+
|
|
69
|
+
scanner = AxoniusIntegration(plan_id=regscale_ssp_id)
|
|
70
|
+
scanner.sync_findings(plan_id=regscale_ssp_id)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
"""Burp Scanner RegScale integration"""
|
|
4
|
+
from datetime import datetime
|
|
4
5
|
from pathlib import Path
|
|
6
|
+
from typing import Optional
|
|
5
7
|
|
|
6
8
|
import click
|
|
7
9
|
|
|
@@ -54,6 +56,18 @@ def import_burp(
|
|
|
54
56
|
"""
|
|
55
57
|
Import Burp scans, vulnerabilities and assets to RegScale from burp files
|
|
56
58
|
|
|
59
|
+
"""
|
|
60
|
+
import_burp_scan(folder_path, regscale_ssp_id, scan_date, upload_file)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def import_burp_scan(folder_path: Path, regscale_ssp_id: int, scan_date: datetime, upload_file: Optional[bool] = True):
|
|
64
|
+
"""
|
|
65
|
+
Import Burp scans, vulnerabilities and assets to RegScale from burp files
|
|
66
|
+
|
|
67
|
+
:param folder_path: Path to burp scan files
|
|
68
|
+
:param regscale_ssp_id: RegScale Security Plan ID
|
|
69
|
+
:param scan_date: Scan date
|
|
70
|
+
:param upload_file: Whether to upload the file to RegScale after processing. Default is True.
|
|
57
71
|
"""
|
|
58
72
|
app = Application()
|
|
59
73
|
if not validate_regscale_object(regscale_ssp_id, "securityplans"):
|
|
@@ -22,6 +22,7 @@ def grype():
|
|
|
22
22
|
message="File path to the folder containing JFrog XRay .json files to process to RegScale.",
|
|
23
23
|
prompt="File path for Grype files",
|
|
24
24
|
import_name="grype",
|
|
25
|
+
support_component=True,
|
|
25
26
|
)
|
|
26
27
|
@click.option(
|
|
27
28
|
"--destination",
|
|
@@ -41,6 +42,7 @@ def import_scans(
|
|
|
41
42
|
file_pattern: str,
|
|
42
43
|
folder_path: Path,
|
|
43
44
|
regscale_ssp_id: int,
|
|
45
|
+
component_id: int,
|
|
44
46
|
scan_date: datetime,
|
|
45
47
|
mappings_path: Path,
|
|
46
48
|
disable_mapping: bool,
|
|
@@ -56,8 +58,13 @@ def import_scans(
|
|
|
56
58
|
|
|
57
59
|
if s3_bucket and not folder_path:
|
|
58
60
|
folder_path = s3_bucket
|
|
61
|
+
|
|
62
|
+
if not regscale_ssp_id and not component_id:
|
|
63
|
+
raise click.UsageError("You must provide either a --regscale_ssp_id or a --component_id to import Grype scans.")
|
|
64
|
+
|
|
59
65
|
gi = GrypeIntegration(
|
|
60
|
-
plan_id=regscale_ssp_id,
|
|
66
|
+
plan_id=component_id if component_id else regscale_ssp_id,
|
|
67
|
+
is_component=True if component_id else False,
|
|
61
68
|
file_path=str(folder_path) if folder_path else None,
|
|
62
69
|
s3_bucket=s3_bucket,
|
|
63
70
|
s3_prefix=s3_prefix,
|
|
@@ -54,6 +54,7 @@ class GrypeIntegration(JSONLScannerIntegration):
|
|
|
54
54
|
kwargs["read_files_only"] = True
|
|
55
55
|
kwargs["file_pattern"] = "*.json"
|
|
56
56
|
self.disable_mapping = kwargs["disable_mapping"] = True
|
|
57
|
+
self.is_component = kwargs.get("is_component", False)
|
|
57
58
|
super().__init__(*args, **kwargs)
|
|
58
59
|
|
|
59
60
|
def is_valid_file(self, data: Any, file_path: Union[Path, str]) -> Tuple[bool, Optional[Dict[str, Any]]]:
|
|
@@ -125,7 +126,7 @@ class GrypeIntegration(JSONLScannerIntegration):
|
|
|
125
126
|
other_tracking_number=source_target_data.get("userInput", source_target_data.get("UserInput", "Unknown")),
|
|
126
127
|
fqdn=source_target_data.get("userInput", source_target_data.get("UserInput", "Unknown")),
|
|
127
128
|
parent_id=self.plan_id,
|
|
128
|
-
parent_module="securityplans",
|
|
129
|
+
parent_module="securityplans" if not self.is_component else "components",
|
|
129
130
|
)
|
|
130
131
|
|
|
131
132
|
def parse_finding(self, asset_identifier: str, data: Dict[str, Any], item: Dict[str, Any]) -> IntegrationFinding:
|