cartography 0.101.1rc2__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.

@@ -0,0 +1,102 @@
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 LoadBalancerNodeProperties(CartographyNodeProperties):
16
+ id: PropertyRef = PropertyRef('id')
17
+ name: PropertyRef = PropertyRef('name')
18
+ dnsname: PropertyRef = PropertyRef('dnsname', extra_index=True)
19
+ canonicalhostedzonename: PropertyRef = PropertyRef('canonicalhostedzonename')
20
+ canonicalhostedzonenameid: PropertyRef = PropertyRef('canonicalhostedzonenameid')
21
+ scheme: PropertyRef = PropertyRef('scheme')
22
+ region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
23
+ createdtime: PropertyRef = PropertyRef('createdtime')
24
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
25
+
26
+
27
+ @dataclass(frozen=True)
28
+ class LoadBalancerToAWSAccountRelProperties(CartographyRelProperties):
29
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class LoadBalancerToAWSAccount(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: LoadBalancerToAWSAccountRelProperties = LoadBalancerToAWSAccountRelProperties()
41
+
42
+
43
+ @dataclass(frozen=True)
44
+ class LoadBalancerToSecurityGroupRelProperties(CartographyRelProperties):
45
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
46
+
47
+
48
+ @dataclass(frozen=True)
49
+ class LoadBalancerToSourceSecurityGroup(CartographyRelSchema):
50
+ target_node_label: str = 'EC2SecurityGroup'
51
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
52
+ {'name': PropertyRef('GROUP_NAME')},
53
+ )
54
+ direction: LinkDirection = LinkDirection.OUTWARD
55
+ rel_label: str = "SOURCE_SECURITY_GROUP"
56
+ properties: LoadBalancerToSecurityGroupRelProperties = LoadBalancerToSecurityGroupRelProperties()
57
+
58
+
59
+ @dataclass(frozen=True)
60
+ class LoadBalancerToEC2SecurityGroupRelProperties(CartographyRelProperties):
61
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
62
+
63
+
64
+ @dataclass(frozen=True)
65
+ class LoadBalancerToEC2SecurityGroup(CartographyRelSchema):
66
+ target_node_label: str = 'EC2SecurityGroup'
67
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
68
+ {'groupid': PropertyRef('GROUP_IDS', one_to_many=True)},
69
+ )
70
+ direction: LinkDirection = LinkDirection.OUTWARD
71
+ rel_label: str = "MEMBER_OF_EC2_SECURITY_GROUP"
72
+ properties: LoadBalancerToEC2SecurityGroupRelProperties = LoadBalancerToEC2SecurityGroupRelProperties()
73
+
74
+
75
+ @dataclass(frozen=True)
76
+ class LoadBalancerToEC2InstanceRelProperties(CartographyRelProperties):
77
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
78
+
79
+
80
+ @dataclass(frozen=True)
81
+ class LoadBalancerToEC2Instance(CartographyRelSchema):
82
+ target_node_label: str = 'EC2Instance'
83
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
84
+ {'instanceid': PropertyRef('INSTANCE_IDS', one_to_many=True)},
85
+ )
86
+ direction: LinkDirection = LinkDirection.OUTWARD
87
+ rel_label: str = "EXPOSE"
88
+ properties: LoadBalancerToEC2InstanceRelProperties = LoadBalancerToEC2InstanceRelProperties()
89
+
90
+
91
+ @dataclass(frozen=True)
92
+ class LoadBalancerSchema(CartographyNodeSchema):
93
+ label: str = 'LoadBalancer'
94
+ properties: LoadBalancerNodeProperties = LoadBalancerNodeProperties()
95
+ sub_resource_relationship: LoadBalancerToAWSAccount = LoadBalancerToAWSAccount()
96
+ other_relationships: OtherRelationships = OtherRelationships(
97
+ [
98
+ LoadBalancerToSourceSecurityGroup(),
99
+ LoadBalancerToEC2SecurityGroup(),
100
+ LoadBalancerToEC2Instance(),
101
+ ],
102
+ )
@@ -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
+ ])
File without changes
@@ -0,0 +1,33 @@
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.nodes import ExtraNodeLabels
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class EntraTenantNodeProperties(CartographyNodeProperties):
11
+ id: PropertyRef = PropertyRef('id')
12
+ created_date_time: PropertyRef = PropertyRef('created_date_time')
13
+ default_usage_location: PropertyRef = PropertyRef('default_usage_location')
14
+ deleted_date_time: PropertyRef = PropertyRef('deleted_date_time')
15
+ display_name: PropertyRef = PropertyRef('display_name')
16
+ marketing_notification_emails: PropertyRef = PropertyRef('marketing_notification_emails')
17
+ mobile_device_management_authority: PropertyRef = PropertyRef('mobile_device_management_authority')
18
+ on_premises_last_sync_date_time: PropertyRef = PropertyRef('on_premises_last_sync_date_time')
19
+ on_premises_sync_enabled: PropertyRef = PropertyRef('on_premises_sync_enabled')
20
+ partner_tenant_type: PropertyRef = PropertyRef('partner_tenant_type')
21
+ postal_code: PropertyRef = PropertyRef('postal_code')
22
+ preferred_language: PropertyRef = PropertyRef('preferred_language')
23
+ state: PropertyRef = PropertyRef('state')
24
+ street: PropertyRef = PropertyRef('street')
25
+ tenant_type: PropertyRef = PropertyRef('tenant_type')
26
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class EntraTenantSchema(CartographyNodeSchema):
31
+ label: str = 'AzureTenant'
32
+ properties: EntraTenantNodeProperties = EntraTenantNodeProperties()
33
+ extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(['EntraTenant'])
@@ -0,0 +1,83 @@
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 EntraUserNodeProperties(CartographyNodeProperties):
15
+ id: PropertyRef = PropertyRef('id')
16
+ user_principal_name: PropertyRef = PropertyRef('user_principal_name')
17
+ display_name: PropertyRef = PropertyRef('display_name')
18
+ given_name: PropertyRef = PropertyRef('given_name')
19
+ surname: PropertyRef = PropertyRef('surname')
20
+ # The underlying datatype calls this 'mail' but everything else in cartography uses 'email'
21
+ email: PropertyRef = PropertyRef('mail', extra_index=True)
22
+ other_mails: PropertyRef = PropertyRef('other_mails')
23
+ preferred_language: PropertyRef = PropertyRef('preferred_language')
24
+ preferred_name: PropertyRef = PropertyRef('preferred_name')
25
+ state: PropertyRef = PropertyRef('state')
26
+ usage_location: PropertyRef = PropertyRef('usage_location')
27
+ user_type: PropertyRef = PropertyRef('user_type')
28
+ show_in_address_list: PropertyRef = PropertyRef('show_in_address_list')
29
+ sign_in_sessions_valid_from_date_time: PropertyRef = PropertyRef('sign_in_sessions_valid_from_date_time')
30
+ security_identifier: PropertyRef = PropertyRef('security_identifier')
31
+ account_enabled: PropertyRef = PropertyRef('account_enabled')
32
+ city: PropertyRef = PropertyRef('city')
33
+ company_name: PropertyRef = PropertyRef('company_name')
34
+ consent_provided_for_minor: PropertyRef = PropertyRef('consent_provided_for_minor')
35
+ country: PropertyRef = PropertyRef('country')
36
+ created_date_time: PropertyRef = PropertyRef('created_date_time')
37
+ creation_type: PropertyRef = PropertyRef('creation_type')
38
+ deleted_date_time: PropertyRef = PropertyRef('deleted_date_time')
39
+ department: PropertyRef = PropertyRef('department')
40
+ employee_id: PropertyRef = PropertyRef('employee_id')
41
+ employee_type: PropertyRef = PropertyRef('employee_type')
42
+ external_user_state: PropertyRef = PropertyRef('external_user_state')
43
+ external_user_state_change_date_time: PropertyRef = PropertyRef('external_user_state_change_date_time')
44
+ hire_date: PropertyRef = PropertyRef('hire_date')
45
+ is_management_restricted: PropertyRef = PropertyRef('is_management_restricted')
46
+ is_resource_account: PropertyRef = PropertyRef('is_resource_account')
47
+ job_title: PropertyRef = PropertyRef('job_title')
48
+ last_password_change_date_time: PropertyRef = PropertyRef('last_password_change_date_time')
49
+ mail_nickname: PropertyRef = PropertyRef('mail_nickname')
50
+ office_location: PropertyRef = PropertyRef('office_location')
51
+ on_premises_distinguished_name: PropertyRef = PropertyRef('on_premises_distinguished_name')
52
+ on_premises_domain_name: PropertyRef = PropertyRef('on_premises_domain_name')
53
+ on_premises_immutable_id: PropertyRef = PropertyRef('on_premises_immutable_id')
54
+ on_premises_last_sync_date_time: PropertyRef = PropertyRef('on_premises_last_sync_date_time')
55
+ on_premises_sam_account_name: PropertyRef = PropertyRef('on_premises_sam_account_name')
56
+ on_premises_security_identifier: PropertyRef = PropertyRef('on_premises_security_identifier')
57
+ on_premises_sync_enabled: PropertyRef = PropertyRef('on_premises_sync_enabled')
58
+ on_premises_user_principal_name: PropertyRef = PropertyRef('on_premises_user_principal_name')
59
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
60
+
61
+
62
+ @dataclass(frozen=True)
63
+ class EntraTenantToUserRelProperties(CartographyRelProperties):
64
+ lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
65
+
66
+
67
+ @dataclass(frozen=True)
68
+ # (:EntraUser)<-[:RESOURCE]-(:AzureTenant)
69
+ class EntraUserToTenantRel(CartographyRelSchema):
70
+ target_node_label: str = 'AzureTenant'
71
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
72
+ {'id': PropertyRef('TENANT_ID', set_in_kwargs=True)},
73
+ )
74
+ direction: LinkDirection = LinkDirection.INWARD
75
+ rel_label: str = "RESOURCE"
76
+ properties: EntraTenantToUserRelProperties = EntraTenantToUserRelProperties()
77
+
78
+
79
+ @dataclass(frozen=True)
80
+ class EntraUserSchema(CartographyNodeSchema):
81
+ label: str = 'EntraUser'
82
+ properties: EntraUserNodeProperties = EntraUserNodeProperties()
83
+ sub_resource_relationship: EntraUserToTenantRel = EntraUserToTenantRel()
cartography/sync.py CHANGED
@@ -20,6 +20,7 @@ import cartography.intel.crowdstrike
20
20
  import cartography.intel.cve
21
21
  import cartography.intel.digitalocean
22
22
  import cartography.intel.duo
23
+ import cartography.intel.entra
23
24
  import cartography.intel.gcp
24
25
  import cartography.intel.github
25
26
  import cartography.intel.gsuite
@@ -42,6 +43,7 @@ TOP_LEVEL_MODULES = OrderedDict({ # preserve order so that the default sync alw
42
43
  'create-indexes': cartography.intel.create_indexes.run,
43
44
  'aws': cartography.intel.aws.start_aws_ingestion,
44
45
  'azure': cartography.intel.azure.start_azure_ingestion,
46
+ 'entra': cartography.intel.entra.start_entra_ingestion,
45
47
  'crowdstrike': cartography.intel.crowdstrike.start_crowdstrike_ingestion,
46
48
  'gcp': cartography.intel.gcp.start_gcp_ingestion,
47
49
  'gsuite': cartography.intel.gsuite.start_gsuite_ingestion,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cartography
3
- Version: 0.101.1rc2
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
@@ -47,6 +47,7 @@ Requires-Dist: msrestazure>=0.6.4
47
47
  Requires-Dist: azure-mgmt-storage>=16.0.0
48
48
  Requires-Dist: azure-mgmt-sql<=1.0.0
49
49
  Requires-Dist: azure-identity>=1.5.0
50
+ Requires-Dist: msgraph-sdk
50
51
  Requires-Dist: kubernetes>=22.6.0
51
52
  Requires-Dist: pdpyras>=4.3.0
52
53
  Requires-Dist: crowdstrike-falconpy>=0.5.1
@@ -61,6 +62,7 @@ Requires-Dist: pytest>=6.2.4; extra == "dev"
61
62
  Requires-Dist: pytest-mock; extra == "dev"
62
63
  Requires-Dist: pytest-cov==6.1.1; extra == "dev"
63
64
  Requires-Dist: pytest-rerunfailures; extra == "dev"
65
+ Requires-Dist: pytest-asyncio; extra == "dev"
64
66
  Requires-Dist: types-PyYAML; extra == "dev"
65
67
  Requires-Dist: types-requests<2.32.0.20250329; extra == "dev"
66
68
  Dynamic: license-file
@@ -97,6 +99,7 @@ You can learn more about the story behind Cartography in our [presentation at BS
97
99
  - [GitHub](https://cartography-cncf.github.io/cartography/modules/github/index.html) - repos, branches, users, teams
98
100
  - [DigitalOcean](https://cartography-cncf.github.io/cartography/modules/digitalocean/index.html)
99
101
  - [Microsoft Azure](https://cartography-cncf.github.io/cartography/modules/azure/index.html) - CosmosDB, SQL, Storage, Virtual Machine
102
+ - [Microsoft Entra ID](https://cartography-cncf.github.io/cartography/modules/entra/index.html) - Users
100
103
  - [Kubernetes](https://cartography-cncf.github.io/cartography/modules/kubernetes/index.html) - Cluster, Namespace, Service, Pod, Container
101
104
  - [PagerDuty](https://cartography-cncf.github.io/cartography/modules/pagerduty/index.html) - Users, teams, services, schedules, escalation policies, integrations, vendors
102
105
  - [Crowdstrike Falcon](https://cartography-cncf.github.io/cartography/modules/crowdstrike/index.html) - Hosts, Spotlight vulnerabilities, CVEs