cartography 0.111.0rc1__py3-none-any.whl → 0.112.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 (68) hide show
  1. cartography/_version.py +2 -2
  2. cartography/cli.py +57 -0
  3. cartography/config.py +24 -0
  4. cartography/data/indexes.cypher +0 -2
  5. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  6. cartography/intel/aws/apigateway.py +128 -17
  7. cartography/intel/aws/ec2/instances.py +3 -1
  8. cartography/intel/aws/ec2/network_interfaces.py +1 -1
  9. cartography/intel/aws/ec2/vpc_peerings.py +262 -125
  10. cartography/intel/azure/__init__.py +35 -32
  11. cartography/intel/azure/subscription.py +2 -2
  12. cartography/intel/azure/tenant.py +39 -30
  13. cartography/intel/azure/util/credentials.py +49 -174
  14. cartography/intel/entra/__init__.py +47 -1
  15. cartography/intel/entra/applications.py +220 -170
  16. cartography/intel/entra/groups.py +41 -22
  17. cartography/intel/entra/ou.py +28 -20
  18. cartography/intel/entra/users.py +24 -18
  19. cartography/intel/gcp/__init__.py +25 -8
  20. cartography/intel/gcp/compute.py +47 -12
  21. cartography/intel/github/repos.py +19 -10
  22. cartography/intel/github/util.py +12 -0
  23. cartography/intel/keycloak/__init__.py +153 -0
  24. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  25. cartography/intel/keycloak/authenticationflows.py +77 -0
  26. cartography/intel/keycloak/clients.py +187 -0
  27. cartography/intel/keycloak/groups.py +126 -0
  28. cartography/intel/keycloak/identityproviders.py +94 -0
  29. cartography/intel/keycloak/organizations.py +163 -0
  30. cartography/intel/keycloak/realms.py +61 -0
  31. cartography/intel/keycloak/roles.py +202 -0
  32. cartography/intel/keycloak/scopes.py +73 -0
  33. cartography/intel/keycloak/users.py +70 -0
  34. cartography/intel/keycloak/util.py +47 -0
  35. cartography/intel/kubernetes/__init__.py +26 -0
  36. cartography/intel/kubernetes/eks.py +402 -0
  37. cartography/intel/kubernetes/rbac.py +133 -0
  38. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  39. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  40. cartography/models/aws/ec2/vpc_peering.py +157 -0
  41. cartography/models/azure/principal.py +44 -0
  42. cartography/models/azure/tenant.py +20 -0
  43. cartography/models/keycloak/__init__.py +0 -0
  44. cartography/models/keycloak/authenticationexecution.py +160 -0
  45. cartography/models/keycloak/authenticationflow.py +54 -0
  46. cartography/models/keycloak/client.py +177 -0
  47. cartography/models/keycloak/group.py +101 -0
  48. cartography/models/keycloak/identityprovider.py +89 -0
  49. cartography/models/keycloak/organization.py +116 -0
  50. cartography/models/keycloak/organizationdomain.py +73 -0
  51. cartography/models/keycloak/realm.py +173 -0
  52. cartography/models/keycloak/role.py +126 -0
  53. cartography/models/keycloak/scope.py +73 -0
  54. cartography/models/keycloak/user.py +51 -0
  55. cartography/models/kubernetes/clusterrolebindings.py +40 -0
  56. cartography/models/kubernetes/groups.py +107 -0
  57. cartography/models/kubernetes/oidc.py +51 -0
  58. cartography/models/kubernetes/rolebindings.py +40 -0
  59. cartography/models/kubernetes/users.py +105 -0
  60. cartography/sync.py +2 -0
  61. cartography/util.py +10 -0
  62. {cartography-0.111.0rc1.dist-info → cartography-0.112.0.dist-info}/METADATA +9 -5
  63. {cartography-0.111.0rc1.dist-info → cartography-0.112.0.dist-info}/RECORD +67 -34
  64. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  65. {cartography-0.111.0rc1.dist-info → cartography-0.112.0.dist-info}/WHEEL +0 -0
  66. {cartography-0.111.0rc1.dist-info → cartography-0.112.0.dist-info}/entry_points.txt +0 -0
  67. {cartography-0.111.0rc1.dist-info → cartography-0.112.0.dist-info}/licenses/LICENSE +0 -0
  68. {cartography-0.111.0rc1.dist-info → cartography-0.112.0.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,19 @@
1
1
  import logging
2
+ from typing import Any
2
3
  from typing import Dict
3
4
  from typing import List
5
+ from typing import Tuple
4
6
 
5
7
  import boto3
6
8
  import neo4j
7
9
 
10
+ from cartography.client.core.tx import load
11
+ from cartography.graph.job import GraphJob
12
+ from cartography.models.aws.ec2.vpc import AWSVpcSchema
13
+ from cartography.models.aws.ec2.vpc_cidr import AWSIPv4CidrBlockSchema
14
+ from cartography.models.aws.ec2.vpc_peering import AWSAccountVPCPeeringSchema
15
+ from cartography.models.aws.ec2.vpc_peering import AWSPeeringConnectionSchema
8
16
  from cartography.util import aws_handle_regions
9
- from cartography.util import run_cleanup_job
10
17
  from cartography.util import timeit
11
18
 
12
19
  from .util import get_botocore_config
@@ -29,148 +36,258 @@ def get_vpc_peerings_data(
29
36
 
30
37
 
31
38
  @timeit
32
- def load_vpc_peerings(
39
+ def transform_vpc_peering_data(
40
+ vpc_peerings: List[Dict],
41
+ ) -> Tuple[
42
+ List[Dict[str, Any]],
43
+ List[Dict[str, Any]],
44
+ List[Dict[str, Any]],
45
+ List[Dict[str, Any]],
46
+ ]:
47
+ transformed_peerings: List[Dict[str, Any]] = []
48
+ accepter_cidr_blocks: List[Dict[str, Any]] = []
49
+ requester_cidr_blocks: List[Dict[str, Any]] = []
50
+ vpc_nodes: List[Dict[str, Any]] = []
51
+
52
+ for peering in vpc_peerings:
53
+ accepter_cidr_ids: List[str] = []
54
+ for c_b in peering.get("AccepterVpcInfo", {}).get("CidrBlockSet", []):
55
+ block_id = f"{peering.get('AccepterVpcInfo', {}).get('VpcId')}|{c_b.get('CidrBlock')}"
56
+ accepter_cidr_blocks.append(
57
+ {
58
+ "Id": block_id,
59
+ "VpcId": peering.get("AccepterVpcInfo", {}).get("VpcId"),
60
+ "AssociationId": c_b.get("AssociationId"),
61
+ "CidrBlock": c_b.get("CidrBlock"),
62
+ "BlockState": c_b.get("CidrBlockState", {}).get("State"),
63
+ "BlockStateMessage": c_b.get("CidrBlockState", {}).get(
64
+ "StatusMessage",
65
+ ),
66
+ },
67
+ )
68
+ accepter_cidr_ids.append(block_id)
69
+
70
+ requester_cidr_ids: List[str] = []
71
+ for c_b in peering.get("RequesterVpcInfo", {}).get("CidrBlockSet", []):
72
+ block_id = f"{peering.get('RequesterVpcInfo', {}).get('VpcId')}|{c_b.get('CidrBlock')}"
73
+ requester_cidr_blocks.append(
74
+ {
75
+ "Id": block_id,
76
+ "VpcId": peering.get("RequesterVpcInfo", {}).get("VpcId"),
77
+ "AssociationId": c_b.get("AssociationId"),
78
+ "CidrBlock": c_b.get("CidrBlock"),
79
+ "BlockState": c_b.get("CidrBlockState", {}).get("State"),
80
+ "BlockStateMessage": c_b.get("CidrBlockState", {}).get(
81
+ "StatusMessage",
82
+ ),
83
+ },
84
+ )
85
+ requester_cidr_ids.append(block_id)
86
+
87
+ # Create VPC nodes for accepter and requester VPCs
88
+ accepter_vpc_id = peering.get("AccepterVpcInfo", {}).get("VpcId")
89
+ accepter_owner_id = peering.get("AccepterVpcInfo", {}).get("OwnerId")
90
+ if accepter_vpc_id:
91
+ vpc_nodes.append(
92
+ {
93
+ "VpcId": accepter_vpc_id,
94
+ "PrimaryCIDRBlock": None, # VPCs from peering data don't have complete info
95
+ "InstanceTenancy": None,
96
+ "State": None,
97
+ "IsDefault": None,
98
+ "DhcpOptionsId": None,
99
+ "AccountId": accepter_owner_id, # Account that owns this VPC
100
+ }
101
+ )
102
+
103
+ requester_vpc_id = peering.get("RequesterVpcInfo", {}).get("VpcId")
104
+ requester_owner_id = peering.get("RequesterVpcInfo", {}).get("OwnerId")
105
+ if requester_vpc_id:
106
+ vpc_nodes.append(
107
+ {
108
+ "VpcId": requester_vpc_id,
109
+ "PrimaryCIDRBlock": None, # VPCs from peering data don't have complete info
110
+ "InstanceTenancy": None,
111
+ "State": None,
112
+ "IsDefault": None,
113
+ "DhcpOptionsId": None,
114
+ "AccountId": requester_owner_id, # Account that owns this VPC
115
+ }
116
+ )
117
+
118
+ transformed_peerings.append(
119
+ {
120
+ "VpcPeeringConnectionId": peering.get("VpcPeeringConnectionId"),
121
+ "AllowDnsResolutionFromRemoteVpc": peering.get(
122
+ "RequesterVpcInfo",
123
+ {},
124
+ )
125
+ .get("PeeringOptions", {})
126
+ .get(
127
+ "AllowDnsResolutionFromRemoteVpc",
128
+ ),
129
+ "AllowEgressFromLocalClassicLinkToRemoteVpc": peering.get(
130
+ "RequesterVpcInfo",
131
+ {},
132
+ )
133
+ .get("PeeringOptions", {})
134
+ .get(
135
+ "AllowEgressFromLocalClassicLinkToRemoteVpc",
136
+ ),
137
+ "AllowEgressFromLocalVpcToRemoteClassicLink": peering.get(
138
+ "RequesterVpcInfo",
139
+ {},
140
+ )
141
+ .get("PeeringOptions", {})
142
+ .get(
143
+ "AllowEgressFromLocalVpcToRemoteClassicLink",
144
+ ),
145
+ "RequesterRegion": peering.get("RequesterVpcInfo", {}).get(
146
+ "Region",
147
+ ),
148
+ "AccepterRegion": peering.get("AccepterVpcInfo", {}).get(
149
+ "Region",
150
+ ),
151
+ "StatusCode": peering.get("Status", {}).get("Code"),
152
+ "StatusMessage": peering.get("Status", {}).get("Message"),
153
+ "AccepterVpcId": peering.get("AccepterVpcInfo", {}).get("VpcId"),
154
+ "RequesterVpcId": peering.get("RequesterVpcInfo", {}).get(
155
+ "VpcId",
156
+ ),
157
+ "ACCEPTER_CIDR_BLOCK_IDS": accepter_cidr_ids,
158
+ "REQUESTER_CIDR_BLOCK_IDS": requester_cidr_ids,
159
+ },
160
+ )
161
+
162
+ return transformed_peerings, accepter_cidr_blocks, requester_cidr_blocks, vpc_nodes
163
+
164
+
165
+ @timeit
166
+ def transform_aws_accounts_from_vpc_peering(
167
+ vpc_peerings: List[Dict],
168
+ ) -> List[Dict[str, Any]]:
169
+ """
170
+ Transform VPC peering data to extract AWS account information.
171
+ Creates composite AWS account nodes with context from VPC peering.
172
+ """
173
+ account_data: Dict[str, Dict[str, Any]] = {}
174
+
175
+ for peering in vpc_peerings:
176
+ # Extract accepter account
177
+ accepter_owner_id = peering.get("AccepterVpcInfo", {}).get("OwnerId")
178
+ if accepter_owner_id:
179
+ account_data[accepter_owner_id] = {
180
+ "id": accepter_owner_id,
181
+ }
182
+
183
+ # Extract requester account
184
+ requester_owner_id = peering.get("RequesterVpcInfo", {}).get("OwnerId")
185
+ if requester_owner_id:
186
+ account_data[requester_owner_id] = {
187
+ "id": requester_owner_id,
188
+ }
189
+
190
+ return list(account_data.values())
191
+
192
+
193
+ @timeit
194
+ def load_accepter_cidrs(
33
195
  neo4j_session: neo4j.Session,
34
- data: List[Dict],
196
+ accepter_cidrs: List[Dict[str, Any]],
35
197
  region: str,
36
198
  aws_account_id: str,
37
199
  update_tag: int,
38
200
  ) -> None:
39
- ingest_vpc_peerings = """
40
- UNWIND $vpc_peerings AS vpc_peering
41
-
42
- MERGE (pcx:AWSPeeringConnection{id: vpc_peering.VpcPeeringConnectionId})
43
- ON CREATE SET pcx.firstseen = timestamp()
44
- SET pcx.lastupdated = $update_tag,
45
- pcx.allow_dns_resolution_from_remote_vpc =
46
- vpc_peering.RequesterVpcInfo.PeeringOptions.AllowDnsResolutionFromRemoteVpc,
47
- pcx.allow_egress_from_local_classic_link_to_remote_vpc =
48
- vpc_peering.RequesterVpcInfo.PeeringOptions.AllowEgressFromLocalClassicLinkToRemoteVpc,
49
- pcx.allow_egress_from_local_vpc_to_remote_classic_link =
50
- vpc_peering.RequesterVpcInfo.PeeringOptions.AllowEgressFromLocalVpcToRemoteClassicLink,
51
- pcx.requester_region = vpc_peering.RequesterVpcInfo.Region,
52
- pcx.accepter_region = vpc_peering.AccepterVpcInfo.Region,
53
- pcx.status_code = vpc_peering.Status.Code,
54
- pcx.status_message = vpc_peering.Status.Message
55
-
56
- MERGE (avpc:AWSVpc{id: vpc_peering.AccepterVpcInfo.VpcId})
57
- ON CREATE SET avpc.firstseen = timestamp()
58
- SET avpc.lastupdated = $update_tag, avpc.vpcid = vpc_peering.AccepterVpcInfo.VpcId
59
-
60
- MERGE (rvpc:AWSVpc{id: vpc_peering.RequesterVpcInfo.VpcId})
61
- ON CREATE SET rvpc.firstseen = timestamp()
62
- SET rvpc.lastupdated = $update_tag, rvpc.vpcid = vpc_peering.RequesterVpcInfo.VpcId
63
-
64
- MERGE (aaccount:AWSAccount{id: vpc_peering.AccepterVpcInfo.OwnerId})
65
- ON CREATE SET aaccount.firstseen = timestamp()
66
- SET aaccount.lastupdated = $update_tag
67
-
68
- MERGE (raccount:AWSAccount{id: vpc_peering.RequesterVpcInfo.OwnerId})
69
- ON CREATE SET raccount.firstseen = timestamp()
70
- SET raccount.lastupdated = $update_tag
71
-
72
- MERGE (pcx)-[rav:ACCEPTER_VPC]->(avpc)
73
- ON CREATE SET rav.firstseen = timestamp()
74
- SET rav.lastupdated = $update_tag
75
-
76
- MERGE (aaccount)-[ra:RESOURCE]->(avpc)
77
- ON CREATE SET ra.firstseen = timestamp()
78
- SET ra.lastupdated = $update_tag
79
-
80
- MERGE (pcx)-[rrv:REQUESTER_VPC]->(rvpc)
81
- ON CREATE SET rrv.firstseen = timestamp()
82
- SET rrv.lastupdated = $update_tag
83
-
84
- MERGE (raccount)-[rr:RESOURCE]->(rvpc)
85
- ON CREATE SET rr.firstseen = timestamp()
86
- SET rr.lastupdated = $update_tag
87
-
88
- """
89
-
90
- neo4j_session.run(
91
- ingest_vpc_peerings,
92
- vpc_peerings=data,
93
- update_tag=update_tag,
94
- region=region,
95
- aws_account_id=aws_account_id,
201
+ load(
202
+ neo4j_session,
203
+ AWSIPv4CidrBlockSchema(),
204
+ accepter_cidrs,
205
+ lastupdated=update_tag,
96
206
  )
97
207
 
98
208
 
99
209
  @timeit
100
- def load_accepter_cidrs(
210
+ def load_requester_cidrs(
101
211
  neo4j_session: neo4j.Session,
102
- data: List[Dict],
212
+ requester_cidrs: List[Dict[str, Any]],
103
213
  region: str,
104
214
  aws_account_id: str,
105
215
  update_tag: int,
106
216
  ) -> None:
217
+ load(
218
+ neo4j_session,
219
+ AWSIPv4CidrBlockSchema(),
220
+ requester_cidrs,
221
+ lastupdated=update_tag,
222
+ )
107
223
 
108
- ingest_accepter_cidr = """
109
- UNWIND $vpc_peerings AS vpc_peering
110
- UNWIND vpc_peering.AccepterVpcInfo.CidrBlockSet AS c_b
111
-
112
- MERGE (ac_b:AWSCidrBlock:AWSIpv4CidrBlock{id: vpc_peering.AccepterVpcInfo.VpcId + '|' + c_b.CidrBlock})
113
- ON CREATE SET ac_b.firstseen = timestamp()
114
- SET ac_b.lastupdated = $update_tag, ac_b.cidr_block = c_b.CidrBlock
115
-
116
- WITH vpc_peering, ac_b
117
- MATCH (pcx:AWSPeeringConnection{id: vpc_peering.VpcPeeringConnectionId}), (cb:AWSCidrBlock{id: ac_b.id})
118
- MERGE (pcx)-[r:ACCEPTER_CIDR]->(cb)
119
- ON CREATE SET r.firstseen = timestamp()
120
- SET r.lastupdated = $update_tag
121
-
122
- WITH vpc_peering, ac_b
123
- MATCH (vpc:AWSVpc{id: vpc_peering.AccepterVpcInfo.VpcId}), (cb:AWSCidrBlock{id: ac_b.id})
124
- MERGE (vpc)-[r:BLOCK_ASSOCIATION]->(cb)
125
- ON CREATE SET r.firstseen = timestamp()
126
- SET r.lastupdated = $update_tag
127
- """
128
224
 
129
- neo4j_session.run(
130
- ingest_accepter_cidr,
131
- vpc_peerings=data,
132
- update_tag=update_tag,
133
- region=region,
134
- aws_account_id=aws_account_id,
225
+ @timeit
226
+ def load_aws_accounts_from_vpc_peering(
227
+ neo4j_session: neo4j.Session,
228
+ aws_accounts: List[Dict[str, Any]],
229
+ update_tag: int,
230
+ ) -> None:
231
+ """
232
+ Load AWS account nodes using the composite schema.
233
+ This allows VPC peering data to provide additional context about AWS accounts.
234
+ """
235
+ load(
236
+ neo4j_session,
237
+ AWSAccountVPCPeeringSchema(),
238
+ aws_accounts,
239
+ lastupdated=update_tag,
135
240
  )
136
241
 
137
242
 
138
243
  @timeit
139
- def load_requester_cidrs(
244
+ def load_vpc_nodes(
140
245
  neo4j_session: neo4j.Session,
141
- data: List[Dict],
246
+ vpc_nodes: List[Dict[str, Any]],
142
247
  region: str,
143
248
  aws_account_id: str,
144
249
  update_tag: int,
145
250
  ) -> None:
251
+ # Group VPC nodes by their actual account ID
252
+ vpc_nodes_by_account: Dict[str, List[Dict[str, Any]]] = {}
253
+ for vpc in vpc_nodes:
254
+ account_id = vpc.get(
255
+ "AccountId", aws_account_id
256
+ ) # Use VPC's own account or fallback
257
+ if account_id not in vpc_nodes_by_account:
258
+ vpc_nodes_by_account[account_id] = []
259
+ vpc_nodes_by_account[account_id].append(vpc)
260
+
261
+ # Load VPCs for each account separately
262
+ for account_id, account_vpc_nodes in vpc_nodes_by_account.items():
263
+ # Remove the AccountId field as it's not part of the VPC schema
264
+ for vpc in account_vpc_nodes:
265
+ vpc.pop("AccountId", None)
266
+
267
+ load(
268
+ neo4j_session,
269
+ AWSVpcSchema(),
270
+ account_vpc_nodes,
271
+ lastupdated=update_tag,
272
+ AWS_ID=account_id,
273
+ Region=region,
274
+ )
146
275
 
147
- ingest_requester_cidr = """
148
- UNWIND $vpc_peerings AS vpc_peering
149
- UNWIND vpc_peering.RequesterVpcInfo.CidrBlockSet AS c_b
150
-
151
- MERGE (rc_b:AWSCidrBlock:AWSIpv4CidrBlock{id: vpc_peering.RequesterVpcInfo.VpcId + '|' + c_b.CidrBlock})
152
- ON CREATE SET rc_b.firstseen = timestamp()
153
- SET rc_b.lastupdated = $update_tag, rc_b.cidr_block = c_b.CidrBlock
154
-
155
- WITH vpc_peering, rc_b
156
- MATCH (pcx:AWSPeeringConnection{id: vpc_peering.VpcPeeringConnectionId}), (cb:AWSCidrBlock{id: rc_b.id})
157
- MERGE (pcx)-[r:REQUESTER_CIDR]->(cb)
158
- ON CREATE SET r.firstseen = timestamp()
159
- SET r.lastupdated = $update_tag
160
-
161
- WITH vpc_peering, rc_b
162
- MATCH (vpc:AWSVpc{id: vpc_peering.RequesterVpcInfo.VpcId}), (cb:AWSCidrBlock{id: rc_b.id})
163
- MERGE (vpc)-[r:BLOCK_ASSOCIATION]->(cb)
164
- ON CREATE SET r.firstseen = timestamp()
165
- SET r.lastupdated = $update_tag
166
- """
167
276
 
168
- neo4j_session.run(
169
- ingest_requester_cidr,
170
- vpc_peerings=data,
171
- update_tag=update_tag,
172
- region=region,
173
- aws_account_id=aws_account_id,
277
+ @timeit
278
+ def load_vpc_peerings(
279
+ neo4j_session: neo4j.Session,
280
+ vpc_peerings: List[Dict[str, Any]],
281
+ region: str,
282
+ aws_account_id: str,
283
+ update_tag: int,
284
+ ) -> None:
285
+ load(
286
+ neo4j_session,
287
+ AWSPeeringConnectionSchema(),
288
+ vpc_peerings,
289
+ lastupdated=update_tag,
290
+ AWS_ID=aws_account_id,
174
291
  )
175
292
 
176
293
 
@@ -179,11 +296,10 @@ def cleanup_vpc_peerings(
179
296
  neo4j_session: neo4j.Session,
180
297
  common_job_parameters: Dict,
181
298
  ) -> None:
182
- run_cleanup_job(
183
- "aws_import_vpc_peering_cleanup.json",
184
- neo4j_session,
299
+ GraphJob.from_node_schema(
300
+ AWSPeeringConnectionSchema(),
185
301
  common_job_parameters,
186
- )
302
+ ).run(neo4j_session)
187
303
 
188
304
 
189
305
  @timeit
@@ -201,24 +317,45 @@ def sync_vpc_peerings(
201
317
  region,
202
318
  current_aws_account_id,
203
319
  )
204
- data = get_vpc_peerings_data(boto3_session, region)
205
- load_vpc_peerings(
320
+ raw_data = get_vpc_peerings_data(boto3_session, region)
321
+ vpc_peerings, accepter_cidrs, requester_cidrs, vpc_nodes = (
322
+ transform_vpc_peering_data(
323
+ raw_data,
324
+ )
325
+ )
326
+ aws_accounts = transform_aws_accounts_from_vpc_peering(raw_data)
327
+
328
+ # Load AWS accounts first (composite pattern)
329
+ load_aws_accounts_from_vpc_peering(
330
+ neo4j_session,
331
+ aws_accounts,
332
+ update_tag,
333
+ )
334
+
335
+ load_vpc_nodes(
206
336
  neo4j_session,
207
- data,
337
+ vpc_nodes,
208
338
  region,
209
339
  current_aws_account_id,
210
340
  update_tag,
211
341
  )
212
342
  load_accepter_cidrs(
213
343
  neo4j_session,
214
- data,
344
+ accepter_cidrs,
215
345
  region,
216
346
  current_aws_account_id,
217
347
  update_tag,
218
348
  )
219
349
  load_requester_cidrs(
220
350
  neo4j_session,
221
- data,
351
+ requester_cidrs,
352
+ region,
353
+ current_aws_account_id,
354
+ update_tag,
355
+ )
356
+ load_vpc_peerings(
357
+ neo4j_session,
358
+ vpc_peerings,
222
359
  region,
223
360
  current_aws_account_id,
224
361
  update_tag,
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  from typing import Dict
3
3
  from typing import List
4
- from typing import Optional
5
4
 
6
5
  import neo4j
7
6
 
@@ -29,28 +28,28 @@ def _sync_one_subscription(
29
28
  ) -> None:
30
29
  compute.sync(
31
30
  neo4j_session,
32
- credentials.arm_credentials,
31
+ credentials.credential,
33
32
  subscription_id,
34
33
  update_tag,
35
34
  common_job_parameters,
36
35
  )
37
36
  cosmosdb.sync(
38
37
  neo4j_session,
39
- credentials.arm_credentials,
38
+ credentials.credential,
40
39
  subscription_id,
41
40
  update_tag,
42
41
  common_job_parameters,
43
42
  )
44
43
  sql.sync(
45
44
  neo4j_session,
46
- credentials.arm_credentials,
45
+ credentials.credential,
47
46
  subscription_id,
48
47
  update_tag,
49
48
  common_job_parameters,
50
49
  )
51
50
  storage.sync(
52
51
  neo4j_session,
53
- credentials.arm_credentials,
52
+ credentials.credential,
54
53
  subscription_id,
55
54
  update_tag,
56
55
  common_job_parameters,
@@ -59,13 +58,12 @@ def _sync_one_subscription(
59
58
 
60
59
  def _sync_tenant(
61
60
  neo4j_session: neo4j.Session,
62
- tenant_id: str,
63
- current_user: Optional[str],
61
+ credentials: Credentials,
64
62
  update_tag: int,
65
63
  common_job_parameters: Dict,
66
64
  ) -> None:
67
- logger.info("Syncing Azure Tenant: %s", tenant_id)
68
- tenant.sync(neo4j_session, tenant_id, current_user, update_tag, common_job_parameters) # type: ignore
65
+ logger.info("Syncing Azure Tenant: %s", credentials.tenant_id)
66
+ tenant.sync(neo4j_session, credentials.tenant_id, None, update_tag, common_job_parameters) # type: ignore
69
67
 
70
68
 
71
69
  def _sync_multiple_subscriptions(
@@ -122,40 +120,45 @@ def start_azure_ingestion(neo4j_session: neo4j.Session, config: Config) -> None:
122
120
  logger.error(
123
121
  (
124
122
  "Unable to authenticate with Azure Service Principal, an error occurred: %s."
125
- "Make sure your Azure Service Principal details are provided correctly."
123
+ "Make sure your credentials (CLI or Service Principal) are configured correctly."
126
124
  ),
127
125
  e,
128
126
  )
129
127
  return
130
128
 
129
+ if not credentials:
130
+ return
131
+
132
+ common_job_parameters["TENANT_ID"] = credentials.tenant_id
133
+
131
134
  _sync_tenant(
132
135
  neo4j_session,
133
- credentials.get_tenant_id(),
134
- credentials.get_current_user(),
136
+ credentials,
135
137
  config.update_tag,
136
138
  common_job_parameters,
137
139
  )
140
+ if credentials.tenant_id:
141
+ if config.azure_sync_all_subscriptions:
142
+ subscriptions = subscription.get_all_azure_subscriptions(credentials)
138
143
 
139
- if config.azure_sync_all_subscriptions:
140
- subscriptions = subscription.get_all_azure_subscriptions(credentials)
144
+ else:
145
+ sub_id_to_sync = config.azure_subscription_id or credentials.subscription_id
146
+ subscriptions = subscription.get_current_azure_subscription(
147
+ credentials,
148
+ sub_id_to_sync,
149
+ )
141
150
 
142
- else:
143
- subscriptions = subscription.get_current_azure_subscription(
144
- credentials,
145
- credentials.subscription_id,
146
- )
151
+ if not subscriptions:
152
+ logger.warning(
153
+ "No valid Azure credentials are found. No Azure subscriptions can be synced. Exiting Azure sync stage.",
154
+ )
155
+ return
147
156
 
148
- if not subscriptions:
149
- logger.warning(
150
- "No valid Azure credentials are found. No Azure subscriptions can be synced. Exiting Azure sync stage.",
157
+ _sync_multiple_subscriptions(
158
+ neo4j_session,
159
+ credentials,
160
+ credentials.tenant_id,
161
+ subscriptions,
162
+ config.update_tag,
163
+ common_job_parameters,
151
164
  )
152
- return
153
-
154
- _sync_multiple_subscriptions(
155
- neo4j_session,
156
- credentials,
157
- credentials.get_tenant_id(),
158
- subscriptions,
159
- config.update_tag,
160
- common_job_parameters,
161
- )
@@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
18
18
  def get_all_azure_subscriptions(credentials: Credentials) -> List[Dict]:
19
19
  try:
20
20
  # Create the client
21
- client = SubscriptionClient(credentials.arm_credentials)
21
+ client = SubscriptionClient(credentials.credential)
22
22
 
23
23
  # Get all the accessible subscriptions
24
24
  subs = list(client.subscriptions.list())
@@ -52,7 +52,7 @@ def get_current_azure_subscription(
52
52
  ) -> List[Dict]:
53
53
  try:
54
54
  # Create the client
55
- client = SubscriptionClient(credentials.arm_credentials)
55
+ client = SubscriptionClient(credentials.credential)
56
56
 
57
57
  # Get all the accessible subscriptions
58
58
  sub = client.subscriptions.get(subscription_id)