cartography 0.102.0rc1__py3-none-any.whl → 0.102.0rc2__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 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.102.0rc1'
20
+ __version__ = version = '0.102.0rc2'
21
21
  __version_tuple__ = version_tuple = (0, 102, 0)
@@ -0,0 +1,287 @@
1
+ import logging
2
+ from typing import Any
3
+
4
+ import boto3
5
+ import neo4j
6
+
7
+ from cartography.client.core.tx import load
8
+ from cartography.graph.job import GraphJob
9
+ from cartography.intel.aws.ec2.util import get_botocore_config
10
+ from cartography.models.aws.ec2.route_table_associations import RouteTableAssociationSchema
11
+ from cartography.models.aws.ec2.route_tables import RouteTableSchema
12
+ from cartography.models.aws.ec2.routes import RouteSchema
13
+ from cartography.util import aws_handle_regions
14
+ from cartography.util import timeit
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ def _get_route_id_and_target(route_table_id: str, route: dict[str, Any]) -> tuple[str, str | None]:
20
+ """
21
+ Generate a unique identifier for an AWS EC2 route and return the target of the route
22
+ regardless of its type.
23
+
24
+ Args:
25
+ route_table_id: The ID of the route table this route belongs to
26
+ route: The route data from AWS API
27
+
28
+ Returns:
29
+ A tuple containing the unique identifier for the route and the target of the route
30
+ """
31
+ route_target_keys = [
32
+ 'DestinationCidrBlock',
33
+ 'DestinationIpv6CidrBlock',
34
+ 'GatewayId',
35
+ 'InstanceId',
36
+ 'NatGatewayId',
37
+ 'TransitGatewayId',
38
+ 'LocalGatewayId',
39
+ 'CarrierGatewayId',
40
+ 'NetworkInterfaceId',
41
+ 'VpcPeeringConnectionId',
42
+ 'EgressOnlyInternetGatewayId',
43
+ 'CoreNetworkArn',
44
+ ]
45
+
46
+ # Start with the route table ID
47
+ parts = [route_table_id]
48
+ target = None
49
+ found_target = False
50
+
51
+ for key in route_target_keys:
52
+ # Each route is a "union"-like data structure, so only one of the keys will be present.
53
+ if key in route:
54
+ parts.append(route[key])
55
+ target = route[key]
56
+ found_target = True
57
+ break
58
+
59
+ if not found_target:
60
+ logger.warning(
61
+ f"No target found for route in {route_table_id}. Please review the route and file an issue to "
62
+ "https://github.com/cartography-cncf/cartography/issues sharing what the route table looks like "
63
+ "so that we can update the available keys.",
64
+ )
65
+
66
+ return '|'.join(parts), target
67
+
68
+
69
+ @timeit
70
+ @aws_handle_regions
71
+ def get_route_tables(boto3_session: boto3.session.Session, region: str) -> list[dict[str, Any]]:
72
+ client = boto3_session.client('ec2', region_name=region, config=get_botocore_config())
73
+ paginator = client.get_paginator('describe_route_tables')
74
+ route_tables: list[dict[str, Any]] = []
75
+ for page in paginator.paginate():
76
+ route_tables.extend(page['RouteTables'])
77
+ return route_tables
78
+
79
+
80
+ def _transform_route_table_associations(
81
+ route_table_id: str,
82
+ associations: list[dict[str, Any]],
83
+ ) -> tuple[list[dict[str, Any]], bool]:
84
+ """
85
+ Transform route table association data into a format suitable for cartography ingestion.
86
+
87
+ Args:
88
+ route_table_id: The ID of the route table
89
+ associations: List of association data from AWS API
90
+
91
+ Returns:
92
+ 1. List of transformed association data
93
+ 2. Boolean indicating if the association is the main association, meaning that the route table is the main
94
+ route table for the VPC
95
+ """
96
+ transformed = []
97
+ is_main = False
98
+ for association in associations:
99
+ if association.get('SubnetId'):
100
+ target = association['SubnetId']
101
+ elif association.get('GatewayId'):
102
+ target = association['GatewayId']
103
+ else:
104
+ is_main = True
105
+ target = 'main'
106
+
107
+ transformed_association = {
108
+ 'id': association['RouteTableAssociationId'],
109
+ 'route_table_id': route_table_id,
110
+ 'subnet_id': association.get('SubnetId'),
111
+ 'gateway_id': association.get('GatewayId'),
112
+ 'main': association.get('Main', False),
113
+ 'association_state': association.get('AssociationState', {}).get('State'),
114
+ 'association_state_message': association.get('AssociationState', {}).get('Message'),
115
+ '_target': target,
116
+ }
117
+ transformed.append(transformed_association)
118
+ return transformed, is_main
119
+
120
+
121
+ def _transform_route_table_routes(route_table_id: str, routes: list[dict[str, Any]]) -> list[dict[str, Any]]:
122
+ """
123
+ Transform route table route data into a format suitable for cartography ingestion.
124
+
125
+ Args:
126
+ route_table_id: The ID of the route table
127
+ routes: List of route data from AWS API
128
+
129
+ Returns:
130
+ List of transformed route data
131
+ """
132
+ transformed = []
133
+ for route in routes:
134
+ route_id, target = _get_route_id_and_target(route_table_id, route)
135
+
136
+ transformed_route = {
137
+ 'id': route_id,
138
+ 'route_table_id': route_table_id,
139
+ 'destination_cidr_block': route.get('DestinationCidrBlock'),
140
+ 'destination_ipv6_cidr_block': route.get('DestinationIpv6CidrBlock'),
141
+ 'gateway_id': route.get('GatewayId'),
142
+ 'instance_id': route.get('InstanceId'),
143
+ 'instance_owner_id': route.get('InstanceOwnerId'),
144
+ 'nat_gateway_id': route.get('NatGatewayId'),
145
+ 'transit_gateway_id': route.get('TransitGatewayId'),
146
+ 'local_gateway_id': route.get('LocalGatewayId'),
147
+ 'carrier_gateway_id': route.get('CarrierGatewayId'),
148
+ 'network_interface_id': route.get('NetworkInterfaceId'),
149
+ 'vpc_peering_connection_id': route.get('VpcPeeringConnectionId'),
150
+ 'state': route.get('State'),
151
+ 'origin': route.get('Origin'),
152
+ 'core_network_arn': route.get('CoreNetworkArn'),
153
+ 'destination_prefix_list_id': route.get('DestinationPrefixListId'),
154
+ 'egress_only_internet_gateway_id': route.get('EgressOnlyInternetGatewayId'),
155
+ '_target': target,
156
+ }
157
+ transformed.append(transformed_route)
158
+ return transformed
159
+
160
+
161
+ def transform_route_table_data(
162
+ route_tables: list[dict[str, Any]],
163
+ ) -> tuple[list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]]]:
164
+ """
165
+ Transform route table data into a format suitable for cartography ingestion.
166
+
167
+ Args:
168
+ route_tables: List of route table data from AWS API
169
+
170
+ Returns:
171
+ Tuple of (transformed route table data, transformed association data, transformed route data)
172
+ """
173
+ transformed_tables = []
174
+ association_data = []
175
+ route_data = []
176
+
177
+ for rt in route_tables:
178
+ route_table_id = rt['RouteTableId']
179
+
180
+ # Transform routes
181
+ current_routes = []
182
+ if rt.get('Routes'):
183
+ current_routes = _transform_route_table_routes(route_table_id, rt['Routes'])
184
+ route_data.extend(current_routes)
185
+
186
+ # If the rt has a association marked with main=True, then it is the main route table for the VPC.
187
+ is_main = False
188
+ # Transform associations
189
+ if rt.get('Associations'):
190
+ associations, is_main = _transform_route_table_associations(route_table_id, rt['Associations'])
191
+ association_data.extend(associations)
192
+
193
+ transformed_rt = {
194
+ 'id': route_table_id,
195
+ 'route_table_id': route_table_id,
196
+ 'owner_id': rt.get('OwnerId'),
197
+ 'vpc_id': rt.get('VpcId'),
198
+ 'VpnGatewayIds': [vgw['GatewayId'] for vgw in rt.get('PropagatingVgws', [])],
199
+ 'RouteTableAssociationIds': [assoc['RouteTableAssociationId'] for assoc in rt.get('Associations', [])],
200
+ 'RouteIds': [route['id'] for route in current_routes],
201
+ 'tags': rt.get('Tags', []),
202
+ 'main': is_main,
203
+ }
204
+ transformed_tables.append(transformed_rt)
205
+
206
+ return transformed_tables, association_data, route_data
207
+
208
+
209
+ @timeit
210
+ def load_route_tables(
211
+ neo4j_session: neo4j.Session,
212
+ data: list[dict[str, Any]],
213
+ region: str,
214
+ current_aws_account_id: str,
215
+ update_tag: int,
216
+ ) -> None:
217
+ load(
218
+ neo4j_session,
219
+ RouteTableSchema(),
220
+ data,
221
+ Region=region,
222
+ AWS_ID=current_aws_account_id,
223
+ lastupdated=update_tag,
224
+ )
225
+
226
+
227
+ @timeit
228
+ def load_route_table_associations(
229
+ neo4j_session: neo4j.Session,
230
+ data: list[dict[str, Any]],
231
+ region: str,
232
+ current_aws_account_id: str,
233
+ update_tag: int,
234
+ ) -> None:
235
+ load(
236
+ neo4j_session,
237
+ RouteTableAssociationSchema(),
238
+ data,
239
+ Region=region,
240
+ AWS_ID=current_aws_account_id,
241
+ lastupdated=update_tag,
242
+ )
243
+
244
+
245
+ @timeit
246
+ def load_routes(
247
+ neo4j_session: neo4j.Session,
248
+ data: list[dict[str, Any]],
249
+ region: str,
250
+ current_aws_account_id: str,
251
+ update_tag: int,
252
+ ) -> None:
253
+ load(
254
+ neo4j_session,
255
+ RouteSchema(),
256
+ data,
257
+ Region=region,
258
+ AWS_ID=current_aws_account_id,
259
+ lastupdated=update_tag,
260
+ )
261
+
262
+
263
+ @timeit
264
+ def cleanup(neo4j_session: neo4j.Session, common_job_parameters: dict[str, Any]) -> None:
265
+ logger.debug("Running EC2 route tables cleanup")
266
+ GraphJob.from_node_schema(RouteTableSchema(), common_job_parameters).run(neo4j_session)
267
+ GraphJob.from_node_schema(RouteSchema(), common_job_parameters).run(neo4j_session)
268
+ GraphJob.from_node_schema(RouteTableAssociationSchema(), common_job_parameters).run(neo4j_session)
269
+
270
+
271
+ @timeit
272
+ def sync_route_tables(
273
+ neo4j_session: neo4j.Session,
274
+ boto3_session: boto3.session.Session,
275
+ regions: list[str],
276
+ current_aws_account_id: str,
277
+ update_tag: int,
278
+ common_job_parameters: dict[str, Any],
279
+ ) -> None:
280
+ for region in regions:
281
+ logger.info("Syncing EC2 route tables for region '%s' in account '%s'.", region, current_aws_account_id)
282
+ route_tables = get_route_tables(boto3_session, region)
283
+ transformed_tables, association_data, route_data = transform_route_table_data(route_tables)
284
+ load_routes(neo4j_session, route_data, region, current_aws_account_id, update_tag)
285
+ load_route_table_associations(neo4j_session, association_data, region, current_aws_account_id, update_tag)
286
+ load_route_tables(neo4j_session, transformed_tables, region, current_aws_account_id, update_tag)
287
+ cleanup(neo4j_session, common_job_parameters)
@@ -45,6 +45,7 @@ from .ec2.volumes import sync_ebs_volumes
45
45
  from .ec2.vpc import sync_vpc
46
46
  from .ec2.vpc_peerings import sync_vpc_peerings
47
47
  from .iam_instance_profiles import sync_iam_instance_profiles
48
+ from cartography.intel.aws.ec2.route_tables import sync_route_tables
48
49
 
49
50
  RESOURCE_FUNCTIONS: Dict[str, Callable[..., None]] = {
50
51
  'iam': iam.sync,
@@ -62,6 +63,7 @@ RESOURCE_FUNCTIONS: Dict[str, Callable[..., None]] = {
62
63
  'ec2:load_balancer_v2': sync_load_balancer_v2s,
63
64
  'ec2:network_acls': sync_network_acls,
64
65
  'ec2:network_interface': sync_network_interfaces,
66
+ 'ec2:route_table': sync_route_tables,
65
67
  'ec2:security_group': sync_ec2_security_groupinfo,
66
68
  'ec2:subnet': sync_subnets,
67
69
  'ec2:tgw': sync_transit_gateways,
@@ -0,0 +1,87 @@
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 RouteTableAssociationNodeProperties(CartographyNodeProperties):
16
+ id: PropertyRef = PropertyRef('id')
17
+ route_table_association_id: PropertyRef = PropertyRef('id', extra_index=True)
18
+ target: PropertyRef = PropertyRef('_target')
19
+ gateway_id: PropertyRef = PropertyRef('gateway_id')
20
+ main: PropertyRef = PropertyRef('main')
21
+ route_table_id: PropertyRef = PropertyRef('route_table_id')
22
+ subnet_id: PropertyRef = PropertyRef('subnet_id')
23
+ association_state: PropertyRef = PropertyRef('association_state')
24
+ association_state_message: PropertyRef = PropertyRef('association_state_message')
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 RouteTableAssociationToAwsAccountRelProperties(CartographyRelProperties):
31
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
32
+
33
+
34
+ @dataclass(frozen=True)
35
+ class RouteTableAssociationToAWSAccount(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: RouteTableAssociationToAwsAccountRelProperties = RouteTableAssociationToAwsAccountRelProperties()
43
+
44
+
45
+ @dataclass(frozen=True)
46
+ class RouteTableAssociationToSubnetRelProperties(CartographyRelProperties):
47
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
48
+
49
+
50
+ @dataclass(frozen=True)
51
+ class RouteTableAssociationToSubnet(CartographyRelSchema):
52
+ target_node_label: str = 'EC2Subnet'
53
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
54
+ {'subnetid': PropertyRef('subnet_id')},
55
+ )
56
+ direction: LinkDirection = LinkDirection.OUTWARD
57
+ rel_label: str = "ASSOCIATED_SUBNET"
58
+ properties: RouteTableAssociationToSubnetRelProperties = RouteTableAssociationToSubnetRelProperties()
59
+
60
+
61
+ @dataclass(frozen=True)
62
+ class RouteTableAssociationToIgwRelProperties(CartographyRelProperties):
63
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
64
+
65
+
66
+ @dataclass(frozen=True)
67
+ class RouteTableAssociationToIgw(CartographyRelSchema):
68
+ target_node_label: str = 'AWSInternetGateway'
69
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
70
+ {'id': PropertyRef('gateway_id')},
71
+ )
72
+ direction: LinkDirection = LinkDirection.OUTWARD
73
+ rel_label: str = "ASSOCIATED_IGW_FOR_INGRESS"
74
+ properties: RouteTableAssociationToIgwRelProperties = RouteTableAssociationToIgwRelProperties()
75
+
76
+
77
+ @dataclass(frozen=True)
78
+ class RouteTableAssociationSchema(CartographyNodeSchema):
79
+ label: str = 'EC2RouteTableAssociation'
80
+ properties: RouteTableAssociationNodeProperties = RouteTableAssociationNodeProperties()
81
+ sub_resource_relationship: RouteTableAssociationToAWSAccount = RouteTableAssociationToAWSAccount()
82
+ other_relationships: OtherRelationships = OtherRelationships(
83
+ [
84
+ RouteTableAssociationToSubnet(),
85
+ RouteTableAssociationToIgw(),
86
+ ],
87
+ )
@@ -0,0 +1,121 @@
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 RouteTableNodeProperties(CartographyNodeProperties):
16
+ """
17
+ Schema describing a RouteTable.
18
+ """
19
+ id: PropertyRef = PropertyRef('id')
20
+ route_table_id: PropertyRef = PropertyRef('route_table_id', extra_index=True)
21
+ owner_id: PropertyRef = PropertyRef('owner_id')
22
+ vpc_id: PropertyRef = PropertyRef('VpcId')
23
+ region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
24
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
25
+ main: PropertyRef = PropertyRef('main')
26
+
27
+
28
+ @dataclass(frozen=True)
29
+ class RouteTableToAwsAccountRelProperties(CartographyRelProperties):
30
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
31
+
32
+
33
+ @dataclass(frozen=True)
34
+ class RouteTableToAWSAccount(CartographyRelSchema):
35
+ target_node_label: str = 'AWSAccount'
36
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
37
+ {'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
38
+ )
39
+ direction: LinkDirection = LinkDirection.INWARD
40
+ rel_label: str = "RESOURCE"
41
+ properties: RouteTableToAwsAccountRelProperties = RouteTableToAwsAccountRelProperties()
42
+
43
+
44
+ @dataclass(frozen=True)
45
+ class RouteTableToVpcRelProperties(CartographyRelProperties):
46
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
47
+
48
+
49
+ @dataclass(frozen=True)
50
+ class RouteTableToVpc(CartographyRelSchema):
51
+ target_node_label: str = 'AWSVpc'
52
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
53
+ {'id': PropertyRef('vpc_id')},
54
+ )
55
+ direction: LinkDirection = LinkDirection.OUTWARD
56
+ rel_label: str = "MEMBER_OF_AWS_VPC"
57
+ properties: RouteTableToVpcRelProperties = RouteTableToVpcRelProperties()
58
+
59
+
60
+ @dataclass(frozen=True)
61
+ class RouteTableToRouteRelProperties(CartographyRelProperties):
62
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
63
+
64
+
65
+ @dataclass(frozen=True)
66
+ class RouteTableToRoute(CartographyRelSchema):
67
+ target_node_label: str = 'EC2Route'
68
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
69
+ {'id': PropertyRef('RouteIds', one_to_many=True)},
70
+ )
71
+ direction: LinkDirection = LinkDirection.OUTWARD
72
+ rel_label: str = "ROUTE"
73
+ properties: RouteTableToRouteRelProperties = RouteTableToRouteRelProperties()
74
+
75
+
76
+ @dataclass(frozen=True)
77
+ class RouteTableToAssociationRelProperties(CartographyRelProperties):
78
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
79
+
80
+
81
+ @dataclass(frozen=True)
82
+ class RouteTableToAssociation(CartographyRelSchema):
83
+ target_node_label: str = 'EC2RouteTableAssociation'
84
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
85
+ {'id': PropertyRef('RouteTableAssociationIds', one_to_many=True)},
86
+ )
87
+ direction: LinkDirection = LinkDirection.OUTWARD
88
+ rel_label: str = "ASSOCIATION"
89
+ properties: RouteTableToAssociationRelProperties = RouteTableToAssociationRelProperties()
90
+
91
+
92
+ @dataclass(frozen=True)
93
+ class RouteTableToVpnGatewayRelProperties(CartographyRelProperties):
94
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
95
+
96
+
97
+ # TODO implement AWSVpnGateways
98
+ @dataclass(frozen=True)
99
+ class RouteTableToVpnGateway(CartographyRelSchema):
100
+ target_node_label: str = 'AWSVpnGateway'
101
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
102
+ {'id': PropertyRef('VpnGatewayIds', one_to_many=True)},
103
+ )
104
+ direction: LinkDirection = LinkDirection.OUTWARD
105
+ rel_label: str = "CONNECTED_TO"
106
+ properties: RouteTableToVpnGatewayRelProperties = RouteTableToVpnGatewayRelProperties()
107
+
108
+
109
+ @dataclass(frozen=True)
110
+ class RouteTableSchema(CartographyNodeSchema):
111
+ label: str = 'EC2RouteTable'
112
+ properties: RouteTableNodeProperties = RouteTableNodeProperties()
113
+ sub_resource_relationship: RouteTableToAWSAccount = RouteTableToAWSAccount()
114
+ other_relationships: OtherRelationships = OtherRelationships(
115
+ [
116
+ RouteTableToVpc(),
117
+ RouteTableToRoute(),
118
+ RouteTableToAssociation(),
119
+ RouteTableToVpnGateway(),
120
+ ],
121
+ )
@@ -0,0 +1,77 @@
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 RouteNodeProperties(CartographyNodeProperties):
16
+ id: PropertyRef = PropertyRef('id')
17
+ carrier_gateway_id: PropertyRef = PropertyRef('carrier_gateway_id')
18
+ core_network_arn: PropertyRef = PropertyRef('core_network_arn')
19
+ destination_cidr_block: PropertyRef = PropertyRef('destination_cidr_block')
20
+ destination_ipv6_cidr_block: PropertyRef = PropertyRef('destination_ipv6_cidr_block')
21
+ destination_prefix_list_id: PropertyRef = PropertyRef('destination_prefix_list_id')
22
+ egress_only_internet_gateway_id: PropertyRef = PropertyRef('egress_only_internet_gateway_id')
23
+ gateway_id: PropertyRef = PropertyRef('gateway_id')
24
+ instance_id: PropertyRef = PropertyRef('instance_id')
25
+ instance_owner_id: PropertyRef = PropertyRef('instance_owner_id')
26
+ local_gateway_id: PropertyRef = PropertyRef('local_gateway_id')
27
+ nat_gateway_id: PropertyRef = PropertyRef('nat_gateway_id')
28
+ network_interface_id: PropertyRef = PropertyRef('network_interface_id')
29
+ origin: PropertyRef = PropertyRef('origin')
30
+ state: PropertyRef = PropertyRef('state')
31
+ transit_gateway_id: PropertyRef = PropertyRef('transit_gateway_id')
32
+ vpc_peering_connection_id: PropertyRef = PropertyRef('vpc_peering_connection_id')
33
+ region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
34
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
35
+ target: PropertyRef = PropertyRef('_target')
36
+
37
+
38
+ @dataclass(frozen=True)
39
+ class RouteToAwsAccountRelProperties(CartographyRelProperties):
40
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
41
+
42
+
43
+ @dataclass(frozen=True)
44
+ class RouteToAWSAccount(CartographyRelSchema):
45
+ target_node_label: str = 'AWSAccount'
46
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
47
+ {'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
48
+ )
49
+ direction: LinkDirection = LinkDirection.INWARD
50
+ rel_label: str = "RESOURCE"
51
+ properties: RouteToAwsAccountRelProperties = RouteToAwsAccountRelProperties()
52
+
53
+
54
+ @dataclass(frozen=True)
55
+ class RouteToInternetGatewayRelProperties(CartographyRelProperties):
56
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
57
+
58
+
59
+ @dataclass(frozen=True)
60
+ class RouteToInternetGateway(CartographyRelSchema):
61
+ target_node_label: str = 'AWSInternetGateway'
62
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
63
+ {'id': PropertyRef('gateway_id')},
64
+ )
65
+ direction: LinkDirection = LinkDirection.OUTWARD
66
+ rel_label: str = "ROUTES_TO_GATEWAY"
67
+ properties: RouteToInternetGatewayRelProperties = RouteToInternetGatewayRelProperties()
68
+
69
+
70
+ @dataclass(frozen=True)
71
+ class RouteSchema(CartographyNodeSchema):
72
+ label: str = 'EC2Route'
73
+ properties: RouteNodeProperties = RouteNodeProperties()
74
+ sub_resource_relationship: RouteToAWSAccount = RouteToAWSAccount()
75
+ other_relationships: OtherRelationships = OtherRelationships([
76
+ RouteToInternetGateway(),
77
+ ])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cartography
3
- Version: 0.102.0rc1
3
+ Version: 0.102.0rc2
4
4
  Summary: Explore assets and their relationships across your technical infrastructure.
5
5
  Maintainer: Cartography Contributors
6
6
  License: apache2
@@ -1,6 +1,6 @@
1
1
  cartography/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  cartography/__main__.py,sha256=JftXT_nUPkqcEh8uxCCT4n-OyHYqbldEgrDS-4ygy0U,101
3
- cartography/_version.py,sha256=q6TYvfOuC2Uhe9vDriWNPGMCELT7yrGBm93mUcBnafo,518
3
+ cartography/_version.py,sha256=OI9fh-YQyeutwYIFkGxdZOniCKb7_CUDhbEwgHnJdYI,518
4
4
  cartography/cli.py,sha256=-fGIdBx3IwauUeYojsb-NnQPma2wtS7mFRgOETyfCg4,34796
5
5
  cartography/config.py,sha256=xXM0OqsDl5Du55C-hr2LgjdtpU1_znPsmAgujrPGPgo,12553
6
6
  cartography/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -160,7 +160,7 @@ cartography/intel/aws/permission_relationships.py,sha256=IarV9gt5BaplZ5TPo_mfypt
160
160
  cartography/intel/aws/rds.py,sha256=vnlNYmrO2Cc0PNn31CeG2QwYhwjVosbQFE9Ol1vQyLE,25252
161
161
  cartography/intel/aws/redshift.py,sha256=KOqiXIllHmtPTeaNGl-cX4srY5pFE6o12j8MQ5-zWpc,6694
162
162
  cartography/intel/aws/resourcegroupstaggingapi.py,sha256=I2VrL-oplGj2Jyhbo312V6vnER_FXpJRrc6OBJ-_VmI,10375
163
- cartography/intel/aws/resources.py,sha256=lg5j0z6Iwj16Gv25yuAb3gHG6x4vOfRNm43FoOVRfqg,3541
163
+ cartography/intel/aws/resources.py,sha256=jb2U6xsrwwp2AYirqHYc09ttOpIqYEsk-CR7He-qgzQ,3652
164
164
  cartography/intel/aws/route53.py,sha256=IYqeQud1HuHnf11A7T-Jeif5DWgjpaaU-Jfr2cLUc_o,14099
165
165
  cartography/intel/aws/s3.py,sha256=SVxUMtMSkbdjZv5qOSYIbYb8BQa-QTojbHG85-EFWLA,27034
166
166
  cartography/intel/aws/secretsmanager.py,sha256=YogwRPT6qZPVg5HrND71zI-nNn60oxoWaW7eUlhuTS0,3304
@@ -180,6 +180,7 @@ cartography/intel/aws/ec2/load_balancers.py,sha256=ah9-lXvipzVDjGFqfpNCrEyBfdu-B
180
180
  cartography/intel/aws/ec2/network_acls.py,sha256=_UiOx79OxcqH0ecRjcVMglAzz5XJ4aVYLlv6dl_ism4,6809
181
181
  cartography/intel/aws/ec2/network_interfaces.py,sha256=CzF8PooCYUQ2pk8DR8JDAhkWRUQSBj_27OsIfkL_-Cs,9199
182
182
  cartography/intel/aws/ec2/reserved_instances.py,sha256=jv8-VLI5KL8jN1QRI20yim8lzZ7I7wR8a5EF8DckahA,3122
183
+ cartography/intel/aws/ec2/route_tables.py,sha256=h3oXZP1TCUeEbjmknIgSIDGHmmofXrqtBK45lXh06cQ,10182
183
184
  cartography/intel/aws/ec2/security_groups.py,sha256=vxLeaCpCowkbl-YpON1UdbjtPolMfj_reOEuKujN80Y,6060
184
185
  cartography/intel/aws/ec2/snapshots.py,sha256=R3U6ZwE4bQPy5yikLCRcUHyXN1dD7TzS-3jULQO-F0g,5432
185
186
  cartography/intel/aws/ec2/subnets.py,sha256=42KODMXswv4OCVnkWDHZbZDLUnc_ZAD-1TDMk88rWdo,3892
@@ -307,6 +308,9 @@ cartography/models/aws/ec2/networkinterface_instance.py,sha256=t3oqcQ4GjYf7dwqPU
307
308
  cartography/models/aws/ec2/networkinterfaces.py,sha256=z1-Dl6I79-TCxXKG8QBpSKga93lPCPaLR1XqKJZK3ME,4127
308
309
  cartography/models/aws/ec2/privateip_networkinterface.py,sha256=j8MyiZsiUCuzuGUH_4PBKV3rLTk1GkE-SZb6K11oSdM,3038
309
310
  cartography/models/aws/ec2/reservations.py,sha256=dE9uSB3Em-ca1dDbetbu79JXr4ZWHC3r5gA1S3mjhVU,1930
311
+ cartography/models/aws/ec2/route_table_associations.py,sha256=MfP41U64XM86G0VMz_kbmlOc4cxMG6MbVWk1mfVoTaI,3846
312
+ cartography/models/aws/ec2/route_tables.py,sha256=qFdfb1QExqJ8r3wCMUPaticWY_ppoLKEjyZx8Xs9etE,4725
313
+ cartography/models/aws/ec2/routes.py,sha256=qmWkhvNavycKv422ih0b3jUYd02tOgHNAuIpivwj6XM,3626
310
314
  cartography/models/aws/ec2/securitygroup_instance.py,sha256=RZS9TzHHatTOESQgcs5_YHmF9sM7pRkUq2VPjk9FJlU,2876
311
315
  cartography/models/aws/ec2/securitygroup_networkinterface.py,sha256=PiaA8J82kybZyZ1wDsa-ACIDa88vt4NoA3smGNiwl14,2399
312
316
  cartography/models/aws/ec2/subnet_instance.py,sha256=ct_ibXiPN2C5ld06TczwSTXtsnlov5VCW6elphtbvPs,2752
@@ -369,9 +373,9 @@ cartography/models/snipeit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
369
373
  cartography/models/snipeit/asset.py,sha256=FyRAaeXuZjMy0eUQcSDFcgEAF5lbLMlvqp1Tv9d3Lv4,3238
370
374
  cartography/models/snipeit/tenant.py,sha256=p4rFnpNNuF1W5ilGBbexDaETWTwavfb38RcQGoImkQI,679
371
375
  cartography/models/snipeit/user.py,sha256=MsB4MiCVNTH6JpESime7cOkB89autZOXQpL6Z0l7L6o,2113
372
- cartography-0.102.0rc1.dist-info/licenses/LICENSE,sha256=kvLEBRYaQ1RvUni6y7Ti9uHeooqnjPoo6n_-0JO1ETc,11351
373
- cartography-0.102.0rc1.dist-info/METADATA,sha256=GkNEwQom09u69HGJrgQGXtYl7pBv1k6uTjsu9bmjUdQ,12087
374
- cartography-0.102.0rc1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
375
- cartography-0.102.0rc1.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
376
- cartography-0.102.0rc1.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
377
- cartography-0.102.0rc1.dist-info/RECORD,,
376
+ cartography-0.102.0rc2.dist-info/licenses/LICENSE,sha256=kvLEBRYaQ1RvUni6y7Ti9uHeooqnjPoo6n_-0JO1ETc,11351
377
+ cartography-0.102.0rc2.dist-info/METADATA,sha256=n51HlV7I_bq7yGnIkU9rXzv-D7mOeJHXIU7HeQl3lO8,12087
378
+ cartography-0.102.0rc2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
379
+ cartography-0.102.0rc2.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
380
+ cartography-0.102.0rc2.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
381
+ cartography-0.102.0rc2.dist-info/RECORD,,