cartography 0.108.0rc1__py3-none-any.whl → 0.109.0rc1__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/data/indexes.cypher +0 -2
- 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 +593 -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/resourcegroupstaggingapi.py +77 -18
- 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/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/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-0.108.0rc1.dist-info → cartography-0.109.0rc1.dist-info}/METADATA +1 -1
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0rc1.dist-info}/RECORD +36 -25
- cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0rc1.dist-info}/WHEEL +0 -0
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0rc1.dist-info}/entry_points.txt +0 -0
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0rc1.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.108.0rc1.dist-info → cartography-0.109.0rc1.dist-info}/top_level.txt +0 -0
cartography/intel/gcp/compute.py
CHANGED
|
@@ -14,6 +14,9 @@ import neo4j
|
|
|
14
14
|
from googleapiclient.discovery import HttpError
|
|
15
15
|
from googleapiclient.discovery import Resource
|
|
16
16
|
|
|
17
|
+
from cartography.client.core.tx import load
|
|
18
|
+
from cartography.graph.job import GraphJob
|
|
19
|
+
from cartography.models.gcp.compute.vpc import GCPVpcSchema
|
|
17
20
|
from cartography.util import run_cleanup_job
|
|
18
21
|
from cartography.util import timeit
|
|
19
22
|
|
|
@@ -600,48 +603,17 @@ def load_gcp_instances(
|
|
|
600
603
|
@timeit
|
|
601
604
|
def load_gcp_vpcs(
|
|
602
605
|
neo4j_session: neo4j.Session,
|
|
603
|
-
vpcs:
|
|
606
|
+
vpcs: list[dict[str, Any]],
|
|
604
607
|
gcp_update_tag: int,
|
|
608
|
+
project_id: str,
|
|
605
609
|
) -> None:
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
query = """
|
|
614
|
-
MERGE(p:GCPProject{id:$ProjectId})
|
|
615
|
-
ON CREATE SET p.firstseen = timestamp()
|
|
616
|
-
SET p.lastupdated = $gcp_update_tag
|
|
617
|
-
|
|
618
|
-
MERGE(vpc:GCPVpc{id:$PartialUri})
|
|
619
|
-
ON CREATE SET vpc.firstseen = timestamp(),
|
|
620
|
-
vpc.partial_uri = $PartialUri
|
|
621
|
-
SET vpc.self_link = $SelfLink,
|
|
622
|
-
vpc.name = $VpcName,
|
|
623
|
-
vpc.project_id = $ProjectId,
|
|
624
|
-
vpc.auto_create_subnetworks = $AutoCreateSubnetworks,
|
|
625
|
-
vpc.routing_config_routing_mode = $RoutingMode,
|
|
626
|
-
vpc.description = $Description,
|
|
627
|
-
vpc.lastupdated = $gcp_update_tag
|
|
628
|
-
|
|
629
|
-
MERGE (p)-[r:RESOURCE]->(vpc)
|
|
630
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
631
|
-
SET r.lastupdated = $gcp_update_tag
|
|
632
|
-
"""
|
|
633
|
-
for vpc in vpcs:
|
|
634
|
-
neo4j_session.run(
|
|
635
|
-
query,
|
|
636
|
-
ProjectId=vpc["project_id"],
|
|
637
|
-
PartialUri=vpc["partial_uri"],
|
|
638
|
-
SelfLink=vpc["self_link"],
|
|
639
|
-
VpcName=vpc["name"],
|
|
640
|
-
AutoCreateSubnetworks=vpc["auto_create_subnetworks"],
|
|
641
|
-
RoutingMode=vpc["routing_config_routing_mode"],
|
|
642
|
-
Description=vpc["description"],
|
|
643
|
-
gcp_update_tag=gcp_update_tag,
|
|
644
|
-
)
|
|
610
|
+
load(
|
|
611
|
+
neo4j_session,
|
|
612
|
+
GCPVpcSchema(),
|
|
613
|
+
vpcs,
|
|
614
|
+
PROJECT_ID=project_id,
|
|
615
|
+
LASTUPDATED=gcp_update_tag,
|
|
616
|
+
)
|
|
645
617
|
|
|
646
618
|
|
|
647
619
|
@timeit
|
|
@@ -1159,6 +1131,12 @@ def cleanup_gcp_vpcs(neo4j_session: neo4j.Session, common_job_parameters: Dict)
|
|
|
1159
1131
|
:param common_job_parameters: dict of other job parameters to pass to Neo4j
|
|
1160
1132
|
:return: Nothing
|
|
1161
1133
|
"""
|
|
1134
|
+
GraphJob.from_node_schema(
|
|
1135
|
+
GCPVpcSchema(),
|
|
1136
|
+
common_job_parameters,
|
|
1137
|
+
).run(neo4j_session)
|
|
1138
|
+
|
|
1139
|
+
# TODO: remove this once we refactor GCP instances and add the instance to vpc rel as an object
|
|
1162
1140
|
run_cleanup_job(
|
|
1163
1141
|
"gcp_compute_vpc_cleanup.json",
|
|
1164
1142
|
neo4j_session,
|
|
@@ -1267,8 +1245,7 @@ def sync_gcp_vpcs(
|
|
|
1267
1245
|
"""
|
|
1268
1246
|
vpc_res = get_gcp_vpcs(project_id, compute)
|
|
1269
1247
|
vpcs = transform_gcp_vpcs(vpc_res)
|
|
1270
|
-
load_gcp_vpcs(neo4j_session, vpcs, gcp_update_tag)
|
|
1271
|
-
# TODO scope the cleanup to the current project - https://github.com/cartography-cncf/cartography/issues/381
|
|
1248
|
+
load_gcp_vpcs(neo4j_session, vpcs, gcp_update_tag, project_id)
|
|
1272
1249
|
cleanup_gcp_vpcs(neo4j_session, common_job_parameters)
|
|
1273
1250
|
|
|
1274
1251
|
|
|
@@ -29,12 +29,6 @@ class AssumedRoleRelProperties(CartographyRelProperties):
|
|
|
29
29
|
times_used: PropertyRef = PropertyRef("times_used")
|
|
30
30
|
first_seen_in_time_window: PropertyRef = PropertyRef("first_seen_in_time_window")
|
|
31
31
|
|
|
32
|
-
# Event type tracking properties
|
|
33
|
-
event_types: PropertyRef = PropertyRef("event_types")
|
|
34
|
-
assume_role_count: PropertyRef = PropertyRef("assume_role_count")
|
|
35
|
-
saml_count: PropertyRef = PropertyRef("saml_count")
|
|
36
|
-
web_identity_count: PropertyRef = PropertyRef("web_identity_count")
|
|
37
|
-
|
|
38
32
|
|
|
39
33
|
@dataclass(frozen=True)
|
|
40
34
|
class AssumedRoleMatchLink(CartographyRelSchema):
|
|
@@ -62,3 +56,98 @@ class AssumedRoleMatchLink(CartographyRelSchema):
|
|
|
62
56
|
direction: LinkDirection = LinkDirection.OUTWARD
|
|
63
57
|
rel_label: str = "ASSUMED_ROLE"
|
|
64
58
|
properties: AssumedRoleRelProperties = AssumedRoleRelProperties()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass(frozen=True)
|
|
62
|
+
class AssumedRoleWithSAMLRelProperties(CartographyRelProperties):
|
|
63
|
+
"""
|
|
64
|
+
Properties for the ASSUMED_ROLE_WITH_SAML relationship representing SAML-based role assumption events.
|
|
65
|
+
Focuses specifically on SAML federated identity role assumptions.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
# Mandatory fields for MatchLinks
|
|
69
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
70
|
+
_sub_resource_label: PropertyRef = PropertyRef(
|
|
71
|
+
"_sub_resource_label", set_in_kwargs=True
|
|
72
|
+
)
|
|
73
|
+
_sub_resource_id: PropertyRef = PropertyRef("_sub_resource_id", set_in_kwargs=True)
|
|
74
|
+
|
|
75
|
+
# CloudTrail-specific relationship properties
|
|
76
|
+
last_used: PropertyRef = PropertyRef("last_used")
|
|
77
|
+
times_used: PropertyRef = PropertyRef("times_used")
|
|
78
|
+
first_seen_in_time_window: PropertyRef = PropertyRef("first_seen_in_time_window")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True)
|
|
82
|
+
class AssumedRoleWithSAMLMatchLink(CartographyRelSchema):
|
|
83
|
+
"""
|
|
84
|
+
MatchLink schema for ASSUMED_ROLE_WITH_SAML relationships from CloudTrail SAML events.
|
|
85
|
+
Creates relationships like: (AWSRole)-[:ASSUMED_ROLE_WITH_SAML]->(AWSRole)
|
|
86
|
+
|
|
87
|
+
This MatchLink handles SAML-based role assumption relationships discovered via CloudTrail
|
|
88
|
+
AssumeRoleWithSAML events. It creates separate relationships from regular AssumeRole events
|
|
89
|
+
to preserve visibility into authentication methods used.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
# MatchLink-specific fields
|
|
93
|
+
source_node_label: str = "AWSSSOUser" # Match against AWS SSO User nodes
|
|
94
|
+
source_node_matcher: SourceNodeMatcher = make_source_node_matcher(
|
|
95
|
+
{"user_name": PropertyRef("source_principal_arn")},
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# Standard CartographyRelSchema fields
|
|
99
|
+
target_node_label: str = "AWSRole"
|
|
100
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
101
|
+
{"arn": PropertyRef("destination_principal_arn")},
|
|
102
|
+
)
|
|
103
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
104
|
+
rel_label: str = "ASSUMED_ROLE_WITH_SAML"
|
|
105
|
+
properties: AssumedRoleWithSAMLRelProperties = AssumedRoleWithSAMLRelProperties()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@dataclass(frozen=True)
|
|
109
|
+
class AssumeRoleWithWebIdentityRelProperties(CartographyRelProperties):
|
|
110
|
+
"""
|
|
111
|
+
Properties for the ASSUMED_ROLE_WITH_WEB_IDENTITY relationship representing web identity-based role assumption events.
|
|
112
|
+
Focuses specifically on web identity federation role assumptions (Google, Amazon, Facebook, etc.).
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
# Mandatory fields for MatchLinks
|
|
116
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
117
|
+
_sub_resource_label: PropertyRef = PropertyRef(
|
|
118
|
+
"_sub_resource_label", set_in_kwargs=True
|
|
119
|
+
)
|
|
120
|
+
_sub_resource_id: PropertyRef = PropertyRef("_sub_resource_id", set_in_kwargs=True)
|
|
121
|
+
|
|
122
|
+
# CloudTrail-specific relationship properties
|
|
123
|
+
last_used: PropertyRef = PropertyRef("last_used")
|
|
124
|
+
times_used: PropertyRef = PropertyRef("times_used")
|
|
125
|
+
first_seen_in_time_window: PropertyRef = PropertyRef("first_seen_in_time_window")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@dataclass(frozen=True)
|
|
129
|
+
class GitHubRepoAssumeRoleWithWebIdentityMatchLink(CartographyRelSchema):
|
|
130
|
+
"""
|
|
131
|
+
MatchLink schema for ASSUMED_ROLE_WITH_WEB_IDENTITY relationships from GitHub Actions to AWS roles.
|
|
132
|
+
Creates relationships like: (GitHubRepository)-[:ASSUMED_ROLE_WITH_WEB_IDENTITY]->(AWSRole)
|
|
133
|
+
|
|
134
|
+
This MatchLink provides granular visibility into which specific GitHub repositories are assuming
|
|
135
|
+
AWS roles via GitHub Actions OIDC, rather than just showing provider-level relationships.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
# MatchLink-specific fields for GitHub repositories
|
|
139
|
+
source_node_label: str = "GitHubRepository"
|
|
140
|
+
source_node_matcher: SourceNodeMatcher = make_source_node_matcher(
|
|
141
|
+
{"fullname": PropertyRef("source_repo_fullname")},
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# Standard CartographyRelSchema fields
|
|
145
|
+
target_node_label: str = "AWSRole"
|
|
146
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
147
|
+
{"arn": PropertyRef("destination_principal_arn")},
|
|
148
|
+
)
|
|
149
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
150
|
+
rel_label: str = "ASSUMED_ROLE_WITH_WEB_IDENTITY"
|
|
151
|
+
properties: AssumeRoleWithWebIdentityRelProperties = (
|
|
152
|
+
AssumeRoleWithWebIdentityRelProperties()
|
|
153
|
+
)
|
|
@@ -73,6 +73,26 @@ class CloudTrailTrailToS3BucketRel(CartographyRelSchema):
|
|
|
73
73
|
)
|
|
74
74
|
|
|
75
75
|
|
|
76
|
+
@dataclass(frozen=True)
|
|
77
|
+
class CloudTrailTrailToCloudWatchLogGroupRelProperties(CartographyRelProperties):
|
|
78
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True)
|
|
82
|
+
class CloudTrailTrailToCloudWatchLogGroupRel(CartographyRelSchema):
|
|
83
|
+
target_node_label: str = "CloudWatchLogGroup"
|
|
84
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
85
|
+
{
|
|
86
|
+
"id": PropertyRef("CloudWatchLogsLogGroupArn"),
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
90
|
+
rel_label: str = "SENDS_LOGS_TO_CLOUDWATCH"
|
|
91
|
+
properties: CloudTrailTrailToCloudWatchLogGroupRelProperties = (
|
|
92
|
+
CloudTrailTrailToCloudWatchLogGroupRelProperties()
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
76
96
|
@dataclass(frozen=True)
|
|
77
97
|
class CloudTrailTrailSchema(CartographyNodeSchema):
|
|
78
98
|
label: str = "CloudTrailTrail"
|
|
@@ -81,5 +101,6 @@ class CloudTrailTrailSchema(CartographyNodeSchema):
|
|
|
81
101
|
other_relationships: OtherRelationships = OtherRelationships(
|
|
82
102
|
[
|
|
83
103
|
CloudTrailTrailToS3BucketRel(),
|
|
104
|
+
CloudTrailTrailToCloudWatchLogGroupRel(),
|
|
84
105
|
]
|
|
85
106
|
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class CloudWatchMetricAlarmNodeProperties(CartographyNodeProperties):
|
|
15
|
+
id: PropertyRef = PropertyRef("AlarmArn")
|
|
16
|
+
arn: PropertyRef = PropertyRef("AlarmArn", extra_index=True)
|
|
17
|
+
alarm_name: PropertyRef = PropertyRef("AlarmName")
|
|
18
|
+
alarm_description: PropertyRef = PropertyRef("AlarmDescription")
|
|
19
|
+
state_value: PropertyRef = PropertyRef("StateValue")
|
|
20
|
+
state_reason: PropertyRef = PropertyRef("StateReason")
|
|
21
|
+
actions_enabled: PropertyRef = PropertyRef("ActionsEnabled")
|
|
22
|
+
comparison_operator: PropertyRef = PropertyRef("ComparisonOperator")
|
|
23
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
24
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class CloudWatchMetricAlarmToAwsAccountRelProperties(CartographyRelProperties):
|
|
29
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class CloudWatchMetricAlarmToAWSAccountRel(CartographyRelSchema):
|
|
34
|
+
target_node_label: str = "AWSAccount"
|
|
35
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
36
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)},
|
|
37
|
+
)
|
|
38
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
39
|
+
rel_label: str = "RESOURCE"
|
|
40
|
+
properties: CloudWatchMetricAlarmToAwsAccountRelProperties = (
|
|
41
|
+
CloudWatchMetricAlarmToAwsAccountRelProperties()
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(frozen=True)
|
|
46
|
+
class CloudWatchMetricAlarmSchema(CartographyNodeSchema):
|
|
47
|
+
label: str = "CloudWatchMetricAlarm"
|
|
48
|
+
properties: CloudWatchMetricAlarmNodeProperties = (
|
|
49
|
+
CloudWatchMetricAlarmNodeProperties()
|
|
50
|
+
)
|
|
51
|
+
sub_resource_relationship: CloudWatchMetricAlarmToAWSAccountRel = (
|
|
52
|
+
CloudWatchMetricAlarmToAWSAccountRel()
|
|
53
|
+
)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.aws.ec2.auto_scaling_groups import EC2SubnetToAWSAccountRel
|
|
4
|
+
from cartography.models.core.common import PropertyRef
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
6
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
8
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
9
|
+
from cartography.models.core.relationships import LinkDirection
|
|
10
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
11
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
12
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class EC2SubnetNodeProperties(CartographyNodeProperties):
|
|
17
|
+
id: PropertyRef = PropertyRef("SubnetId")
|
|
18
|
+
subnetid: PropertyRef = PropertyRef("SubnetId", extra_index=True)
|
|
19
|
+
subnet_id: PropertyRef = PropertyRef("SubnetId", extra_index=True)
|
|
20
|
+
subnet_arn: PropertyRef = PropertyRef("SubnetArn")
|
|
21
|
+
name: PropertyRef = PropertyRef("CidrBlock")
|
|
22
|
+
cidr_block: PropertyRef = PropertyRef("CidrBlock")
|
|
23
|
+
available_ip_address_count: PropertyRef = PropertyRef("AvailableIpAddressCount")
|
|
24
|
+
default_for_az: PropertyRef = PropertyRef("DefaultForAz")
|
|
25
|
+
map_customer_owned_ip_on_launch: PropertyRef = PropertyRef(
|
|
26
|
+
"MapCustomerOwnedIpOnLaunch"
|
|
27
|
+
)
|
|
28
|
+
state: PropertyRef = PropertyRef("State")
|
|
29
|
+
assignipv6addressoncreation: PropertyRef = PropertyRef(
|
|
30
|
+
"AssignIpv6AddressOnCreation"
|
|
31
|
+
)
|
|
32
|
+
map_public_ip_on_launch: PropertyRef = PropertyRef("MapPublicIpOnLaunch")
|
|
33
|
+
availability_zone: PropertyRef = PropertyRef("AvailabilityZone")
|
|
34
|
+
availability_zone_id: PropertyRef = PropertyRef("AvailabilityZoneId")
|
|
35
|
+
vpc_id: PropertyRef = PropertyRef("VpcId")
|
|
36
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
37
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True)
|
|
41
|
+
class EC2SubnetToVpcRelProperties(CartographyRelProperties):
|
|
42
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(frozen=True)
|
|
46
|
+
class EC2SubnetToVpcRel(CartographyRelSchema):
|
|
47
|
+
target_node_label: str = "AWSVpc"
|
|
48
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
49
|
+
{"id": PropertyRef("VpcId")}
|
|
50
|
+
)
|
|
51
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
52
|
+
rel_label: str = "MEMBER_OF_AWS_VPC"
|
|
53
|
+
properties: EC2SubnetToVpcRelProperties = EC2SubnetToVpcRelProperties()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass(frozen=True)
|
|
57
|
+
class EC2SubnetSchema(CartographyNodeSchema):
|
|
58
|
+
label: str = "EC2Subnet"
|
|
59
|
+
properties: EC2SubnetNodeProperties = EC2SubnetNodeProperties()
|
|
60
|
+
sub_resource_relationship: EC2SubnetToAWSAccountRel = EC2SubnetToAWSAccountRel()
|
|
61
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
62
|
+
[
|
|
63
|
+
EC2SubnetToVpcRel(),
|
|
64
|
+
]
|
|
65
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class ECRImageNodeProperties(CartographyNodeProperties):
|
|
15
|
+
id: PropertyRef = PropertyRef("imageDigest")
|
|
16
|
+
digest: PropertyRef = PropertyRef("imageDigest")
|
|
17
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
18
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True)
|
|
22
|
+
class ECRImageToAWSAccountRelProperties(CartographyRelProperties):
|
|
23
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class ECRImageToAWSAccountRel(CartographyRelSchema):
|
|
28
|
+
target_node_label: str = "AWSAccount"
|
|
29
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
30
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)}
|
|
31
|
+
)
|
|
32
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
33
|
+
rel_label: str = "RESOURCE"
|
|
34
|
+
properties: ECRImageToAWSAccountRelProperties = ECRImageToAWSAccountRelProperties()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(frozen=True)
|
|
38
|
+
class ECRImageSchema(CartographyNodeSchema):
|
|
39
|
+
label: str = "ECRImage"
|
|
40
|
+
properties: ECRImageNodeProperties = ECRImageNodeProperties()
|
|
41
|
+
sub_resource_relationship: ECRImageToAWSAccountRel = ECRImageToAWSAccountRel()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
11
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class ECRRepositoryNodeProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef("repositoryArn")
|
|
17
|
+
arn: PropertyRef = PropertyRef("repositoryArn", extra_index=True)
|
|
18
|
+
name: PropertyRef = PropertyRef("repositoryName", extra_index=True)
|
|
19
|
+
uri: PropertyRef = PropertyRef("repositoryUri", extra_index=True)
|
|
20
|
+
created_at: PropertyRef = PropertyRef("createdAt")
|
|
21
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
22
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(frozen=True)
|
|
26
|
+
class ECRRepositoryToAWSAccountRelProperties(CartographyRelProperties):
|
|
27
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class ECRRepositoryToAWSAccountRel(CartographyRelSchema):
|
|
32
|
+
target_node_label: str = "AWSAccount"
|
|
33
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
34
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)}
|
|
35
|
+
)
|
|
36
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
37
|
+
rel_label: str = "RESOURCE"
|
|
38
|
+
properties: ECRRepositoryToAWSAccountRelProperties = (
|
|
39
|
+
ECRRepositoryToAWSAccountRelProperties()
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass(frozen=True)
|
|
44
|
+
class ECRRepositoryToRepositoryImageRelProperties(CartographyRelProperties):
|
|
45
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
class ECRRepositoryToRepositoryImageRel(CartographyRelSchema):
|
|
50
|
+
target_node_label: str = "ECRRepositoryImage"
|
|
51
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
52
|
+
{"id": PropertyRef("id")}
|
|
53
|
+
)
|
|
54
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
55
|
+
rel_label: str = "REPO_IMAGE"
|
|
56
|
+
properties: ECRRepositoryToRepositoryImageRelProperties = (
|
|
57
|
+
ECRRepositoryToRepositoryImageRelProperties()
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass(frozen=True)
|
|
62
|
+
class ECRRepositorySchema(CartographyNodeSchema):
|
|
63
|
+
label: str = "ECRRepository"
|
|
64
|
+
properties: ECRRepositoryNodeProperties = ECRRepositoryNodeProperties()
|
|
65
|
+
sub_resource_relationship: ECRRepositoryToAWSAccountRel = (
|
|
66
|
+
ECRRepositoryToAWSAccountRel()
|
|
67
|
+
)
|
|
68
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
69
|
+
[
|
|
70
|
+
ECRRepositoryToRepositoryImageRel(),
|
|
71
|
+
]
|
|
72
|
+
)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
11
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class ECRRepositoryImageNodeProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef("id")
|
|
17
|
+
tag: PropertyRef = PropertyRef("imageTag")
|
|
18
|
+
uri: PropertyRef = PropertyRef("uri")
|
|
19
|
+
repo_uri: PropertyRef = PropertyRef("repo_uri")
|
|
20
|
+
image_size_bytes: PropertyRef = PropertyRef("imageSizeInBytes")
|
|
21
|
+
image_pushed_at: PropertyRef = PropertyRef("imagePushedAt")
|
|
22
|
+
image_manifest_media_type: PropertyRef = PropertyRef("imageManifestMediaType")
|
|
23
|
+
artifact_media_type: PropertyRef = PropertyRef("artifactMediaType")
|
|
24
|
+
last_recorded_pull_time: PropertyRef = PropertyRef("lastRecordedPullTime")
|
|
25
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
26
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class ECRRepositoryImageToAWSAccountRelProperties(CartographyRelProperties):
|
|
31
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass(frozen=True)
|
|
35
|
+
class ECRRepositoryImageToAWSAccountRel(CartographyRelSchema):
|
|
36
|
+
target_node_label: str = "AWSAccount"
|
|
37
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
38
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)}
|
|
39
|
+
)
|
|
40
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
41
|
+
rel_label: str = "RESOURCE"
|
|
42
|
+
properties: ECRRepositoryImageToAWSAccountRelProperties = (
|
|
43
|
+
ECRRepositoryImageToAWSAccountRelProperties()
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True)
|
|
48
|
+
class ECRRepositoryImageToECRRepositoryRelProperties(CartographyRelProperties):
|
|
49
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True)
|
|
53
|
+
class ECRRepositoryImageToECRRepositoryRel(CartographyRelSchema):
|
|
54
|
+
target_node_label: str = "ECRRepository"
|
|
55
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
56
|
+
{"uri": PropertyRef("repo_uri")}
|
|
57
|
+
)
|
|
58
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
59
|
+
rel_label: str = "REPO_IMAGE"
|
|
60
|
+
properties: ECRRepositoryImageToECRRepositoryRelProperties = (
|
|
61
|
+
ECRRepositoryImageToECRRepositoryRelProperties()
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass(frozen=True)
|
|
66
|
+
class ECRRepositoryImageToECRImageRelProperties(CartographyRelProperties):
|
|
67
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass(frozen=True)
|
|
71
|
+
class ECRRepositoryImageToECRImageRel(CartographyRelSchema):
|
|
72
|
+
target_node_label: str = "ECRImage"
|
|
73
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
74
|
+
{"id": PropertyRef("imageDigest")}
|
|
75
|
+
)
|
|
76
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
77
|
+
rel_label: str = "IMAGE"
|
|
78
|
+
properties: ECRRepositoryImageToECRImageRelProperties = (
|
|
79
|
+
ECRRepositoryImageToECRImageRelProperties()
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass(frozen=True)
|
|
84
|
+
class ECRRepositoryImageSchema(CartographyNodeSchema):
|
|
85
|
+
label: str = "ECRRepositoryImage"
|
|
86
|
+
properties: ECRRepositoryImageNodeProperties = ECRRepositoryImageNodeProperties()
|
|
87
|
+
sub_resource_relationship: ECRRepositoryImageToAWSAccountRel = (
|
|
88
|
+
ECRRepositoryImageToAWSAccountRel()
|
|
89
|
+
)
|
|
90
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
91
|
+
[
|
|
92
|
+
ECRRepositoryImageToECRRepositoryRel(),
|
|
93
|
+
ECRRepositoryImageToECRImageRel(),
|
|
94
|
+
]
|
|
95
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class ElasticacheClusterNodeProperties(CartographyNodeProperties):
|
|
15
|
+
id: PropertyRef = PropertyRef("ARN")
|
|
16
|
+
arn: PropertyRef = PropertyRef("ARN", extra_index=True)
|
|
17
|
+
cache_cluster_id: PropertyRef = PropertyRef("CacheClusterId")
|
|
18
|
+
cache_node_type: PropertyRef = PropertyRef("CacheNodeType")
|
|
19
|
+
engine: PropertyRef = PropertyRef("Engine")
|
|
20
|
+
engine_version: PropertyRef = PropertyRef("EngineVersion")
|
|
21
|
+
cache_cluster_status: PropertyRef = PropertyRef("CacheClusterStatus")
|
|
22
|
+
num_cache_nodes: PropertyRef = PropertyRef("NumCacheNodes")
|
|
23
|
+
preferred_availability_zone: PropertyRef = PropertyRef("PreferredAvailabilityZone")
|
|
24
|
+
preferred_maintenance_window: PropertyRef = PropertyRef(
|
|
25
|
+
"PreferredMaintenanceWindow"
|
|
26
|
+
)
|
|
27
|
+
cache_cluster_create_time: PropertyRef = PropertyRef("CacheClusterCreateTime")
|
|
28
|
+
cache_subnet_group_name: PropertyRef = PropertyRef("CacheSubnetGroupName")
|
|
29
|
+
auto_minor_version_upgrade: PropertyRef = PropertyRef("AutoMinorVersionUpgrade")
|
|
30
|
+
replication_group_id: PropertyRef = PropertyRef("ReplicationGroupId")
|
|
31
|
+
snapshot_retention_limit: PropertyRef = PropertyRef("SnapshotRetentionLimit")
|
|
32
|
+
snapshot_window: PropertyRef = PropertyRef("SnapshotWindow")
|
|
33
|
+
auth_token_enabled: PropertyRef = PropertyRef("AuthTokenEnabled")
|
|
34
|
+
transit_encryption_enabled: PropertyRef = PropertyRef("TransitEncryptionEnabled")
|
|
35
|
+
at_rest_encryption_enabled: PropertyRef = PropertyRef("AtRestEncryptionEnabled")
|
|
36
|
+
topic_arn: PropertyRef = PropertyRef("TopicArn")
|
|
37
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
38
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(frozen=True)
|
|
42
|
+
class ElasticacheClusterToAWSAccountRelProperties(CartographyRelProperties):
|
|
43
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass(frozen=True)
|
|
47
|
+
class ElasticacheClusterToAWSAccountRel(CartographyRelSchema):
|
|
48
|
+
target_node_label: str = "AWSAccount"
|
|
49
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
50
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)}
|
|
51
|
+
)
|
|
52
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
53
|
+
rel_label: str = "RESOURCE"
|
|
54
|
+
properties: ElasticacheClusterToAWSAccountRelProperties = (
|
|
55
|
+
ElasticacheClusterToAWSAccountRelProperties()
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass(frozen=True)
|
|
60
|
+
class ElasticacheClusterSchema(CartographyNodeSchema):
|
|
61
|
+
label: str = "ElasticacheCluster"
|
|
62
|
+
properties: ElasticacheClusterNodeProperties = ElasticacheClusterNodeProperties()
|
|
63
|
+
sub_resource_relationship: ElasticacheClusterToAWSAccountRel = (
|
|
64
|
+
ElasticacheClusterToAWSAccountRel()
|
|
65
|
+
)
|