cartography 0.102.0rc2__py3-none-any.whl → 0.103.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 (297) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +2 -2
  3. cartography/cli.py +376 -249
  4. cartography/client/core/tx.py +39 -18
  5. cartography/config.py +28 -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/cloudwatch.py +93 -0
  23. cartography/intel/aws/config.py +56 -20
  24. cartography/intel/aws/dynamodb.py +108 -40
  25. cartography/intel/aws/ec2/__init__.py +2 -2
  26. cartography/intel/aws/ec2/auto_scaling_groups.py +181 -78
  27. cartography/intel/aws/ec2/elastic_ip_addresses.py +41 -13
  28. cartography/intel/aws/ec2/images.py +49 -20
  29. cartography/intel/aws/ec2/instances.py +234 -136
  30. cartography/intel/aws/ec2/internet_gateways.py +40 -11
  31. cartography/intel/aws/ec2/key_pairs.py +44 -20
  32. cartography/intel/aws/ec2/launch_templates.py +101 -59
  33. cartography/intel/aws/ec2/load_balancer_v2s.py +104 -39
  34. cartography/intel/aws/ec2/load_balancers.py +82 -42
  35. cartography/intel/aws/ec2/network_acls.py +89 -65
  36. cartography/intel/aws/ec2/network_interfaces.py +146 -87
  37. cartography/intel/aws/ec2/reserved_instances.py +45 -16
  38. cartography/intel/aws/ec2/route_tables.py +138 -98
  39. cartography/intel/aws/ec2/security_groups.py +71 -21
  40. cartography/intel/aws/ec2/snapshots.py +61 -22
  41. cartography/intel/aws/ec2/subnets.py +54 -18
  42. cartography/intel/aws/ec2/tgw.py +100 -34
  43. cartography/intel/aws/ec2/util.py +1 -1
  44. cartography/intel/aws/ec2/volumes.py +69 -41
  45. cartography/intel/aws/ec2/vpc.py +37 -12
  46. cartography/intel/aws/ec2/vpc_peerings.py +83 -24
  47. cartography/intel/aws/ecr.py +88 -32
  48. cartography/intel/aws/ecs.py +83 -47
  49. cartography/intel/aws/efs.py +93 -0
  50. cartography/intel/aws/eks.py +55 -29
  51. cartography/intel/aws/elasticache.py +42 -18
  52. cartography/intel/aws/elasticsearch.py +57 -20
  53. cartography/intel/aws/emr.py +61 -23
  54. cartography/intel/aws/iam.py +401 -145
  55. cartography/intel/aws/iam_instance_profiles.py +22 -22
  56. cartography/intel/aws/identitycenter.py +71 -37
  57. cartography/intel/aws/inspector.py +159 -89
  58. cartography/intel/aws/kms.py +92 -38
  59. cartography/intel/aws/lambda_function.py +103 -34
  60. cartography/intel/aws/organizations.py +30 -10
  61. cartography/intel/aws/permission_relationships.py +133 -51
  62. cartography/intel/aws/rds.py +249 -85
  63. cartography/intel/aws/redshift.py +107 -46
  64. cartography/intel/aws/resourcegroupstaggingapi.py +120 -66
  65. cartography/intel/aws/resources.py +57 -46
  66. cartography/intel/aws/route53.py +108 -61
  67. cartography/intel/aws/s3.py +168 -83
  68. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  69. cartography/intel/aws/secretsmanager.py +24 -12
  70. cartography/intel/aws/securityhub.py +20 -9
  71. cartography/intel/aws/sns.py +166 -0
  72. cartography/intel/aws/sqs.py +60 -28
  73. cartography/intel/aws/ssm.py +70 -30
  74. cartography/intel/aws/util/arns.py +7 -7
  75. cartography/intel/aws/util/common.py +31 -4
  76. cartography/intel/azure/__init__.py +78 -19
  77. cartography/intel/azure/compute.py +101 -27
  78. cartography/intel/azure/cosmosdb.py +496 -170
  79. cartography/intel/azure/sql.py +296 -105
  80. cartography/intel/azure/storage.py +322 -113
  81. cartography/intel/azure/subscription.py +39 -23
  82. cartography/intel/azure/tenant.py +13 -4
  83. cartography/intel/azure/util/credentials.py +95 -55
  84. cartography/intel/bigfix/__init__.py +2 -2
  85. cartography/intel/bigfix/computers.py +93 -65
  86. cartography/intel/cloudflare/__init__.py +74 -0
  87. cartography/intel/cloudflare/accounts.py +57 -0
  88. cartography/intel/cloudflare/dnsrecords.py +64 -0
  89. cartography/intel/cloudflare/members.py +75 -0
  90. cartography/intel/cloudflare/roles.py +65 -0
  91. cartography/intel/cloudflare/zones.py +64 -0
  92. cartography/intel/create_indexes.py +3 -2
  93. cartography/intel/crowdstrike/__init__.py +11 -9
  94. cartography/intel/crowdstrike/endpoints.py +5 -1
  95. cartography/intel/crowdstrike/spotlight.py +8 -3
  96. cartography/intel/cve/__init__.py +46 -13
  97. cartography/intel/cve/feed.py +48 -12
  98. cartography/intel/digitalocean/__init__.py +22 -13
  99. cartography/intel/digitalocean/compute.py +75 -108
  100. cartography/intel/digitalocean/management.py +44 -80
  101. cartography/intel/digitalocean/platform.py +48 -43
  102. cartography/intel/dns.py +36 -10
  103. cartography/intel/duo/__init__.py +21 -16
  104. cartography/intel/duo/api_host.py +14 -9
  105. cartography/intel/duo/endpoints.py +50 -45
  106. cartography/intel/duo/groups.py +18 -14
  107. cartography/intel/duo/phones.py +37 -34
  108. cartography/intel/duo/tokens.py +26 -23
  109. cartography/intel/duo/users.py +54 -50
  110. cartography/intel/duo/web_authn_credentials.py +30 -25
  111. cartography/intel/entra/__init__.py +25 -7
  112. cartography/intel/entra/ou.py +112 -0
  113. cartography/intel/entra/users.py +69 -63
  114. cartography/intel/gcp/__init__.py +185 -49
  115. cartography/intel/gcp/compute.py +418 -231
  116. cartography/intel/gcp/crm.py +96 -43
  117. cartography/intel/gcp/dns.py +60 -19
  118. cartography/intel/gcp/gke.py +72 -38
  119. cartography/intel/gcp/iam.py +61 -41
  120. cartography/intel/gcp/storage.py +84 -55
  121. cartography/intel/github/__init__.py +13 -11
  122. cartography/intel/github/repos.py +270 -137
  123. cartography/intel/github/teams.py +170 -88
  124. cartography/intel/github/users.py +70 -39
  125. cartography/intel/github/util.py +36 -34
  126. cartography/intel/gsuite/__init__.py +47 -26
  127. cartography/intel/gsuite/api.py +73 -30
  128. cartography/intel/jamf/__init__.py +19 -1
  129. cartography/intel/jamf/computers.py +30 -7
  130. cartography/intel/jamf/util.py +7 -2
  131. cartography/intel/kandji/__init__.py +6 -3
  132. cartography/intel/kandji/devices.py +14 -8
  133. cartography/intel/kubernetes/namespaces.py +7 -4
  134. cartography/intel/kubernetes/pods.py +7 -4
  135. cartography/intel/kubernetes/services.py +8 -4
  136. cartography/intel/lastpass/__init__.py +2 -2
  137. cartography/intel/lastpass/users.py +23 -12
  138. cartography/intel/oci/__init__.py +44 -11
  139. cartography/intel/oci/iam.py +134 -38
  140. cartography/intel/oci/organizations.py +13 -6
  141. cartography/intel/oci/utils.py +43 -20
  142. cartography/intel/okta/__init__.py +66 -15
  143. cartography/intel/okta/applications.py +42 -20
  144. cartography/intel/okta/awssaml.py +93 -33
  145. cartography/intel/okta/factors.py +16 -4
  146. cartography/intel/okta/groups.py +56 -29
  147. cartography/intel/okta/organization.py +5 -1
  148. cartography/intel/okta/origins.py +6 -2
  149. cartography/intel/okta/roles.py +15 -5
  150. cartography/intel/okta/users.py +20 -8
  151. cartography/intel/okta/utils.py +6 -4
  152. cartography/intel/openai/__init__.py +86 -0
  153. cartography/intel/openai/adminapikeys.py +90 -0
  154. cartography/intel/openai/apikeys.py +96 -0
  155. cartography/intel/openai/projects.py +94 -0
  156. cartography/intel/openai/serviceaccounts.py +82 -0
  157. cartography/intel/openai/users.py +78 -0
  158. cartography/intel/openai/util.py +29 -0
  159. cartography/intel/pagerduty/__init__.py +8 -7
  160. cartography/intel/pagerduty/escalation_policies.py +18 -6
  161. cartography/intel/pagerduty/schedules.py +12 -4
  162. cartography/intel/pagerduty/services.py +11 -4
  163. cartography/intel/pagerduty/teams.py +8 -3
  164. cartography/intel/pagerduty/users.py +3 -1
  165. cartography/intel/pagerduty/vendors.py +3 -1
  166. cartography/intel/semgrep/__init__.py +24 -6
  167. cartography/intel/semgrep/dependencies.py +50 -28
  168. cartography/intel/semgrep/deployment.py +3 -1
  169. cartography/intel/semgrep/findings.py +42 -18
  170. cartography/intel/snipeit/__init__.py +17 -3
  171. cartography/intel/snipeit/asset.py +12 -6
  172. cartography/intel/snipeit/user.py +8 -5
  173. cartography/intel/snipeit/util.py +9 -4
  174. cartography/intel/tailscale/__init__.py +77 -0
  175. cartography/intel/tailscale/acls.py +146 -0
  176. cartography/intel/tailscale/devices.py +127 -0
  177. cartography/intel/tailscale/postureintegrations.py +81 -0
  178. cartography/intel/tailscale/tailnets.py +76 -0
  179. cartography/intel/tailscale/users.py +80 -0
  180. cartography/intel/tailscale/utils.py +132 -0
  181. cartography/models/aws/apigateway.py +21 -17
  182. cartography/models/aws/apigatewaycertificate.py +28 -22
  183. cartography/models/aws/apigatewayresource.py +28 -20
  184. cartography/models/aws/apigatewaystage.py +33 -25
  185. cartography/models/aws/cloudtrail/__init__.py +0 -0
  186. cartography/models/aws/cloudtrail/trail.py +61 -0
  187. cartography/models/aws/cloudwatch/__init__.py +0 -0
  188. cartography/models/aws/cloudwatch/loggroup.py +52 -0
  189. cartography/models/aws/dynamodb/gsi.py +30 -22
  190. cartography/models/aws/dynamodb/tables.py +25 -17
  191. cartography/models/aws/ec2/auto_scaling_groups.py +102 -82
  192. cartography/models/aws/ec2/images.py +36 -34
  193. cartography/models/aws/ec2/instances.py +51 -45
  194. cartography/models/aws/ec2/keypair.py +21 -16
  195. cartography/models/aws/ec2/keypair_instance.py +28 -21
  196. cartography/models/aws/ec2/launch_configurations.py +30 -26
  197. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  198. cartography/models/aws/ec2/launch_templates.py +21 -17
  199. cartography/models/aws/ec2/load_balancer_listeners.py +27 -23
  200. cartography/models/aws/ec2/load_balancers.py +47 -37
  201. cartography/models/aws/ec2/network_acl_rules.py +38 -30
  202. cartography/models/aws/ec2/network_acls.py +38 -29
  203. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  204. cartography/models/aws/ec2/networkinterfaces.py +53 -37
  205. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  206. cartography/models/aws/ec2/reservations.py +18 -14
  207. cartography/models/aws/ec2/route_table_associations.py +44 -34
  208. cartography/models/aws/ec2/route_tables.py +50 -43
  209. cartography/models/aws/ec2/routes.py +45 -37
  210. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  211. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  212. cartography/models/aws/ec2/subnet_instance.py +24 -19
  213. cartography/models/aws/ec2/subnet_networkinterface.py +40 -31
  214. cartography/models/aws/ec2/volumes.py +47 -40
  215. cartography/models/aws/efs/__init__.py +0 -0
  216. cartography/models/aws/efs/mount_target.py +52 -0
  217. cartography/models/aws/eks/clusters.py +23 -21
  218. cartography/models/aws/emr.py +32 -30
  219. cartography/models/aws/iam/instanceprofile.py +33 -24
  220. cartography/models/aws/identitycenter/awsidentitycenter.py +18 -14
  221. cartography/models/aws/identitycenter/awspermissionset.py +37 -29
  222. cartography/models/aws/identitycenter/awsssouser.py +23 -21
  223. cartography/models/aws/inspector/findings.py +77 -65
  224. cartography/models/aws/inspector/packages.py +35 -29
  225. cartography/models/aws/s3/__init__.py +0 -0
  226. cartography/models/aws/s3/account_public_access_block.py +51 -0
  227. cartography/models/aws/sns/__init__.py +0 -0
  228. cartography/models/aws/sns/topic.py +50 -0
  229. cartography/models/aws/ssm/instance_information.py +51 -39
  230. cartography/models/aws/ssm/instance_patch.py +32 -26
  231. cartography/models/bigfix/bigfix_computer.py +42 -38
  232. cartography/models/bigfix/bigfix_root.py +3 -3
  233. cartography/models/cloudflare/__init__.py +0 -0
  234. cartography/models/cloudflare/account.py +25 -0
  235. cartography/models/cloudflare/dnsrecord.py +55 -0
  236. cartography/models/cloudflare/member.py +82 -0
  237. cartography/models/cloudflare/role.py +44 -0
  238. cartography/models/cloudflare/zone.py +59 -0
  239. cartography/models/core/common.py +12 -10
  240. cartography/models/core/nodes.py +5 -2
  241. cartography/models/core/relationships.py +14 -6
  242. cartography/models/crowdstrike/hosts.py +37 -35
  243. cartography/models/cve/cve.py +34 -32
  244. cartography/models/cve/cve_feed.py +6 -6
  245. cartography/models/digitalocean/__init__.py +0 -0
  246. cartography/models/digitalocean/account.py +21 -0
  247. cartography/models/digitalocean/droplet.py +56 -0
  248. cartography/models/digitalocean/project.py +48 -0
  249. cartography/models/duo/api_host.py +3 -3
  250. cartography/models/duo/endpoint.py +43 -41
  251. cartography/models/duo/group.py +14 -14
  252. cartography/models/duo/phone.py +27 -27
  253. cartography/models/duo/token.py +16 -16
  254. cartography/models/duo/user.py +46 -44
  255. cartography/models/duo/web_authn_credential.py +27 -19
  256. cartography/models/entra/ou.py +48 -0
  257. cartography/models/entra/tenant.py +24 -18
  258. cartography/models/entra/user.py +64 -48
  259. cartography/models/gcp/iam.py +23 -23
  260. cartography/models/github/orgs.py +5 -4
  261. cartography/models/github/teams.py +37 -31
  262. cartography/models/github/users.py +34 -23
  263. cartography/models/kandji/device.py +22 -16
  264. cartography/models/kandji/tenant.py +6 -4
  265. cartography/models/lastpass/tenant.py +3 -3
  266. cartography/models/lastpass/user.py +32 -28
  267. cartography/models/openai/__init__.py +0 -0
  268. cartography/models/openai/adminapikey.py +90 -0
  269. cartography/models/openai/apikey.py +84 -0
  270. cartography/models/openai/organization.py +17 -0
  271. cartography/models/openai/project.py +70 -0
  272. cartography/models/openai/serviceaccount.py +50 -0
  273. cartography/models/openai/user.py +49 -0
  274. cartography/models/semgrep/dependencies.py +36 -24
  275. cartography/models/semgrep/deployment.py +5 -5
  276. cartography/models/semgrep/findings.py +58 -42
  277. cartography/models/semgrep/locations.py +27 -21
  278. cartography/models/snipeit/asset.py +30 -21
  279. cartography/models/snipeit/tenant.py +6 -4
  280. cartography/models/snipeit/user.py +19 -12
  281. cartography/models/tailscale/__init__.py +0 -0
  282. cartography/models/tailscale/device.py +95 -0
  283. cartography/models/tailscale/group.py +86 -0
  284. cartography/models/tailscale/postureintegration.py +58 -0
  285. cartography/models/tailscale/tag.py +102 -0
  286. cartography/models/tailscale/tailnet.py +29 -0
  287. cartography/models/tailscale/user.py +52 -0
  288. cartography/stats.py +3 -3
  289. cartography/sync.py +113 -31
  290. cartography/util.py +84 -62
  291. {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/METADATA +8 -15
  292. cartography-0.103.0.dist-info/RECORD +442 -0
  293. {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/WHEEL +1 -1
  294. cartography-0.102.0rc2.dist-info/RECORD +0 -381
  295. {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/entry_points.txt +0 -0
  296. {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/licenses/LICENSE +0 -0
  297. {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/top_level.txt +0 -0
@@ -12,15 +12,19 @@ from azure.core.exceptions import HttpResponseError
12
12
  from azure.core.exceptions import ResourceNotFoundError
13
13
  from azure.mgmt.cosmosdb import CosmosDBManagementClient
14
14
 
15
- from .util.credentials import Credentials
16
15
  from cartography.util import run_cleanup_job
17
16
  from cartography.util import timeit
18
17
 
18
+ from .util.credentials import Credentials
19
+
19
20
  logger = logging.getLogger(__name__)
20
21
 
21
22
 
22
23
  @timeit
23
- def get_client(credentials: Credentials, subscription_id: str) -> CosmosDBManagementClient:
24
+ def get_client(
25
+ credentials: Credentials,
26
+ subscription_id: str,
27
+ ) -> CosmosDBManagementClient:
24
28
  """
25
29
  Getting the CosmosDB client
26
30
  """
@@ -29,28 +33,36 @@ def get_client(credentials: Credentials, subscription_id: str) -> CosmosDBManage
29
33
 
30
34
 
31
35
  @timeit
32
- def get_database_account_list(credentials: Credentials, subscription_id: str) -> List[Dict]:
36
+ def get_database_account_list(
37
+ credentials: Credentials,
38
+ subscription_id: str,
39
+ ) -> List[Dict]:
33
40
  """
34
41
  Get a list of all database accounts.
35
42
  """
36
43
  try:
37
44
  client = get_client(credentials, subscription_id)
38
- database_account_list = list(map(lambda x: x.as_dict(), client.database_accounts.list()))
45
+ database_account_list = list(
46
+ map(lambda x: x.as_dict(), client.database_accounts.list()),
47
+ )
39
48
 
40
49
  # ClientAuthenticationError and ResourceNotFoundError are subclasses under HttpResponseError
41
50
  except ClientAuthenticationError:
42
- logger.warning('Client Authentication Error while retrieving database accounts', exc_info=True)
51
+ logger.warning(
52
+ "Client Authentication Error while retrieving database accounts",
53
+ exc_info=True,
54
+ )
43
55
  return []
44
56
  except ResourceNotFoundError:
45
- logger.warning('Database Account not found error', exc_info=True)
57
+ logger.warning("Database Account not found error", exc_info=True)
46
58
  return []
47
59
  except HttpResponseError:
48
- logger.warning('Error while retrieving database accounts', exc_info=True)
60
+ logger.warning("Error while retrieving database accounts", exc_info=True)
49
61
  return []
50
62
 
51
63
  for database_account in database_account_list:
52
- x = database_account['id'].split('/')
53
- database_account['resourceGroup'] = x[x.index('resourceGroups') + 1]
64
+ x = database_account["id"].split("/")
65
+ database_account["resourceGroup"] = x[x.index("resourceGroups") + 1]
54
66
 
55
67
  return database_account_list
56
68
 
@@ -63,19 +75,25 @@ def transform_database_account_data(database_account_list: List[Dict]) -> List[D
63
75
  for database_account in database_account_list:
64
76
  capabilities: List[str] = []
65
77
  iprules: List[str] = []
66
- if 'capabilities' in database_account and len(database_account['capabilities']) > 0:
67
- capabilities = [x['name'] for x in database_account['capabilities']]
68
- if 'ip_rules' in database_account and len(database_account['ip_rules']) > 0:
69
- iprules = [x['ip_address_or_range'] for x in database_account['ip_rules']]
70
- database_account['ipruleslist'] = iprules
71
- database_account['list_of_capabilities'] = capabilities
78
+ if (
79
+ "capabilities" in database_account
80
+ and len(database_account["capabilities"]) > 0
81
+ ):
82
+ capabilities = [x["name"] for x in database_account["capabilities"]]
83
+ if "ip_rules" in database_account and len(database_account["ip_rules"]) > 0:
84
+ iprules = [x["ip_address_or_range"] for x in database_account["ip_rules"]]
85
+ database_account["ipruleslist"] = iprules
86
+ database_account["list_of_capabilities"] = capabilities
72
87
 
73
88
  return database_account_list
74
89
 
75
90
 
76
91
  @timeit
77
92
  def load_database_account_data(
78
- neo4j_session: neo4j.Session, subscription_id: str, database_account_list: List[Dict], azure_update_tag: int,
93
+ neo4j_session: neo4j.Session,
94
+ subscription_id: str,
95
+ database_account_list: List[Dict],
96
+ azure_update_tag: int,
79
97
  ) -> None:
80
98
  """
81
99
  Ingest data of all database accounts into neo4j.
@@ -124,7 +142,10 @@ def load_database_account_data(
124
142
 
125
143
  @timeit
126
144
  def sync_database_account_data_resources(
127
- neo4j_session: neo4j.Session, subscription_id: str, database_account_list: List[Dict], azure_update_tag: int,
145
+ neo4j_session: neo4j.Session,
146
+ subscription_id: str,
147
+ database_account_list: List[Dict],
148
+ azure_update_tag: int,
128
149
  ) -> None:
129
150
  """
130
151
  This function calls the load functions for the resources that are present as a part of the database account
@@ -132,24 +153,53 @@ def sync_database_account_data_resources(
132
153
  """
133
154
  for database_account in database_account_list:
134
155
  _load_cosmosdb_cors_policy(neo4j_session, database_account, azure_update_tag)
135
- _load_cosmosdb_failover_policies(neo4j_session, database_account, azure_update_tag)
136
- _load_cosmosdb_private_endpoint_connections(neo4j_session, database_account, azure_update_tag)
137
- _load_cosmosdb_virtual_network_rules(neo4j_session, database_account, azure_update_tag)
138
- _load_database_account_write_locations(neo4j_session, database_account, azure_update_tag)
139
- _load_database_account_read_locations(neo4j_session, database_account, azure_update_tag)
140
- _load_database_account_associated_locations(neo4j_session, database_account, azure_update_tag)
156
+ _load_cosmosdb_failover_policies(
157
+ neo4j_session,
158
+ database_account,
159
+ azure_update_tag,
160
+ )
161
+ _load_cosmosdb_private_endpoint_connections(
162
+ neo4j_session,
163
+ database_account,
164
+ azure_update_tag,
165
+ )
166
+ _load_cosmosdb_virtual_network_rules(
167
+ neo4j_session,
168
+ database_account,
169
+ azure_update_tag,
170
+ )
171
+ _load_database_account_write_locations(
172
+ neo4j_session,
173
+ database_account,
174
+ azure_update_tag,
175
+ )
176
+ _load_database_account_read_locations(
177
+ neo4j_session,
178
+ database_account,
179
+ azure_update_tag,
180
+ )
181
+ _load_database_account_associated_locations(
182
+ neo4j_session,
183
+ database_account,
184
+ azure_update_tag,
185
+ )
141
186
 
142
187
 
143
188
  @timeit
144
189
  def _load_database_account_write_locations(
145
- neo4j_session: neo4j.Session, database_account: Dict, azure_update_tag: int,
190
+ neo4j_session: neo4j.Session,
191
+ database_account: Dict,
192
+ azure_update_tag: int,
146
193
  ) -> None:
147
194
  """
148
195
  Ingest the details of location with write permission enabled.
149
196
  """
150
- if 'write_locations' in database_account and len(database_account['write_locations']) > 0:
151
- database_account_id = database_account['id']
152
- write_locations = database_account['write_locations']
197
+ if (
198
+ "write_locations" in database_account
199
+ and len(database_account["write_locations"]) > 0
200
+ ):
201
+ database_account_id = database_account["id"]
202
+ write_locations = database_account["write_locations"]
153
203
 
154
204
  ingest_write_location = """
155
205
  UNWIND $write_locations_list as wl
@@ -178,14 +228,19 @@ def _load_database_account_write_locations(
178
228
 
179
229
  @timeit
180
230
  def _load_database_account_read_locations(
181
- neo4j_session: neo4j.Session, database_account: Dict, azure_update_tag: int,
231
+ neo4j_session: neo4j.Session,
232
+ database_account: Dict,
233
+ azure_update_tag: int,
182
234
  ) -> None:
183
235
  """
184
236
  Ingest the details of location with read permission enabled.
185
237
  """
186
- if 'read_locations' in database_account and len(database_account['read_locations']) > 0:
187
- database_account_id = database_account['id']
188
- read_locations = database_account['read_locations']
238
+ if (
239
+ "read_locations" in database_account
240
+ and len(database_account["read_locations"]) > 0
241
+ ):
242
+ database_account_id = database_account["id"]
243
+ read_locations = database_account["read_locations"]
189
244
 
190
245
  ingest_read_location = """
191
246
  UNWIND $read_locations_list as rl
@@ -214,14 +269,16 @@ def _load_database_account_read_locations(
214
269
 
215
270
  @timeit
216
271
  def _load_database_account_associated_locations(
217
- neo4j_session: neo4j.Session, database_account: Dict, azure_update_tag: int,
272
+ neo4j_session: neo4j.Session,
273
+ database_account: Dict,
274
+ azure_update_tag: int,
218
275
  ) -> None:
219
276
  """
220
277
  Ingest the details of enabled location for the database account.
221
278
  """
222
- if 'locations' in database_account and len(database_account['locations']) > 0:
223
- database_account_id = database_account['id']
224
- associated_locations = database_account['locations']
279
+ if "locations" in database_account and len(database_account["locations"]) > 0:
280
+ database_account_id = database_account["id"]
281
+ associated_locations = database_account["locations"]
225
282
 
226
283
  ingest_associated_location = """
227
284
  UNWIND $associated_locations_list as al
@@ -253,24 +310,26 @@ def transform_cosmosdb_cors_policy(database_account: Dict) -> Dict:
253
310
  """
254
311
  Transform CosmosDB Cors Policy response for neo4j ingestion.
255
312
  """
256
- for policy in database_account['cors']:
257
- if 'cors_policy_unique_id' not in policy:
258
- policy['cors_policy_unique_id'] = str(uuid.uuid4())
313
+ for policy in database_account["cors"]:
314
+ if "cors_policy_unique_id" not in policy:
315
+ policy["cors_policy_unique_id"] = str(uuid.uuid4())
259
316
 
260
317
  return database_account
261
318
 
262
319
 
263
320
  @timeit
264
321
  def _load_cosmosdb_cors_policy(
265
- neo4j_session: neo4j.Session, database_account: Dict, azure_update_tag: int,
322
+ neo4j_session: neo4j.Session,
323
+ database_account: Dict,
324
+ azure_update_tag: int,
266
325
  ) -> None:
267
326
  """
268
327
  Ingest the details of the Cors Policy of the database account.
269
328
  """
270
- if 'cors' in database_account and len(database_account['cors']) > 0:
329
+ if "cors" in database_account and len(database_account["cors"]) > 0:
271
330
  database_account = transform_cosmosdb_cors_policy(database_account)
272
- database_account_id = database_account['id']
273
- cors_policies = database_account['cors']
331
+ database_account_id = database_account["id"]
332
+ cors_policies = database_account["cors"]
274
333
 
275
334
  ingest_cors_policy = """
276
335
  UNWIND $cors_policies_list AS cp
@@ -299,14 +358,19 @@ def _load_cosmosdb_cors_policy(
299
358
 
300
359
  @timeit
301
360
  def _load_cosmosdb_failover_policies(
302
- neo4j_session: neo4j.Session, database_account: Dict, azure_update_tag: int,
361
+ neo4j_session: neo4j.Session,
362
+ database_account: Dict,
363
+ azure_update_tag: int,
303
364
  ) -> None:
304
365
  """
305
366
  Ingest the details of the Failover Policies of the database account.
306
367
  """
307
- if 'failover_policies' in database_account and len(database_account['failover_policies']) > 0:
308
- database_account_id = database_account['id']
309
- failover_policies = database_account['failover_policies']
368
+ if (
369
+ "failover_policies" in database_account
370
+ and len(database_account["failover_policies"]) > 0
371
+ ):
372
+ database_account_id = database_account["id"]
373
+ failover_policies = database_account["failover_policies"]
310
374
 
311
375
  ingest_failover_policies = """
312
376
  UNWIND $failover_policies_list AS fp
@@ -332,16 +396,22 @@ def _load_cosmosdb_failover_policies(
332
396
 
333
397
  @timeit
334
398
  def _load_cosmosdb_private_endpoint_connections(
335
- neo4j_session: neo4j.Session, database_account: Dict, azure_update_tag: int,
399
+ neo4j_session: neo4j.Session,
400
+ database_account: Dict,
401
+ azure_update_tag: int,
336
402
  ) -> None:
337
403
  """
338
404
  Ingest the details of the Private Endpoint Connections of the database account.
339
405
  """
340
- if 'private_endpoint_connections' in database_account and len(
341
- database_account['private_endpoint_connections'],
342
- ) > 0:
343
- database_account_id = database_account['id']
344
- private_endpoint_connections = database_account['private_endpoint_connections']
406
+ if (
407
+ "private_endpoint_connections" in database_account
408
+ and len(
409
+ database_account["private_endpoint_connections"],
410
+ )
411
+ > 0
412
+ ):
413
+ database_account_id = database_account["id"]
414
+ private_endpoint_connections = database_account["private_endpoint_connections"]
345
415
 
346
416
  ingest_private_endpoint_connections = """
347
417
  UNWIND $private_endpoint_connections_list AS connection
@@ -369,14 +439,19 @@ def _load_cosmosdb_private_endpoint_connections(
369
439
 
370
440
  @timeit
371
441
  def _load_cosmosdb_virtual_network_rules(
372
- neo4j_session: neo4j.Session, database_account: Dict, azure_update_tag: int,
442
+ neo4j_session: neo4j.Session,
443
+ database_account: Dict,
444
+ azure_update_tag: int,
373
445
  ) -> None:
374
446
  """
375
447
  Ingest the details of the Virtual Network Rules of the database account.
376
448
  """
377
- if 'virtual_network_rules' in database_account and len(database_account['virtual_network_rules']) > 0:
378
- database_account_id = database_account['id']
379
- virtual_network_rules = database_account['virtual_network_rules']
449
+ if (
450
+ "virtual_network_rules" in database_account
451
+ and len(database_account["virtual_network_rules"]) > 0
452
+ ):
453
+ database_account_id = database_account["id"]
454
+ virtual_network_rules = database_account["virtual_network_rules"]
380
455
 
381
456
  ingest_virtual_network_rules = """
382
457
  UNWIND $virtual_network_rules_list AS vnr
@@ -401,33 +476,70 @@ def _load_cosmosdb_virtual_network_rules(
401
476
 
402
477
  @timeit
403
478
  def sync_database_account_details(
404
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
405
- database_account_list: List[Dict], sync_tag: int, common_job_parameters: Dict,
479
+ neo4j_session: neo4j.Session,
480
+ credentials: Credentials,
481
+ subscription_id: str,
482
+ database_account_list: List[Dict],
483
+ sync_tag: int,
484
+ common_job_parameters: Dict,
406
485
  ) -> None:
407
- details = get_database_account_details(credentials, subscription_id, database_account_list)
408
- load_database_account_details(neo4j_session, credentials, subscription_id, details, sync_tag, common_job_parameters)
486
+ details = get_database_account_details(
487
+ credentials,
488
+ subscription_id,
489
+ database_account_list,
490
+ )
491
+ load_database_account_details(
492
+ neo4j_session,
493
+ credentials,
494
+ subscription_id,
495
+ details,
496
+ sync_tag,
497
+ common_job_parameters,
498
+ )
409
499
 
410
500
 
411
501
  @timeit
412
502
  def get_database_account_details(
413
- credentials: Credentials, subscription_id: str, database_account_list: List[Dict],
503
+ credentials: Credentials,
504
+ subscription_id: str,
505
+ database_account_list: List[Dict],
414
506
  ) -> Generator[Any, Any, Any]:
415
507
  """
416
508
  Iterate over the database accounts and return the list of SQL and MongoDB databases, Cassandra keyspaces and
417
509
  table resources associated with each database account.
418
510
  """
419
511
  for database_account in database_account_list:
420
- sql_databases = get_sql_databases(credentials, subscription_id, database_account)
421
- cassandra_keyspaces = get_cassandra_keyspaces(credentials, subscription_id, database_account)
422
- mongodb_databases = get_mongodb_databases(credentials, subscription_id, database_account)
423
- table_resources = get_table_resources(credentials, subscription_id, database_account)
424
- yield database_account['id'], database_account['name'], database_account[
425
- 'resourceGroup'
512
+ sql_databases = get_sql_databases(
513
+ credentials,
514
+ subscription_id,
515
+ database_account,
516
+ )
517
+ cassandra_keyspaces = get_cassandra_keyspaces(
518
+ credentials,
519
+ subscription_id,
520
+ database_account,
521
+ )
522
+ mongodb_databases = get_mongodb_databases(
523
+ credentials,
524
+ subscription_id,
525
+ database_account,
526
+ )
527
+ table_resources = get_table_resources(
528
+ credentials,
529
+ subscription_id,
530
+ database_account,
531
+ )
532
+ yield database_account["id"], database_account["name"], database_account[
533
+ "resourceGroup"
426
534
  ], sql_databases, cassandra_keyspaces, mongodb_databases, table_resources
427
535
 
428
536
 
429
537
  @timeit
430
- def get_sql_databases(credentials: Credentials, subscription_id: str, database_account: Dict) -> List[Dict]:
538
+ def get_sql_databases(
539
+ credentials: Credentials,
540
+ subscription_id: str,
541
+ database_account: Dict,
542
+ ) -> List[Dict]:
431
543
  """
432
544
  Return the list of SQL Databases in a database account.
433
545
  """
@@ -437,27 +549,34 @@ def get_sql_databases(credentials: Credentials, subscription_id: str, database_a
437
549
  map(
438
550
  lambda x: x.as_dict(),
439
551
  client.sql_resources.list_sql_databases(
440
- database_account['resourceGroup'],
441
- database_account['name'],
552
+ database_account["resourceGroup"],
553
+ database_account["name"],
442
554
  ),
443
555
  ),
444
556
  )
445
557
 
446
558
  except ClientAuthenticationError:
447
- logger.warning('Client Authentication Error while retrieving SQL databases', exc_info=True)
559
+ logger.warning(
560
+ "Client Authentication Error while retrieving SQL databases",
561
+ exc_info=True,
562
+ )
448
563
  return []
449
564
  except ResourceNotFoundError:
450
- logger.warning('SQL databases resource not found error', exc_info=True)
565
+ logger.warning("SQL databases resource not found error", exc_info=True)
451
566
  return []
452
567
  except HttpResponseError:
453
- logger.warning('Error while retrieving SQL Database list', exc_info=True)
568
+ logger.warning("Error while retrieving SQL Database list", exc_info=True)
454
569
  return []
455
570
 
456
571
  return sql_database_list
457
572
 
458
573
 
459
574
  @timeit
460
- def get_cassandra_keyspaces(credentials: Credentials, subscription_id: str, database_account: Dict) -> List[Dict]:
575
+ def get_cassandra_keyspaces(
576
+ credentials: Credentials,
577
+ subscription_id: str,
578
+ database_account: Dict,
579
+ ) -> List[Dict]:
461
580
  """
462
581
  Return the list of Cassandra Keyspaces in a database account.
463
582
  """
@@ -467,27 +586,34 @@ def get_cassandra_keyspaces(credentials: Credentials, subscription_id: str, data
467
586
  map(
468
587
  lambda x: x.as_dict(),
469
588
  client.cassandra_resources.list_cassandra_keyspaces(
470
- database_account['resourceGroup'],
471
- database_account['name'],
589
+ database_account["resourceGroup"],
590
+ database_account["name"],
472
591
  ),
473
592
  ),
474
593
  )
475
594
 
476
595
  except ClientAuthenticationError:
477
- logger.warning('Client Authentication Error while retrieving Cassandra keyspaces', exc_info=True)
596
+ logger.warning(
597
+ "Client Authentication Error while retrieving Cassandra keyspaces",
598
+ exc_info=True,
599
+ )
478
600
  return []
479
601
  except ResourceNotFoundError:
480
- logger.warning('Cassandra keyspaces resource not found error', exc_info=True)
602
+ logger.warning("Cassandra keyspaces resource not found error", exc_info=True)
481
603
  return []
482
604
  except HttpResponseError:
483
- logger.warning('Error while retrieving Cassandra keyspaces list', exc_info=True)
605
+ logger.warning("Error while retrieving Cassandra keyspaces list", exc_info=True)
484
606
  return []
485
607
 
486
608
  return cassandra_keyspace_list
487
609
 
488
610
 
489
611
  @timeit
490
- def get_mongodb_databases(credentials: Credentials, subscription_id: str, database_account: Dict) -> List[Dict]:
612
+ def get_mongodb_databases(
613
+ credentials: Credentials,
614
+ subscription_id: str,
615
+ database_account: Dict,
616
+ ) -> List[Dict]:
491
617
  """
492
618
  Return the list of MongoDB Databases in a database account.
493
619
  """
@@ -497,27 +623,34 @@ def get_mongodb_databases(credentials: Credentials, subscription_id: str, databa
497
623
  map(
498
624
  lambda x: x.as_dict(),
499
625
  client.mongo_db_resources.list_mongo_db_databases(
500
- database_account['resourceGroup'],
501
- database_account['name'],
626
+ database_account["resourceGroup"],
627
+ database_account["name"],
502
628
  ),
503
629
  ),
504
630
  )
505
631
 
506
632
  except ClientAuthenticationError:
507
- logger.warning('Client Authentication Error while retrieving MongoDB Databases', exc_info=True)
633
+ logger.warning(
634
+ "Client Authentication Error while retrieving MongoDB Databases",
635
+ exc_info=True,
636
+ )
508
637
  return []
509
638
  except ResourceNotFoundError:
510
- logger.warning('MongoDB Databases resource not found error', exc_info=True)
639
+ logger.warning("MongoDB Databases resource not found error", exc_info=True)
511
640
  return []
512
641
  except HttpResponseError:
513
- logger.warning('Error while retrieving MongoDB Databases list', exc_info=True)
642
+ logger.warning("Error while retrieving MongoDB Databases list", exc_info=True)
514
643
  return []
515
644
 
516
645
  return mongodb_database_list
517
646
 
518
647
 
519
648
  @timeit
520
- def get_table_resources(credentials: Credentials, subscription_id: str, database_account: Dict) -> List[Dict]:
649
+ def get_table_resources(
650
+ credentials: Credentials,
651
+ subscription_id: str,
652
+ database_account: Dict,
653
+ ) -> List[Dict]:
521
654
  """
522
655
  Return the list of Table Resources in a database account.
523
656
  """
@@ -527,20 +660,23 @@ def get_table_resources(credentials: Credentials, subscription_id: str, database
527
660
  map(
528
661
  lambda x: x.as_dict(),
529
662
  client.table_resources.list_tables(
530
- database_account['resourceGroup'],
531
- database_account['name'],
663
+ database_account["resourceGroup"],
664
+ database_account["name"],
532
665
  ),
533
666
  ),
534
667
  )
535
668
 
536
669
  except ClientAuthenticationError:
537
- logger.warning('Client Authentication Error while retrieving Table resources', exc_info=True)
670
+ logger.warning(
671
+ "Client Authentication Error while retrieving Table resources",
672
+ exc_info=True,
673
+ )
538
674
  return []
539
675
  except ResourceNotFoundError:
540
- logger.warning('Table resource not found error', exc_info=True)
676
+ logger.warning("Table resource not found error", exc_info=True)
541
677
  return []
542
678
  except HttpResponseError:
543
- logger.warning('Error while retrieving Table resources list', exc_info=True)
679
+ logger.warning("Error while retrieving Table resources list", exc_info=True)
544
680
  return []
545
681
 
546
682
  return table_resources_list
@@ -548,22 +684,29 @@ def get_table_resources(credentials: Credentials, subscription_id: str, database
548
684
 
549
685
  @timeit
550
686
  def transform_database_account_resources(
551
- account_id: Any, name: Any, resource_group: Any, resources: List[Dict],
687
+ account_id: Any,
688
+ name: Any,
689
+ resource_group: Any,
690
+ resources: List[Dict],
552
691
  ) -> List[Dict]:
553
692
  """
554
693
  Transform the SQL Database/Cassandra Keyspace/MongoDB Database/Table Resource response for neo4j ingestion.
555
694
  """
556
695
  for resource in resources:
557
- resource['database_account_name'] = name
558
- resource['database_account_id'] = account_id
559
- resource['resource_group_name'] = resource_group
696
+ resource["database_account_name"] = name
697
+ resource["database_account_id"] = account_id
698
+ resource["resource_group_name"] = resource_group
560
699
  return resources
561
700
 
562
701
 
563
702
  @timeit
564
703
  def load_database_account_details(
565
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
566
- details: List[Tuple[Any, Any, Any, Any, Any, Any, Any]], update_tag: int, common_job_parameters: Dict,
704
+ neo4j_session: neo4j.Session,
705
+ credentials: Credentials,
706
+ subscription_id: str,
707
+ details: List[Tuple[Any, Any, Any, Any, Any, Any, Any]],
708
+ update_tag: int,
709
+ common_job_parameters: Dict,
567
710
  ) -> None:
568
711
  """
569
712
  Create dictionaries for SQL Databases, Cassandra Keyspaces, MongoDB Databases and table resources.
@@ -573,21 +716,49 @@ def load_database_account_details(
573
716
  mongodb_databases: List[Dict] = []
574
717
  table_resources: List[Dict] = []
575
718
 
576
- for account_id, name, resourceGroup, sql_database, cassandra_keyspace, mongodb_database, table in details:
719
+ for (
720
+ account_id,
721
+ name,
722
+ resourceGroup,
723
+ sql_database,
724
+ cassandra_keyspace,
725
+ mongodb_database,
726
+ table,
727
+ ) in details:
577
728
  if len(sql_database) > 0:
578
- dbs = transform_database_account_resources(account_id, name, resourceGroup, sql_database)
729
+ dbs = transform_database_account_resources(
730
+ account_id,
731
+ name,
732
+ resourceGroup,
733
+ sql_database,
734
+ )
579
735
  sql_databases.extend(dbs)
580
736
 
581
737
  if len(cassandra_keyspace) > 0:
582
- keyspaces = transform_database_account_resources(account_id, name, resourceGroup, cassandra_keyspace)
738
+ keyspaces = transform_database_account_resources(
739
+ account_id,
740
+ name,
741
+ resourceGroup,
742
+ cassandra_keyspace,
743
+ )
583
744
  cassandra_keyspaces.extend(keyspaces)
584
745
 
585
746
  if len(mongodb_database) > 0:
586
- mongo_dbs = transform_database_account_resources(account_id, name, resourceGroup, mongodb_database)
747
+ mongo_dbs = transform_database_account_resources(
748
+ account_id,
749
+ name,
750
+ resourceGroup,
751
+ mongodb_database,
752
+ )
587
753
  mongodb_databases.extend(mongo_dbs)
588
754
 
589
755
  if len(table) > 0:
590
- t = transform_database_account_resources(account_id, name, resourceGroup, table)
756
+ t = transform_database_account_resources(
757
+ account_id,
758
+ name,
759
+ resourceGroup,
760
+ table,
761
+ )
591
762
  table_resources.extend(t)
592
763
 
593
764
  # Loading the table resources
@@ -601,21 +772,37 @@ def load_database_account_details(
601
772
  _load_mongodb_databases(neo4j_session, mongodb_databases, update_tag)
602
773
 
603
774
  sync_sql_database_details(
604
- neo4j_session, credentials, subscription_id, sql_databases, update_tag,
775
+ neo4j_session,
776
+ credentials,
777
+ subscription_id,
778
+ sql_databases,
779
+ update_tag,
605
780
  common_job_parameters,
606
781
  )
607
782
  sync_cassandra_keyspace_details(
608
- neo4j_session, credentials, subscription_id, cassandra_keyspaces, update_tag,
783
+ neo4j_session,
784
+ credentials,
785
+ subscription_id,
786
+ cassandra_keyspaces,
787
+ update_tag,
609
788
  common_job_parameters,
610
789
  )
611
790
  sync_mongodb_database_details(
612
- neo4j_session, credentials, subscription_id, mongodb_databases, update_tag,
791
+ neo4j_session,
792
+ credentials,
793
+ subscription_id,
794
+ mongodb_databases,
795
+ update_tag,
613
796
  common_job_parameters,
614
797
  )
615
798
 
616
799
 
617
800
  @timeit
618
- def _load_sql_databases(neo4j_session: neo4j.Session, sql_databases: List[Dict], update_tag: int) -> None:
801
+ def _load_sql_databases(
802
+ neo4j_session: neo4j.Session,
803
+ sql_databases: List[Dict],
804
+ update_tag: int,
805
+ ) -> None:
619
806
  """
620
807
  Ingest SQL Databases into neo4j.
621
808
  """
@@ -643,7 +830,11 @@ def _load_sql_databases(neo4j_session: neo4j.Session, sql_databases: List[Dict],
643
830
 
644
831
 
645
832
  @timeit
646
- def _load_cassandra_keyspaces(neo4j_session: neo4j.Session, cassandra_keyspaces: List[Dict], update_tag: int) -> None:
833
+ def _load_cassandra_keyspaces(
834
+ neo4j_session: neo4j.Session,
835
+ cassandra_keyspaces: List[Dict],
836
+ update_tag: int,
837
+ ) -> None:
647
838
  """
648
839
  Ingest Cassandra keyspaces into neo4j.
649
840
  """
@@ -671,7 +862,11 @@ def _load_cassandra_keyspaces(neo4j_session: neo4j.Session, cassandra_keyspaces:
671
862
 
672
863
 
673
864
  @timeit
674
- def _load_mongodb_databases(neo4j_session: neo4j.Session, mongodb_databases: List[Dict], update_tag: int) -> None:
865
+ def _load_mongodb_databases(
866
+ neo4j_session: neo4j.Session,
867
+ mongodb_databases: List[Dict],
868
+ update_tag: int,
869
+ ) -> None:
675
870
  """
676
871
  Ingest MongoDB databases into neo4j.
677
872
  """
@@ -699,7 +894,11 @@ def _load_mongodb_databases(neo4j_session: neo4j.Session, mongodb_databases: Lis
699
894
 
700
895
 
701
896
  @timeit
702
- def _load_table_resources(neo4j_session: neo4j.Session, table_resources: List[Dict], update_tag: int) -> None:
897
+ def _load_table_resources(
898
+ neo4j_session: neo4j.Session,
899
+ table_resources: List[Dict],
900
+ update_tag: int,
901
+ ) -> None:
703
902
  """
704
903
  Ingest Table resources into neo4j.
705
904
  """
@@ -728,28 +927,42 @@ def _load_table_resources(neo4j_session: neo4j.Session, table_resources: List[Di
728
927
 
729
928
  @timeit
730
929
  def sync_sql_database_details(
731
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str, sql_databases: List[Dict],
732
- update_tag: int, common_job_parameters: Dict,
930
+ neo4j_session: neo4j.Session,
931
+ credentials: Credentials,
932
+ subscription_id: str,
933
+ sql_databases: List[Dict],
934
+ update_tag: int,
935
+ common_job_parameters: Dict,
733
936
  ) -> None:
734
- sql_database_details = get_sql_database_details(credentials, subscription_id, sql_databases)
937
+ sql_database_details = get_sql_database_details(
938
+ credentials,
939
+ subscription_id,
940
+ sql_databases,
941
+ )
735
942
  load_sql_database_details(neo4j_session, sql_database_details, update_tag)
736
943
  cleanup_sql_database_details(neo4j_session, common_job_parameters)
737
944
 
738
945
 
739
946
  @timeit
740
947
  def get_sql_database_details(
741
- credentials: Credentials, subscription_id: str, sql_databases: List[Dict],
948
+ credentials: Credentials,
949
+ subscription_id: str,
950
+ sql_databases: List[Dict],
742
951
  ) -> Generator[Any, Any, Any]:
743
952
  """
744
953
  Iterate over the SQL databases to retrieve the SQL containers in them.
745
954
  """
746
955
  for database in sql_databases:
747
956
  containers = get_sql_containers(credentials, subscription_id, database)
748
- yield database['id'], containers
957
+ yield database["id"], containers
749
958
 
750
959
 
751
960
  @timeit
752
- def get_sql_containers(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
961
+ def get_sql_containers(
962
+ credentials: Credentials,
963
+ subscription_id: str,
964
+ database: Dict,
965
+ ) -> List[Dict]:
753
966
  """
754
967
  Returns the list of SQL containers in a database.
755
968
  """
@@ -759,28 +972,35 @@ def get_sql_containers(credentials: Credentials, subscription_id: str, database:
759
972
  map(
760
973
  lambda x: x.as_dict(),
761
974
  client.sql_resources.list_sql_containers(
762
- database['resource_group_name'],
763
- database['database_account_name'],
764
- database['name'],
975
+ database["resource_group_name"],
976
+ database["database_account_name"],
977
+ database["name"],
765
978
  ),
766
979
  ),
767
980
  )
768
981
 
769
982
  except ClientAuthenticationError:
770
- logger.warning('Client Authentication Error while retrieving SQL containers', exc_info=True)
983
+ logger.warning(
984
+ "Client Authentication Error while retrieving SQL containers",
985
+ exc_info=True,
986
+ )
771
987
  return []
772
988
  except ResourceNotFoundError:
773
- logger.warning('SQL containers not found error', exc_info=True)
989
+ logger.warning("SQL containers not found error", exc_info=True)
774
990
  return []
775
991
  except HttpResponseError:
776
- logger.warning('Error while retrieving SQL containers list', exc_info=True)
992
+ logger.warning("Error while retrieving SQL containers list", exc_info=True)
777
993
  return []
778
994
 
779
995
  return containers
780
996
 
781
997
 
782
998
  @timeit
783
- def load_sql_database_details(neo4j_session: neo4j.Session, details: List[Tuple[Any, Any]], update_tag: int) -> None:
999
+ def load_sql_database_details(
1000
+ neo4j_session: neo4j.Session,
1001
+ details: List[Tuple[Any, Any]],
1002
+ update_tag: int,
1003
+ ) -> None:
784
1004
  """
785
1005
  Create dictionary for SQL Containers
786
1006
  """
@@ -789,14 +1009,18 @@ def load_sql_database_details(neo4j_session: neo4j.Session, details: List[Tuple[
789
1009
  for database_id, container in details:
790
1010
  if len(container) > 0:
791
1011
  for c in container:
792
- c['database_id'] = database_id
1012
+ c["database_id"] = database_id
793
1013
  containers.extend(container)
794
1014
 
795
1015
  _load_sql_containers(neo4j_session, containers, update_tag)
796
1016
 
797
1017
 
798
1018
  @timeit
799
- def _load_sql_containers(neo4j_session: neo4j.Session, containers: List[Dict], update_tag: int) -> None:
1019
+ def _load_sql_containers(
1020
+ neo4j_session: neo4j.Session,
1021
+ containers: List[Dict],
1022
+ update_tag: int,
1023
+ ) -> None:
800
1024
  """
801
1025
  Ingest SQL Container details into neo4j.
802
1026
  """
@@ -831,28 +1055,46 @@ def _load_sql_containers(neo4j_session: neo4j.Session, containers: List[Dict], u
831
1055
 
832
1056
  @timeit
833
1057
  def sync_cassandra_keyspace_details(
834
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str, cassandra_keyspaces: List[Dict],
835
- update_tag: int, common_job_parameters: Dict,
1058
+ neo4j_session: neo4j.Session,
1059
+ credentials: Credentials,
1060
+ subscription_id: str,
1061
+ cassandra_keyspaces: List[Dict],
1062
+ update_tag: int,
1063
+ common_job_parameters: Dict,
836
1064
  ) -> None:
837
- cassandra_keyspace_details = get_cassandra_keyspace_details(credentials, subscription_id, cassandra_keyspaces)
838
- load_cassandra_keyspace_details(neo4j_session, cassandra_keyspace_details, update_tag)
1065
+ cassandra_keyspace_details = get_cassandra_keyspace_details(
1066
+ credentials,
1067
+ subscription_id,
1068
+ cassandra_keyspaces,
1069
+ )
1070
+ load_cassandra_keyspace_details(
1071
+ neo4j_session,
1072
+ cassandra_keyspace_details,
1073
+ update_tag,
1074
+ )
839
1075
  cleanup_cassandra_keyspace_details(neo4j_session, common_job_parameters)
840
1076
 
841
1077
 
842
1078
  @timeit
843
1079
  def get_cassandra_keyspace_details(
844
- credentials: Credentials, subscription_id: str, cassandra_keyspaces: List[Dict],
1080
+ credentials: Credentials,
1081
+ subscription_id: str,
1082
+ cassandra_keyspaces: List[Dict],
845
1083
  ) -> Generator[Any, Any, Any]:
846
1084
  """
847
1085
  Iterate through the Cassandra keyspaces to get the list of tables in each keyspace.
848
1086
  """
849
1087
  for keyspace in cassandra_keyspaces:
850
1088
  cassandra_tables = get_cassandra_tables(credentials, subscription_id, keyspace)
851
- yield keyspace['id'], cassandra_tables
1089
+ yield keyspace["id"], cassandra_tables
852
1090
 
853
1091
 
854
1092
  @timeit
855
- def get_cassandra_tables(credentials: Credentials, subscription_id: str, keyspace: Dict) -> List[Dict]:
1093
+ def get_cassandra_tables(
1094
+ credentials: Credentials,
1095
+ subscription_id: str,
1096
+ keyspace: Dict,
1097
+ ) -> List[Dict]:
856
1098
  """
857
1099
  Returns the list of tables in a Cassandra Keyspace.
858
1100
  """
@@ -862,21 +1104,24 @@ def get_cassandra_tables(credentials: Credentials, subscription_id: str, keyspac
862
1104
  map(
863
1105
  lambda x: x.as_dict(),
864
1106
  client.cassandra_resources.list_cassandra_tables(
865
- keyspace['resource_group_name'],
866
- keyspace['database_account_name'],
867
- keyspace['name'],
1107
+ keyspace["resource_group_name"],
1108
+ keyspace["database_account_name"],
1109
+ keyspace["name"],
868
1110
  ),
869
1111
  ),
870
1112
  )
871
1113
 
872
1114
  except ClientAuthenticationError:
873
- logger.warning('Client Authentication Error while retrieving Cassandra tables', exc_info=True)
1115
+ logger.warning(
1116
+ "Client Authentication Error while retrieving Cassandra tables",
1117
+ exc_info=True,
1118
+ )
874
1119
  return []
875
1120
  except ResourceNotFoundError:
876
- logger.warning('Cassandra tables not found error', exc_info=True)
1121
+ logger.warning("Cassandra tables not found error", exc_info=True)
877
1122
  return []
878
1123
  except HttpResponseError:
879
- logger.warning('Error while retrieving Cassandra tables list', exc_info=True)
1124
+ logger.warning("Error while retrieving Cassandra tables list", exc_info=True)
880
1125
  return []
881
1126
 
882
1127
  return cassandra_tables
@@ -884,7 +1129,9 @@ def get_cassandra_tables(credentials: Credentials, subscription_id: str, keyspac
884
1129
 
885
1130
  @timeit
886
1131
  def load_cassandra_keyspace_details(
887
- neo4j_session: neo4j.Session, details: List[Tuple[Any, Any]], update_tag: int,
1132
+ neo4j_session: neo4j.Session,
1133
+ details: List[Tuple[Any, Any]],
1134
+ update_tag: int,
888
1135
  ) -> None:
889
1136
  """
890
1137
  Create a dictionary for Cassandra tables.
@@ -894,14 +1141,18 @@ def load_cassandra_keyspace_details(
894
1141
  for keyspace_id, cassandra_table in details:
895
1142
  if len(cassandra_table) > 0:
896
1143
  for t in cassandra_table:
897
- t['keyspace_id'] = keyspace_id
1144
+ t["keyspace_id"] = keyspace_id
898
1145
  cassandra_tables.extend(cassandra_table)
899
1146
 
900
1147
  _load_cassandra_tables(neo4j_session, cassandra_tables, update_tag)
901
1148
 
902
1149
 
903
1150
  @timeit
904
- def _load_cassandra_tables(neo4j_session: neo4j.Session, cassandra_tables: List[Dict], update_tag: int) -> None:
1151
+ def _load_cassandra_tables(
1152
+ neo4j_session: neo4j.Session,
1153
+ cassandra_tables: List[Dict],
1154
+ update_tag: int,
1155
+ ) -> None:
905
1156
  """
906
1157
  Ingest Cassandra Tables into neo4j.
907
1158
  """
@@ -933,28 +1184,42 @@ def _load_cassandra_tables(neo4j_session: neo4j.Session, cassandra_tables: List[
933
1184
 
934
1185
  @timeit
935
1186
  def sync_mongodb_database_details(
936
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str, mongodb_databases: List[Dict],
937
- update_tag: int, common_job_parameters: Dict,
1187
+ neo4j_session: neo4j.Session,
1188
+ credentials: Credentials,
1189
+ subscription_id: str,
1190
+ mongodb_databases: List[Dict],
1191
+ update_tag: int,
1192
+ common_job_parameters: Dict,
938
1193
  ) -> None:
939
- mongodb_databases_details = get_mongodb_databases_details(credentials, subscription_id, mongodb_databases)
1194
+ mongodb_databases_details = get_mongodb_databases_details(
1195
+ credentials,
1196
+ subscription_id,
1197
+ mongodb_databases,
1198
+ )
940
1199
  load_mongodb_databases_details(neo4j_session, mongodb_databases_details, update_tag)
941
1200
  cleanup_mongodb_database_details(neo4j_session, common_job_parameters)
942
1201
 
943
1202
 
944
1203
  @timeit
945
1204
  def get_mongodb_databases_details(
946
- credentials: Credentials, subscription_id: str, mongodb_databases: List[Dict],
1205
+ credentials: Credentials,
1206
+ subscription_id: str,
1207
+ mongodb_databases: List[Dict],
947
1208
  ) -> Generator[Any, Any, Any]:
948
1209
  """
949
1210
  Iterate through the MongoDB Databases to get the list of collections in each mongoDB database.
950
1211
  """
951
1212
  for database in mongodb_databases:
952
1213
  collections = get_mongodb_collections(credentials, subscription_id, database)
953
- yield database['id'], collections
1214
+ yield database["id"], collections
954
1215
 
955
1216
 
956
1217
  @timeit
957
- def get_mongodb_collections(credentials: Credentials, subscription_id: str, database: Dict) -> List[Dict]:
1218
+ def get_mongodb_collections(
1219
+ credentials: Credentials,
1220
+ subscription_id: str,
1221
+ database: Dict,
1222
+ ) -> List[Dict]:
958
1223
  """
959
1224
  Returns the list of collections in a MongoDB Database.
960
1225
  """
@@ -964,21 +1229,24 @@ def get_mongodb_collections(credentials: Credentials, subscription_id: str, data
964
1229
  map(
965
1230
  lambda x: x.as_dict(),
966
1231
  client.mongo_db_resources.list_mongo_db_collections(
967
- database['resource_group_name'],
968
- database['database_account_name'],
969
- database['name'],
1232
+ database["resource_group_name"],
1233
+ database["database_account_name"],
1234
+ database["name"],
970
1235
  ),
971
1236
  ),
972
1237
  )
973
1238
 
974
1239
  except ClientAuthenticationError:
975
- logger.warning('Client Authentication Error while retrieving MongoDB collections', exc_info=True)
1240
+ logger.warning(
1241
+ "Client Authentication Error while retrieving MongoDB collections",
1242
+ exc_info=True,
1243
+ )
976
1244
  return []
977
1245
  except ResourceNotFoundError:
978
- logger.warning('MongoDB collections not found error', exc_info=True)
1246
+ logger.warning("MongoDB collections not found error", exc_info=True)
979
1247
  return []
980
1248
  except HttpResponseError:
981
- logger.warning('Error while retrieving MongoDB collections list', exc_info=True)
1249
+ logger.warning("Error while retrieving MongoDB collections list", exc_info=True)
982
1250
  return []
983
1251
 
984
1252
  return collections
@@ -986,7 +1254,9 @@ def get_mongodb_collections(credentials: Credentials, subscription_id: str, data
986
1254
 
987
1255
  @timeit
988
1256
  def load_mongodb_databases_details(
989
- neo4j_session: neo4j.Session, details: List[Tuple[Any, Any]], update_tag: int,
1257
+ neo4j_session: neo4j.Session,
1258
+ details: List[Tuple[Any, Any]],
1259
+ update_tag: int,
990
1260
  ) -> None:
991
1261
  """
992
1262
  Create a dictionary for MongoDB tables.
@@ -996,14 +1266,18 @@ def load_mongodb_databases_details(
996
1266
  for database_id, collection in details:
997
1267
  if len(collection) > 0:
998
1268
  for c in collection:
999
- c['database_id'] = database_id
1269
+ c["database_id"] = database_id
1000
1270
  collections.extend(collection)
1001
1271
 
1002
1272
  _load_collections(neo4j_session, collections, update_tag)
1003
1273
 
1004
1274
 
1005
1275
  @timeit
1006
- def _load_collections(neo4j_session: neo4j.Session, collections: List[Dict], update_tag: int) -> None:
1276
+ def _load_collections(
1277
+ neo4j_session: neo4j.Session,
1278
+ collections: List[Dict],
1279
+ update_tag: int,
1280
+ ) -> None:
1007
1281
  """
1008
1282
  Ingest MongoDB Collections into neo4j.
1009
1283
  """
@@ -1033,42 +1307,94 @@ def _load_collections(neo4j_session: neo4j.Session, collections: List[Dict], upd
1033
1307
 
1034
1308
 
1035
1309
  @timeit
1036
- def cleanup_azure_database_accounts(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
1037
- run_cleanup_job('azure_database_account_cleanup.json', neo4j_session, common_job_parameters)
1310
+ def cleanup_azure_database_accounts(
1311
+ neo4j_session: neo4j.Session,
1312
+ common_job_parameters: Dict,
1313
+ ) -> None:
1314
+ run_cleanup_job(
1315
+ "azure_database_account_cleanup.json",
1316
+ neo4j_session,
1317
+ common_job_parameters,
1318
+ )
1038
1319
 
1039
1320
 
1040
1321
  @timeit
1041
- def cleanup_sql_database_details(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
1042
- run_cleanup_job('azure_cosmosdb_sql_database_cleanup.json', neo4j_session, common_job_parameters)
1322
+ def cleanup_sql_database_details(
1323
+ neo4j_session: neo4j.Session,
1324
+ common_job_parameters: Dict,
1325
+ ) -> None:
1326
+ run_cleanup_job(
1327
+ "azure_cosmosdb_sql_database_cleanup.json",
1328
+ neo4j_session,
1329
+ common_job_parameters,
1330
+ )
1043
1331
 
1044
1332
 
1045
1333
  @timeit
1046
- def cleanup_cassandra_keyspace_details(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
1047
- run_cleanup_job('azure_cosmosdb_cassandra_keyspace_cleanup.json', neo4j_session, common_job_parameters)
1334
+ def cleanup_cassandra_keyspace_details(
1335
+ neo4j_session: neo4j.Session,
1336
+ common_job_parameters: Dict,
1337
+ ) -> None:
1338
+ run_cleanup_job(
1339
+ "azure_cosmosdb_cassandra_keyspace_cleanup.json",
1340
+ neo4j_session,
1341
+ common_job_parameters,
1342
+ )
1048
1343
 
1049
1344
 
1050
1345
  @timeit
1051
- def cleanup_mongodb_database_details(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
1052
- run_cleanup_job('azure_cosmosdb_mongodb_database_cleanup.json', neo4j_session, common_job_parameters)
1346
+ def cleanup_mongodb_database_details(
1347
+ neo4j_session: neo4j.Session,
1348
+ common_job_parameters: Dict,
1349
+ ) -> None:
1350
+ run_cleanup_job(
1351
+ "azure_cosmosdb_mongodb_database_cleanup.json",
1352
+ neo4j_session,
1353
+ common_job_parameters,
1354
+ )
1053
1355
 
1054
1356
 
1055
1357
  @timeit
1056
- def cleanup_table_resources(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
1057
- run_cleanup_job('azure_cosmosdb_table_resources_cleanup.json', neo4j_session, common_job_parameters)
1358
+ def cleanup_table_resources(
1359
+ neo4j_session: neo4j.Session,
1360
+ common_job_parameters: Dict,
1361
+ ) -> None:
1362
+ run_cleanup_job(
1363
+ "azure_cosmosdb_table_resources_cleanup.json",
1364
+ neo4j_session,
1365
+ common_job_parameters,
1366
+ )
1058
1367
 
1059
1368
 
1060
1369
  @timeit
1061
1370
  def sync(
1062
- neo4j_session: neo4j.Session, credentials: Credentials, subscription_id: str,
1063
- sync_tag: int, common_job_parameters: Dict,
1371
+ neo4j_session: neo4j.Session,
1372
+ credentials: Credentials,
1373
+ subscription_id: str,
1374
+ sync_tag: int,
1375
+ common_job_parameters: Dict,
1064
1376
  ) -> None:
1065
1377
  logger.info("Syncing Azure CosmosDB for subscription '%s'.", subscription_id)
1066
1378
  database_account_list = get_database_account_list(credentials, subscription_id)
1067
1379
  database_account_list = transform_database_account_data(database_account_list)
1068
- load_database_account_data(neo4j_session, subscription_id, database_account_list, sync_tag)
1069
- sync_database_account_data_resources(neo4j_session, subscription_id, database_account_list, sync_tag)
1380
+ load_database_account_data(
1381
+ neo4j_session,
1382
+ subscription_id,
1383
+ database_account_list,
1384
+ sync_tag,
1385
+ )
1386
+ sync_database_account_data_resources(
1387
+ neo4j_session,
1388
+ subscription_id,
1389
+ database_account_list,
1390
+ sync_tag,
1391
+ )
1070
1392
  sync_database_account_details(
1071
- neo4j_session, credentials, subscription_id, database_account_list, sync_tag,
1393
+ neo4j_session,
1394
+ credentials,
1395
+ subscription_id,
1396
+ database_account_list,
1397
+ sync_tag,
1072
1398
  common_job_parameters,
1073
1399
  )
1074
1400
  cleanup_azure_database_accounts(neo4j_session, common_job_parameters)