cartography 0.108.0rc1__py3-none-any.whl → 0.109.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 cartography might be problematic. Click here for more details.
- cartography/_version.py +2 -2
- cartography/cli.py +14 -0
- cartography/config.py +4 -0
- cartography/data/indexes.cypher +0 -17
- cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
- cartography/intel/aws/cloudtrail.py +17 -4
- cartography/intel/aws/cloudtrail_management_events.py +614 -16
- cartography/intel/aws/cloudwatch.py +73 -4
- cartography/intel/aws/ec2/subnets.py +37 -63
- cartography/intel/aws/ecr.py +55 -80
- cartography/intel/aws/elasticache.py +102 -79
- cartography/intel/aws/eventbridge.py +91 -0
- cartography/intel/aws/glue.py +117 -0
- cartography/intel/aws/identitycenter.py +71 -23
- cartography/intel/aws/kms.py +160 -200
- cartography/intel/aws/lambda_function.py +206 -190
- cartography/intel/aws/rds.py +243 -458
- cartography/intel/aws/resourcegroupstaggingapi.py +77 -18
- cartography/intel/aws/resources.py +4 -0
- cartography/intel/aws/route53.py +334 -332
- cartography/intel/aws/secretsmanager.py +62 -44
- cartography/intel/entra/groups.py +29 -1
- cartography/intel/gcp/__init__.py +10 -0
- cartography/intel/gcp/compute.py +19 -42
- cartography/intel/trivy/__init__.py +73 -13
- cartography/intel/trivy/scanner.py +115 -92
- cartography/models/aws/cloudtrail/management_events.py +95 -6
- cartography/models/aws/cloudtrail/trail.py +21 -0
- cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
- cartography/models/aws/ec2/subnets.py +65 -0
- cartography/models/aws/ecr/__init__.py +0 -0
- cartography/models/aws/ecr/image.py +41 -0
- cartography/models/aws/ecr/repository.py +72 -0
- cartography/models/aws/ecr/repository_image.py +95 -0
- cartography/models/aws/elasticache/__init__.py +0 -0
- cartography/models/aws/elasticache/cluster.py +65 -0
- cartography/models/aws/elasticache/topic.py +67 -0
- cartography/models/aws/eventbridge/__init__.py +0 -0
- cartography/models/aws/eventbridge/rule.py +77 -0
- cartography/models/aws/glue/__init__.py +0 -0
- cartography/models/aws/glue/connection.py +51 -0
- cartography/models/aws/identitycenter/awspermissionset.py +44 -0
- cartography/models/aws/kms/__init__.py +0 -0
- cartography/models/aws/kms/aliases.py +86 -0
- cartography/models/aws/kms/grants.py +65 -0
- cartography/models/aws/kms/keys.py +88 -0
- cartography/models/aws/lambda_function/__init__.py +0 -0
- cartography/models/aws/lambda_function/alias.py +74 -0
- cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
- cartography/models/aws/lambda_function/lambda_function.py +89 -0
- cartography/models/aws/lambda_function/layer.py +72 -0
- cartography/models/aws/rds/__init__.py +0 -0
- cartography/models/aws/rds/cluster.py +89 -0
- cartography/models/aws/rds/instance.py +154 -0
- cartography/models/aws/rds/snapshot.py +108 -0
- cartography/models/aws/rds/subnet_group.py +101 -0
- cartography/models/aws/route53/__init__.py +0 -0
- cartography/models/aws/route53/dnsrecord.py +214 -0
- cartography/models/aws/route53/nameserver.py +63 -0
- cartography/models/aws/route53/subzone.py +40 -0
- cartography/models/aws/route53/zone.py +47 -0
- cartography/models/aws/secretsmanager/secret.py +106 -0
- cartography/models/entra/group.py +26 -0
- cartography/models/entra/user.py +6 -0
- cartography/models/gcp/compute/__init__.py +0 -0
- cartography/models/gcp/compute/vpc.py +50 -0
- cartography/util.py +8 -1
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/METADATA +2 -2
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/RECORD +73 -44
- cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
- cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +0 -16
- cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
- cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
- cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
- cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/WHEEL +0 -0
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/top_level.txt +0 -0
cartography/_version.py
CHANGED
|
@@ -17,5 +17,5 @@ __version__: str
|
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
|
18
18
|
version_tuple: VERSION_TUPLE
|
|
19
19
|
|
|
20
|
-
__version__ = version = '0.
|
|
21
|
-
__version_tuple__ = version_tuple = (0,
|
|
20
|
+
__version__ = version = '0.109.0'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 109, 0)
|
cartography/cli.py
CHANGED
|
@@ -700,6 +700,15 @@ class CLI:
|
|
|
700
700
|
"Required if you are using the Trivy module. Ignored otherwise."
|
|
701
701
|
),
|
|
702
702
|
)
|
|
703
|
+
parser.add_argument(
|
|
704
|
+
"--trivy-results-dir",
|
|
705
|
+
type=str,
|
|
706
|
+
default=None,
|
|
707
|
+
help=(
|
|
708
|
+
"Path to a directory containing Trivy JSON results on disk. "
|
|
709
|
+
"Required if you are using the Trivy module with local results."
|
|
710
|
+
),
|
|
711
|
+
)
|
|
703
712
|
parser.add_argument(
|
|
704
713
|
"--scaleway-org",
|
|
705
714
|
type=str,
|
|
@@ -1089,6 +1098,9 @@ class CLI:
|
|
|
1089
1098
|
if config.trivy_s3_prefix:
|
|
1090
1099
|
logger.debug(f"Trivy S3 prefix: {config.trivy_s3_prefix}")
|
|
1091
1100
|
|
|
1101
|
+
if config.trivy_results_dir:
|
|
1102
|
+
logger.debug(f"Trivy results dir: {config.trivy_results_dir}")
|
|
1103
|
+
|
|
1092
1104
|
# Scaleway config
|
|
1093
1105
|
if config.scaleway_secret_key_env_var:
|
|
1094
1106
|
logger.debug(
|
|
@@ -1118,6 +1130,8 @@ class CLI:
|
|
|
1118
1130
|
config.sentinelone_api_token = os.environ.get(
|
|
1119
1131
|
config.sentinelone_api_token_env_var
|
|
1120
1132
|
)
|
|
1133
|
+
else:
|
|
1134
|
+
config.sentinelone_api_token = None
|
|
1121
1135
|
|
|
1122
1136
|
# Run cartography
|
|
1123
1137
|
try:
|
cartography/config.py
CHANGED
|
@@ -152,6 +152,8 @@ class Config:
|
|
|
152
152
|
:param trivy_s3_bucket: The S3 bucket name containing Trivy scan results. Optional.
|
|
153
153
|
:type trivy_s3_prefix: str
|
|
154
154
|
:param trivy_s3_prefix: The S3 prefix path containing Trivy scan results. Optional.
|
|
155
|
+
:type trivy_results_dir: str
|
|
156
|
+
:param trivy_results_dir: Local directory containing Trivy scan results. Optional.
|
|
155
157
|
:type scaleway_access_key: str
|
|
156
158
|
:param scaleway_access_key: Scaleway access key. Optional.
|
|
157
159
|
:type scaleway_secret_key: str
|
|
@@ -243,6 +245,7 @@ class Config:
|
|
|
243
245
|
airbyte_api_url=None,
|
|
244
246
|
trivy_s3_bucket=None,
|
|
245
247
|
trivy_s3_prefix=None,
|
|
248
|
+
trivy_results_dir=None,
|
|
246
249
|
scaleway_access_key=None,
|
|
247
250
|
scaleway_secret_key=None,
|
|
248
251
|
scaleway_org=None,
|
|
@@ -327,6 +330,7 @@ class Config:
|
|
|
327
330
|
self.airbyte_api_url = airbyte_api_url
|
|
328
331
|
self.trivy_s3_bucket = trivy_s3_bucket
|
|
329
332
|
self.trivy_s3_prefix = trivy_s3_prefix
|
|
333
|
+
self.trivy_results_dir = trivy_results_dir
|
|
330
334
|
self.scaleway_access_key = scaleway_access_key
|
|
331
335
|
self.scaleway_secret_key = scaleway_secret_key
|
|
332
336
|
self.scaleway_org = scaleway_org
|
cartography/data/indexes.cypher
CHANGED
|
@@ -29,14 +29,6 @@ CREATE INDEX IF NOT EXISTS FOR (n:AWSIpv4CidrBlock) ON (n.id);
|
|
|
29
29
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSIpv4CidrBlock) ON (n.lastupdated);
|
|
30
30
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSIpv6CidrBlock) ON (n.id);
|
|
31
31
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSIpv6CidrBlock) ON (n.lastupdated);
|
|
32
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSLambda) ON (n.id);
|
|
33
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSLambda) ON (n.lastupdated);
|
|
34
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSLambdaEventSourceMapping) ON (n.id);
|
|
35
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSLambdaEventSourceMapping) ON (n.lastupdated);
|
|
36
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSLambdaFunctionAlias) ON (n.id);
|
|
37
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSLambdaFunctionAlias) ON (n.lastupdated);
|
|
38
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSLambdaLayer) ON (n.id);
|
|
39
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSLambdaLayer) ON (n.lastupdated);
|
|
40
32
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSPeeringConnection) ON (n.id);
|
|
41
33
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSPeeringConnection) ON (n.lastupdated);
|
|
42
34
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSPolicy) ON (n.id);
|
|
@@ -158,13 +150,6 @@ CREATE INDEX IF NOT EXISTS FOR (n:IpRange) ON (n.id);
|
|
|
158
150
|
CREATE INDEX IF NOT EXISTS FOR (n:IpRange) ON (n.lastupdated);
|
|
159
151
|
CREATE INDEX IF NOT EXISTS FOR (n:JamfComputerGroup) ON (n.id);
|
|
160
152
|
CREATE INDEX IF NOT EXISTS FOR (n:JamfComputerGroup) ON (n.lastupdated);
|
|
161
|
-
CREATE INDEX IF NOT EXISTS FOR (n:KMSKey) ON (n.id);
|
|
162
|
-
CREATE INDEX IF NOT EXISTS FOR (n:KMSKey) ON (n.arn);
|
|
163
|
-
CREATE INDEX IF NOT EXISTS FOR (n:KMSKey) ON (n.lastupdated);
|
|
164
|
-
CREATE INDEX IF NOT EXISTS FOR (n:KMSAlias) ON (n.id);
|
|
165
|
-
CREATE INDEX IF NOT EXISTS FOR (n:KMSAlias) ON (n.lastupdated);
|
|
166
|
-
CREATE INDEX IF NOT EXISTS FOR (n:KMSGrant) ON (n.id);
|
|
167
|
-
CREATE INDEX IF NOT EXISTS FOR (n:KMSGrant) ON (n.lastupdated);
|
|
168
153
|
CREATE INDEX IF NOT EXISTS FOR (n:LaunchConfiguration) ON (n.id);
|
|
169
154
|
CREATE INDEX IF NOT EXISTS FOR (n:LaunchConfiguration) ON (n.name);
|
|
170
155
|
CREATE INDEX IF NOT EXISTS FOR (n:LaunchConfiguration) ON (n.lastupdated);
|
|
@@ -259,8 +244,6 @@ CREATE INDEX IF NOT EXISTS FOR (n:S3Bucket) ON (n.id);
|
|
|
259
244
|
CREATE INDEX IF NOT EXISTS FOR (n:S3Bucket) ON (n.name);
|
|
260
245
|
CREATE INDEX IF NOT EXISTS FOR (n:S3Bucket) ON (n.arn);
|
|
261
246
|
CREATE INDEX IF NOT EXISTS FOR (n:S3Bucket) ON (n.lastupdated);
|
|
262
|
-
CREATE INDEX IF NOT EXISTS FOR (n:SecretsManagerSecret) ON (n.id);
|
|
263
|
-
CREATE INDEX IF NOT EXISTS FOR (n:SecretsManagerSecret) ON (n.lastupdated);
|
|
264
247
|
CREATE INDEX IF NOT EXISTS FOR (n:SecurityHub) ON (n.id);
|
|
265
248
|
CREATE INDEX IF NOT EXISTS FOR (n:SecurityHub) ON (n.lastupdated);
|
|
266
249
|
CREATE INDEX IF NOT EXISTS FOR (n:SpotlightVulnerability) ON (n.id);
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"statements": [
|
|
3
|
-
{
|
|
4
|
-
"query": "MATCH (n:GCPVpc) WHERE n.lastupdated <> $UPDATE_TAG WITH n LIMIT $LIMIT_SIZE DETACH DELETE (n)",
|
|
5
|
-
"iterative": true,
|
|
6
|
-
"iterationsize": 100,
|
|
7
|
-
"__comment__": "Delete GCP VPCs that no longer exist and detach them from all previously connected nodes."
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
"query": "MATCH (:GCPVpc)<-[r:RESOURCE]-(:GCPProject) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r)",
|
|
11
|
-
"iterative": true,
|
|
12
|
-
"iterationsize": 100,
|
|
13
|
-
"__comment__": "Remove GCP VPC-to-Project relationships that are out of date."
|
|
14
|
-
},
|
|
15
3
|
{
|
|
16
4
|
"query": "MATCH (:GCPInstance)-[r:MEMBER_OF_GCP_VPC]->(:GCPVpc) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r)",
|
|
17
5
|
"iterative": true,
|
|
@@ -26,13 +26,25 @@ def get_cloudtrail_trails(
|
|
|
26
26
|
)
|
|
27
27
|
|
|
28
28
|
trails = client.describe_trails()["trailList"]
|
|
29
|
-
|
|
30
|
-
# CloudTrail multi-region trails are shown in list_trails,
|
|
31
|
-
# but the get_trail call only works in the home region
|
|
32
29
|
trails_filtered = [trail for trail in trails if trail.get("HomeRegion") == region]
|
|
30
|
+
|
|
33
31
|
return trails_filtered
|
|
34
32
|
|
|
35
33
|
|
|
34
|
+
def transform_cloudtrail_trails(
|
|
35
|
+
trails: List[Dict[str, Any]], region: str
|
|
36
|
+
) -> List[Dict[str, Any]]:
|
|
37
|
+
"""
|
|
38
|
+
Transform CloudTrail trail data for ingestion
|
|
39
|
+
"""
|
|
40
|
+
for trail in trails:
|
|
41
|
+
arn = trail.get("CloudWatchLogsLogGroupArn")
|
|
42
|
+
if arn:
|
|
43
|
+
trail["CloudWatchLogsLogGroupArn"] = arn.split(":*")[0]
|
|
44
|
+
|
|
45
|
+
return trails
|
|
46
|
+
|
|
47
|
+
|
|
36
48
|
@timeit
|
|
37
49
|
def load_cloudtrail_trails(
|
|
38
50
|
neo4j_session: neo4j.Session,
|
|
@@ -79,7 +91,8 @@ def sync(
|
|
|
79
91
|
logger.info(
|
|
80
92
|
f"Syncing CloudTrail for region '{region}' in account '{current_aws_account_id}'.",
|
|
81
93
|
)
|
|
82
|
-
|
|
94
|
+
trails_filtered = get_cloudtrail_trails(boto3_session, region)
|
|
95
|
+
trails = transform_cloudtrail_trails(trails_filtered, region)
|
|
83
96
|
|
|
84
97
|
load_cloudtrail_trails(
|
|
85
98
|
neo4j_session,
|