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.

Files changed (81) hide show
  1. cartography/_version.py +2 -2
  2. cartography/cli.py +14 -0
  3. cartography/config.py +4 -0
  4. cartography/data/indexes.cypher +0 -17
  5. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  6. cartography/intel/aws/cloudtrail.py +17 -4
  7. cartography/intel/aws/cloudtrail_management_events.py +614 -16
  8. cartography/intel/aws/cloudwatch.py +73 -4
  9. cartography/intel/aws/ec2/subnets.py +37 -63
  10. cartography/intel/aws/ecr.py +55 -80
  11. cartography/intel/aws/elasticache.py +102 -79
  12. cartography/intel/aws/eventbridge.py +91 -0
  13. cartography/intel/aws/glue.py +117 -0
  14. cartography/intel/aws/identitycenter.py +71 -23
  15. cartography/intel/aws/kms.py +160 -200
  16. cartography/intel/aws/lambda_function.py +206 -190
  17. cartography/intel/aws/rds.py +243 -458
  18. cartography/intel/aws/resourcegroupstaggingapi.py +77 -18
  19. cartography/intel/aws/resources.py +4 -0
  20. cartography/intel/aws/route53.py +334 -332
  21. cartography/intel/aws/secretsmanager.py +62 -44
  22. cartography/intel/entra/groups.py +29 -1
  23. cartography/intel/gcp/__init__.py +10 -0
  24. cartography/intel/gcp/compute.py +19 -42
  25. cartography/intel/trivy/__init__.py +73 -13
  26. cartography/intel/trivy/scanner.py +115 -92
  27. cartography/models/aws/cloudtrail/management_events.py +95 -6
  28. cartography/models/aws/cloudtrail/trail.py +21 -0
  29. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  30. cartography/models/aws/ec2/subnets.py +65 -0
  31. cartography/models/aws/ecr/__init__.py +0 -0
  32. cartography/models/aws/ecr/image.py +41 -0
  33. cartography/models/aws/ecr/repository.py +72 -0
  34. cartography/models/aws/ecr/repository_image.py +95 -0
  35. cartography/models/aws/elasticache/__init__.py +0 -0
  36. cartography/models/aws/elasticache/cluster.py +65 -0
  37. cartography/models/aws/elasticache/topic.py +67 -0
  38. cartography/models/aws/eventbridge/__init__.py +0 -0
  39. cartography/models/aws/eventbridge/rule.py +77 -0
  40. cartography/models/aws/glue/__init__.py +0 -0
  41. cartography/models/aws/glue/connection.py +51 -0
  42. cartography/models/aws/identitycenter/awspermissionset.py +44 -0
  43. cartography/models/aws/kms/__init__.py +0 -0
  44. cartography/models/aws/kms/aliases.py +86 -0
  45. cartography/models/aws/kms/grants.py +65 -0
  46. cartography/models/aws/kms/keys.py +88 -0
  47. cartography/models/aws/lambda_function/__init__.py +0 -0
  48. cartography/models/aws/lambda_function/alias.py +74 -0
  49. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  50. cartography/models/aws/lambda_function/lambda_function.py +89 -0
  51. cartography/models/aws/lambda_function/layer.py +72 -0
  52. cartography/models/aws/rds/__init__.py +0 -0
  53. cartography/models/aws/rds/cluster.py +89 -0
  54. cartography/models/aws/rds/instance.py +154 -0
  55. cartography/models/aws/rds/snapshot.py +108 -0
  56. cartography/models/aws/rds/subnet_group.py +101 -0
  57. cartography/models/aws/route53/__init__.py +0 -0
  58. cartography/models/aws/route53/dnsrecord.py +214 -0
  59. cartography/models/aws/route53/nameserver.py +63 -0
  60. cartography/models/aws/route53/subzone.py +40 -0
  61. cartography/models/aws/route53/zone.py +47 -0
  62. cartography/models/aws/secretsmanager/secret.py +106 -0
  63. cartography/models/entra/group.py +26 -0
  64. cartography/models/entra/user.py +6 -0
  65. cartography/models/gcp/compute/__init__.py +0 -0
  66. cartography/models/gcp/compute/vpc.py +50 -0
  67. cartography/util.py +8 -1
  68. {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/METADATA +2 -2
  69. {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/RECORD +73 -44
  70. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  71. cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +0 -16
  72. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  73. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  74. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  75. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  76. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  77. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  78. {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/WHEEL +0 -0
  79. {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/entry_points.txt +0 -0
  80. {cartography-0.108.0rc1.dist-info → cartography-0.109.0.dist-info}/licenses/LICENSE +0 -0
  81. {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.108.0rc1'
21
- __version_tuple__ = version_tuple = (0, 108, 0, 'rc1')
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
@@ -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
- trails = get_cloudtrail_trails(boto3_session, region)
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,