cartography 0.102.0rc2__py3-none-any.whl → 0.103.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.

Files changed (251) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +2 -2
  3. cartography/cli.py +302 -253
  4. cartography/client/core/tx.py +39 -18
  5. cartography/config.py +4 -0
  6. cartography/driftdetect/__main__.py +1 -2
  7. cartography/driftdetect/add_shortcut.py +10 -2
  8. cartography/driftdetect/cli.py +71 -75
  9. cartography/driftdetect/detect_deviations.py +7 -3
  10. cartography/driftdetect/get_states.py +20 -8
  11. cartography/driftdetect/model.py +5 -5
  12. cartography/driftdetect/serializers.py +8 -6
  13. cartography/driftdetect/storage.py +2 -2
  14. cartography/graph/cleanupbuilder.py +35 -15
  15. cartography/graph/job.py +46 -17
  16. cartography/graph/querybuilder.py +165 -80
  17. cartography/graph/statement.py +35 -26
  18. cartography/intel/analysis.py +4 -1
  19. cartography/intel/aws/__init__.py +114 -55
  20. cartography/intel/aws/apigateway.py +134 -63
  21. cartography/intel/aws/cloudtrail.py +127 -0
  22. cartography/intel/aws/config.py +56 -20
  23. cartography/intel/aws/dynamodb.py +108 -40
  24. cartography/intel/aws/ec2/__init__.py +2 -2
  25. cartography/intel/aws/ec2/auto_scaling_groups.py +181 -78
  26. cartography/intel/aws/ec2/elastic_ip_addresses.py +41 -13
  27. cartography/intel/aws/ec2/images.py +49 -20
  28. cartography/intel/aws/ec2/instances.py +234 -136
  29. cartography/intel/aws/ec2/internet_gateways.py +40 -11
  30. cartography/intel/aws/ec2/key_pairs.py +44 -20
  31. cartography/intel/aws/ec2/launch_templates.py +101 -59
  32. cartography/intel/aws/ec2/load_balancer_v2s.py +104 -39
  33. cartography/intel/aws/ec2/load_balancers.py +82 -42
  34. cartography/intel/aws/ec2/network_acls.py +89 -65
  35. cartography/intel/aws/ec2/network_interfaces.py +146 -87
  36. cartography/intel/aws/ec2/reserved_instances.py +45 -16
  37. cartography/intel/aws/ec2/route_tables.py +138 -98
  38. cartography/intel/aws/ec2/security_groups.py +71 -21
  39. cartography/intel/aws/ec2/snapshots.py +61 -22
  40. cartography/intel/aws/ec2/subnets.py +54 -18
  41. cartography/intel/aws/ec2/tgw.py +100 -34
  42. cartography/intel/aws/ec2/util.py +1 -1
  43. cartography/intel/aws/ec2/volumes.py +69 -41
  44. cartography/intel/aws/ec2/vpc.py +37 -12
  45. cartography/intel/aws/ec2/vpc_peerings.py +83 -24
  46. cartography/intel/aws/ecr.py +88 -32
  47. cartography/intel/aws/ecs.py +83 -47
  48. cartography/intel/aws/eks.py +55 -29
  49. cartography/intel/aws/elasticache.py +42 -18
  50. cartography/intel/aws/elasticsearch.py +57 -20
  51. cartography/intel/aws/emr.py +61 -23
  52. cartography/intel/aws/iam.py +401 -145
  53. cartography/intel/aws/iam_instance_profiles.py +22 -22
  54. cartography/intel/aws/identitycenter.py +71 -37
  55. cartography/intel/aws/inspector.py +159 -89
  56. cartography/intel/aws/kms.py +92 -38
  57. cartography/intel/aws/lambda_function.py +103 -34
  58. cartography/intel/aws/organizations.py +30 -10
  59. cartography/intel/aws/permission_relationships.py +133 -51
  60. cartography/intel/aws/rds.py +249 -85
  61. cartography/intel/aws/redshift.py +107 -46
  62. cartography/intel/aws/resourcegroupstaggingapi.py +120 -66
  63. cartography/intel/aws/resources.py +53 -46
  64. cartography/intel/aws/route53.py +108 -61
  65. cartography/intel/aws/s3.py +168 -83
  66. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  67. cartography/intel/aws/secretsmanager.py +24 -12
  68. cartography/intel/aws/securityhub.py +20 -9
  69. cartography/intel/aws/sns.py +166 -0
  70. cartography/intel/aws/sqs.py +60 -28
  71. cartography/intel/aws/ssm.py +70 -30
  72. cartography/intel/aws/util/arns.py +7 -7
  73. cartography/intel/aws/util/common.py +31 -4
  74. cartography/intel/azure/__init__.py +78 -19
  75. cartography/intel/azure/compute.py +101 -27
  76. cartography/intel/azure/cosmosdb.py +496 -170
  77. cartography/intel/azure/sql.py +296 -105
  78. cartography/intel/azure/storage.py +322 -113
  79. cartography/intel/azure/subscription.py +39 -23
  80. cartography/intel/azure/tenant.py +13 -4
  81. cartography/intel/azure/util/credentials.py +95 -55
  82. cartography/intel/bigfix/__init__.py +2 -2
  83. cartography/intel/bigfix/computers.py +93 -65
  84. cartography/intel/create_indexes.py +3 -2
  85. cartography/intel/crowdstrike/__init__.py +11 -9
  86. cartography/intel/crowdstrike/endpoints.py +5 -1
  87. cartography/intel/crowdstrike/spotlight.py +8 -3
  88. cartography/intel/cve/__init__.py +46 -13
  89. cartography/intel/cve/feed.py +48 -12
  90. cartography/intel/digitalocean/__init__.py +22 -13
  91. cartography/intel/digitalocean/compute.py +75 -108
  92. cartography/intel/digitalocean/management.py +44 -80
  93. cartography/intel/digitalocean/platform.py +48 -43
  94. cartography/intel/dns.py +36 -10
  95. cartography/intel/duo/__init__.py +21 -16
  96. cartography/intel/duo/api_host.py +14 -9
  97. cartography/intel/duo/endpoints.py +50 -45
  98. cartography/intel/duo/groups.py +18 -14
  99. cartography/intel/duo/phones.py +37 -34
  100. cartography/intel/duo/tokens.py +26 -23
  101. cartography/intel/duo/users.py +54 -50
  102. cartography/intel/duo/web_authn_credentials.py +30 -25
  103. cartography/intel/entra/__init__.py +25 -7
  104. cartography/intel/entra/ou.py +112 -0
  105. cartography/intel/entra/users.py +69 -63
  106. cartography/intel/gcp/__init__.py +185 -49
  107. cartography/intel/gcp/compute.py +418 -231
  108. cartography/intel/gcp/crm.py +96 -43
  109. cartography/intel/gcp/dns.py +60 -19
  110. cartography/intel/gcp/gke.py +72 -38
  111. cartography/intel/gcp/iam.py +61 -41
  112. cartography/intel/gcp/storage.py +84 -55
  113. cartography/intel/github/__init__.py +13 -11
  114. cartography/intel/github/repos.py +270 -137
  115. cartography/intel/github/teams.py +170 -88
  116. cartography/intel/github/users.py +70 -39
  117. cartography/intel/github/util.py +36 -34
  118. cartography/intel/gsuite/__init__.py +47 -26
  119. cartography/intel/gsuite/api.py +73 -30
  120. cartography/intel/jamf/__init__.py +19 -1
  121. cartography/intel/jamf/computers.py +30 -7
  122. cartography/intel/jamf/util.py +7 -2
  123. cartography/intel/kandji/__init__.py +6 -3
  124. cartography/intel/kandji/devices.py +14 -8
  125. cartography/intel/kubernetes/namespaces.py +7 -4
  126. cartography/intel/kubernetes/pods.py +7 -4
  127. cartography/intel/kubernetes/services.py +8 -4
  128. cartography/intel/lastpass/__init__.py +2 -2
  129. cartography/intel/lastpass/users.py +23 -12
  130. cartography/intel/oci/__init__.py +44 -11
  131. cartography/intel/oci/iam.py +134 -38
  132. cartography/intel/oci/organizations.py +13 -6
  133. cartography/intel/oci/utils.py +43 -20
  134. cartography/intel/okta/__init__.py +66 -15
  135. cartography/intel/okta/applications.py +42 -20
  136. cartography/intel/okta/awssaml.py +93 -33
  137. cartography/intel/okta/factors.py +16 -4
  138. cartography/intel/okta/groups.py +56 -29
  139. cartography/intel/okta/organization.py +5 -1
  140. cartography/intel/okta/origins.py +6 -2
  141. cartography/intel/okta/roles.py +15 -5
  142. cartography/intel/okta/users.py +20 -8
  143. cartography/intel/okta/utils.py +6 -4
  144. cartography/intel/pagerduty/__init__.py +8 -7
  145. cartography/intel/pagerduty/escalation_policies.py +18 -6
  146. cartography/intel/pagerduty/schedules.py +12 -4
  147. cartography/intel/pagerduty/services.py +11 -4
  148. cartography/intel/pagerduty/teams.py +8 -3
  149. cartography/intel/pagerduty/users.py +3 -1
  150. cartography/intel/pagerduty/vendors.py +3 -1
  151. cartography/intel/semgrep/__init__.py +24 -6
  152. cartography/intel/semgrep/dependencies.py +50 -28
  153. cartography/intel/semgrep/deployment.py +3 -1
  154. cartography/intel/semgrep/findings.py +42 -18
  155. cartography/intel/snipeit/__init__.py +17 -3
  156. cartography/intel/snipeit/asset.py +12 -6
  157. cartography/intel/snipeit/user.py +8 -5
  158. cartography/intel/snipeit/util.py +9 -4
  159. cartography/models/aws/apigateway.py +21 -17
  160. cartography/models/aws/apigatewaycertificate.py +28 -22
  161. cartography/models/aws/apigatewayresource.py +28 -20
  162. cartography/models/aws/apigatewaystage.py +33 -25
  163. cartography/models/aws/cloudtrail/__init__.py +0 -0
  164. cartography/models/aws/cloudtrail/trail.py +61 -0
  165. cartography/models/aws/dynamodb/gsi.py +30 -22
  166. cartography/models/aws/dynamodb/tables.py +25 -17
  167. cartography/models/aws/ec2/auto_scaling_groups.py +102 -82
  168. cartography/models/aws/ec2/images.py +36 -34
  169. cartography/models/aws/ec2/instances.py +51 -45
  170. cartography/models/aws/ec2/keypair.py +21 -16
  171. cartography/models/aws/ec2/keypair_instance.py +28 -21
  172. cartography/models/aws/ec2/launch_configurations.py +30 -26
  173. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  174. cartography/models/aws/ec2/launch_templates.py +21 -17
  175. cartography/models/aws/ec2/load_balancer_listeners.py +27 -23
  176. cartography/models/aws/ec2/load_balancers.py +47 -37
  177. cartography/models/aws/ec2/network_acl_rules.py +38 -30
  178. cartography/models/aws/ec2/network_acls.py +38 -29
  179. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  180. cartography/models/aws/ec2/networkinterfaces.py +53 -37
  181. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  182. cartography/models/aws/ec2/reservations.py +18 -14
  183. cartography/models/aws/ec2/route_table_associations.py +44 -34
  184. cartography/models/aws/ec2/route_tables.py +50 -43
  185. cartography/models/aws/ec2/routes.py +45 -37
  186. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  187. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  188. cartography/models/aws/ec2/subnet_instance.py +24 -19
  189. cartography/models/aws/ec2/subnet_networkinterface.py +40 -31
  190. cartography/models/aws/ec2/volumes.py +47 -40
  191. cartography/models/aws/eks/clusters.py +23 -21
  192. cartography/models/aws/emr.py +32 -30
  193. cartography/models/aws/iam/instanceprofile.py +33 -24
  194. cartography/models/aws/identitycenter/awsidentitycenter.py +18 -14
  195. cartography/models/aws/identitycenter/awspermissionset.py +37 -29
  196. cartography/models/aws/identitycenter/awsssouser.py +23 -21
  197. cartography/models/aws/inspector/findings.py +77 -65
  198. cartography/models/aws/inspector/packages.py +35 -29
  199. cartography/models/aws/s3/__init__.py +0 -0
  200. cartography/models/aws/s3/account_public_access_block.py +51 -0
  201. cartography/models/aws/sns/__init__.py +0 -0
  202. cartography/models/aws/sns/topic.py +50 -0
  203. cartography/models/aws/ssm/instance_information.py +51 -39
  204. cartography/models/aws/ssm/instance_patch.py +32 -26
  205. cartography/models/bigfix/bigfix_computer.py +42 -38
  206. cartography/models/bigfix/bigfix_root.py +3 -3
  207. cartography/models/core/common.py +12 -10
  208. cartography/models/core/nodes.py +5 -2
  209. cartography/models/core/relationships.py +14 -6
  210. cartography/models/crowdstrike/hosts.py +37 -35
  211. cartography/models/cve/cve.py +34 -32
  212. cartography/models/cve/cve_feed.py +6 -6
  213. cartography/models/digitalocean/__init__.py +0 -0
  214. cartography/models/digitalocean/account.py +21 -0
  215. cartography/models/digitalocean/droplet.py +56 -0
  216. cartography/models/digitalocean/project.py +48 -0
  217. cartography/models/duo/api_host.py +3 -3
  218. cartography/models/duo/endpoint.py +43 -41
  219. cartography/models/duo/group.py +14 -14
  220. cartography/models/duo/phone.py +27 -27
  221. cartography/models/duo/token.py +16 -16
  222. cartography/models/duo/user.py +46 -44
  223. cartography/models/duo/web_authn_credential.py +27 -19
  224. cartography/models/entra/ou.py +48 -0
  225. cartography/models/entra/tenant.py +24 -18
  226. cartography/models/entra/user.py +64 -48
  227. cartography/models/gcp/iam.py +23 -23
  228. cartography/models/github/orgs.py +5 -4
  229. cartography/models/github/teams.py +37 -31
  230. cartography/models/github/users.py +34 -23
  231. cartography/models/kandji/device.py +22 -16
  232. cartography/models/kandji/tenant.py +6 -4
  233. cartography/models/lastpass/tenant.py +3 -3
  234. cartography/models/lastpass/user.py +32 -28
  235. cartography/models/semgrep/dependencies.py +36 -24
  236. cartography/models/semgrep/deployment.py +5 -5
  237. cartography/models/semgrep/findings.py +58 -42
  238. cartography/models/semgrep/locations.py +27 -21
  239. cartography/models/snipeit/asset.py +30 -21
  240. cartography/models/snipeit/tenant.py +6 -4
  241. cartography/models/snipeit/user.py +19 -12
  242. cartography/stats.py +3 -3
  243. cartography/sync.py +107 -31
  244. cartography/util.py +84 -62
  245. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/METADATA +3 -14
  246. cartography-0.103.0rc1.dist-info/RECORD +396 -0
  247. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/WHEEL +1 -1
  248. cartography-0.102.0rc2.dist-info/RECORD +0 -381
  249. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/entry_points.txt +0 -0
  250. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/licenses/LICENSE +0 -0
  251. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/top_level.txt +0 -0
@@ -14,10 +14,11 @@ from azure.mgmt.sql.models import SecurityAlertPolicyName
14
14
  from azure.mgmt.sql.models import TransparentDataEncryptionName
15
15
  from msrestazure.azure_exceptions import CloudError
16
16
 
17
- from .util.credentials import Credentials
18
17
  from cartography.util import run_cleanup_job
19
18
  from cartography.util import timeit
20
19
 
20
+ from .util.credentials import Credentials
21
+
21
22
  logger = logging.getLogger(__name__)
22
23
 
23
24
 
@@ -51,16 +52,18 @@ def get_server_list(credentials: Credentials, subscription_id: str) -> List[Dict
51
52
  return []
52
53
 
53
54
  for server in server_list:
54
- x = server['id'].split('/')
55
- server['resourceGroup'] = x[x.index('resourceGroups') + 1]
55
+ x = server["id"].split("/")
56
+ server["resourceGroup"] = x[x.index("resourceGroups") + 1]
56
57
 
57
58
  return server_list
58
59
 
59
60
 
60
61
  @timeit
61
62
  def load_server_data(
62
- neo4j_session: neo4j.Session, subscription_id: str, server_list: List[Dict],
63
- azure_update_tag: int,
63
+ neo4j_session: neo4j.Session,
64
+ subscription_id: str,
65
+ server_list: List[Dict],
66
+ azure_update_tag: int,
64
67
  ) -> None:
65
68
  """
66
69
  Ingest the server details into neo4j.
@@ -92,8 +95,11 @@ def load_server_data(
92
95
 
93
96
  @timeit
94
97
  def sync_server_details(
95
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
96
- server_list: List[Dict], sync_tag: int,
98
+ neo4j_session: neo4j.Session,
99
+ credentials: Credentials,
100
+ subscription_id: str,
101
+ server_list: List[Dict],
102
+ sync_tag: int,
97
103
  ) -> None:
98
104
  details = get_server_details(credentials, subscription_id, server_list)
99
105
  load_server_details(neo4j_session, credentials, subscription_id, details, sync_tag) # type: ignore
@@ -101,7 +107,9 @@ def sync_server_details(
101
107
 
102
108
  @timeit
103
109
  def get_server_details(
104
- credentials: Credentials, subscription_id: str, server_list: List[Dict],
110
+ credentials: Credentials,
111
+ subscription_id: str,
112
+ server_list: List[Dict],
105
113
  ) -> Generator[Any, Any, Any]:
106
114
  """
107
115
  Iterate over each servers to get its resource details.
@@ -110,17 +118,25 @@ def get_server_details(
110
118
  dns_alias = get_dns_aliases(credentials, subscription_id, server)
111
119
  ad_admins = get_ad_admins(credentials, subscription_id, server)
112
120
  r_databases = get_recoverable_databases(credentials, subscription_id, server)
113
- rd_databases = get_restorable_dropped_databases(credentials, subscription_id, server)
121
+ rd_databases = get_restorable_dropped_databases(
122
+ credentials,
123
+ subscription_id,
124
+ server,
125
+ )
114
126
  fgs = get_failover_groups(credentials, subscription_id, server)
115
127
  elastic_pools = get_elastic_pools(credentials, subscription_id, server)
116
128
  databases = get_databases(credentials, subscription_id, server)
117
- yield server['id'], server['name'], server[
118
- 'resourceGroup'
129
+ yield server["id"], server["name"], server[
130
+ "resourceGroup"
119
131
  ], dns_alias, ad_admins, r_databases, rd_databases, fgs, elastic_pools, databases
120
132
 
121
133
 
122
134
  @timeit
123
- def get_dns_aliases(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
135
+ def get_dns_aliases(
136
+ credentials: Credentials,
137
+ subscription_id: str,
138
+ server: Dict,
139
+ ) -> List[Dict]:
124
140
  """
125
141
  Returns details of the DNS aliases in a server.
126
142
  """
@@ -129,12 +145,17 @@ def get_dns_aliases(credentials: Credentials, subscription_id: str, server: Dict
129
145
  dns_aliases = list(
130
146
  map(
131
147
  lambda x: x.as_dict(),
132
- client.server_dns_aliases.list_by_server(server['resourceGroup'], server['name']),
148
+ client.server_dns_aliases.list_by_server(
149
+ server["resourceGroup"],
150
+ server["name"],
151
+ ),
133
152
  ),
134
153
  )
135
154
 
136
155
  except ClientAuthenticationError as e:
137
- logger.warning(f"Client Authentication Error while retrieving DNS Aliases - {e}")
156
+ logger.warning(
157
+ f"Client Authentication Error while retrieving DNS Aliases - {e}",
158
+ )
138
159
  return []
139
160
  except ResourceNotFoundError as e:
140
161
  logger.warning(f"DNS Alias resource not found error - {e}")
@@ -147,7 +168,11 @@ def get_dns_aliases(credentials: Credentials, subscription_id: str, server: Dict
147
168
 
148
169
 
149
170
  @timeit
150
- def get_ad_admins(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
171
+ def get_ad_admins(
172
+ credentials: Credentials,
173
+ subscription_id: str,
174
+ server: Dict,
175
+ ) -> List[Dict]:
151
176
  """
152
177
  Returns details of the Server AD Administrators in a server.
153
178
  """
@@ -157,14 +182,16 @@ def get_ad_admins(credentials: Credentials, subscription_id: str, server: Dict)
157
182
  map(
158
183
  lambda x: x.as_dict(),
159
184
  client.server_azure_ad_administrators.list_by_server(
160
- server['resourceGroup'],
161
- server['name'],
185
+ server["resourceGroup"],
186
+ server["name"],
162
187
  ),
163
188
  ),
164
189
  )
165
190
 
166
191
  except ClientAuthenticationError as e:
167
- logger.warning(f"Client Authentication Error while retrieving Azure AD Administrators - {e}")
192
+ logger.warning(
193
+ f"Client Authentication Error while retrieving Azure AD Administrators - {e}",
194
+ )
168
195
  return []
169
196
  except ResourceNotFoundError as e:
170
197
  logger.warning(f"Azure AD Administrators resource not found error - {e}")
@@ -177,7 +204,11 @@ def get_ad_admins(credentials: Credentials, subscription_id: str, server: Dict)
177
204
 
178
205
 
179
206
  @timeit
180
- def get_recoverable_databases(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
207
+ def get_recoverable_databases(
208
+ credentials: Credentials,
209
+ subscription_id: str,
210
+ server: Dict,
211
+ ) -> List[Dict]:
181
212
  """
182
213
  Returns details of the Recoverable databases in a server.
183
214
  """
@@ -187,8 +218,8 @@ def get_recoverable_databases(credentials: Credentials, subscription_id: str, se
187
218
  map(
188
219
  lambda x: x.as_dict(),
189
220
  client.recoverable_databases.list_by_server(
190
- server['resourceGroup'],
191
- server['name'],
221
+ server["resourceGroup"],
222
+ server["name"],
192
223
  ),
193
224
  ),
194
225
  )
@@ -197,7 +228,9 @@ def get_recoverable_databases(credentials: Credentials, subscription_id: str, se
197
228
  # The API returns a '404 CloudError: Not Found for url: <url>' if no recoverable databases are present.
198
229
  return []
199
230
  except ClientAuthenticationError as e:
200
- logger.warning(f"Client Authentication Error while retrieving recoverable databases - {e}")
231
+ logger.warning(
232
+ f"Client Authentication Error while retrieving recoverable databases - {e}",
233
+ )
201
234
  return []
202
235
  except ResourceNotFoundError as e:
203
236
  logger.warning(f"Recoverable databases resource not found error - {e}")
@@ -210,7 +243,11 @@ def get_recoverable_databases(credentials: Credentials, subscription_id: str, se
210
243
 
211
244
 
212
245
  @timeit
213
- def get_restorable_dropped_databases(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
246
+ def get_restorable_dropped_databases(
247
+ credentials: Credentials,
248
+ subscription_id: str,
249
+ server: Dict,
250
+ ) -> List[Dict]:
214
251
  """
215
252
  Returns details of the Restorable Dropped Databases in a server.
216
253
  """
@@ -220,13 +257,16 @@ def get_restorable_dropped_databases(credentials: Credentials, subscription_id:
220
257
  map(
221
258
  lambda x: x.as_dict(),
222
259
  client.restorable_dropped_databases.list_by_server(
223
- server['resourceGroup'], server['name'],
260
+ server["resourceGroup"],
261
+ server["name"],
224
262
  ),
225
263
  ),
226
264
  )
227
265
 
228
266
  except ClientAuthenticationError as e:
229
- logger.warning(f"Client Authentication Error while retrieving Restorable Dropped Databases - {e}")
267
+ logger.warning(
268
+ f"Client Authentication Error while retrieving Restorable Dropped Databases - {e}",
269
+ )
230
270
  return []
231
271
  except ResourceNotFoundError as e:
232
272
  logger.warning(f"Restorable Dropped Databases resource not found error - {e}")
@@ -239,18 +279,30 @@ def get_restorable_dropped_databases(credentials: Credentials, subscription_id:
239
279
 
240
280
 
241
281
  @timeit
242
- def get_failover_groups(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
282
+ def get_failover_groups(
283
+ credentials: Credentials,
284
+ subscription_id: str,
285
+ server: Dict,
286
+ ) -> List[Dict]:
243
287
  """
244
288
  Returns details of Failover groups in a server.
245
289
  """
246
290
  try:
247
291
  client = get_client(credentials, subscription_id)
248
292
  failover_groups = list(
249
- map(lambda x: x.as_dict(), client.failover_groups.list_by_server(server['resourceGroup'], server['name'])),
293
+ map(
294
+ lambda x: x.as_dict(),
295
+ client.failover_groups.list_by_server(
296
+ server["resourceGroup"],
297
+ server["name"],
298
+ ),
299
+ ),
250
300
  )
251
301
 
252
302
  except ClientAuthenticationError as e:
253
- logger.warning(f"Client Authentication Error while retrieving Failover groups - {e}")
303
+ logger.warning(
304
+ f"Client Authentication Error while retrieving Failover groups - {e}",
305
+ )
254
306
  return []
255
307
  except ResourceNotFoundError as e:
256
308
  logger.warning(f"Failover groups resource not found error - {e}")
@@ -263,18 +315,30 @@ def get_failover_groups(credentials: Credentials, subscription_id: str, server:
263
315
 
264
316
 
265
317
  @timeit
266
- def get_elastic_pools(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
318
+ def get_elastic_pools(
319
+ credentials: Credentials,
320
+ subscription_id: str,
321
+ server: Dict,
322
+ ) -> List[Dict]:
267
323
  """
268
324
  Returns details of Elastic Pools in a server.
269
325
  """
270
326
  try:
271
327
  client = get_client(credentials, subscription_id)
272
328
  elastic_pools = list(
273
- map(lambda x: x.as_dict(), client.elastic_pools.list_by_server(server['resourceGroup'], server['name'])),
329
+ map(
330
+ lambda x: x.as_dict(),
331
+ client.elastic_pools.list_by_server(
332
+ server["resourceGroup"],
333
+ server["name"],
334
+ ),
335
+ ),
274
336
  )
275
337
 
276
338
  except ClientAuthenticationError as e:
277
- logger.warning(f"Client Authentication Error while retrieving Elastic Pools - {e}")
339
+ logger.warning(
340
+ f"Client Authentication Error while retrieving Elastic Pools - {e}",
341
+ )
278
342
  return []
279
343
  except ResourceNotFoundError as e:
280
344
  logger.warning(f"Elastic Pools resource not found error - {e}")
@@ -287,18 +351,30 @@ def get_elastic_pools(credentials: Credentials, subscription_id: str, server: Di
287
351
 
288
352
 
289
353
  @timeit
290
- def get_databases(credentials: Credentials, subscription_id: str, server: Dict) -> List[Dict]:
354
+ def get_databases(
355
+ credentials: Credentials,
356
+ subscription_id: str,
357
+ server: Dict,
358
+ ) -> List[Dict]:
291
359
  """
292
360
  Returns details of Databases in a SQL server.
293
361
  """
294
362
  try:
295
363
  client = get_client(credentials, subscription_id)
296
364
  databases = list(
297
- map(lambda x: x.as_dict(), client.databases.list_by_server(server['resourceGroup'], server['name'])),
365
+ map(
366
+ lambda x: x.as_dict(),
367
+ client.databases.list_by_server(
368
+ server["resourceGroup"],
369
+ server["name"],
370
+ ),
371
+ ),
298
372
  )
299
373
 
300
374
  except ClientAuthenticationError as e:
301
- logger.warning(f"Client Authentication Error while retrieving SQL databases - {e}")
375
+ logger.warning(
376
+ f"Client Authentication Error while retrieving SQL databases - {e}",
377
+ )
302
378
  return []
303
379
  except ResourceNotFoundError as e:
304
380
  logger.warning(f"SQL databases resource not found error - {e}")
@@ -312,8 +388,11 @@ def get_databases(credentials: Credentials, subscription_id: str, server: Dict)
312
388
 
313
389
  @timeit
314
390
  def load_server_details(
315
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
316
- details: List[Tuple[Any, Any, Any, Any, Any, Any, Any, Any, Any, Any]], update_tag: int,
391
+ neo4j_session: neo4j.Session,
392
+ credentials: Credentials,
393
+ subscription_id: str,
394
+ details: List[Tuple[Any, Any, Any, Any, Any, Any, Any, Any, Any, Any]],
395
+ update_tag: int,
317
396
  ) -> None:
318
397
  """
319
398
  Create dictionaries for every resource in the server so we can import them in a single query
@@ -326,64 +405,87 @@ def load_server_details(
326
405
  elastic_pools = []
327
406
  databases = []
328
407
 
329
- for server_id, name, rg, dns_alias, ad_admin, r_database, rd_database, fg, elastic_pool, database in details:
408
+ for (
409
+ server_id,
410
+ name,
411
+ rg,
412
+ dns_alias,
413
+ ad_admin,
414
+ r_database,
415
+ rd_database,
416
+ fg,
417
+ elastic_pool,
418
+ database,
419
+ ) in details:
330
420
  if len(dns_alias) > 0:
331
421
  for alias in dns_alias:
332
- alias['server_name'] = name
333
- alias['server_id'] = server_id
422
+ alias["server_name"] = name
423
+ alias["server_id"] = server_id
334
424
  dns_aliases.append(alias)
335
425
 
336
426
  if len(ad_admin) > 0:
337
427
  for admin in ad_admin:
338
- admin['server_name'] = name
339
- admin['server_id'] = server_id
428
+ admin["server_name"] = name
429
+ admin["server_id"] = server_id
340
430
  ad_admins.append(admin)
341
431
 
342
432
  if len(r_database) > 0:
343
433
  for rdb in r_database:
344
- rdb['server_name'] = name
345
- rdb['server_id'] = server_id
434
+ rdb["server_name"] = name
435
+ rdb["server_id"] = server_id
346
436
  recoverable_databases.append(rdb)
347
437
 
348
438
  if len(rd_database) > 0:
349
439
  for rddb in rd_database:
350
- rddb['server_name'] = name
351
- rddb['server_id'] = server_id
440
+ rddb["server_name"] = name
441
+ rddb["server_id"] = server_id
352
442
  restorable_dropped_databases.append(rddb)
353
443
 
354
444
  if len(fg) > 0:
355
445
  for group in fg:
356
- group['server_name'] = name
357
- group['server_id'] = server_id
446
+ group["server_name"] = name
447
+ group["server_id"] = server_id
358
448
  failover_groups.append(group)
359
449
 
360
450
  if len(elastic_pool) > 0:
361
451
  for pool in elastic_pool:
362
- pool['server_name'] = name
363
- pool['server_id'] = server_id
452
+ pool["server_name"] = name
453
+ pool["server_id"] = server_id
364
454
  elastic_pools.append(pool)
365
455
 
366
456
  if len(database) > 0:
367
457
  for db in database:
368
- db['server_name'] = name
369
- db['server_id'] = server_id
370
- db['resource_group_name'] = rg
458
+ db["server_name"] = name
459
+ db["server_id"] = server_id
460
+ db["resource_group_name"] = rg
371
461
  databases.append(db)
372
462
 
373
463
  _load_server_dns_aliases(neo4j_session, dns_aliases, update_tag)
374
464
  _load_server_ad_admins(neo4j_session, ad_admins, update_tag)
375
465
  _load_recoverable_databases(neo4j_session, recoverable_databases, update_tag)
376
- _load_restorable_dropped_databases(neo4j_session, restorable_dropped_databases, update_tag)
466
+ _load_restorable_dropped_databases(
467
+ neo4j_session,
468
+ restorable_dropped_databases,
469
+ update_tag,
470
+ )
377
471
  _load_failover_groups(neo4j_session, failover_groups, update_tag)
378
472
  _load_elastic_pools(neo4j_session, elastic_pools, update_tag)
379
473
  _load_databases(neo4j_session, databases, update_tag)
380
474
 
381
- sync_database_details(neo4j_session, credentials, subscription_id, databases, update_tag)
475
+ sync_database_details(
476
+ neo4j_session,
477
+ credentials,
478
+ subscription_id,
479
+ databases,
480
+ update_tag,
481
+ )
382
482
 
383
483
 
384
484
  @timeit
385
485
  def _load_server_dns_aliases(
386
- neo4j_session: neo4j.Session, dns_aliases: List[Dict], update_tag: int,
486
+ neo4j_session: neo4j.Session,
487
+ dns_aliases: List[Dict],
488
+ update_tag: int,
387
489
  ) -> None:
388
490
  """
389
491
  Ingest the DNS Alias details into neo4j.
@@ -411,7 +513,9 @@ def _load_server_dns_aliases(
411
513
 
412
514
  @timeit
413
515
  def _load_server_ad_admins(
414
- neo4j_session: neo4j.Session, ad_admins: List[Dict], update_tag: int,
516
+ neo4j_session: neo4j.Session,
517
+ ad_admins: List[Dict],
518
+ update_tag: int,
415
519
  ) -> None:
416
520
  """
417
521
  Ingest the Server AD Administrators details into neo4j.
@@ -440,7 +544,9 @@ def _load_server_ad_admins(
440
544
 
441
545
  @timeit
442
546
  def _load_recoverable_databases(
443
- neo4j_session: neo4j.Session, recoverable_databases: List[Dict], update_tag: int,
547
+ neo4j_session: neo4j.Session,
548
+ recoverable_databases: List[Dict],
549
+ update_tag: int,
444
550
  ) -> None:
445
551
  """
446
552
  Ingest the recoverable database details into neo4j.
@@ -470,7 +576,9 @@ def _load_recoverable_databases(
470
576
 
471
577
  @timeit
472
578
  def _load_restorable_dropped_databases(
473
- neo4j_session: neo4j.Session, restorable_dropped_databases: List[Dict], update_tag: int,
579
+ neo4j_session: neo4j.Session,
580
+ restorable_dropped_databases: List[Dict],
581
+ update_tag: int,
474
582
  ) -> None:
475
583
  """
476
584
  Ingest the restorable dropped database details into neo4j.
@@ -504,7 +612,9 @@ def _load_restorable_dropped_databases(
504
612
 
505
613
  @timeit
506
614
  def _load_failover_groups(
507
- neo4j_session: neo4j.Session, failover_groups: List[Dict], update_tag: int,
615
+ neo4j_session: neo4j.Session,
616
+ failover_groups: List[Dict],
617
+ update_tag: int,
508
618
  ) -> None:
509
619
  """
510
620
  Ingest the failover groups details into neo4j.
@@ -533,7 +643,9 @@ def _load_failover_groups(
533
643
 
534
644
  @timeit
535
645
  def _load_elastic_pools(
536
- neo4j_session: neo4j.Session, elastic_pools: List[Dict], update_tag: int,
646
+ neo4j_session: neo4j.Session,
647
+ elastic_pools: List[Dict],
648
+ update_tag: int,
537
649
  ) -> None:
538
650
  """
539
651
  Ingest the elastic pool details into neo4j.
@@ -566,7 +678,9 @@ def _load_elastic_pools(
566
678
 
567
679
  @timeit
568
680
  def _load_databases(
569
- neo4j_session: neo4j.Session, databases: List[Dict], update_tag: int,
681
+ neo4j_session: neo4j.Session,
682
+ databases: List[Dict],
683
+ update_tag: int,
570
684
  ) -> None:
571
685
  """
572
686
  Ingest the database details into neo4j.
@@ -605,8 +719,11 @@ def _load_databases(
605
719
 
606
720
  @timeit
607
721
  def sync_database_details(
608
- neo4j_session: neo4j.Session, credentials: Credentials,
609
- subscription_id: str, databases: List[Dict], update_tag: int,
722
+ neo4j_session: neo4j.Session,
723
+ credentials: Credentials,
724
+ subscription_id: str,
725
+ databases: List[Dict],
726
+ update_tag: int,
610
727
  ) -> None:
611
728
  db_details = get_database_details(credentials, subscription_id, databases)
612
729
  load_database_details(neo4j_session, db_details, update_tag) # type: ignore
@@ -614,23 +731,41 @@ def sync_database_details(
614
731
 
615
732
  @timeit
616
733
  def get_database_details(
617
- credentials: Credentials, subscription_id: str, databases: List[Dict],
734
+ credentials: Credentials,
735
+ subscription_id: str,
736
+ databases: List[Dict],
618
737
  ) -> Generator[Any, Any, Any]:
619
738
  """
620
739
  Iterate over the databases to get the details of resources in it.
621
740
  """
622
741
  for database in databases:
623
- replication_links = get_replication_links(credentials, subscription_id, database)
624
- db_threat_detection_policies = get_db_threat_detection_policies(credentials, subscription_id, database)
742
+ replication_links = get_replication_links(
743
+ credentials,
744
+ subscription_id,
745
+ database,
746
+ )
747
+ db_threat_detection_policies = get_db_threat_detection_policies(
748
+ credentials,
749
+ subscription_id,
750
+ database,
751
+ )
625
752
  restore_points = get_restore_points(credentials, subscription_id, database)
626
- transparent_data_encryptions = get_transparent_data_encryptions(credentials, subscription_id, database)
753
+ transparent_data_encryptions = get_transparent_data_encryptions(
754
+ credentials,
755
+ subscription_id,
756
+ database,
757
+ )
627
758
  yield database[
628
- 'id'
759
+ "id"
629
760
  ], replication_links, db_threat_detection_policies, restore_points, transparent_data_encryptions
630
761
 
631
762
 
632
763
  @timeit
633
- def get_replication_links(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
764
+ def get_replication_links(
765
+ credentials: Credentials,
766
+ subscription_id: str,
767
+ database: Dict,
768
+ ) -> List[Dict]:
634
769
  """
635
770
  Returns the details of replication links in a database.
636
771
  """
@@ -640,15 +775,17 @@ def get_replication_links(credentials: Credentials, subscription_id: str, databa
640
775
  map(
641
776
  lambda x: x.as_dict(),
642
777
  client.replication_links.list_by_database(
643
- database['resource_group_name'],
644
- database['server_name'],
645
- database['name'],
778
+ database["resource_group_name"],
779
+ database["server_name"],
780
+ database["name"],
646
781
  ),
647
782
  ),
648
783
  )
649
784
 
650
785
  except ClientAuthenticationError as e:
651
- logger.warning(f"Client Authentication Error while retrieving replication links - {e}")
786
+ logger.warning(
787
+ f"Client Authentication Error while retrieving replication links - {e}",
788
+ )
652
789
  return []
653
790
  except ResourceNotFoundError as e:
654
791
  logger.warning(f"Replication links resource not found error - {e}")
@@ -661,33 +798,45 @@ def get_replication_links(credentials: Credentials, subscription_id: str, databa
661
798
 
662
799
 
663
800
  @timeit
664
- def get_db_threat_detection_policies(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
801
+ def get_db_threat_detection_policies(
802
+ credentials: Credentials,
803
+ subscription_id: str,
804
+ database: Dict,
805
+ ) -> List[Dict]:
665
806
  """
666
807
  Returns the threat detection policy of a database.
667
808
  """
668
809
  try:
669
810
  client = get_client(credentials, subscription_id)
670
811
  db_threat_detection_policies = client.database_threat_detection_policies.get(
671
- database['resource_group_name'],
672
- database['server_name'],
673
- database['name'],
812
+ database["resource_group_name"],
813
+ database["server_name"],
814
+ database["name"],
674
815
  SecurityAlertPolicyName.DEFAULT,
675
816
  ).as_dict()
676
817
  except ClientAuthenticationError as e:
677
- logger.warning(f"Client Authentication Error while retrieving threat detection policy - {e}")
818
+ logger.warning(
819
+ f"Client Authentication Error while retrieving threat detection policy - {e}",
820
+ )
678
821
  return []
679
822
  except ResourceNotFoundError as e:
680
823
  logger.warning(f"Threat detection policy resource not found error - {e}")
681
824
  return []
682
825
  except HttpResponseError as e:
683
- logger.warning(f"Error while retrieving database threat detection policies - {e}")
826
+ logger.warning(
827
+ f"Error while retrieving database threat detection policies - {e}",
828
+ )
684
829
  return []
685
830
 
686
831
  return db_threat_detection_policies
687
832
 
688
833
 
689
834
  @timeit
690
- def get_restore_points(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
835
+ def get_restore_points(
836
+ credentials: Credentials,
837
+ subscription_id: str,
838
+ database: Dict,
839
+ ) -> List[Dict]:
691
840
  """
692
841
  Returns the details of restore points in a database.
693
842
  """
@@ -697,15 +846,17 @@ def get_restore_points(credentials: Credentials, subscription_id: str, database:
697
846
  map(
698
847
  lambda x: x.as_dict(),
699
848
  client.restore_points.list_by_database(
700
- database['resource_group_name'],
701
- database['server_name'],
702
- database['name'],
849
+ database["resource_group_name"],
850
+ database["server_name"],
851
+ database["name"],
703
852
  ),
704
853
  ),
705
854
  )
706
855
 
707
856
  except ClientAuthenticationError as e:
708
- logger.warning(f"Client Authentication Error while retrieving restore points - {e}")
857
+ logger.warning(
858
+ f"Client Authentication Error while retrieving restore points - {e}",
859
+ )
709
860
  return []
710
861
  except ResourceNotFoundError as e:
711
862
  logger.warning(f"Restore points resource not found error - {e}")
@@ -718,20 +869,26 @@ def get_restore_points(credentials: Credentials, subscription_id: str, database:
718
869
 
719
870
 
720
871
  @timeit
721
- def get_transparent_data_encryptions(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
872
+ def get_transparent_data_encryptions(
873
+ credentials: Credentials,
874
+ subscription_id: str,
875
+ database: Dict,
876
+ ) -> List[Dict]:
722
877
  """
723
878
  Returns the details of transparent data encryptions in a database.
724
879
  """
725
880
  try:
726
881
  client = get_client(credentials, subscription_id)
727
882
  transparent_data_encryptions_list = client.transparent_data_encryptions.get(
728
- database['resource_group_name'],
729
- database['server_name'],
730
- database['name'],
883
+ database["resource_group_name"],
884
+ database["server_name"],
885
+ database["name"],
731
886
  TransparentDataEncryptionName.CURRENT,
732
887
  ).as_dict()
733
888
  except ClientAuthenticationError as e:
734
- logger.warning(f"Client Authentication Error while retrieving transparent data encryptions - {e}")
889
+ logger.warning(
890
+ f"Client Authentication Error while retrieving transparent data encryptions - {e}",
891
+ )
735
892
  return []
736
893
  except ResourceNotFoundError as e:
737
894
  logger.warning(f"Transparent data encryptions resource not found error - {e}")
@@ -745,7 +902,9 @@ def get_transparent_data_encryptions(credentials: Credentials, subscription_id:
745
902
 
746
903
  @timeit
747
904
  def load_database_details(
748
- neo4j_session: neo4j.Session, details: List[Tuple[Any, Any, Any, Any, Any]], update_tag: int,
905
+ neo4j_session: neo4j.Session,
906
+ details: List[Tuple[Any, Any, Any, Any, Any]],
907
+ update_tag: int,
749
908
  ) -> None:
750
909
  """
751
910
  Create dictionaries for every resource in a database so we can import them in a single query
@@ -755,34 +914,46 @@ def load_database_details(
755
914
  restore_points = []
756
915
  encryptions_list = []
757
916
 
758
- for databaseId, replication_link, db_threat_detection_policy, restore_point, transparent_data_encryption in details:
917
+ for (
918
+ databaseId,
919
+ replication_link,
920
+ db_threat_detection_policy,
921
+ restore_point,
922
+ transparent_data_encryption,
923
+ ) in details:
759
924
  if len(replication_link) > 0:
760
925
  for link in replication_link:
761
- link['database_id'] = databaseId
926
+ link["database_id"] = databaseId
762
927
  replication_links.append(link)
763
928
 
764
929
  if len(db_threat_detection_policy) > 0:
765
- db_threat_detection_policy['database_id'] = databaseId
930
+ db_threat_detection_policy["database_id"] = databaseId
766
931
  threat_detection_policies.append(db_threat_detection_policy)
767
932
 
768
933
  if len(restore_point) > 0:
769
934
  for point in restore_point:
770
- point['database_id'] = databaseId
935
+ point["database_id"] = databaseId
771
936
  restore_points.append(point)
772
937
 
773
938
  if len(transparent_data_encryption) > 0:
774
- transparent_data_encryption['database_id'] = databaseId
939
+ transparent_data_encryption["database_id"] = databaseId
775
940
  encryptions_list.append(transparent_data_encryption)
776
941
 
777
942
  _load_replication_links(neo4j_session, replication_links, update_tag)
778
- _load_db_threat_detection_policies(neo4j_session, threat_detection_policies, update_tag)
943
+ _load_db_threat_detection_policies(
944
+ neo4j_session,
945
+ threat_detection_policies,
946
+ update_tag,
947
+ )
779
948
  _load_restore_points(neo4j_session, restore_points, update_tag)
780
949
  _load_transparent_data_encryptions(neo4j_session, encryptions_list, update_tag)
781
950
 
782
951
 
783
952
  @timeit
784
953
  def _load_replication_links(
785
- neo4j_session: neo4j.Session, replication_links: List[Dict], update_tag: int,
954
+ neo4j_session: neo4j.Session,
955
+ replication_links: List[Dict],
956
+ update_tag: int,
786
957
  ) -> None:
787
958
  """
788
959
  Ingest replication links into neo4j.
@@ -820,7 +991,9 @@ def _load_replication_links(
820
991
 
821
992
  @timeit
822
993
  def _load_db_threat_detection_policies(
823
- neo4j_session: neo4j.Session, threat_detection_policies: List[Dict], update_tag: int,
994
+ neo4j_session: neo4j.Session,
995
+ threat_detection_policies: List[Dict],
996
+ update_tag: int,
824
997
  ) -> None:
825
998
  """
826
999
  Ingest threat detection policy into neo4j.
@@ -857,7 +1030,9 @@ def _load_db_threat_detection_policies(
857
1030
 
858
1031
  @timeit
859
1032
  def _load_restore_points(
860
- neo4j_session: neo4j.Session, restore_points: List[Dict], update_tag: int,
1033
+ neo4j_session: neo4j.Session,
1034
+ restore_points: List[Dict],
1035
+ update_tag: int,
861
1036
  ) -> None:
862
1037
  """
863
1038
  Ingest restore points into neo4j.
@@ -888,7 +1063,9 @@ def _load_restore_points(
888
1063
 
889
1064
  @timeit
890
1065
  def _load_transparent_data_encryptions(
891
- neo4j_session: neo4j.Session, encryptions_list: List[Dict], update_tag: int,
1066
+ neo4j_session: neo4j.Session,
1067
+ encryptions_list: List[Dict],
1068
+ update_tag: int,
892
1069
  ) -> None:
893
1070
  """
894
1071
  Ingest transparent data encryptions into neo4j.
@@ -917,18 +1094,32 @@ def _load_transparent_data_encryptions(
917
1094
 
918
1095
  @timeit
919
1096
  def cleanup_azure_sql_servers(
920
- neo4j_session: neo4j.Session, common_job_parameters: Dict,
1097
+ neo4j_session: neo4j.Session,
1098
+ common_job_parameters: Dict,
921
1099
  ) -> None:
922
- run_cleanup_job('azure_sql_server_cleanup.json', neo4j_session, common_job_parameters)
1100
+ run_cleanup_job(
1101
+ "azure_sql_server_cleanup.json",
1102
+ neo4j_session,
1103
+ common_job_parameters,
1104
+ )
923
1105
 
924
1106
 
925
1107
  @timeit
926
1108
  def sync(
927
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
928
- sync_tag: int, common_job_parameters: Dict,
1109
+ neo4j_session: neo4j.Session,
1110
+ credentials: Credentials,
1111
+ subscription_id: str,
1112
+ sync_tag: int,
1113
+ common_job_parameters: Dict,
929
1114
  ) -> None:
930
1115
  logger.info("Syncing Azure SQL for subscription '%s'.", subscription_id)
931
1116
  server_list = get_server_list(credentials, subscription_id)
932
1117
  load_server_data(neo4j_session, subscription_id, server_list, sync_tag)
933
- sync_server_details(neo4j_session, credentials, subscription_id, server_list, sync_tag)
1118
+ sync_server_details(
1119
+ neo4j_session,
1120
+ credentials,
1121
+ subscription_id,
1122
+ server_list,
1123
+ sync_tag,
1124
+ )
934
1125
  cleanup_azure_sql_servers(neo4j_session, common_job_parameters)