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.
- cartography/__main__.py +1 -2
- cartography/_version.py +2 -2
- cartography/cli.py +376 -249
- cartography/client/core/tx.py +39 -18
- cartography/config.py +28 -0
- cartography/driftdetect/__main__.py +1 -2
- cartography/driftdetect/add_shortcut.py +10 -2
- cartography/driftdetect/cli.py +71 -75
- cartography/driftdetect/detect_deviations.py +7 -3
- cartography/driftdetect/get_states.py +20 -8
- cartography/driftdetect/model.py +5 -5
- cartography/driftdetect/serializers.py +8 -6
- cartography/driftdetect/storage.py +2 -2
- cartography/graph/cleanupbuilder.py +35 -15
- cartography/graph/job.py +46 -17
- cartography/graph/querybuilder.py +165 -80
- cartography/graph/statement.py +35 -26
- cartography/intel/analysis.py +4 -1
- cartography/intel/aws/__init__.py +114 -55
- cartography/intel/aws/apigateway.py +134 -63
- cartography/intel/aws/cloudtrail.py +127 -0
- cartography/intel/aws/cloudwatch.py +93 -0
- cartography/intel/aws/config.py +56 -20
- cartography/intel/aws/dynamodb.py +108 -40
- cartography/intel/aws/ec2/__init__.py +2 -2
- cartography/intel/aws/ec2/auto_scaling_groups.py +181 -78
- cartography/intel/aws/ec2/elastic_ip_addresses.py +41 -13
- cartography/intel/aws/ec2/images.py +49 -20
- cartography/intel/aws/ec2/instances.py +234 -136
- cartography/intel/aws/ec2/internet_gateways.py +40 -11
- cartography/intel/aws/ec2/key_pairs.py +44 -20
- cartography/intel/aws/ec2/launch_templates.py +101 -59
- cartography/intel/aws/ec2/load_balancer_v2s.py +104 -39
- cartography/intel/aws/ec2/load_balancers.py +82 -42
- cartography/intel/aws/ec2/network_acls.py +89 -65
- cartography/intel/aws/ec2/network_interfaces.py +146 -87
- cartography/intel/aws/ec2/reserved_instances.py +45 -16
- cartography/intel/aws/ec2/route_tables.py +138 -98
- cartography/intel/aws/ec2/security_groups.py +71 -21
- cartography/intel/aws/ec2/snapshots.py +61 -22
- cartography/intel/aws/ec2/subnets.py +54 -18
- cartography/intel/aws/ec2/tgw.py +100 -34
- cartography/intel/aws/ec2/util.py +1 -1
- cartography/intel/aws/ec2/volumes.py +69 -41
- cartography/intel/aws/ec2/vpc.py +37 -12
- cartography/intel/aws/ec2/vpc_peerings.py +83 -24
- cartography/intel/aws/ecr.py +88 -32
- cartography/intel/aws/ecs.py +83 -47
- cartography/intel/aws/efs.py +93 -0
- cartography/intel/aws/eks.py +55 -29
- cartography/intel/aws/elasticache.py +42 -18
- cartography/intel/aws/elasticsearch.py +57 -20
- cartography/intel/aws/emr.py +61 -23
- cartography/intel/aws/iam.py +401 -145
- cartography/intel/aws/iam_instance_profiles.py +22 -22
- cartography/intel/aws/identitycenter.py +71 -37
- cartography/intel/aws/inspector.py +159 -89
- cartography/intel/aws/kms.py +92 -38
- cartography/intel/aws/lambda_function.py +103 -34
- cartography/intel/aws/organizations.py +30 -10
- cartography/intel/aws/permission_relationships.py +133 -51
- cartography/intel/aws/rds.py +249 -85
- cartography/intel/aws/redshift.py +107 -46
- cartography/intel/aws/resourcegroupstaggingapi.py +120 -66
- cartography/intel/aws/resources.py +57 -46
- cartography/intel/aws/route53.py +108 -61
- cartography/intel/aws/s3.py +168 -83
- cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
- cartography/intel/aws/secretsmanager.py +24 -12
- cartography/intel/aws/securityhub.py +20 -9
- cartography/intel/aws/sns.py +166 -0
- cartography/intel/aws/sqs.py +60 -28
- cartography/intel/aws/ssm.py +70 -30
- cartography/intel/aws/util/arns.py +7 -7
- cartography/intel/aws/util/common.py +31 -4
- cartography/intel/azure/__init__.py +78 -19
- cartography/intel/azure/compute.py +101 -27
- cartography/intel/azure/cosmosdb.py +496 -170
- cartography/intel/azure/sql.py +296 -105
- cartography/intel/azure/storage.py +322 -113
- cartography/intel/azure/subscription.py +39 -23
- cartography/intel/azure/tenant.py +13 -4
- cartography/intel/azure/util/credentials.py +95 -55
- cartography/intel/bigfix/__init__.py +2 -2
- cartography/intel/bigfix/computers.py +93 -65
- cartography/intel/cloudflare/__init__.py +74 -0
- cartography/intel/cloudflare/accounts.py +57 -0
- cartography/intel/cloudflare/dnsrecords.py +64 -0
- cartography/intel/cloudflare/members.py +75 -0
- cartography/intel/cloudflare/roles.py +65 -0
- cartography/intel/cloudflare/zones.py +64 -0
- cartography/intel/create_indexes.py +3 -2
- cartography/intel/crowdstrike/__init__.py +11 -9
- cartography/intel/crowdstrike/endpoints.py +5 -1
- cartography/intel/crowdstrike/spotlight.py +8 -3
- cartography/intel/cve/__init__.py +46 -13
- cartography/intel/cve/feed.py +48 -12
- cartography/intel/digitalocean/__init__.py +22 -13
- cartography/intel/digitalocean/compute.py +75 -108
- cartography/intel/digitalocean/management.py +44 -80
- cartography/intel/digitalocean/platform.py +48 -43
- cartography/intel/dns.py +36 -10
- cartography/intel/duo/__init__.py +21 -16
- cartography/intel/duo/api_host.py +14 -9
- cartography/intel/duo/endpoints.py +50 -45
- cartography/intel/duo/groups.py +18 -14
- cartography/intel/duo/phones.py +37 -34
- cartography/intel/duo/tokens.py +26 -23
- cartography/intel/duo/users.py +54 -50
- cartography/intel/duo/web_authn_credentials.py +30 -25
- cartography/intel/entra/__init__.py +25 -7
- cartography/intel/entra/ou.py +112 -0
- cartography/intel/entra/users.py +69 -63
- cartography/intel/gcp/__init__.py +185 -49
- cartography/intel/gcp/compute.py +418 -231
- cartography/intel/gcp/crm.py +96 -43
- cartography/intel/gcp/dns.py +60 -19
- cartography/intel/gcp/gke.py +72 -38
- cartography/intel/gcp/iam.py +61 -41
- cartography/intel/gcp/storage.py +84 -55
- cartography/intel/github/__init__.py +13 -11
- cartography/intel/github/repos.py +270 -137
- cartography/intel/github/teams.py +170 -88
- cartography/intel/github/users.py +70 -39
- cartography/intel/github/util.py +36 -34
- cartography/intel/gsuite/__init__.py +47 -26
- cartography/intel/gsuite/api.py +73 -30
- cartography/intel/jamf/__init__.py +19 -1
- cartography/intel/jamf/computers.py +30 -7
- cartography/intel/jamf/util.py +7 -2
- cartography/intel/kandji/__init__.py +6 -3
- cartography/intel/kandji/devices.py +14 -8
- cartography/intel/kubernetes/namespaces.py +7 -4
- cartography/intel/kubernetes/pods.py +7 -4
- cartography/intel/kubernetes/services.py +8 -4
- cartography/intel/lastpass/__init__.py +2 -2
- cartography/intel/lastpass/users.py +23 -12
- cartography/intel/oci/__init__.py +44 -11
- cartography/intel/oci/iam.py +134 -38
- cartography/intel/oci/organizations.py +13 -6
- cartography/intel/oci/utils.py +43 -20
- cartography/intel/okta/__init__.py +66 -15
- cartography/intel/okta/applications.py +42 -20
- cartography/intel/okta/awssaml.py +93 -33
- cartography/intel/okta/factors.py +16 -4
- cartography/intel/okta/groups.py +56 -29
- cartography/intel/okta/organization.py +5 -1
- cartography/intel/okta/origins.py +6 -2
- cartography/intel/okta/roles.py +15 -5
- cartography/intel/okta/users.py +20 -8
- cartography/intel/okta/utils.py +6 -4
- cartography/intel/openai/__init__.py +86 -0
- cartography/intel/openai/adminapikeys.py +90 -0
- cartography/intel/openai/apikeys.py +96 -0
- cartography/intel/openai/projects.py +94 -0
- cartography/intel/openai/serviceaccounts.py +82 -0
- cartography/intel/openai/users.py +78 -0
- cartography/intel/openai/util.py +29 -0
- cartography/intel/pagerduty/__init__.py +8 -7
- cartography/intel/pagerduty/escalation_policies.py +18 -6
- cartography/intel/pagerduty/schedules.py +12 -4
- cartography/intel/pagerduty/services.py +11 -4
- cartography/intel/pagerduty/teams.py +8 -3
- cartography/intel/pagerduty/users.py +3 -1
- cartography/intel/pagerduty/vendors.py +3 -1
- cartography/intel/semgrep/__init__.py +24 -6
- cartography/intel/semgrep/dependencies.py +50 -28
- cartography/intel/semgrep/deployment.py +3 -1
- cartography/intel/semgrep/findings.py +42 -18
- cartography/intel/snipeit/__init__.py +17 -3
- cartography/intel/snipeit/asset.py +12 -6
- cartography/intel/snipeit/user.py +8 -5
- cartography/intel/snipeit/util.py +9 -4
- cartography/intel/tailscale/__init__.py +77 -0
- cartography/intel/tailscale/acls.py +146 -0
- cartography/intel/tailscale/devices.py +127 -0
- cartography/intel/tailscale/postureintegrations.py +81 -0
- cartography/intel/tailscale/tailnets.py +76 -0
- cartography/intel/tailscale/users.py +80 -0
- cartography/intel/tailscale/utils.py +132 -0
- cartography/models/aws/apigateway.py +21 -17
- cartography/models/aws/apigatewaycertificate.py +28 -22
- cartography/models/aws/apigatewayresource.py +28 -20
- cartography/models/aws/apigatewaystage.py +33 -25
- cartography/models/aws/cloudtrail/__init__.py +0 -0
- cartography/models/aws/cloudtrail/trail.py +61 -0
- cartography/models/aws/cloudwatch/__init__.py +0 -0
- cartography/models/aws/cloudwatch/loggroup.py +52 -0
- cartography/models/aws/dynamodb/gsi.py +30 -22
- cartography/models/aws/dynamodb/tables.py +25 -17
- cartography/models/aws/ec2/auto_scaling_groups.py +102 -82
- cartography/models/aws/ec2/images.py +36 -34
- cartography/models/aws/ec2/instances.py +51 -45
- cartography/models/aws/ec2/keypair.py +21 -16
- cartography/models/aws/ec2/keypair_instance.py +28 -21
- cartography/models/aws/ec2/launch_configurations.py +30 -26
- cartography/models/aws/ec2/launch_template_versions.py +48 -38
- cartography/models/aws/ec2/launch_templates.py +21 -17
- cartography/models/aws/ec2/load_balancer_listeners.py +27 -23
- cartography/models/aws/ec2/load_balancers.py +47 -37
- cartography/models/aws/ec2/network_acl_rules.py +38 -30
- cartography/models/aws/ec2/network_acls.py +38 -29
- cartography/models/aws/ec2/networkinterface_instance.py +52 -39
- cartography/models/aws/ec2/networkinterfaces.py +53 -37
- cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
- cartography/models/aws/ec2/reservations.py +18 -14
- cartography/models/aws/ec2/route_table_associations.py +44 -34
- cartography/models/aws/ec2/route_tables.py +50 -43
- cartography/models/aws/ec2/routes.py +45 -37
- cartography/models/aws/ec2/securitygroup_instance.py +29 -20
- cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
- cartography/models/aws/ec2/subnet_instance.py +24 -19
- cartography/models/aws/ec2/subnet_networkinterface.py +40 -31
- cartography/models/aws/ec2/volumes.py +47 -40
- cartography/models/aws/efs/__init__.py +0 -0
- cartography/models/aws/efs/mount_target.py +52 -0
- cartography/models/aws/eks/clusters.py +23 -21
- cartography/models/aws/emr.py +32 -30
- cartography/models/aws/iam/instanceprofile.py +33 -24
- cartography/models/aws/identitycenter/awsidentitycenter.py +18 -14
- cartography/models/aws/identitycenter/awspermissionset.py +37 -29
- cartography/models/aws/identitycenter/awsssouser.py +23 -21
- cartography/models/aws/inspector/findings.py +77 -65
- cartography/models/aws/inspector/packages.py +35 -29
- cartography/models/aws/s3/__init__.py +0 -0
- cartography/models/aws/s3/account_public_access_block.py +51 -0
- cartography/models/aws/sns/__init__.py +0 -0
- cartography/models/aws/sns/topic.py +50 -0
- cartography/models/aws/ssm/instance_information.py +51 -39
- cartography/models/aws/ssm/instance_patch.py +32 -26
- cartography/models/bigfix/bigfix_computer.py +42 -38
- cartography/models/bigfix/bigfix_root.py +3 -3
- cartography/models/cloudflare/__init__.py +0 -0
- cartography/models/cloudflare/account.py +25 -0
- cartography/models/cloudflare/dnsrecord.py +55 -0
- cartography/models/cloudflare/member.py +82 -0
- cartography/models/cloudflare/role.py +44 -0
- cartography/models/cloudflare/zone.py +59 -0
- cartography/models/core/common.py +12 -10
- cartography/models/core/nodes.py +5 -2
- cartography/models/core/relationships.py +14 -6
- cartography/models/crowdstrike/hosts.py +37 -35
- cartography/models/cve/cve.py +34 -32
- cartography/models/cve/cve_feed.py +6 -6
- cartography/models/digitalocean/__init__.py +0 -0
- cartography/models/digitalocean/account.py +21 -0
- cartography/models/digitalocean/droplet.py +56 -0
- cartography/models/digitalocean/project.py +48 -0
- cartography/models/duo/api_host.py +3 -3
- cartography/models/duo/endpoint.py +43 -41
- cartography/models/duo/group.py +14 -14
- cartography/models/duo/phone.py +27 -27
- cartography/models/duo/token.py +16 -16
- cartography/models/duo/user.py +46 -44
- cartography/models/duo/web_authn_credential.py +27 -19
- cartography/models/entra/ou.py +48 -0
- cartography/models/entra/tenant.py +24 -18
- cartography/models/entra/user.py +64 -48
- cartography/models/gcp/iam.py +23 -23
- cartography/models/github/orgs.py +5 -4
- cartography/models/github/teams.py +37 -31
- cartography/models/github/users.py +34 -23
- cartography/models/kandji/device.py +22 -16
- cartography/models/kandji/tenant.py +6 -4
- cartography/models/lastpass/tenant.py +3 -3
- cartography/models/lastpass/user.py +32 -28
- cartography/models/openai/__init__.py +0 -0
- cartography/models/openai/adminapikey.py +90 -0
- cartography/models/openai/apikey.py +84 -0
- cartography/models/openai/organization.py +17 -0
- cartography/models/openai/project.py +70 -0
- cartography/models/openai/serviceaccount.py +50 -0
- cartography/models/openai/user.py +49 -0
- cartography/models/semgrep/dependencies.py +36 -24
- cartography/models/semgrep/deployment.py +5 -5
- cartography/models/semgrep/findings.py +58 -42
- cartography/models/semgrep/locations.py +27 -21
- cartography/models/snipeit/asset.py +30 -21
- cartography/models/snipeit/tenant.py +6 -4
- cartography/models/snipeit/user.py +19 -12
- cartography/models/tailscale/__init__.py +0 -0
- cartography/models/tailscale/device.py +95 -0
- cartography/models/tailscale/group.py +86 -0
- cartography/models/tailscale/postureintegration.py +58 -0
- cartography/models/tailscale/tag.py +102 -0
- cartography/models/tailscale/tailnet.py +29 -0
- cartography/models/tailscale/user.py +52 -0
- cartography/stats.py +3 -3
- cartography/sync.py +113 -31
- cartography/util.py +84 -62
- {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/METADATA +8 -15
- cartography-0.103.0.dist-info/RECORD +442 -0
- {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/WHEEL +1 -1
- cartography-0.102.0rc2.dist-info/RECORD +0 -381
- {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.102.0rc2.dist-info → cartography-0.103.0.dist-info}/licenses/LICENSE +0 -0
- {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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
57
|
+
logger.warning("Database Account not found error", exc_info=True)
|
|
46
58
|
return []
|
|
47
59
|
except HttpResponseError:
|
|
48
|
-
logger.warning(
|
|
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[
|
|
53
|
-
database_account[
|
|
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
|
|
67
|
-
capabilities
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
database_account[
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
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
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
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
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
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
|
|
223
|
-
database_account_id = database_account[
|
|
224
|
-
associated_locations = database_account[
|
|
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[
|
|
257
|
-
if
|
|
258
|
-
policy[
|
|
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
|
-
|
|
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
|
|
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[
|
|
273
|
-
cors_policies = database_account[
|
|
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
|
-
|
|
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
|
|
308
|
-
|
|
309
|
-
|
|
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
|
-
|
|
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
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
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
|
-
|
|
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
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
405
|
-
|
|
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(
|
|
408
|
-
|
|
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
|
-
|
|
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(
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
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(
|
|
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[
|
|
441
|
-
database_account[
|
|
552
|
+
database_account["resourceGroup"],
|
|
553
|
+
database_account["name"],
|
|
442
554
|
),
|
|
443
555
|
),
|
|
444
556
|
)
|
|
445
557
|
|
|
446
558
|
except ClientAuthenticationError:
|
|
447
|
-
logger.warning(
|
|
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(
|
|
565
|
+
logger.warning("SQL databases resource not found error", exc_info=True)
|
|
451
566
|
return []
|
|
452
567
|
except HttpResponseError:
|
|
453
|
-
logger.warning(
|
|
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(
|
|
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[
|
|
471
|
-
database_account[
|
|
589
|
+
database_account["resourceGroup"],
|
|
590
|
+
database_account["name"],
|
|
472
591
|
),
|
|
473
592
|
),
|
|
474
593
|
)
|
|
475
594
|
|
|
476
595
|
except ClientAuthenticationError:
|
|
477
|
-
logger.warning(
|
|
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(
|
|
602
|
+
logger.warning("Cassandra keyspaces resource not found error", exc_info=True)
|
|
481
603
|
return []
|
|
482
604
|
except HttpResponseError:
|
|
483
|
-
logger.warning(
|
|
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(
|
|
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[
|
|
501
|
-
database_account[
|
|
626
|
+
database_account["resourceGroup"],
|
|
627
|
+
database_account["name"],
|
|
502
628
|
),
|
|
503
629
|
),
|
|
504
630
|
)
|
|
505
631
|
|
|
506
632
|
except ClientAuthenticationError:
|
|
507
|
-
logger.warning(
|
|
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(
|
|
639
|
+
logger.warning("MongoDB Databases resource not found error", exc_info=True)
|
|
511
640
|
return []
|
|
512
641
|
except HttpResponseError:
|
|
513
|
-
logger.warning(
|
|
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(
|
|
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[
|
|
531
|
-
database_account[
|
|
663
|
+
database_account["resourceGroup"],
|
|
664
|
+
database_account["name"],
|
|
532
665
|
),
|
|
533
666
|
),
|
|
534
667
|
)
|
|
535
668
|
|
|
536
669
|
except ClientAuthenticationError:
|
|
537
|
-
logger.warning(
|
|
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(
|
|
676
|
+
logger.warning("Table resource not found error", exc_info=True)
|
|
541
677
|
return []
|
|
542
678
|
except HttpResponseError:
|
|
543
|
-
logger.warning(
|
|
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
|
-
|
|
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[
|
|
558
|
-
resource[
|
|
559
|
-
resource[
|
|
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
|
-
|
|
566
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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,
|
|
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,
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
732
|
-
|
|
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(
|
|
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
|
-
|
|
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[
|
|
957
|
+
yield database["id"], containers
|
|
749
958
|
|
|
750
959
|
|
|
751
960
|
@timeit
|
|
752
|
-
def get_sql_containers(
|
|
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[
|
|
763
|
-
database[
|
|
764
|
-
database[
|
|
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(
|
|
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(
|
|
989
|
+
logger.warning("SQL containers not found error", exc_info=True)
|
|
774
990
|
return []
|
|
775
991
|
except HttpResponseError:
|
|
776
|
-
logger.warning(
|
|
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(
|
|
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[
|
|
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(
|
|
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
|
-
|
|
835
|
-
|
|
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(
|
|
838
|
-
|
|
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
|
-
|
|
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[
|
|
1089
|
+
yield keyspace["id"], cassandra_tables
|
|
852
1090
|
|
|
853
1091
|
|
|
854
1092
|
@timeit
|
|
855
|
-
def get_cassandra_tables(
|
|
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[
|
|
866
|
-
keyspace[
|
|
867
|
-
keyspace[
|
|
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(
|
|
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(
|
|
1121
|
+
logger.warning("Cassandra tables not found error", exc_info=True)
|
|
877
1122
|
return []
|
|
878
1123
|
except HttpResponseError:
|
|
879
|
-
logger.warning(
|
|
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
|
-
|
|
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[
|
|
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(
|
|
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
|
-
|
|
937
|
-
|
|
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(
|
|
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
|
-
|
|
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[
|
|
1214
|
+
yield database["id"], collections
|
|
954
1215
|
|
|
955
1216
|
|
|
956
1217
|
@timeit
|
|
957
|
-
def get_mongodb_collections(
|
|
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[
|
|
968
|
-
database[
|
|
969
|
-
database[
|
|
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(
|
|
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(
|
|
1246
|
+
logger.warning("MongoDB collections not found error", exc_info=True)
|
|
979
1247
|
return []
|
|
980
1248
|
except HttpResponseError:
|
|
981
|
-
logger.warning(
|
|
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
|
-
|
|
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[
|
|
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(
|
|
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(
|
|
1037
|
-
|
|
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(
|
|
1042
|
-
|
|
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(
|
|
1047
|
-
|
|
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(
|
|
1052
|
-
|
|
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(
|
|
1057
|
-
|
|
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
|
-
|
|
1063
|
-
|
|
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(
|
|
1069
|
-
|
|
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,
|
|
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)
|