cartography 0.93.0rc1__py3-none-any.whl → 0.123.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.
- cartography/__main__.py +1 -2
- cartography/_version.py +34 -0
- cartography/cli.py +903 -225
- cartography/client/aws/__init__.py +19 -0
- cartography/client/aws/ecr.py +51 -0
- cartography/client/core/tx.py +400 -27
- cartography/config.py +215 -10
- cartography/data/azure_permission_relationships.yaml +20 -0
- cartography/data/gcp_permission_relationships.yaml +21 -0
- cartography/data/indexes.cypher +1 -200
- cartography/data/jobs/analysis/aws_ec2_asset_exposure.json +17 -2
- cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
- cartography/data/jobs/analysis/gcp_compute_asset_inet_exposure.json +1 -1
- cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
- cartography/data/jobs/cleanup/crowdstrike_import_cleanup.json +0 -5
- cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
- cartography/data/jobs/cleanup/github_repos_cleanup.json +27 -0
- cartography/data/jobs/scoped_analysis/aws_ec2_iaminstanceprofile.json +15 -0
- cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json +13 -13
- cartography/driftdetect/__main__.py +1 -2
- cartography/driftdetect/add_shortcut.py +10 -2
- cartography/driftdetect/cli.py +72 -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 +255 -35
- cartography/graph/job.py +104 -20
- cartography/graph/querybuilder.py +689 -91
- cartography/graph/statement.py +49 -36
- cartography/intel/airbyte/__init__.py +105 -0
- cartography/intel/airbyte/connections.py +120 -0
- cartography/intel/airbyte/destinations.py +81 -0
- cartography/intel/airbyte/organizations.py +59 -0
- cartography/intel/airbyte/sources.py +78 -0
- cartography/intel/airbyte/tags.py +64 -0
- cartography/intel/airbyte/users.py +106 -0
- cartography/intel/airbyte/util.py +122 -0
- cartography/intel/airbyte/workspaces.py +63 -0
- cartography/intel/analysis.py +4 -1
- cartography/intel/anthropic/__init__.py +62 -0
- cartography/intel/anthropic/apikeys.py +72 -0
- cartography/intel/anthropic/users.py +75 -0
- cartography/intel/anthropic/util.py +51 -0
- cartography/intel/anthropic/workspaces.py +95 -0
- cartography/intel/aws/__init__.py +137 -59
- cartography/intel/aws/acm.py +124 -0
- cartography/intel/aws/apigateway.py +482 -217
- cartography/intel/aws/apigatewayv2.py +116 -0
- cartography/intel/aws/cloudtrail.py +105 -0
- cartography/intel/aws/cloudtrail_management_events.py +962 -0
- cartography/intel/aws/cloudwatch.py +239 -0
- cartography/intel/aws/codebuild.py +132 -0
- cartography/intel/aws/cognito.py +201 -0
- cartography/intel/aws/config.py +63 -23
- cartography/intel/aws/dynamodb.py +108 -40
- cartography/intel/aws/ec2/__init__.py +2 -2
- cartography/intel/aws/ec2/auto_scaling_groups.py +254 -189
- cartography/intel/aws/ec2/elastic_ip_addresses.py +44 -14
- cartography/intel/aws/ec2/images.py +74 -39
- cartography/intel/aws/ec2/instances.py +262 -137
- cartography/intel/aws/ec2/internet_gateways.py +44 -13
- cartography/intel/aws/ec2/key_pairs.py +72 -39
- cartography/intel/aws/ec2/launch_templates.py +143 -66
- cartography/intel/aws/ec2/load_balancer_v2s.py +119 -45
- cartography/intel/aws/ec2/load_balancers.py +165 -147
- cartography/intel/aws/ec2/network_acls.py +233 -0
- cartography/intel/aws/ec2/network_interfaces.py +150 -87
- cartography/intel/aws/ec2/reserved_instances.py +48 -17
- cartography/intel/aws/ec2/route_tables.py +327 -0
- cartography/intel/aws/ec2/security_groups.py +189 -121
- cartography/intel/aws/ec2/snapshots.py +93 -91
- cartography/intel/aws/ec2/subnets.py +70 -58
- cartography/intel/aws/ec2/tgw.py +111 -39
- cartography/intel/aws/ec2/util.py +1 -1
- cartography/intel/aws/ec2/volumes.py +69 -41
- cartography/intel/aws/ec2/vpc.py +157 -116
- cartography/intel/aws/ec2/vpc_peerings.py +317 -121
- cartography/intel/aws/ecr.py +336 -93
- cartography/intel/aws/ecr_image_layers.py +923 -0
- cartography/intel/aws/ecs.py +310 -403
- cartography/intel/aws/efs.py +261 -0
- cartography/intel/aws/eks.py +55 -29
- cartography/intel/aws/elasticache.py +130 -83
- cartography/intel/aws/elasticsearch.py +70 -24
- cartography/intel/aws/emr.py +61 -23
- cartography/intel/aws/eventbridge.py +164 -0
- cartography/intel/aws/glue.py +181 -0
- cartography/intel/aws/guardduty.py +443 -0
- cartography/intel/aws/iam.py +978 -464
- cartography/intel/aws/iam_instance_profiles.py +73 -0
- cartography/intel/aws/identitycenter.py +847 -0
- cartography/intel/aws/inspector.py +330 -133
- cartography/intel/aws/kms.py +235 -209
- cartography/intel/aws/lambda_function.py +328 -176
- cartography/intel/aws/organizations.py +40 -19
- cartography/intel/aws/permission_relationships.py +144 -68
- cartography/intel/aws/rds.py +467 -412
- cartography/intel/aws/redshift.py +116 -50
- cartography/intel/aws/resourcegroupstaggingapi.py +198 -82
- cartography/intel/aws/resources.py +80 -42
- cartography/intel/aws/route53.py +419 -318
- cartography/intel/aws/s3.py +489 -96
- cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
- cartography/intel/aws/secretsmanager.py +217 -40
- cartography/intel/aws/securityhub.py +23 -10
- cartography/intel/aws/sns.py +226 -0
- cartography/intel/aws/sqs.py +74 -96
- cartography/intel/aws/ssm.py +142 -33
- cartography/intel/aws/util/arns.py +7 -7
- cartography/intel/aws/util/common.py +31 -4
- cartography/intel/azure/__init__.py +259 -46
- cartography/intel/azure/aks.py +175 -0
- cartography/intel/azure/app_service.py +105 -0
- cartography/intel/azure/compute.py +141 -120
- cartography/intel/azure/container_instances.py +95 -0
- cartography/intel/azure/cosmosdb.py +706 -519
- cartography/intel/azure/data_factory.py +85 -0
- cartography/intel/azure/data_factory_dataset.py +128 -0
- cartography/intel/azure/data_factory_linked_service.py +119 -0
- cartography/intel/azure/data_factory_pipeline.py +142 -0
- cartography/intel/azure/data_lake.py +124 -0
- cartography/intel/azure/event_grid.py +94 -0
- cartography/intel/azure/functions.py +124 -0
- cartography/intel/azure/load_balancers.py +263 -0
- cartography/intel/azure/logic_apps.py +101 -0
- cartography/intel/azure/monitor.py +105 -0
- cartography/intel/azure/network.py +467 -0
- cartography/intel/azure/permission_relationships.py +466 -0
- cartography/intel/azure/rbac.py +309 -0
- cartography/intel/azure/resource_groups.py +82 -0
- cartography/intel/azure/security_center.py +106 -0
- cartography/intel/azure/sql.py +436 -392
- cartography/intel/azure/storage.py +467 -335
- cartography/intel/azure/subscription.py +49 -55
- cartography/intel/azure/tenant.py +46 -28
- cartography/intel/azure/util/common.py +13 -0
- cartography/intel/azure/util/credentials.py +58 -143
- cartography/intel/azure/util/tag.py +41 -0
- 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 +5 -3
- cartography/intel/crowdstrike/__init__.py +26 -12
- cartography/intel/crowdstrike/endpoints.py +17 -45
- cartography/intel/crowdstrike/spotlight.py +13 -5
- cartography/intel/cve/__init__.py +91 -26
- cartography/intel/cve/feed.py +77 -56
- 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 +41 -12
- 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 +160 -0
- cartography/intel/entra/app_role_assignments.py +284 -0
- cartography/intel/entra/applications.py +182 -0
- cartography/intel/entra/federation/__init__.py +0 -0
- cartography/intel/entra/federation/aws_identity_center.py +77 -0
- cartography/intel/entra/groups.py +198 -0
- cartography/intel/entra/ou.py +136 -0
- cartography/intel/entra/service_principals.py +217 -0
- cartography/intel/entra/users.py +259 -0
- cartography/intel/gcp/__init__.py +381 -175
- cartography/intel/gcp/bigtable_app_profile.py +101 -0
- cartography/intel/gcp/bigtable_backup.py +91 -0
- cartography/intel/gcp/bigtable_cluster.py +93 -0
- cartography/intel/gcp/bigtable_instance.py +86 -0
- cartography/intel/gcp/bigtable_table.py +87 -0
- cartography/intel/gcp/cai.py +292 -0
- cartography/intel/gcp/clients.py +112 -0
- cartography/intel/gcp/compute.py +521 -325
- cartography/intel/gcp/crm/__init__.py +0 -0
- cartography/intel/gcp/crm/folders.py +114 -0
- cartography/intel/gcp/crm/orgs.py +70 -0
- cartography/intel/gcp/crm/projects.py +120 -0
- cartography/intel/gcp/dns.py +134 -179
- cartography/intel/gcp/gke.py +100 -107
- cartography/intel/gcp/iam.py +262 -0
- cartography/intel/gcp/permission_relationships.py +394 -0
- cartography/intel/gcp/policy_bindings.py +225 -0
- cartography/intel/gcp/storage.py +103 -158
- cartography/intel/github/__init__.py +66 -27
- cartography/intel/github/commits.py +423 -0
- cartography/intel/github/repos.py +871 -160
- cartography/intel/github/teams.py +386 -53
- cartography/intel/github/users.py +214 -49
- cartography/intel/github/util.py +50 -35
- cartography/intel/googleworkspace/__init__.py +193 -0
- cartography/intel/googleworkspace/devices.py +254 -0
- cartography/intel/googleworkspace/groups.py +568 -0
- cartography/intel/googleworkspace/oauth_apps.py +259 -0
- cartography/intel/googleworkspace/tenant.py +85 -0
- cartography/intel/googleworkspace/users.py +138 -0
- cartography/intel/gsuite/__init__.py +101 -42
- cartography/intel/gsuite/groups.py +291 -0
- cartography/intel/gsuite/users.py +142 -0
- cartography/intel/jamf/__init__.py +19 -1
- cartography/intel/jamf/computers.py +37 -8
- cartography/intel/jamf/util.py +7 -2
- cartography/intel/kandji/__init__.py +6 -3
- cartography/intel/kandji/devices.py +40 -10
- cartography/intel/keycloak/__init__.py +153 -0
- cartography/intel/keycloak/authenticationexecutions.py +322 -0
- cartography/intel/keycloak/authenticationflows.py +77 -0
- cartography/intel/keycloak/clients.py +187 -0
- cartography/intel/keycloak/groups.py +126 -0
- cartography/intel/keycloak/identityproviders.py +94 -0
- cartography/intel/keycloak/organizations.py +163 -0
- cartography/intel/keycloak/realms.py +61 -0
- cartography/intel/keycloak/roles.py +202 -0
- cartography/intel/keycloak/scopes.py +73 -0
- cartography/intel/keycloak/users.py +70 -0
- cartography/intel/keycloak/util.py +47 -0
- cartography/intel/kubernetes/__init__.py +60 -14
- cartography/intel/kubernetes/clusters.py +86 -0
- cartography/intel/kubernetes/eks.py +402 -0
- cartography/intel/kubernetes/namespaces.py +60 -55
- cartography/intel/kubernetes/pods.py +171 -75
- cartography/intel/kubernetes/rbac.py +597 -0
- cartography/intel/kubernetes/secrets.py +95 -45
- cartography/intel/kubernetes/services.py +131 -63
- cartography/intel/kubernetes/util.py +142 -14
- 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 +157 -47
- cartography/intel/oci/organizations.py +16 -7
- cartography/intel/oci/utils.py +71 -25
- cartography/intel/okta/__init__.py +66 -15
- cartography/intel/okta/applications.py +57 -25
- cartography/intel/okta/awssaml.py +105 -41
- cartography/intel/okta/factors.py +19 -5
- cartography/intel/okta/groups.py +61 -31
- cartography/intel/okta/organization.py +8 -2
- cartography/intel/okta/origins.py +9 -3
- cartography/intel/okta/roles.py +20 -7
- cartography/intel/okta/users.py +31 -10
- cartography/intel/okta/utils.py +6 -4
- cartography/intel/ontology/__init__.py +44 -0
- cartography/intel/ontology/devices.py +54 -0
- cartography/intel/ontology/users.py +54 -0
- cartography/intel/ontology/utils.py +176 -0
- cartography/intel/openai/__init__.py +86 -0
- cartography/intel/openai/adminapikeys.py +89 -0
- cartography/intel/openai/apikeys.py +96 -0
- cartography/intel/openai/projects.py +97 -0
- cartography/intel/openai/serviceaccounts.py +82 -0
- cartography/intel/openai/users.py +75 -0
- cartography/intel/openai/util.py +45 -0
- cartography/intel/pagerduty/__init__.py +8 -7
- cartography/intel/pagerduty/escalation_policies.py +31 -12
- cartography/intel/pagerduty/schedules.py +21 -8
- cartography/intel/pagerduty/services.py +18 -7
- cartography/intel/pagerduty/teams.py +13 -5
- cartography/intel/pagerduty/users.py +6 -2
- cartography/intel/pagerduty/vendors.py +6 -2
- cartography/intel/scaleway/__init__.py +127 -0
- cartography/intel/scaleway/iam/__init__.py +0 -0
- cartography/intel/scaleway/iam/apikeys.py +71 -0
- cartography/intel/scaleway/iam/applications.py +71 -0
- cartography/intel/scaleway/iam/groups.py +71 -0
- cartography/intel/scaleway/iam/users.py +71 -0
- cartography/intel/scaleway/instances/__init__.py +0 -0
- cartography/intel/scaleway/instances/flexibleips.py +86 -0
- cartography/intel/scaleway/instances/instances.py +92 -0
- cartography/intel/scaleway/projects.py +79 -0
- cartography/intel/scaleway/storage/__init__.py +0 -0
- cartography/intel/scaleway/storage/snapshots.py +86 -0
- cartography/intel/scaleway/storage/volumes.py +84 -0
- cartography/intel/scaleway/utils.py +37 -0
- cartography/intel/semgrep/__init__.py +30 -5
- cartography/intel/semgrep/dependencies.py +255 -0
- cartography/intel/semgrep/deployment.py +69 -0
- cartography/intel/semgrep/findings.py +157 -117
- cartography/intel/sentinelone/__init__.py +75 -0
- cartography/intel/sentinelone/account.py +140 -0
- cartography/intel/sentinelone/agent.py +139 -0
- cartography/intel/sentinelone/api.py +124 -0
- cartography/intel/sentinelone/application.py +248 -0
- cartography/intel/sentinelone/cve.py +119 -0
- cartography/intel/sentinelone/utils.py +28 -0
- cartography/intel/slack/__init__.py +78 -0
- cartography/intel/slack/channels.py +80 -0
- cartography/intel/slack/groups.py +90 -0
- cartography/intel/slack/teams.py +65 -0
- cartography/intel/slack/users.py +57 -0
- cartography/intel/slack/utils.py +29 -0
- cartography/intel/snipeit/__init__.py +44 -0
- cartography/intel/snipeit/asset.py +80 -0
- cartography/intel/snipeit/user.py +78 -0
- cartography/intel/snipeit/util.py +40 -0
- cartography/intel/spacelift/__init__.py +161 -0
- cartography/intel/spacelift/account.py +73 -0
- cartography/intel/spacelift/ec2_ownership.py +280 -0
- cartography/intel/spacelift/runs.py +463 -0
- cartography/intel/spacelift/spaces.py +112 -0
- cartography/intel/spacelift/stacks.py +119 -0
- cartography/intel/spacelift/util.py +122 -0
- cartography/intel/spacelift/workerpools.py +131 -0
- cartography/intel/spacelift/workers.py +128 -0
- 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/intel/trivy/__init__.py +272 -0
- cartography/intel/trivy/scanner.py +386 -0
- cartography/models/airbyte/__init__.py +0 -0
- cartography/models/airbyte/connection.py +138 -0
- cartography/models/airbyte/destination.py +75 -0
- cartography/models/airbyte/organization.py +19 -0
- cartography/models/airbyte/source.py +75 -0
- cartography/models/airbyte/stream.py +74 -0
- cartography/models/airbyte/tag.py +69 -0
- cartography/models/airbyte/user.py +115 -0
- cartography/models/airbyte/workspace.py +46 -0
- cartography/models/anthropic/__init__.py +0 -0
- cartography/models/anthropic/apikey.py +94 -0
- cartography/models/anthropic/organization.py +19 -0
- cartography/models/anthropic/user.py +52 -0
- cartography/models/anthropic/workspace.py +90 -0
- cartography/models/aws/acm/__init__.py +0 -0
- cartography/models/aws/acm/certificate.py +75 -0
- cartography/models/aws/apigateway/__init__.py +0 -0
- cartography/models/aws/apigateway/apigateway.py +51 -0
- cartography/models/aws/apigateway/apigatewaycertificate.py +72 -0
- cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
- cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
- cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
- cartography/models/aws/apigateway/apigatewayresource.py +70 -0
- cartography/models/aws/apigateway/apigatewaystage.py +75 -0
- cartography/models/aws/apigatewayv2/__init__.py +0 -0
- cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
- cartography/models/aws/cloudtrail/__init__.py +0 -0
- cartography/models/aws/cloudtrail/management_events.py +153 -0
- cartography/models/aws/cloudtrail/trail.py +106 -0
- cartography/models/aws/cloudwatch/__init__.py +0 -0
- cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
- cartography/models/aws/cloudwatch/loggroup.py +52 -0
- cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
- cartography/models/aws/codebuild/__init__.py +0 -0
- cartography/models/aws/codebuild/project.py +49 -0
- cartography/models/aws/cognito/__init__.py +0 -0
- cartography/models/aws/cognito/identity_pool.py +70 -0
- cartography/models/aws/cognito/user_pool.py +47 -0
- cartography/models/aws/dynamodb/gsi.py +30 -22
- cartography/models/aws/dynamodb/tables.py +27 -17
- cartography/models/aws/ec2/auto_scaling_groups.py +224 -0
- cartography/models/aws/ec2/images.py +36 -34
- cartography/models/aws/ec2/instances.py +85 -38
- cartography/models/aws/ec2/keypair.py +59 -0
- cartography/models/aws/ec2/keypair_instance.py +76 -0
- cartography/models/aws/ec2/launch_configurations.py +59 -0
- 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 +72 -0
- cartography/models/aws/ec2/load_balancers.py +112 -0
- cartography/models/aws/ec2/network_acl_rules.py +106 -0
- cartography/models/aws/ec2/network_acls.py +95 -0
- cartography/models/aws/ec2/networkinterface_instance.py +52 -39
- cartography/models/aws/ec2/networkinterfaces.py +57 -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 +97 -0
- cartography/models/aws/ec2/route_tables.py +128 -0
- cartography/models/aws/ec2/routes.py +85 -0
- cartography/models/aws/ec2/security_group_rules.py +109 -0
- cartography/models/aws/ec2/security_groups.py +90 -0
- cartography/models/aws/ec2/securitygroup_instance.py +29 -20
- cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
- cartography/models/aws/ec2/snapshots.py +58 -0
- cartography/models/aws/ec2/subnet_instance.py +26 -19
- cartography/models/aws/ec2/subnet_networkinterface.py +42 -31
- cartography/models/aws/ec2/subnets.py +65 -0
- cartography/models/aws/ec2/volumes.py +67 -40
- cartography/models/aws/ec2/vpc.py +46 -0
- cartography/models/aws/ec2/vpc_cidr.py +102 -0
- cartography/models/aws/ec2/vpc_peering.py +157 -0
- cartography/models/aws/ecr/__init__.py +0 -0
- cartography/models/aws/ecr/image.py +146 -0
- cartography/models/aws/ecr/image_layer.py +107 -0
- cartography/models/aws/ecr/repository.py +72 -0
- cartography/models/aws/ecr/repository_image.py +95 -0
- cartography/models/aws/ecs/__init__.py +0 -0
- cartography/models/aws/ecs/clusters.py +64 -0
- cartography/models/aws/ecs/container_definitions.py +93 -0
- cartography/models/aws/ecs/container_instances.py +84 -0
- cartography/models/aws/ecs/containers.py +101 -0
- cartography/models/aws/ecs/services.py +134 -0
- cartography/models/aws/ecs/task_definitions.py +135 -0
- cartography/models/aws/ecs/tasks.py +134 -0
- cartography/models/aws/efs/__init__.py +0 -0
- cartography/models/aws/efs/access_point.py +77 -0
- cartography/models/aws/efs/file_system.py +60 -0
- cartography/models/aws/efs/mount_target.py +79 -0
- cartography/models/aws/eks/clusters.py +23 -21
- cartography/models/aws/elasticache/__init__.py +0 -0
- cartography/models/aws/elasticache/cluster.py +65 -0
- cartography/models/aws/elasticache/topic.py +67 -0
- cartography/models/aws/emr.py +32 -30
- cartography/models/aws/eventbridge/__init__.py +0 -0
- cartography/models/aws/eventbridge/rule.py +77 -0
- cartography/models/aws/eventbridge/target.py +71 -0
- cartography/models/aws/glue/__init__.py +0 -0
- cartography/models/aws/glue/connection.py +51 -0
- cartography/models/aws/glue/job.py +69 -0
- cartography/models/aws/guardduty/__init__.py +1 -0
- cartography/models/aws/guardduty/detectors.py +50 -0
- cartography/models/aws/guardduty/findings.py +121 -0
- cartography/models/aws/iam/__init__.py +0 -0
- cartography/models/aws/iam/access_key.py +103 -0
- cartography/models/aws/iam/account_role.py +24 -0
- cartography/models/aws/iam/federated_principal.py +60 -0
- cartography/models/aws/iam/group.py +60 -0
- cartography/models/aws/iam/group_membership.py +27 -0
- cartography/models/aws/iam/inline_policy.py +78 -0
- cartography/models/aws/iam/instanceprofile.py +76 -0
- cartography/models/aws/iam/managed_policy.py +51 -0
- cartography/models/aws/iam/policy_statement.py +57 -0
- cartography/models/aws/iam/role.py +83 -0
- cartography/models/aws/iam/root_principal.py +52 -0
- cartography/models/aws/iam/service_principal.py +30 -0
- cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
- cartography/models/aws/iam/user.py +59 -0
- cartography/models/aws/identitycenter/__init__.py +0 -0
- cartography/models/aws/identitycenter/awsidentitycenter.py +49 -0
- cartography/models/aws/identitycenter/awspermissionset.py +162 -0
- cartography/models/aws/identitycenter/awssogroup.py +70 -0
- cartography/models/aws/identitycenter/awsssouser.py +110 -0
- cartography/models/aws/inspector/findings.py +124 -58
- cartography/models/aws/inspector/packages.py +18 -42
- cartography/models/aws/kms/__init__.py +0 -0
- cartography/models/aws/kms/aliases.py +86 -0
- cartography/models/aws/kms/grants.py +65 -0
- cartography/models/aws/kms/keys.py +88 -0
- cartography/models/aws/lambda_function/__init__.py +0 -0
- cartography/models/aws/lambda_function/alias.py +74 -0
- cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
- cartography/models/aws/lambda_function/lambda_function.py +91 -0
- cartography/models/aws/lambda_function/layer.py +72 -0
- cartography/models/aws/rds/__init__.py +0 -0
- cartography/models/aws/rds/cluster.py +91 -0
- cartography/models/aws/rds/event_subscription.py +146 -0
- cartography/models/aws/rds/instance.py +156 -0
- cartography/models/aws/rds/snapshot.py +108 -0
- cartography/models/aws/rds/subnet_group.py +101 -0
- cartography/models/aws/route53/__init__.py +0 -0
- cartography/models/aws/route53/dnsrecord.py +235 -0
- cartography/models/aws/route53/nameserver.py +63 -0
- cartography/models/aws/route53/subzone.py +40 -0
- cartography/models/aws/route53/zone.py +47 -0
- cartography/models/aws/s3/__init__.py +0 -0
- cartography/models/aws/s3/account_public_access_block.py +51 -0
- cartography/models/aws/s3/notification.py +24 -0
- cartography/models/aws/secretsmanager/__init__.py +0 -0
- cartography/models/aws/secretsmanager/secret.py +106 -0
- cartography/models/aws/secretsmanager/secret_version.py +114 -0
- cartography/models/aws/sns/__init__.py +0 -0
- cartography/models/aws/sns/topic.py +50 -0
- cartography/models/aws/sns/topic_subscription.py +74 -0
- cartography/models/aws/sqs/__init__.py +0 -0
- cartography/models/aws/sqs/queue.py +89 -0
- cartography/models/aws/ssm/instance_information.py +51 -39
- cartography/models/aws/ssm/instance_patch.py +32 -26
- cartography/models/aws/ssm/parameters.py +84 -0
- cartography/models/azure/__init__.py +0 -0
- cartography/models/azure/aks_cluster.py +54 -0
- cartography/models/azure/aks_nodepool.py +54 -0
- cartography/models/azure/app_service.py +59 -0
- cartography/models/azure/container_instance.py +57 -0
- cartography/models/azure/cosmosdb/__init__.py +0 -0
- cartography/models/azure/cosmosdb/account.py +77 -0
- cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
- cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
- cartography/models/azure/cosmosdb/cassandratable.py +81 -0
- cartography/models/azure/cosmosdb/corspolicy.py +74 -0
- cartography/models/azure/cosmosdb/dblocation.py +120 -0
- cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
- cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
- cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
- cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
- cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
- cartography/models/azure/cosmosdb/tableresource.py +76 -0
- cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
- cartography/models/azure/data_factory/__init__.py +0 -0
- cartography/models/azure/data_factory/data_factory.py +51 -0
- cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
- cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
- cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
- cartography/models/azure/data_lake_filesystem.py +51 -0
- cartography/models/azure/event_grid_topic.py +57 -0
- cartography/models/azure/function_app.py +59 -0
- cartography/models/azure/load_balancer/__init__.py +0 -0
- cartography/models/azure/load_balancer/load_balancer.py +49 -0
- cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
- cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
- cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
- cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
- cartography/models/azure/logic_apps.py +56 -0
- cartography/models/azure/monitor.py +54 -0
- cartography/models/azure/network_interface.py +112 -0
- cartography/models/azure/network_security_group.py +50 -0
- cartography/models/azure/permission_relationships.py +60 -0
- cartography/models/azure/principal.py +41 -0
- cartography/models/azure/public_ip_address.py +50 -0
- cartography/models/azure/rbac.py +268 -0
- cartography/models/azure/resource_groups.py +52 -0
- cartography/models/azure/security_center.py +50 -0
- cartography/models/azure/sql/__init__.py +0 -0
- cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
- cartography/models/azure/sql/elasticpool.py +77 -0
- cartography/models/azure/sql/failovergroup.py +73 -0
- cartography/models/azure/sql/recoverabledatabase.py +75 -0
- cartography/models/azure/sql/replicationlink.py +81 -0
- cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
- cartography/models/azure/sql/restorepoint.py +74 -0
- cartography/models/azure/sql/serveradadministrator.py +74 -0
- cartography/models/azure/sql/serverdnsalias.py +71 -0
- cartography/models/azure/sql/sqldatabase.py +85 -0
- cartography/models/azure/sql/sqlserver.py +50 -0
- cartography/models/azure/sql/transparentdataencryption.py +76 -0
- cartography/models/azure/storage/__init__.py +0 -0
- cartography/models/azure/storage/account.py +59 -0
- cartography/models/azure/storage/blobcontainer.py +85 -0
- cartography/models/azure/storage/blobservice.py +71 -0
- cartography/models/azure/storage/fileservice.py +71 -0
- cartography/models/azure/storage/fileshare.py +82 -0
- cartography/models/azure/storage/queue.py +71 -0
- cartography/models/azure/storage/queueservice.py +73 -0
- cartography/models/azure/storage/table.py +72 -0
- cartography/models/azure/storage/tableservice.py +73 -0
- cartography/models/azure/subnet.py +101 -0
- cartography/models/azure/subscription.py +47 -0
- cartography/models/azure/tags/__init__.py +0 -0
- cartography/models/azure/tags/storage_tag.py +40 -0
- cartography/models/azure/tags/tag.py +37 -0
- cartography/models/azure/tenant.py +17 -0
- cartography/models/azure/virtual_network.py +49 -0
- cartography/models/azure/vm/__init__.py +0 -0
- cartography/models/azure/vm/datadisk.py +80 -0
- cartography/models/azure/vm/disk.py +55 -0
- cartography/models/azure/vm/snapshot.py +56 -0
- cartography/models/azure/vm/virtualmachine.py +59 -0
- 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 +86 -0
- cartography/models/cloudflare/role.py +44 -0
- cartography/models/cloudflare/zone.py +59 -0
- cartography/models/core/common.py +53 -2
- cartography/models/core/nodes.py +20 -4
- cartography/models/core/relationships.py +58 -6
- cartography/models/crowdstrike/__init__.py +0 -0
- cartography/models/crowdstrike/hosts.py +51 -0
- 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 +58 -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 +50 -44
- cartography/models/duo/web_authn_credential.py +27 -19
- cartography/models/entra/__init__.py +0 -0
- cartography/models/entra/app_role_assignment.py +115 -0
- cartography/models/entra/application.py +49 -0
- cartography/models/entra/entra_user_to_aws_sso.py +41 -0
- cartography/models/entra/group.py +117 -0
- cartography/models/entra/ou.py +48 -0
- cartography/models/entra/service_principal.py +104 -0
- cartography/models/entra/tenant.py +39 -0
- cartography/models/entra/user.py +90 -0
- cartography/models/gcp/__init__.py +0 -0
- cartography/models/gcp/bigtable/__init__.py +0 -0
- cartography/models/gcp/bigtable/app_profile.py +94 -0
- cartography/models/gcp/bigtable/backup.py +91 -0
- cartography/models/gcp/bigtable/cluster.py +73 -0
- cartography/models/gcp/bigtable/instance.py +52 -0
- cartography/models/gcp/bigtable/table.py +69 -0
- cartography/models/gcp/compute/__init__.py +0 -0
- cartography/models/gcp/compute/subnet.py +74 -0
- cartography/models/gcp/compute/vpc.py +50 -0
- cartography/models/gcp/crm/__init__.py +0 -0
- cartography/models/gcp/crm/folders.py +98 -0
- cartography/models/gcp/crm/organizations.py +21 -0
- cartography/models/gcp/crm/projects.py +100 -0
- cartography/models/gcp/dns.py +109 -0
- cartography/models/gcp/gke.py +69 -0
- cartography/models/gcp/iam.py +73 -0
- cartography/models/gcp/permission_relationships.py +61 -0
- cartography/models/gcp/policy_bindings.py +93 -0
- cartography/models/gcp/storage/__init__.py +0 -0
- cartography/models/gcp/storage/bucket.py +119 -0
- cartography/models/github/commits.py +63 -0
- cartography/models/github/dependencies.py +73 -0
- cartography/models/github/manifests.py +49 -0
- cartography/models/github/orgs.py +27 -0
- cartography/models/github/teams.py +74 -22
- cartography/models/github/users.py +149 -0
- cartography/models/googleworkspace/__init__.py +0 -0
- cartography/models/googleworkspace/device.py +132 -0
- cartography/models/googleworkspace/group.py +382 -0
- cartography/models/googleworkspace/oauth_app.py +124 -0
- cartography/models/googleworkspace/tenant.py +30 -0
- cartography/models/googleworkspace/user.py +113 -0
- cartography/models/gsuite/__init__.py +0 -0
- cartography/models/gsuite/group.py +218 -0
- cartography/models/gsuite/tenant.py +29 -0
- cartography/models/gsuite/user.py +107 -0
- cartography/models/kandji/device.py +22 -17
- cartography/models/kandji/tenant.py +6 -4
- cartography/models/keycloak/__init__.py +0 -0
- cartography/models/keycloak/authenticationexecution.py +160 -0
- cartography/models/keycloak/authenticationflow.py +54 -0
- cartography/models/keycloak/client.py +179 -0
- cartography/models/keycloak/group.py +101 -0
- cartography/models/keycloak/identityprovider.py +89 -0
- cartography/models/keycloak/organization.py +116 -0
- cartography/models/keycloak/organizationdomain.py +73 -0
- cartography/models/keycloak/realm.py +173 -0
- cartography/models/keycloak/role.py +126 -0
- cartography/models/keycloak/scope.py +73 -0
- cartography/models/keycloak/user.py +55 -0
- cartography/models/kubernetes/__init__.py +0 -0
- cartography/models/kubernetes/clusterrolebindings.py +138 -0
- cartography/models/kubernetes/clusterroles.py +52 -0
- cartography/models/kubernetes/clusters.py +26 -0
- cartography/models/kubernetes/containers.py +133 -0
- cartography/models/kubernetes/groups.py +107 -0
- cartography/models/kubernetes/namespaces.py +51 -0
- cartography/models/kubernetes/oidc.py +51 -0
- cartography/models/kubernetes/pods.py +80 -0
- cartography/models/kubernetes/rolebindings.py +159 -0
- cartography/models/kubernetes/roles.py +76 -0
- cartography/models/kubernetes/secrets.py +79 -0
- cartography/models/kubernetes/serviceaccounts.py +77 -0
- cartography/models/kubernetes/services.py +108 -0
- cartography/models/kubernetes/users.py +105 -0
- cartography/models/lastpass/tenant.py +3 -3
- cartography/models/lastpass/user.py +36 -28
- cartography/models/ontology/__init__.py +0 -0
- cartography/models/ontology/device.py +137 -0
- cartography/models/ontology/mapping/__init__.py +76 -0
- cartography/models/ontology/mapping/data/__init__.py +0 -0
- cartography/models/ontology/mapping/data/apikeys.py +93 -0
- cartography/models/ontology/mapping/data/computeinstance.py +95 -0
- cartography/models/ontology/mapping/data/containers.py +88 -0
- cartography/models/ontology/mapping/data/databases.py +182 -0
- cartography/models/ontology/mapping/data/devices.py +194 -0
- cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
- cartography/models/ontology/mapping/data/useraccounts.py +416 -0
- cartography/models/ontology/mapping/data/users.py +63 -0
- cartography/models/ontology/mapping/specs.py +85 -0
- cartography/models/ontology/user.py +51 -0
- cartography/models/openai/__init__.py +0 -0
- cartography/models/openai/adminapikey.py +94 -0
- cartography/models/openai/apikey.py +88 -0
- cartography/models/openai/organization.py +17 -0
- cartography/models/openai/project.py +89 -0
- cartography/models/openai/serviceaccount.py +50 -0
- cartography/models/openai/user.py +53 -0
- cartography/models/scaleway/__init__.py +0 -0
- cartography/models/scaleway/iam/__init__.py +0 -0
- cartography/models/scaleway/iam/apikey.py +100 -0
- cartography/models/scaleway/iam/application.py +52 -0
- cartography/models/scaleway/iam/group.py +95 -0
- cartography/models/scaleway/iam/user.py +64 -0
- cartography/models/scaleway/instance/__init__.py +0 -0
- cartography/models/scaleway/instance/flexibleip.py +52 -0
- cartography/models/scaleway/instance/instance.py +120 -0
- cartography/models/scaleway/organization.py +19 -0
- cartography/models/scaleway/project.py +48 -0
- cartography/models/scaleway/storage/__init__.py +0 -0
- cartography/models/scaleway/storage/snapshot.py +78 -0
- cartography/models/scaleway/storage/volume.py +51 -0
- cartography/models/semgrep/dependencies.py +102 -0
- cartography/models/semgrep/deployment.py +5 -5
- cartography/models/semgrep/findings.py +58 -40
- cartography/models/semgrep/locations.py +27 -21
- cartography/models/sentinelone/__init__.py +1 -0
- cartography/models/sentinelone/account.py +40 -0
- cartography/models/sentinelone/agent.py +50 -0
- cartography/models/sentinelone/application.py +44 -0
- cartography/models/sentinelone/application_version.py +96 -0
- cartography/models/sentinelone/cve.py +73 -0
- cartography/models/slack/__init__.py +0 -0
- cartography/models/slack/channels.py +92 -0
- cartography/models/slack/group.py +129 -0
- cartography/models/slack/team.py +22 -0
- cartography/models/slack/user.py +62 -0
- cartography/models/snipeit/__init__.py +0 -0
- cartography/models/snipeit/asset.py +92 -0
- cartography/models/snipeit/tenant.py +19 -0
- cartography/models/snipeit/user.py +60 -0
- cartography/models/spacelift/__init__.py +0 -0
- cartography/models/spacelift/cloudtrailevent.py +120 -0
- cartography/models/spacelift/run.py +162 -0
- cartography/models/spacelift/space.py +131 -0
- cartography/models/spacelift/spaceliftaccount.py +31 -0
- cartography/models/spacelift/spaceliftgitcommit.py +157 -0
- cartography/models/spacelift/stack.py +96 -0
- cartography/models/spacelift/user.py +63 -0
- cartography/models/spacelift/worker.py +97 -0
- cartography/models/spacelift/workerpool.py +90 -0
- cartography/models/tailscale/__init__.py +0 -0
- cartography/models/tailscale/device.py +96 -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 +57 -0
- cartography/models/trivy/__init__.py +0 -0
- cartography/models/trivy/findings.py +66 -0
- cartography/models/trivy/fix.py +66 -0
- cartography/models/trivy/package.py +71 -0
- cartography/rules/README.md +1 -0
- cartography/rules/__init__.py +0 -0
- cartography/rules/cli.py +261 -0
- cartography/rules/data/__init__.py +0 -0
- cartography/rules/data/rules/__init__.py +46 -0
- cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
- cartography/rules/data/rules/compute_instance_exposed.py +51 -0
- cartography/rules/data/rules/database_instance_exposed.py +53 -0
- cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
- cartography/rules/data/rules/identity_administration_privileges.py +100 -0
- cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
- cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
- cartography/rules/data/rules/mfa_missing.py +46 -0
- cartography/rules/data/rules/object_storage_public.py +100 -0
- cartography/rules/data/rules/policy_administration_privileges.py +104 -0
- cartography/rules/data/rules/unmanaged_accounts.py +43 -0
- cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
- cartography/rules/formatters.py +108 -0
- cartography/rules/runners.py +216 -0
- cartography/rules/spec/__init__.py +0 -0
- cartography/rules/spec/model.py +267 -0
- cartography/rules/spec/result.py +38 -0
- cartography/stats.py +4 -4
- cartography/sync.py +137 -31
- cartography/util.py +187 -77
- cartography-0.123.0.dist-info/METADATA +230 -0
- cartography-0.123.0.dist-info/RECORD +856 -0
- {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/WHEEL +1 -1
- {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
- {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info/licenses}/LICENSE +1 -1
- cartography/data/jobs/analysis/aws_ec2_iaminstance.json +0 -10
- cartography/data/jobs/analysis/aws_ec2_iaminstanceprofile.json +0 -10
- cartography/data/jobs/cleanup/aws_apigateway_details.json +0 -10
- cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
- cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
- cartography/data/jobs/cleanup/aws_import_apigateway_cleanup.json +0 -45
- cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
- cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
- cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
- cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
- cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
- cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
- cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
- cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
- cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
- cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
- cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
- cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
- cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
- cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
- cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
- cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
- cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
- cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
- cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
- cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
- cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
- cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
- cartography/data/jobs/cleanup/crxcavator_import_cleanup.json +0 -18
- cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
- cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
- cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
- cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
- cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
- cartography/data/jobs/cleanup/github_users_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
- cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
- cartography/intel/crxcavator/__init__.py +0 -44
- cartography/intel/crxcavator/crxcavator.py +0 -329
- cartography/intel/gcp/crm.py +0 -302
- cartography/intel/gsuite/api.py +0 -284
- cartography/models/aws/ec2/keypairs.py +0 -64
- cartography-0.93.0rc1.dist-info/METADATA +0 -55
- cartography-0.93.0rc1.dist-info/NOTICE +0 -4
- cartography-0.93.0rc1.dist-info/RECORD +0 -341
- /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
- {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
|
@@ -12,15 +12,51 @@ 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 .
|
|
16
|
-
from cartography.
|
|
15
|
+
from cartography.client.core.tx import load
|
|
16
|
+
from cartography.graph.job import GraphJob
|
|
17
|
+
from cartography.models.azure.cosmosdb.account import AzureCosmosDBAccountSchema
|
|
18
|
+
from cartography.models.azure.cosmosdb.accountfailoverpolicy import (
|
|
19
|
+
AzureCosmosDBAccountFailoverPolicySchema,
|
|
20
|
+
)
|
|
21
|
+
from cartography.models.azure.cosmosdb.cassandrakeyspace import (
|
|
22
|
+
AzureCosmosDBCassandraKeyspaceSchema,
|
|
23
|
+
)
|
|
24
|
+
from cartography.models.azure.cosmosdb.cassandratable import (
|
|
25
|
+
AzureCosmosDBCassandraTableSchema,
|
|
26
|
+
)
|
|
27
|
+
from cartography.models.azure.cosmosdb.corspolicy import AzureCosmosDBCorsPolicySchema
|
|
28
|
+
from cartography.models.azure.cosmosdb.dblocation import AzureCosmosDBLocationSchema
|
|
29
|
+
from cartography.models.azure.cosmosdb.mongodbcollection import (
|
|
30
|
+
AzureCosmosDBMongoDBCollectionSchema,
|
|
31
|
+
)
|
|
32
|
+
from cartography.models.azure.cosmosdb.mongodbdatabase import (
|
|
33
|
+
AzureCosmosDBMongoDBDatabaseSchema,
|
|
34
|
+
)
|
|
35
|
+
from cartography.models.azure.cosmosdb.privateendpointconnection import (
|
|
36
|
+
AzureCDBPrivateEndpointConnectionSchema,
|
|
37
|
+
)
|
|
38
|
+
from cartography.models.azure.cosmosdb.sqlcontainer import (
|
|
39
|
+
AzureCosmosDBSqlContainerSchema,
|
|
40
|
+
)
|
|
41
|
+
from cartography.models.azure.cosmosdb.sqldatabase import AzureCosmosDBSqlDatabaseSchema
|
|
42
|
+
from cartography.models.azure.cosmosdb.tableresource import (
|
|
43
|
+
AzureCosmosDBTableResourceSchema,
|
|
44
|
+
)
|
|
45
|
+
from cartography.models.azure.cosmosdb.virtualnetworkrule import (
|
|
46
|
+
AzureCosmosDBVirtualNetworkRuleSchema,
|
|
47
|
+
)
|
|
17
48
|
from cartography.util import timeit
|
|
18
49
|
|
|
50
|
+
from .util.credentials import Credentials
|
|
51
|
+
|
|
19
52
|
logger = logging.getLogger(__name__)
|
|
20
53
|
|
|
21
54
|
|
|
22
55
|
@timeit
|
|
23
|
-
def get_client(
|
|
56
|
+
def get_client(
|
|
57
|
+
credentials: Credentials,
|
|
58
|
+
subscription_id: str,
|
|
59
|
+
) -> CosmosDBManagementClient:
|
|
24
60
|
"""
|
|
25
61
|
Getting the CosmosDB client
|
|
26
62
|
"""
|
|
@@ -29,28 +65,36 @@ def get_client(credentials: Credentials, subscription_id: str) -> CosmosDBManage
|
|
|
29
65
|
|
|
30
66
|
|
|
31
67
|
@timeit
|
|
32
|
-
def get_database_account_list(
|
|
68
|
+
def get_database_account_list(
|
|
69
|
+
credentials: Credentials,
|
|
70
|
+
subscription_id: str,
|
|
71
|
+
) -> List[Dict]:
|
|
33
72
|
"""
|
|
34
73
|
Get a list of all database accounts.
|
|
35
74
|
"""
|
|
36
75
|
try:
|
|
37
76
|
client = get_client(credentials, subscription_id)
|
|
38
|
-
database_account_list = list(
|
|
77
|
+
database_account_list = list(
|
|
78
|
+
map(lambda x: x.as_dict(), client.database_accounts.list()),
|
|
79
|
+
)
|
|
39
80
|
|
|
40
81
|
# ClientAuthenticationError and ResourceNotFoundError are subclasses under HttpResponseError
|
|
41
82
|
except ClientAuthenticationError:
|
|
42
|
-
logger.warning(
|
|
83
|
+
logger.warning(
|
|
84
|
+
"Client Authentication Error while retrieving database accounts",
|
|
85
|
+
exc_info=True,
|
|
86
|
+
)
|
|
43
87
|
return []
|
|
44
88
|
except ResourceNotFoundError:
|
|
45
|
-
logger.warning(
|
|
89
|
+
logger.warning("Database Account not found error", exc_info=True)
|
|
46
90
|
return []
|
|
47
91
|
except HttpResponseError:
|
|
48
|
-
logger.warning(
|
|
92
|
+
logger.warning("Error while retrieving database accounts", exc_info=True)
|
|
49
93
|
return []
|
|
50
94
|
|
|
51
95
|
for database_account in database_account_list:
|
|
52
|
-
x = database_account[
|
|
53
|
-
database_account[
|
|
96
|
+
x = database_account["id"].split("/")
|
|
97
|
+
database_account["resourceGroup"] = x[x.index("resourceGroups") + 1]
|
|
54
98
|
|
|
55
99
|
return database_account_list
|
|
56
100
|
|
|
@@ -63,188 +107,169 @@ def transform_database_account_data(database_account_list: List[Dict]) -> List[D
|
|
|
63
107
|
for database_account in database_account_list:
|
|
64
108
|
capabilities: List[str] = []
|
|
65
109
|
iprules: List[str] = []
|
|
66
|
-
if
|
|
67
|
-
capabilities
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
database_account[
|
|
110
|
+
if (
|
|
111
|
+
"capabilities" in database_account
|
|
112
|
+
and len(database_account["capabilities"]) > 0
|
|
113
|
+
):
|
|
114
|
+
capabilities = [x["name"] for x in database_account["capabilities"]]
|
|
115
|
+
if "ip_rules" in database_account and len(database_account["ip_rules"]) > 0:
|
|
116
|
+
iprules = [x["ip_address_or_range"] for x in database_account["ip_rules"]]
|
|
117
|
+
database_account["ipruleslist"] = iprules
|
|
118
|
+
database_account["capabilities"] = capabilities
|
|
72
119
|
|
|
73
120
|
return database_account_list
|
|
74
121
|
|
|
75
122
|
|
|
76
123
|
@timeit
|
|
77
124
|
def load_database_account_data(
|
|
78
|
-
|
|
125
|
+
neo4j_session: neo4j.Session,
|
|
126
|
+
subscription_id: str,
|
|
127
|
+
database_account_list: List[Dict],
|
|
128
|
+
azure_update_tag: int,
|
|
79
129
|
) -> None:
|
|
80
130
|
"""
|
|
81
131
|
Ingest data of all database accounts into neo4j.
|
|
82
132
|
"""
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
d.location = da.location
|
|
89
|
-
SET d.lastupdated = $azure_update_tag,
|
|
90
|
-
d.kind = da.kind,
|
|
91
|
-
d.name = da.name,
|
|
92
|
-
d.ipranges = da.ipruleslist,
|
|
93
|
-
d.capabilities = da.list_of_capabilities,
|
|
94
|
-
d.documentendpoint = da.document_endpoint,
|
|
95
|
-
d.virtualnetworkfilterenabled = da.is_virtual_network_filter_enabled,
|
|
96
|
-
d.enableautomaticfailover = da.enable_automatic_failover,
|
|
97
|
-
d.provisioningstate = da.provisioning_state,
|
|
98
|
-
d.multiplewritelocations = da.enable_multiple_write_locations,
|
|
99
|
-
d.accountoffertype = da.database_account_offer_type,
|
|
100
|
-
d.publicnetworkaccess = da.public_network_access,
|
|
101
|
-
d.enablecassandraconnector = da.enable_cassandra_connector,
|
|
102
|
-
d.connectoroffer = da.connector_offer,
|
|
103
|
-
d.disablekeybasedmetadatawriteaccess = da.disable_key_based_metadata_write_access,
|
|
104
|
-
d.keyvaulturi = da.key_vault_key_uri,
|
|
105
|
-
d.enablefreetier = da.enable_free_tier,
|
|
106
|
-
d.enableanalyticalstorage = da.enable_analytical_storage,
|
|
107
|
-
d.defaultconsistencylevel = da.consistency_policy.default_consistency_level,
|
|
108
|
-
d.maxstalenessprefix = da.consistency_policy.max_staleness_prefix,
|
|
109
|
-
d.maxintervalinseconds = da.consistency_policy.max_interval_in_seconds
|
|
110
|
-
WITH d
|
|
111
|
-
MATCH (owner:AzureSubscription{id: $AZURE_SUBSCRIPTION_ID})
|
|
112
|
-
MERGE (owner)-[r:RESOURCE]->(d)
|
|
113
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
114
|
-
SET r.lastupdated = $azure_update_tag
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
|
-
neo4j_session.run(
|
|
118
|
-
ingest_database_account,
|
|
119
|
-
database_accounts_list=database_account_list,
|
|
133
|
+
load(
|
|
134
|
+
neo4j_session,
|
|
135
|
+
AzureCosmosDBAccountSchema(),
|
|
136
|
+
database_account_list,
|
|
137
|
+
lastupdated=azure_update_tag,
|
|
120
138
|
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
121
|
-
azure_update_tag=azure_update_tag,
|
|
122
139
|
)
|
|
123
140
|
|
|
124
141
|
|
|
125
142
|
@timeit
|
|
126
143
|
def sync_database_account_data_resources(
|
|
127
|
-
|
|
144
|
+
neo4j_session: neo4j.Session,
|
|
145
|
+
subscription_id: str,
|
|
146
|
+
database_account_list: List[Dict],
|
|
147
|
+
azure_update_tag: int,
|
|
128
148
|
) -> None:
|
|
129
149
|
"""
|
|
130
150
|
This function calls the load functions for the resources that are present as a part of the database account
|
|
131
151
|
response (like cors policy, failover policy, private endpoint connections, virtual network rules and locations).
|
|
132
152
|
"""
|
|
133
153
|
for database_account in database_account_list:
|
|
134
|
-
_load_cosmosdb_cors_policy(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
154
|
+
_load_cosmosdb_cors_policy(
|
|
155
|
+
neo4j_session,
|
|
156
|
+
database_account,
|
|
157
|
+
subscription_id,
|
|
158
|
+
azure_update_tag,
|
|
159
|
+
)
|
|
160
|
+
_load_cosmosdb_failover_policies(
|
|
161
|
+
neo4j_session,
|
|
162
|
+
database_account,
|
|
163
|
+
subscription_id,
|
|
164
|
+
azure_update_tag,
|
|
165
|
+
)
|
|
166
|
+
_load_cosmosdb_private_endpoint_connections(
|
|
167
|
+
neo4j_session,
|
|
168
|
+
database_account,
|
|
169
|
+
subscription_id,
|
|
170
|
+
azure_update_tag,
|
|
171
|
+
)
|
|
172
|
+
_load_cosmosdb_virtual_network_rules(
|
|
173
|
+
neo4j_session,
|
|
174
|
+
database_account,
|
|
175
|
+
subscription_id,
|
|
176
|
+
azure_update_tag,
|
|
177
|
+
)
|
|
178
|
+
_load_database_account_write_locations(
|
|
179
|
+
neo4j_session,
|
|
180
|
+
database_account,
|
|
181
|
+
subscription_id,
|
|
182
|
+
azure_update_tag,
|
|
183
|
+
)
|
|
184
|
+
_load_database_account_read_locations(
|
|
185
|
+
neo4j_session,
|
|
186
|
+
database_account,
|
|
187
|
+
subscription_id,
|
|
188
|
+
azure_update_tag,
|
|
189
|
+
)
|
|
190
|
+
_load_database_account_associated_locations(
|
|
191
|
+
neo4j_session,
|
|
192
|
+
database_account,
|
|
193
|
+
subscription_id,
|
|
194
|
+
azure_update_tag,
|
|
195
|
+
)
|
|
141
196
|
|
|
142
197
|
|
|
143
198
|
@timeit
|
|
144
199
|
def _load_database_account_write_locations(
|
|
145
|
-
|
|
200
|
+
neo4j_session: neo4j.Session,
|
|
201
|
+
database_account: Dict,
|
|
202
|
+
subscription_id: str,
|
|
203
|
+
azure_update_tag: int,
|
|
146
204
|
) -> None:
|
|
147
205
|
"""
|
|
148
206
|
Ingest the details of location with write permission enabled.
|
|
149
207
|
"""
|
|
150
|
-
if
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
WITH loc
|
|
165
|
-
MATCH (d:AzureCosmosDBAccount{id: $DatabaseAccountId})
|
|
166
|
-
MERGE (d)-[r:CAN_WRITE_FROM]->(loc)
|
|
167
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
168
|
-
SET r.lastupdated = $azure_update_tag
|
|
169
|
-
"""
|
|
170
|
-
|
|
171
|
-
neo4j_session.run(
|
|
172
|
-
ingest_write_location,
|
|
173
|
-
write_locations_list=write_locations,
|
|
174
|
-
DatabaseAccountId=database_account_id,
|
|
175
|
-
azure_update_tag=azure_update_tag,
|
|
208
|
+
if (
|
|
209
|
+
"write_locations" in database_account
|
|
210
|
+
and len(database_account["write_locations"]) > 0
|
|
211
|
+
):
|
|
212
|
+
write_locations = database_account["write_locations"]
|
|
213
|
+
for wl in write_locations:
|
|
214
|
+
wl["db_write_account_id"] = database_account["id"]
|
|
215
|
+
|
|
216
|
+
load(
|
|
217
|
+
neo4j_session,
|
|
218
|
+
AzureCosmosDBLocationSchema(),
|
|
219
|
+
write_locations,
|
|
220
|
+
lastupdated=azure_update_tag,
|
|
221
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
176
222
|
)
|
|
177
223
|
|
|
178
224
|
|
|
179
225
|
@timeit
|
|
180
226
|
def _load_database_account_read_locations(
|
|
181
|
-
|
|
227
|
+
neo4j_session: neo4j.Session,
|
|
228
|
+
database_account: Dict,
|
|
229
|
+
subscription_id: str,
|
|
230
|
+
azure_update_tag: int,
|
|
182
231
|
) -> None:
|
|
183
232
|
"""
|
|
184
233
|
Ingest the details of location with read permission enabled.
|
|
185
234
|
"""
|
|
186
|
-
if
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
WITH loc
|
|
201
|
-
MATCH (d:AzureCosmosDBAccount{id: $DatabaseAccountId})
|
|
202
|
-
MERGE (d)-[r:CAN_READ_FROM]->(loc)
|
|
203
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
204
|
-
SET r.lastupdated = $azure_update_tag
|
|
205
|
-
"""
|
|
206
|
-
|
|
207
|
-
neo4j_session.run(
|
|
208
|
-
ingest_read_location,
|
|
209
|
-
read_locations_list=read_locations,
|
|
210
|
-
DatabaseAccountId=database_account_id,
|
|
211
|
-
azure_update_tag=azure_update_tag,
|
|
235
|
+
if (
|
|
236
|
+
"read_locations" in database_account
|
|
237
|
+
and len(database_account["read_locations"]) > 0
|
|
238
|
+
):
|
|
239
|
+
read_locations = database_account["read_locations"]
|
|
240
|
+
for rl in read_locations:
|
|
241
|
+
rl["db_read_account_id"] = database_account["id"]
|
|
242
|
+
|
|
243
|
+
load(
|
|
244
|
+
neo4j_session,
|
|
245
|
+
AzureCosmosDBLocationSchema(),
|
|
246
|
+
read_locations,
|
|
247
|
+
lastupdated=azure_update_tag,
|
|
248
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
212
249
|
)
|
|
213
250
|
|
|
214
251
|
|
|
215
252
|
@timeit
|
|
216
253
|
def _load_database_account_associated_locations(
|
|
217
|
-
|
|
254
|
+
neo4j_session: neo4j.Session,
|
|
255
|
+
database_account: Dict,
|
|
256
|
+
subscription_id: str,
|
|
257
|
+
azure_update_tag: int,
|
|
218
258
|
) -> None:
|
|
219
259
|
"""
|
|
220
260
|
Ingest the details of enabled location for the database account.
|
|
221
261
|
"""
|
|
222
|
-
if
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
loc.provisioningstate = al.provisioning_state,
|
|
234
|
-
loc.failoverpriority = al.failover_priority,
|
|
235
|
-
loc.iszoneredundant = al.is_zone_redundant
|
|
236
|
-
WITH loc
|
|
237
|
-
MATCH (d:AzureCosmosDBAccount{id: $DatabaseAccountId})
|
|
238
|
-
MERGE (d)-[r:ASSOCIATED_WITH]->(loc)
|
|
239
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
240
|
-
SET r.lastupdated = $azure_update_tag
|
|
241
|
-
"""
|
|
242
|
-
|
|
243
|
-
neo4j_session.run(
|
|
244
|
-
ingest_associated_location,
|
|
245
|
-
associated_locations_list=associated_locations,
|
|
246
|
-
DatabaseAccountId=database_account_id,
|
|
247
|
-
azure_update_tag=azure_update_tag,
|
|
262
|
+
if "locations" in database_account and len(database_account["locations"]) > 0:
|
|
263
|
+
associated_locations = database_account["locations"]
|
|
264
|
+
for al in associated_locations:
|
|
265
|
+
al["db_associated_account_id"] = database_account["id"]
|
|
266
|
+
|
|
267
|
+
load(
|
|
268
|
+
neo4j_session,
|
|
269
|
+
AzureCosmosDBLocationSchema(),
|
|
270
|
+
associated_locations,
|
|
271
|
+
lastupdated=azure_update_tag,
|
|
272
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
248
273
|
)
|
|
249
274
|
|
|
250
275
|
|
|
@@ -253,181 +278,188 @@ def transform_cosmosdb_cors_policy(database_account: Dict) -> Dict:
|
|
|
253
278
|
"""
|
|
254
279
|
Transform CosmosDB Cors Policy response for neo4j ingestion.
|
|
255
280
|
"""
|
|
256
|
-
for policy in database_account[
|
|
257
|
-
if
|
|
258
|
-
policy[
|
|
281
|
+
for policy in database_account["cors"]:
|
|
282
|
+
if "cors_policy_unique_id" not in policy:
|
|
283
|
+
policy["cors_policy_unique_id"] = str(uuid.uuid4())
|
|
259
284
|
|
|
260
285
|
return database_account
|
|
261
286
|
|
|
262
287
|
|
|
263
288
|
@timeit
|
|
264
289
|
def _load_cosmosdb_cors_policy(
|
|
265
|
-
|
|
290
|
+
neo4j_session: neo4j.Session,
|
|
291
|
+
database_account: Dict,
|
|
292
|
+
subscription_id: str,
|
|
293
|
+
azure_update_tag: int,
|
|
266
294
|
) -> None:
|
|
267
295
|
"""
|
|
268
296
|
Ingest the details of the Cors Policy of the database account.
|
|
269
297
|
"""
|
|
270
|
-
if
|
|
298
|
+
if "cors" in database_account and len(database_account["cors"]) > 0:
|
|
271
299
|
database_account = transform_cosmosdb_cors_policy(database_account)
|
|
272
|
-
database_account_id = database_account[
|
|
273
|
-
cors_policies = database_account[
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
corspolicy.allowedmethods = cp.allowed_methods,
|
|
282
|
-
corspolicy.allowedheaders = cp.allowed_headers,
|
|
283
|
-
corspolicy.exposedheaders = cp.exposed_headers,
|
|
284
|
-
corspolicy.maxageinseconds = cp.max_age_in_seconds
|
|
285
|
-
WITH corspolicy
|
|
286
|
-
MATCH (d:AzureCosmosDBAccount{id: $DatabaseAccountId})
|
|
287
|
-
MERGE (d)-[r:CONTAINS]->(corspolicy)
|
|
288
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
289
|
-
SET r.lastupdated = $azure_update_tag
|
|
290
|
-
"""
|
|
291
|
-
|
|
292
|
-
neo4j_session.run(
|
|
293
|
-
ingest_cors_policy,
|
|
294
|
-
cors_policies_list=cors_policies,
|
|
300
|
+
database_account_id = database_account["id"]
|
|
301
|
+
cors_policies = database_account["cors"]
|
|
302
|
+
|
|
303
|
+
load(
|
|
304
|
+
neo4j_session,
|
|
305
|
+
AzureCosmosDBCorsPolicySchema(),
|
|
306
|
+
cors_policies,
|
|
307
|
+
lastupdated=azure_update_tag,
|
|
308
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
295
309
|
DatabaseAccountId=database_account_id,
|
|
296
|
-
azure_update_tag=azure_update_tag,
|
|
297
310
|
)
|
|
298
311
|
|
|
299
312
|
|
|
300
313
|
@timeit
|
|
301
314
|
def _load_cosmosdb_failover_policies(
|
|
302
|
-
|
|
315
|
+
neo4j_session: neo4j.Session,
|
|
316
|
+
database_account: Dict,
|
|
317
|
+
subscription_id: str,
|
|
318
|
+
azure_update_tag: int,
|
|
303
319
|
) -> None:
|
|
304
320
|
"""
|
|
305
321
|
Ingest the details of the Failover Policies of the database account.
|
|
306
322
|
"""
|
|
307
|
-
if
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
MERGE (d)-[r:CONTAINS]->(fpolicy)
|
|
321
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
322
|
-
SET r.lastupdated = $azure_update_tag
|
|
323
|
-
"""
|
|
324
|
-
|
|
325
|
-
neo4j_session.run(
|
|
326
|
-
ingest_failover_policies,
|
|
327
|
-
failover_policies_list=failover_policies,
|
|
323
|
+
if (
|
|
324
|
+
"failover_policies" in database_account
|
|
325
|
+
and len(database_account["failover_policies"]) > 0
|
|
326
|
+
):
|
|
327
|
+
database_account_id = database_account["id"]
|
|
328
|
+
failover_policies = database_account["failover_policies"]
|
|
329
|
+
|
|
330
|
+
load(
|
|
331
|
+
neo4j_session,
|
|
332
|
+
AzureCosmosDBAccountFailoverPolicySchema(),
|
|
333
|
+
failover_policies,
|
|
334
|
+
lastupdated=azure_update_tag,
|
|
335
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
328
336
|
DatabaseAccountId=database_account_id,
|
|
329
|
-
azure_update_tag=azure_update_tag,
|
|
330
337
|
)
|
|
331
338
|
|
|
332
339
|
|
|
333
340
|
@timeit
|
|
334
341
|
def _load_cosmosdb_private_endpoint_connections(
|
|
335
|
-
|
|
342
|
+
neo4j_session: neo4j.Session,
|
|
343
|
+
database_account: Dict,
|
|
344
|
+
subscription_id: str,
|
|
345
|
+
azure_update_tag: int,
|
|
336
346
|
) -> None:
|
|
337
347
|
"""
|
|
338
348
|
Ingest the details of the Private Endpoint Connections of the database account.
|
|
339
349
|
"""
|
|
340
|
-
if
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
MATCH (d:AzureCosmosDBAccount{id: $DatabaseAccountId})
|
|
357
|
-
MERGE (d)-[r:CONFIGURED_WITH]->(pec)
|
|
358
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
359
|
-
SET r.lastupdated = $azure_update_tag
|
|
360
|
-
"""
|
|
361
|
-
|
|
362
|
-
neo4j_session.run(
|
|
363
|
-
ingest_private_endpoint_connections,
|
|
364
|
-
private_endpoint_connections_list=private_endpoint_connections,
|
|
350
|
+
if (
|
|
351
|
+
"private_endpoint_connections" in database_account
|
|
352
|
+
and len(
|
|
353
|
+
database_account["private_endpoint_connections"],
|
|
354
|
+
)
|
|
355
|
+
> 0
|
|
356
|
+
):
|
|
357
|
+
database_account_id = database_account["id"]
|
|
358
|
+
private_endpoint_connections = database_account["private_endpoint_connections"]
|
|
359
|
+
|
|
360
|
+
load(
|
|
361
|
+
neo4j_session,
|
|
362
|
+
AzureCDBPrivateEndpointConnectionSchema(),
|
|
363
|
+
private_endpoint_connections,
|
|
364
|
+
lastupdated=azure_update_tag,
|
|
365
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
365
366
|
DatabaseAccountId=database_account_id,
|
|
366
|
-
azure_update_tag=azure_update_tag,
|
|
367
367
|
)
|
|
368
368
|
|
|
369
369
|
|
|
370
370
|
@timeit
|
|
371
371
|
def _load_cosmosdb_virtual_network_rules(
|
|
372
|
-
|
|
372
|
+
neo4j_session: neo4j.Session,
|
|
373
|
+
database_account: Dict,
|
|
374
|
+
subscription_id: str,
|
|
375
|
+
azure_update_tag: int,
|
|
373
376
|
) -> None:
|
|
374
377
|
"""
|
|
375
378
|
Ingest the details of the Virtual Network Rules of the database account.
|
|
376
379
|
"""
|
|
377
|
-
if
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
391
|
-
SET r.lastupdated = $azure_update_tag
|
|
392
|
-
"""
|
|
393
|
-
|
|
394
|
-
neo4j_session.run(
|
|
395
|
-
ingest_virtual_network_rules,
|
|
396
|
-
virtual_network_rules_list=virtual_network_rules,
|
|
380
|
+
if (
|
|
381
|
+
"virtual_network_rules" in database_account
|
|
382
|
+
and len(database_account["virtual_network_rules"]) > 0
|
|
383
|
+
):
|
|
384
|
+
database_account_id = database_account["id"]
|
|
385
|
+
virtual_network_rules = database_account["virtual_network_rules"]
|
|
386
|
+
|
|
387
|
+
load(
|
|
388
|
+
neo4j_session,
|
|
389
|
+
AzureCosmosDBVirtualNetworkRuleSchema(),
|
|
390
|
+
virtual_network_rules,
|
|
391
|
+
lastupdated=azure_update_tag,
|
|
392
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
397
393
|
DatabaseAccountId=database_account_id,
|
|
398
|
-
azure_update_tag=azure_update_tag,
|
|
399
394
|
)
|
|
400
395
|
|
|
401
396
|
|
|
402
397
|
@timeit
|
|
403
398
|
def sync_database_account_details(
|
|
404
|
-
|
|
405
|
-
|
|
399
|
+
neo4j_session: neo4j.Session,
|
|
400
|
+
credentials: Credentials,
|
|
401
|
+
subscription_id: str,
|
|
402
|
+
database_account_list: List[Dict],
|
|
403
|
+
sync_tag: int,
|
|
404
|
+
common_job_parameters: Dict,
|
|
406
405
|
) -> None:
|
|
407
|
-
details = get_database_account_details(
|
|
408
|
-
|
|
406
|
+
details = get_database_account_details(
|
|
407
|
+
credentials,
|
|
408
|
+
subscription_id,
|
|
409
|
+
database_account_list,
|
|
410
|
+
)
|
|
411
|
+
load_database_account_details(
|
|
412
|
+
neo4j_session,
|
|
413
|
+
credentials,
|
|
414
|
+
subscription_id,
|
|
415
|
+
details,
|
|
416
|
+
sync_tag,
|
|
417
|
+
common_job_parameters,
|
|
418
|
+
)
|
|
409
419
|
|
|
410
420
|
|
|
411
421
|
@timeit
|
|
412
422
|
def get_database_account_details(
|
|
413
|
-
|
|
423
|
+
credentials: Credentials,
|
|
424
|
+
subscription_id: str,
|
|
425
|
+
database_account_list: List[Dict],
|
|
414
426
|
) -> Generator[Any, Any, Any]:
|
|
415
427
|
"""
|
|
416
428
|
Iterate over the database accounts and return the list of SQL and MongoDB databases, Cassandra keyspaces and
|
|
417
429
|
table resources associated with each database account.
|
|
418
430
|
"""
|
|
419
431
|
for database_account in database_account_list:
|
|
420
|
-
sql_databases = get_sql_databases(
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
432
|
+
sql_databases = get_sql_databases(
|
|
433
|
+
credentials,
|
|
434
|
+
subscription_id,
|
|
435
|
+
database_account,
|
|
436
|
+
)
|
|
437
|
+
cassandra_keyspaces = get_cassandra_keyspaces(
|
|
438
|
+
credentials,
|
|
439
|
+
subscription_id,
|
|
440
|
+
database_account,
|
|
441
|
+
)
|
|
442
|
+
mongodb_databases = get_mongodb_databases(
|
|
443
|
+
credentials,
|
|
444
|
+
subscription_id,
|
|
445
|
+
database_account,
|
|
446
|
+
)
|
|
447
|
+
table_resources = get_table_resources(
|
|
448
|
+
credentials,
|
|
449
|
+
subscription_id,
|
|
450
|
+
database_account,
|
|
451
|
+
)
|
|
452
|
+
yield database_account["id"], database_account["name"], database_account[
|
|
453
|
+
"resourceGroup"
|
|
426
454
|
], sql_databases, cassandra_keyspaces, mongodb_databases, table_resources
|
|
427
455
|
|
|
428
456
|
|
|
429
457
|
@timeit
|
|
430
|
-
def get_sql_databases(
|
|
458
|
+
def get_sql_databases(
|
|
459
|
+
credentials: Credentials,
|
|
460
|
+
subscription_id: str,
|
|
461
|
+
database_account: Dict,
|
|
462
|
+
) -> List[Dict]:
|
|
431
463
|
"""
|
|
432
464
|
Return the list of SQL Databases in a database account.
|
|
433
465
|
"""
|
|
@@ -437,27 +469,34 @@ def get_sql_databases(credentials: Credentials, subscription_id: str, database_a
|
|
|
437
469
|
map(
|
|
438
470
|
lambda x: x.as_dict(),
|
|
439
471
|
client.sql_resources.list_sql_databases(
|
|
440
|
-
database_account[
|
|
441
|
-
database_account[
|
|
472
|
+
database_account["resourceGroup"],
|
|
473
|
+
database_account["name"],
|
|
442
474
|
),
|
|
443
475
|
),
|
|
444
476
|
)
|
|
445
477
|
|
|
446
478
|
except ClientAuthenticationError:
|
|
447
|
-
logger.warning(
|
|
479
|
+
logger.warning(
|
|
480
|
+
"Client Authentication Error while retrieving SQL databases",
|
|
481
|
+
exc_info=True,
|
|
482
|
+
)
|
|
448
483
|
return []
|
|
449
484
|
except ResourceNotFoundError:
|
|
450
|
-
logger.warning(
|
|
485
|
+
logger.warning("SQL databases resource not found error", exc_info=True)
|
|
451
486
|
return []
|
|
452
487
|
except HttpResponseError:
|
|
453
|
-
logger.warning(
|
|
488
|
+
logger.warning("Error while retrieving SQL Database list", exc_info=True)
|
|
454
489
|
return []
|
|
455
490
|
|
|
456
491
|
return sql_database_list
|
|
457
492
|
|
|
458
493
|
|
|
459
494
|
@timeit
|
|
460
|
-
def get_cassandra_keyspaces(
|
|
495
|
+
def get_cassandra_keyspaces(
|
|
496
|
+
credentials: Credentials,
|
|
497
|
+
subscription_id: str,
|
|
498
|
+
database_account: Dict,
|
|
499
|
+
) -> List[Dict]:
|
|
461
500
|
"""
|
|
462
501
|
Return the list of Cassandra Keyspaces in a database account.
|
|
463
502
|
"""
|
|
@@ -467,27 +506,34 @@ def get_cassandra_keyspaces(credentials: Credentials, subscription_id: str, data
|
|
|
467
506
|
map(
|
|
468
507
|
lambda x: x.as_dict(),
|
|
469
508
|
client.cassandra_resources.list_cassandra_keyspaces(
|
|
470
|
-
database_account[
|
|
471
|
-
database_account[
|
|
509
|
+
database_account["resourceGroup"],
|
|
510
|
+
database_account["name"],
|
|
472
511
|
),
|
|
473
512
|
),
|
|
474
513
|
)
|
|
475
514
|
|
|
476
515
|
except ClientAuthenticationError:
|
|
477
|
-
logger.warning(
|
|
516
|
+
logger.warning(
|
|
517
|
+
"Client Authentication Error while retrieving Cassandra keyspaces",
|
|
518
|
+
exc_info=True,
|
|
519
|
+
)
|
|
478
520
|
return []
|
|
479
521
|
except ResourceNotFoundError:
|
|
480
|
-
logger.warning(
|
|
522
|
+
logger.warning("Cassandra keyspaces resource not found error", exc_info=True)
|
|
481
523
|
return []
|
|
482
524
|
except HttpResponseError:
|
|
483
|
-
logger.warning(
|
|
525
|
+
logger.warning("Error while retrieving Cassandra keyspaces list", exc_info=True)
|
|
484
526
|
return []
|
|
485
527
|
|
|
486
528
|
return cassandra_keyspace_list
|
|
487
529
|
|
|
488
530
|
|
|
489
531
|
@timeit
|
|
490
|
-
def get_mongodb_databases(
|
|
532
|
+
def get_mongodb_databases(
|
|
533
|
+
credentials: Credentials,
|
|
534
|
+
subscription_id: str,
|
|
535
|
+
database_account: Dict,
|
|
536
|
+
) -> List[Dict]:
|
|
491
537
|
"""
|
|
492
538
|
Return the list of MongoDB Databases in a database account.
|
|
493
539
|
"""
|
|
@@ -497,27 +543,34 @@ def get_mongodb_databases(credentials: Credentials, subscription_id: str, databa
|
|
|
497
543
|
map(
|
|
498
544
|
lambda x: x.as_dict(),
|
|
499
545
|
client.mongo_db_resources.list_mongo_db_databases(
|
|
500
|
-
database_account[
|
|
501
|
-
database_account[
|
|
546
|
+
database_account["resourceGroup"],
|
|
547
|
+
database_account["name"],
|
|
502
548
|
),
|
|
503
549
|
),
|
|
504
550
|
)
|
|
505
551
|
|
|
506
552
|
except ClientAuthenticationError:
|
|
507
|
-
logger.warning(
|
|
553
|
+
logger.warning(
|
|
554
|
+
"Client Authentication Error while retrieving MongoDB Databases",
|
|
555
|
+
exc_info=True,
|
|
556
|
+
)
|
|
508
557
|
return []
|
|
509
558
|
except ResourceNotFoundError:
|
|
510
|
-
logger.warning(
|
|
559
|
+
logger.warning("MongoDB Databases resource not found error", exc_info=True)
|
|
511
560
|
return []
|
|
512
561
|
except HttpResponseError:
|
|
513
|
-
logger.warning(
|
|
562
|
+
logger.warning("Error while retrieving MongoDB Databases list", exc_info=True)
|
|
514
563
|
return []
|
|
515
564
|
|
|
516
565
|
return mongodb_database_list
|
|
517
566
|
|
|
518
567
|
|
|
519
568
|
@timeit
|
|
520
|
-
def get_table_resources(
|
|
569
|
+
def get_table_resources(
|
|
570
|
+
credentials: Credentials,
|
|
571
|
+
subscription_id: str,
|
|
572
|
+
database_account: Dict,
|
|
573
|
+
) -> List[Dict]:
|
|
521
574
|
"""
|
|
522
575
|
Return the list of Table Resources in a database account.
|
|
523
576
|
"""
|
|
@@ -527,20 +580,23 @@ def get_table_resources(credentials: Credentials, subscription_id: str, database
|
|
|
527
580
|
map(
|
|
528
581
|
lambda x: x.as_dict(),
|
|
529
582
|
client.table_resources.list_tables(
|
|
530
|
-
database_account[
|
|
531
|
-
database_account[
|
|
583
|
+
database_account["resourceGroup"],
|
|
584
|
+
database_account["name"],
|
|
532
585
|
),
|
|
533
586
|
),
|
|
534
587
|
)
|
|
535
588
|
|
|
536
589
|
except ClientAuthenticationError:
|
|
537
|
-
logger.warning(
|
|
590
|
+
logger.warning(
|
|
591
|
+
"Client Authentication Error while retrieving Table resources",
|
|
592
|
+
exc_info=True,
|
|
593
|
+
)
|
|
538
594
|
return []
|
|
539
595
|
except ResourceNotFoundError:
|
|
540
|
-
logger.warning(
|
|
596
|
+
logger.warning("Table resource not found error", exc_info=True)
|
|
541
597
|
return []
|
|
542
598
|
except HttpResponseError:
|
|
543
|
-
logger.warning(
|
|
599
|
+
logger.warning("Error while retrieving Table resources list", exc_info=True)
|
|
544
600
|
return []
|
|
545
601
|
|
|
546
602
|
return table_resources_list
|
|
@@ -548,22 +604,29 @@ def get_table_resources(credentials: Credentials, subscription_id: str, database
|
|
|
548
604
|
|
|
549
605
|
@timeit
|
|
550
606
|
def transform_database_account_resources(
|
|
551
|
-
|
|
607
|
+
account_id: Any,
|
|
608
|
+
name: Any,
|
|
609
|
+
resource_group: Any,
|
|
610
|
+
resources: List[Dict],
|
|
552
611
|
) -> List[Dict]:
|
|
553
612
|
"""
|
|
554
613
|
Transform the SQL Database/Cassandra Keyspace/MongoDB Database/Table Resource response for neo4j ingestion.
|
|
555
614
|
"""
|
|
556
615
|
for resource in resources:
|
|
557
|
-
resource[
|
|
558
|
-
resource[
|
|
559
|
-
resource[
|
|
616
|
+
resource["database_account_name"] = name
|
|
617
|
+
resource["database_account_id"] = account_id
|
|
618
|
+
resource["resource_group_name"] = resource_group
|
|
560
619
|
return resources
|
|
561
620
|
|
|
562
621
|
|
|
563
622
|
@timeit
|
|
564
623
|
def load_database_account_details(
|
|
565
|
-
|
|
566
|
-
|
|
624
|
+
neo4j_session: neo4j.Session,
|
|
625
|
+
credentials: Credentials,
|
|
626
|
+
subscription_id: str,
|
|
627
|
+
details: List[Tuple[Any, Any, Any, Any, Any, Any, Any]],
|
|
628
|
+
update_tag: int,
|
|
629
|
+
common_job_parameters: Dict,
|
|
567
630
|
) -> None:
|
|
568
631
|
"""
|
|
569
632
|
Create dictionaries for SQL Databases, Cassandra Keyspaces, MongoDB Databases and table resources.
|
|
@@ -573,183 +636,207 @@ def load_database_account_details(
|
|
|
573
636
|
mongodb_databases: List[Dict] = []
|
|
574
637
|
table_resources: List[Dict] = []
|
|
575
638
|
|
|
576
|
-
for
|
|
639
|
+
for (
|
|
640
|
+
account_id,
|
|
641
|
+
name,
|
|
642
|
+
resourceGroup,
|
|
643
|
+
sql_database,
|
|
644
|
+
cassandra_keyspace,
|
|
645
|
+
mongodb_database,
|
|
646
|
+
table,
|
|
647
|
+
) in details:
|
|
577
648
|
if len(sql_database) > 0:
|
|
578
|
-
dbs = transform_database_account_resources(
|
|
649
|
+
dbs = transform_database_account_resources(
|
|
650
|
+
account_id,
|
|
651
|
+
name,
|
|
652
|
+
resourceGroup,
|
|
653
|
+
sql_database,
|
|
654
|
+
)
|
|
579
655
|
sql_databases.extend(dbs)
|
|
580
656
|
|
|
581
657
|
if len(cassandra_keyspace) > 0:
|
|
582
|
-
keyspaces = transform_database_account_resources(
|
|
658
|
+
keyspaces = transform_database_account_resources(
|
|
659
|
+
account_id,
|
|
660
|
+
name,
|
|
661
|
+
resourceGroup,
|
|
662
|
+
cassandra_keyspace,
|
|
663
|
+
)
|
|
583
664
|
cassandra_keyspaces.extend(keyspaces)
|
|
584
665
|
|
|
585
666
|
if len(mongodb_database) > 0:
|
|
586
|
-
mongo_dbs = transform_database_account_resources(
|
|
667
|
+
mongo_dbs = transform_database_account_resources(
|
|
668
|
+
account_id,
|
|
669
|
+
name,
|
|
670
|
+
resourceGroup,
|
|
671
|
+
mongodb_database,
|
|
672
|
+
)
|
|
587
673
|
mongodb_databases.extend(mongo_dbs)
|
|
588
674
|
|
|
589
675
|
if len(table) > 0:
|
|
590
|
-
t = transform_database_account_resources(
|
|
676
|
+
t = transform_database_account_resources(
|
|
677
|
+
account_id,
|
|
678
|
+
name,
|
|
679
|
+
resourceGroup,
|
|
680
|
+
table,
|
|
681
|
+
)
|
|
591
682
|
table_resources.extend(t)
|
|
592
683
|
|
|
593
684
|
# Loading the table resources
|
|
594
|
-
_load_table_resources(neo4j_session, table_resources, update_tag)
|
|
685
|
+
_load_table_resources(neo4j_session, table_resources, subscription_id, update_tag)
|
|
595
686
|
# Cleanup of table resources (done here because table resource doesn't have any other child resources in it)
|
|
596
687
|
cleanup_table_resources(neo4j_session, common_job_parameters)
|
|
597
688
|
|
|
598
689
|
# Loading SQL databases, Cassandra Keyspaces and MongoDB databases
|
|
599
|
-
_load_sql_databases(neo4j_session, sql_databases, update_tag)
|
|
600
|
-
_load_cassandra_keyspaces(
|
|
601
|
-
|
|
690
|
+
_load_sql_databases(neo4j_session, sql_databases, subscription_id, update_tag)
|
|
691
|
+
_load_cassandra_keyspaces(
|
|
692
|
+
neo4j_session, cassandra_keyspaces, subscription_id, update_tag
|
|
693
|
+
)
|
|
694
|
+
_load_mongodb_databases(
|
|
695
|
+
neo4j_session, mongodb_databases, subscription_id, update_tag
|
|
696
|
+
)
|
|
602
697
|
|
|
603
698
|
sync_sql_database_details(
|
|
604
|
-
neo4j_session,
|
|
699
|
+
neo4j_session,
|
|
700
|
+
credentials,
|
|
701
|
+
subscription_id,
|
|
702
|
+
sql_databases,
|
|
703
|
+
update_tag,
|
|
605
704
|
common_job_parameters,
|
|
606
705
|
)
|
|
607
706
|
sync_cassandra_keyspace_details(
|
|
608
|
-
neo4j_session,
|
|
707
|
+
neo4j_session,
|
|
708
|
+
credentials,
|
|
709
|
+
subscription_id,
|
|
710
|
+
cassandra_keyspaces,
|
|
711
|
+
update_tag,
|
|
609
712
|
common_job_parameters,
|
|
610
713
|
)
|
|
611
714
|
sync_mongodb_database_details(
|
|
612
|
-
neo4j_session,
|
|
715
|
+
neo4j_session,
|
|
716
|
+
credentials,
|
|
717
|
+
subscription_id,
|
|
718
|
+
mongodb_databases,
|
|
719
|
+
update_tag,
|
|
613
720
|
common_job_parameters,
|
|
614
721
|
)
|
|
615
722
|
|
|
616
723
|
|
|
617
724
|
@timeit
|
|
618
|
-
def _load_sql_databases(
|
|
725
|
+
def _load_sql_databases(
|
|
726
|
+
neo4j_session: neo4j.Session,
|
|
727
|
+
sql_databases: List[Dict],
|
|
728
|
+
subscription_id: str,
|
|
729
|
+
update_tag: int,
|
|
730
|
+
) -> None:
|
|
619
731
|
"""
|
|
620
732
|
Ingest SQL Databases into neo4j.
|
|
621
733
|
"""
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
sdb.throughput = database.options.throughput,
|
|
629
|
-
sdb.maxthroughput = database.options.autoscale_setting.max_throughput,
|
|
630
|
-
sdb.lastupdated = $azure_update_tag
|
|
631
|
-
WITH sdb, database
|
|
632
|
-
MATCH (d:AzureCosmosDBAccount{id: database.database_account_id})
|
|
633
|
-
MERGE (d)-[r:CONTAINS]->(sdb)
|
|
634
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
635
|
-
SET r.lastupdated = $azure_update_tag
|
|
636
|
-
"""
|
|
637
|
-
|
|
638
|
-
neo4j_session.run(
|
|
639
|
-
ingest_sql_databases,
|
|
640
|
-
sql_databases_list=sql_databases,
|
|
641
|
-
azure_update_tag=update_tag,
|
|
734
|
+
load(
|
|
735
|
+
neo4j_session,
|
|
736
|
+
AzureCosmosDBSqlDatabaseSchema(),
|
|
737
|
+
sql_databases,
|
|
738
|
+
lastupdated=update_tag,
|
|
739
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
642
740
|
)
|
|
643
741
|
|
|
644
742
|
|
|
645
743
|
@timeit
|
|
646
|
-
def _load_cassandra_keyspaces(
|
|
744
|
+
def _load_cassandra_keyspaces(
|
|
745
|
+
neo4j_session: neo4j.Session,
|
|
746
|
+
cassandra_keyspaces: List[Dict],
|
|
747
|
+
subscription_id: str,
|
|
748
|
+
update_tag: int,
|
|
749
|
+
) -> None:
|
|
647
750
|
"""
|
|
648
751
|
Ingest Cassandra keyspaces into neo4j.
|
|
649
752
|
"""
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
ck.lastupdated = $azure_update_tag,
|
|
657
|
-
ck.throughput = keyspace.options.throughput,
|
|
658
|
-
ck.maxthroughput = keyspace.options.autoscale_setting.max_throughput
|
|
659
|
-
WITH ck, keyspace
|
|
660
|
-
MATCH (d:AzureCosmosDBAccount{id: keyspace.database_account_id})
|
|
661
|
-
MERGE (d)-[r:CONTAINS]->(ck)
|
|
662
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
663
|
-
SET r.lastupdated = $azure_update_tag
|
|
664
|
-
"""
|
|
665
|
-
|
|
666
|
-
neo4j_session.run(
|
|
667
|
-
ingest_cassandra_keyspaces,
|
|
668
|
-
cassandra_keyspaces_list=cassandra_keyspaces,
|
|
669
|
-
azure_update_tag=update_tag,
|
|
753
|
+
load(
|
|
754
|
+
neo4j_session,
|
|
755
|
+
AzureCosmosDBCassandraKeyspaceSchema(),
|
|
756
|
+
cassandra_keyspaces,
|
|
757
|
+
lastupdated=update_tag,
|
|
758
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
670
759
|
)
|
|
671
760
|
|
|
672
761
|
|
|
673
762
|
@timeit
|
|
674
|
-
def _load_mongodb_databases(
|
|
763
|
+
def _load_mongodb_databases(
|
|
764
|
+
neo4j_session: neo4j.Session,
|
|
765
|
+
mongodb_databases: List[Dict],
|
|
766
|
+
subscription_id: str,
|
|
767
|
+
update_tag: int,
|
|
768
|
+
) -> None:
|
|
675
769
|
"""
|
|
676
770
|
Ingest MongoDB databases into neo4j.
|
|
677
771
|
"""
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
mdb.throughput = database.options.throughput,
|
|
685
|
-
mdb.maxthroughput = database.options.autoscale_setting.max_throughput,
|
|
686
|
-
mdb.lastupdated = $azure_update_tag
|
|
687
|
-
WITH mdb, database
|
|
688
|
-
MATCH (d:AzureCosmosDBAccount{id: database.database_account_id})
|
|
689
|
-
MERGE (d)-[r:CONTAINS]->(mdb)
|
|
690
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
691
|
-
SET r.lastupdated = $azure_update_tag
|
|
692
|
-
"""
|
|
693
|
-
|
|
694
|
-
neo4j_session.run(
|
|
695
|
-
ingest_mongodb_databases,
|
|
696
|
-
mongodb_databases_list=mongodb_databases,
|
|
697
|
-
azure_update_tag=update_tag,
|
|
772
|
+
load(
|
|
773
|
+
neo4j_session,
|
|
774
|
+
AzureCosmosDBMongoDBDatabaseSchema(),
|
|
775
|
+
mongodb_databases,
|
|
776
|
+
lastupdated=update_tag,
|
|
777
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
698
778
|
)
|
|
699
779
|
|
|
700
780
|
|
|
701
781
|
@timeit
|
|
702
|
-
def _load_table_resources(
|
|
782
|
+
def _load_table_resources(
|
|
783
|
+
neo4j_session: neo4j.Session,
|
|
784
|
+
table_resources: List[Dict],
|
|
785
|
+
subscription_id: str,
|
|
786
|
+
update_tag: int,
|
|
787
|
+
) -> None:
|
|
703
788
|
"""
|
|
704
789
|
Ingest Table resources into neo4j.
|
|
705
790
|
"""
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
tr.lastupdated = $azure_update_tag,
|
|
713
|
-
tr.throughput = table.options.throughput,
|
|
714
|
-
tr.maxthroughput = table.options.autoscale_setting.max_throughput
|
|
715
|
-
WITH tr, table
|
|
716
|
-
MATCH (d:AzureCosmosDBAccount{id: table.database_account_id})
|
|
717
|
-
MERGE (d)-[r:CONTAINS]->(tr)
|
|
718
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
719
|
-
SET r.lastupdated = $azure_update_tag
|
|
720
|
-
"""
|
|
721
|
-
|
|
722
|
-
neo4j_session.run(
|
|
723
|
-
ingest_tables,
|
|
724
|
-
table_resources_list=table_resources,
|
|
725
|
-
azure_update_tag=update_tag,
|
|
791
|
+
load(
|
|
792
|
+
neo4j_session,
|
|
793
|
+
AzureCosmosDBTableResourceSchema(),
|
|
794
|
+
table_resources,
|
|
795
|
+
lastupdated=update_tag,
|
|
796
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
726
797
|
)
|
|
727
798
|
|
|
728
799
|
|
|
729
800
|
@timeit
|
|
730
801
|
def sync_sql_database_details(
|
|
731
|
-
|
|
732
|
-
|
|
802
|
+
neo4j_session: neo4j.Session,
|
|
803
|
+
credentials: Credentials,
|
|
804
|
+
subscription_id: str,
|
|
805
|
+
sql_databases: List[Dict],
|
|
806
|
+
update_tag: int,
|
|
807
|
+
common_job_parameters: Dict,
|
|
733
808
|
) -> None:
|
|
734
|
-
sql_database_details = get_sql_database_details(
|
|
735
|
-
|
|
809
|
+
sql_database_details = get_sql_database_details(
|
|
810
|
+
credentials,
|
|
811
|
+
subscription_id,
|
|
812
|
+
sql_databases,
|
|
813
|
+
)
|
|
814
|
+
load_sql_database_details(
|
|
815
|
+
neo4j_session, sql_database_details, subscription_id, update_tag
|
|
816
|
+
)
|
|
736
817
|
cleanup_sql_database_details(neo4j_session, common_job_parameters)
|
|
737
818
|
|
|
738
819
|
|
|
739
820
|
@timeit
|
|
740
821
|
def get_sql_database_details(
|
|
741
|
-
|
|
822
|
+
credentials: Credentials,
|
|
823
|
+
subscription_id: str,
|
|
824
|
+
sql_databases: List[Dict],
|
|
742
825
|
) -> Generator[Any, Any, Any]:
|
|
743
826
|
"""
|
|
744
827
|
Iterate over the SQL databases to retrieve the SQL containers in them.
|
|
745
828
|
"""
|
|
746
829
|
for database in sql_databases:
|
|
747
830
|
containers = get_sql_containers(credentials, subscription_id, database)
|
|
748
|
-
yield database[
|
|
831
|
+
yield database["id"], containers
|
|
749
832
|
|
|
750
833
|
|
|
751
834
|
@timeit
|
|
752
|
-
def get_sql_containers(
|
|
835
|
+
def get_sql_containers(
|
|
836
|
+
credentials: Credentials,
|
|
837
|
+
subscription_id: str,
|
|
838
|
+
database: Dict,
|
|
839
|
+
) -> List[Dict]:
|
|
753
840
|
"""
|
|
754
841
|
Returns the list of SQL containers in a database.
|
|
755
842
|
"""
|
|
@@ -759,28 +846,36 @@ def get_sql_containers(credentials: Credentials, subscription_id: str, database:
|
|
|
759
846
|
map(
|
|
760
847
|
lambda x: x.as_dict(),
|
|
761
848
|
client.sql_resources.list_sql_containers(
|
|
762
|
-
database[
|
|
763
|
-
database[
|
|
764
|
-
database[
|
|
849
|
+
database["resource_group_name"],
|
|
850
|
+
database["database_account_name"],
|
|
851
|
+
database["name"],
|
|
765
852
|
),
|
|
766
853
|
),
|
|
767
854
|
)
|
|
768
855
|
|
|
769
856
|
except ClientAuthenticationError:
|
|
770
|
-
logger.warning(
|
|
857
|
+
logger.warning(
|
|
858
|
+
"Client Authentication Error while retrieving SQL containers",
|
|
859
|
+
exc_info=True,
|
|
860
|
+
)
|
|
771
861
|
return []
|
|
772
862
|
except ResourceNotFoundError:
|
|
773
|
-
logger.warning(
|
|
863
|
+
logger.warning("SQL containers not found error", exc_info=True)
|
|
774
864
|
return []
|
|
775
865
|
except HttpResponseError:
|
|
776
|
-
logger.warning(
|
|
866
|
+
logger.warning("Error while retrieving SQL containers list", exc_info=True)
|
|
777
867
|
return []
|
|
778
868
|
|
|
779
869
|
return containers
|
|
780
870
|
|
|
781
871
|
|
|
782
872
|
@timeit
|
|
783
|
-
def load_sql_database_details(
|
|
873
|
+
def load_sql_database_details(
|
|
874
|
+
neo4j_session: neo4j.Session,
|
|
875
|
+
details: List[Tuple[Any, Any]],
|
|
876
|
+
subscription_id: str,
|
|
877
|
+
update_tag: int,
|
|
878
|
+
) -> None:
|
|
784
879
|
"""
|
|
785
880
|
Create dictionary for SQL Containers
|
|
786
881
|
"""
|
|
@@ -789,70 +884,74 @@ def load_sql_database_details(neo4j_session: neo4j.Session, details: List[Tuple[
|
|
|
789
884
|
for database_id, container in details:
|
|
790
885
|
if len(container) > 0:
|
|
791
886
|
for c in container:
|
|
792
|
-
c[
|
|
887
|
+
c["database_id"] = database_id
|
|
793
888
|
containers.extend(container)
|
|
794
889
|
|
|
795
|
-
_load_sql_containers(neo4j_session, containers, update_tag)
|
|
890
|
+
_load_sql_containers(neo4j_session, containers, subscription_id, update_tag)
|
|
796
891
|
|
|
797
892
|
|
|
798
893
|
@timeit
|
|
799
|
-
def _load_sql_containers(
|
|
894
|
+
def _load_sql_containers(
|
|
895
|
+
neo4j_session: neo4j.Session,
|
|
896
|
+
containers: List[Dict],
|
|
897
|
+
subscription_id: str,
|
|
898
|
+
update_tag: int,
|
|
899
|
+
) -> None:
|
|
800
900
|
"""
|
|
801
901
|
Ingest SQL Container details into neo4j.
|
|
802
902
|
"""
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
c.lastupdated = $azure_update_tag,
|
|
810
|
-
c.throughput = container.options.throughput,
|
|
811
|
-
c.maxthroughput = container.options.autoscale_setting.max_throughput,
|
|
812
|
-
c.container = container.resource.id,
|
|
813
|
-
c.defaultttl = container.resource.default_ttl,
|
|
814
|
-
c.analyticalttl = container.resource.analytical_storage_ttl,
|
|
815
|
-
c.isautomaticindexingpolicy = container.resource.indexing_policy.automatic,
|
|
816
|
-
c.indexingmode = container.resource.indexing_policy.indexing_mode,
|
|
817
|
-
c.conflictresolutionpolicymode = container.resource.conflict_resolution_policy.mode
|
|
818
|
-
WITH c, container
|
|
819
|
-
MATCH (sdb:AzureCosmosDBSqlDatabase{id: container.database_id})
|
|
820
|
-
MERGE (sdb)-[r:CONTAINS]->(c)
|
|
821
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
822
|
-
SET r.lastupdated = $azure_update_tag
|
|
823
|
-
"""
|
|
824
|
-
|
|
825
|
-
neo4j_session.run(
|
|
826
|
-
ingest_containers,
|
|
827
|
-
sql_containers_list=containers,
|
|
828
|
-
azure_update_tag=update_tag,
|
|
903
|
+
load(
|
|
904
|
+
neo4j_session,
|
|
905
|
+
AzureCosmosDBSqlContainerSchema(),
|
|
906
|
+
containers,
|
|
907
|
+
lastupdated=update_tag,
|
|
908
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
829
909
|
)
|
|
830
910
|
|
|
831
911
|
|
|
832
912
|
@timeit
|
|
833
913
|
def sync_cassandra_keyspace_details(
|
|
834
|
-
|
|
835
|
-
|
|
914
|
+
neo4j_session: neo4j.Session,
|
|
915
|
+
credentials: Credentials,
|
|
916
|
+
subscription_id: str,
|
|
917
|
+
cassandra_keyspaces: List[Dict],
|
|
918
|
+
update_tag: int,
|
|
919
|
+
common_job_parameters: Dict,
|
|
836
920
|
) -> None:
|
|
837
|
-
cassandra_keyspace_details = get_cassandra_keyspace_details(
|
|
838
|
-
|
|
921
|
+
cassandra_keyspace_details = get_cassandra_keyspace_details(
|
|
922
|
+
credentials,
|
|
923
|
+
subscription_id,
|
|
924
|
+
cassandra_keyspaces,
|
|
925
|
+
)
|
|
926
|
+
load_cassandra_keyspace_details(
|
|
927
|
+
neo4j_session,
|
|
928
|
+
cassandra_keyspace_details,
|
|
929
|
+
subscription_id,
|
|
930
|
+
update_tag,
|
|
931
|
+
)
|
|
839
932
|
cleanup_cassandra_keyspace_details(neo4j_session, common_job_parameters)
|
|
840
933
|
|
|
841
934
|
|
|
842
935
|
@timeit
|
|
843
936
|
def get_cassandra_keyspace_details(
|
|
844
|
-
|
|
937
|
+
credentials: Credentials,
|
|
938
|
+
subscription_id: str,
|
|
939
|
+
cassandra_keyspaces: List[Dict],
|
|
845
940
|
) -> Generator[Any, Any, Any]:
|
|
846
941
|
"""
|
|
847
942
|
Iterate through the Cassandra keyspaces to get the list of tables in each keyspace.
|
|
848
943
|
"""
|
|
849
944
|
for keyspace in cassandra_keyspaces:
|
|
850
945
|
cassandra_tables = get_cassandra_tables(credentials, subscription_id, keyspace)
|
|
851
|
-
yield keyspace[
|
|
946
|
+
yield keyspace["id"], cassandra_tables
|
|
852
947
|
|
|
853
948
|
|
|
854
949
|
@timeit
|
|
855
|
-
def get_cassandra_tables(
|
|
950
|
+
def get_cassandra_tables(
|
|
951
|
+
credentials: Credentials,
|
|
952
|
+
subscription_id: str,
|
|
953
|
+
keyspace: Dict,
|
|
954
|
+
) -> List[Dict]:
|
|
856
955
|
"""
|
|
857
956
|
Returns the list of tables in a Cassandra Keyspace.
|
|
858
957
|
"""
|
|
@@ -862,21 +961,24 @@ def get_cassandra_tables(credentials: Credentials, subscription_id: str, keyspac
|
|
|
862
961
|
map(
|
|
863
962
|
lambda x: x.as_dict(),
|
|
864
963
|
client.cassandra_resources.list_cassandra_tables(
|
|
865
|
-
keyspace[
|
|
866
|
-
keyspace[
|
|
867
|
-
keyspace[
|
|
964
|
+
keyspace["resource_group_name"],
|
|
965
|
+
keyspace["database_account_name"],
|
|
966
|
+
keyspace["name"],
|
|
868
967
|
),
|
|
869
968
|
),
|
|
870
969
|
)
|
|
871
970
|
|
|
872
971
|
except ClientAuthenticationError:
|
|
873
|
-
logger.warning(
|
|
972
|
+
logger.warning(
|
|
973
|
+
"Client Authentication Error while retrieving Cassandra tables",
|
|
974
|
+
exc_info=True,
|
|
975
|
+
)
|
|
874
976
|
return []
|
|
875
977
|
except ResourceNotFoundError:
|
|
876
|
-
logger.warning(
|
|
978
|
+
logger.warning("Cassandra tables not found error", exc_info=True)
|
|
877
979
|
return []
|
|
878
980
|
except HttpResponseError:
|
|
879
|
-
logger.warning(
|
|
981
|
+
logger.warning("Error while retrieving Cassandra tables list", exc_info=True)
|
|
880
982
|
return []
|
|
881
983
|
|
|
882
984
|
return cassandra_tables
|
|
@@ -884,7 +986,10 @@ def get_cassandra_tables(credentials: Credentials, subscription_id: str, keyspac
|
|
|
884
986
|
|
|
885
987
|
@timeit
|
|
886
988
|
def load_cassandra_keyspace_details(
|
|
887
|
-
|
|
989
|
+
neo4j_session: neo4j.Session,
|
|
990
|
+
details: List[Tuple[Any, Any]],
|
|
991
|
+
subscription_id: str,
|
|
992
|
+
update_tag: int,
|
|
888
993
|
) -> None:
|
|
889
994
|
"""
|
|
890
995
|
Create a dictionary for Cassandra tables.
|
|
@@ -894,67 +999,71 @@ def load_cassandra_keyspace_details(
|
|
|
894
999
|
for keyspace_id, cassandra_table in details:
|
|
895
1000
|
if len(cassandra_table) > 0:
|
|
896
1001
|
for t in cassandra_table:
|
|
897
|
-
t[
|
|
1002
|
+
t["keyspace_id"] = keyspace_id
|
|
898
1003
|
cassandra_tables.extend(cassandra_table)
|
|
899
1004
|
|
|
900
|
-
_load_cassandra_tables(neo4j_session, cassandra_tables, update_tag)
|
|
1005
|
+
_load_cassandra_tables(neo4j_session, cassandra_tables, subscription_id, update_tag)
|
|
901
1006
|
|
|
902
1007
|
|
|
903
1008
|
@timeit
|
|
904
|
-
def _load_cassandra_tables(
|
|
1009
|
+
def _load_cassandra_tables(
|
|
1010
|
+
neo4j_session: neo4j.Session,
|
|
1011
|
+
cassandra_tables: List[Dict],
|
|
1012
|
+
subscription_id: str,
|
|
1013
|
+
update_tag: int,
|
|
1014
|
+
) -> None:
|
|
905
1015
|
"""
|
|
906
1016
|
Ingest Cassandra Tables into neo4j.
|
|
907
1017
|
"""
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
ct.lastupdated = $azure_update_tag,
|
|
915
|
-
ct.throughput = table.options.throughput,
|
|
916
|
-
ct.maxthroughput = table.options.autoscale_setting.max_throughput,
|
|
917
|
-
ct.container = table.resource.id,
|
|
918
|
-
ct.defaultttl = table.resource.default_ttl,
|
|
919
|
-
ct.analyticalttl = table.resource.analytical_storage_ttl
|
|
920
|
-
WITH ct, table
|
|
921
|
-
MATCH (ck:AzureCosmosDBCassandraKeyspace{id: table.keyspace_id})
|
|
922
|
-
MERGE (ck)-[r:CONTAINS]->(ct)
|
|
923
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
924
|
-
SET r.lastupdated = $azure_update_tag
|
|
925
|
-
"""
|
|
926
|
-
|
|
927
|
-
neo4j_session.run(
|
|
928
|
-
ingest_cassandra_tables,
|
|
929
|
-
cassandra_tables_list=cassandra_tables,
|
|
930
|
-
azure_update_tag=update_tag,
|
|
1018
|
+
load(
|
|
1019
|
+
neo4j_session,
|
|
1020
|
+
AzureCosmosDBCassandraTableSchema(),
|
|
1021
|
+
cassandra_tables,
|
|
1022
|
+
lastupdated=update_tag,
|
|
1023
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
931
1024
|
)
|
|
932
1025
|
|
|
933
1026
|
|
|
934
1027
|
@timeit
|
|
935
1028
|
def sync_mongodb_database_details(
|
|
936
|
-
|
|
937
|
-
|
|
1029
|
+
neo4j_session: neo4j.Session,
|
|
1030
|
+
credentials: Credentials,
|
|
1031
|
+
subscription_id: str,
|
|
1032
|
+
mongodb_databases: List[Dict],
|
|
1033
|
+
update_tag: int,
|
|
1034
|
+
common_job_parameters: Dict,
|
|
938
1035
|
) -> None:
|
|
939
|
-
mongodb_databases_details = get_mongodb_databases_details(
|
|
940
|
-
|
|
1036
|
+
mongodb_databases_details = get_mongodb_databases_details(
|
|
1037
|
+
credentials,
|
|
1038
|
+
subscription_id,
|
|
1039
|
+
mongodb_databases,
|
|
1040
|
+
)
|
|
1041
|
+
load_mongodb_databases_details(
|
|
1042
|
+
neo4j_session, mongodb_databases_details, subscription_id, update_tag
|
|
1043
|
+
)
|
|
941
1044
|
cleanup_mongodb_database_details(neo4j_session, common_job_parameters)
|
|
942
1045
|
|
|
943
1046
|
|
|
944
1047
|
@timeit
|
|
945
1048
|
def get_mongodb_databases_details(
|
|
946
|
-
|
|
1049
|
+
credentials: Credentials,
|
|
1050
|
+
subscription_id: str,
|
|
1051
|
+
mongodb_databases: List[Dict],
|
|
947
1052
|
) -> Generator[Any, Any, Any]:
|
|
948
1053
|
"""
|
|
949
1054
|
Iterate through the MongoDB Databases to get the list of collections in each mongoDB database.
|
|
950
1055
|
"""
|
|
951
1056
|
for database in mongodb_databases:
|
|
952
1057
|
collections = get_mongodb_collections(credentials, subscription_id, database)
|
|
953
|
-
yield database[
|
|
1058
|
+
yield database["id"], collections
|
|
954
1059
|
|
|
955
1060
|
|
|
956
1061
|
@timeit
|
|
957
|
-
def get_mongodb_collections(
|
|
1062
|
+
def get_mongodb_collections(
|
|
1063
|
+
credentials: Credentials,
|
|
1064
|
+
subscription_id: str,
|
|
1065
|
+
database: Dict,
|
|
1066
|
+
) -> List[Dict]:
|
|
958
1067
|
"""
|
|
959
1068
|
Returns the list of collections in a MongoDB Database.
|
|
960
1069
|
"""
|
|
@@ -964,21 +1073,24 @@ def get_mongodb_collections(credentials: Credentials, subscription_id: str, data
|
|
|
964
1073
|
map(
|
|
965
1074
|
lambda x: x.as_dict(),
|
|
966
1075
|
client.mongo_db_resources.list_mongo_db_collections(
|
|
967
|
-
database[
|
|
968
|
-
database[
|
|
969
|
-
database[
|
|
1076
|
+
database["resource_group_name"],
|
|
1077
|
+
database["database_account_name"],
|
|
1078
|
+
database["name"],
|
|
970
1079
|
),
|
|
971
1080
|
),
|
|
972
1081
|
)
|
|
973
1082
|
|
|
974
1083
|
except ClientAuthenticationError:
|
|
975
|
-
logger.warning(
|
|
1084
|
+
logger.warning(
|
|
1085
|
+
"Client Authentication Error while retrieving MongoDB collections",
|
|
1086
|
+
exc_info=True,
|
|
1087
|
+
)
|
|
976
1088
|
return []
|
|
977
1089
|
except ResourceNotFoundError:
|
|
978
|
-
logger.warning(
|
|
1090
|
+
logger.warning("MongoDB collections not found error", exc_info=True)
|
|
979
1091
|
return []
|
|
980
1092
|
except HttpResponseError:
|
|
981
|
-
logger.warning(
|
|
1093
|
+
logger.warning("Error while retrieving MongoDB collections list", exc_info=True)
|
|
982
1094
|
return []
|
|
983
1095
|
|
|
984
1096
|
return collections
|
|
@@ -986,7 +1098,10 @@ def get_mongodb_collections(credentials: Credentials, subscription_id: str, data
|
|
|
986
1098
|
|
|
987
1099
|
@timeit
|
|
988
1100
|
def load_mongodb_databases_details(
|
|
989
|
-
|
|
1101
|
+
neo4j_session: neo4j.Session,
|
|
1102
|
+
details: List[Tuple[Any, Any]],
|
|
1103
|
+
subscription_id: str,
|
|
1104
|
+
update_tag: int,
|
|
990
1105
|
) -> None:
|
|
991
1106
|
"""
|
|
992
1107
|
Create a dictionary for MongoDB tables.
|
|
@@ -996,79 +1111,151 @@ def load_mongodb_databases_details(
|
|
|
996
1111
|
for database_id, collection in details:
|
|
997
1112
|
if len(collection) > 0:
|
|
998
1113
|
for c in collection:
|
|
999
|
-
c[
|
|
1114
|
+
c["database_id"] = database_id
|
|
1000
1115
|
collections.extend(collection)
|
|
1001
1116
|
|
|
1002
|
-
_load_collections(neo4j_session, collections, update_tag)
|
|
1117
|
+
_load_collections(neo4j_session, collections, subscription_id, update_tag)
|
|
1003
1118
|
|
|
1004
1119
|
|
|
1005
1120
|
@timeit
|
|
1006
|
-
def _load_collections(
|
|
1121
|
+
def _load_collections(
|
|
1122
|
+
neo4j_session: neo4j.Session,
|
|
1123
|
+
collections: List[Dict],
|
|
1124
|
+
subscription_id: str,
|
|
1125
|
+
update_tag: int,
|
|
1126
|
+
) -> None:
|
|
1007
1127
|
"""
|
|
1008
1128
|
Ingest MongoDB Collections into neo4j.
|
|
1009
1129
|
"""
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
col.lastupdated = $azure_update_tag,
|
|
1017
|
-
col.throughput = collection.options.throughput,
|
|
1018
|
-
col.maxthroughput = collection.options.autoscale_setting.max_throughput,
|
|
1019
|
-
col.collectionname = collection.resource.id,
|
|
1020
|
-
col.analyticalttl = collection.resource.analytical_storage_ttl
|
|
1021
|
-
WITH col, collection
|
|
1022
|
-
MATCH (mdb:AzureCosmosDBMongoDBDatabase{id: collection.database_id})
|
|
1023
|
-
MERGE (mdb)-[r:CONTAINS]->(col)
|
|
1024
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
1025
|
-
SET r.lastupdated = $azure_update_tag
|
|
1026
|
-
"""
|
|
1027
|
-
|
|
1028
|
-
neo4j_session.run(
|
|
1029
|
-
ingest_collections,
|
|
1030
|
-
mongodb_collections_list=collections,
|
|
1031
|
-
azure_update_tag=update_tag,
|
|
1130
|
+
load(
|
|
1131
|
+
neo4j_session,
|
|
1132
|
+
AzureCosmosDBMongoDBCollectionSchema(),
|
|
1133
|
+
collections,
|
|
1134
|
+
lastupdated=update_tag,
|
|
1135
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
1032
1136
|
)
|
|
1033
1137
|
|
|
1034
1138
|
|
|
1035
1139
|
@timeit
|
|
1036
|
-
def cleanup_azure_database_accounts(
|
|
1037
|
-
|
|
1140
|
+
def cleanup_azure_database_accounts(
|
|
1141
|
+
neo4j_session: neo4j.Session,
|
|
1142
|
+
common_job_parameters: Dict,
|
|
1143
|
+
) -> None:
|
|
1144
|
+
GraphJob.from_node_schema(AzureCosmosDBAccountSchema(), common_job_parameters).run(
|
|
1145
|
+
neo4j_session,
|
|
1146
|
+
)
|
|
1147
|
+
GraphJob.from_node_schema(AzureCosmosDBLocationSchema(), common_job_parameters).run(
|
|
1148
|
+
neo4j_session,
|
|
1149
|
+
)
|
|
1150
|
+
GraphJob.from_node_schema(
|
|
1151
|
+
AzureCosmosDBCorsPolicySchema(), common_job_parameters
|
|
1152
|
+
).run(
|
|
1153
|
+
neo4j_session,
|
|
1154
|
+
)
|
|
1155
|
+
GraphJob.from_node_schema(
|
|
1156
|
+
AzureCosmosDBVirtualNetworkRuleSchema(), common_job_parameters
|
|
1157
|
+
).run(
|
|
1158
|
+
neo4j_session,
|
|
1159
|
+
)
|
|
1160
|
+
GraphJob.from_node_schema(
|
|
1161
|
+
AzureCDBPrivateEndpointConnectionSchema(), common_job_parameters
|
|
1162
|
+
).run(
|
|
1163
|
+
neo4j_session,
|
|
1164
|
+
)
|
|
1038
1165
|
|
|
1039
1166
|
|
|
1040
1167
|
@timeit
|
|
1041
|
-
def cleanup_sql_database_details(
|
|
1042
|
-
|
|
1168
|
+
def cleanup_sql_database_details(
|
|
1169
|
+
neo4j_session: neo4j.Session,
|
|
1170
|
+
common_job_parameters: Dict,
|
|
1171
|
+
) -> None:
|
|
1172
|
+
GraphJob.from_node_schema(
|
|
1173
|
+
AzureCosmosDBSqlContainerSchema(), common_job_parameters
|
|
1174
|
+
).run(
|
|
1175
|
+
neo4j_session,
|
|
1176
|
+
)
|
|
1177
|
+
GraphJob.from_node_schema(
|
|
1178
|
+
AzureCosmosDBSqlDatabaseSchema(), common_job_parameters
|
|
1179
|
+
).run(
|
|
1180
|
+
neo4j_session,
|
|
1181
|
+
)
|
|
1043
1182
|
|
|
1044
1183
|
|
|
1045
1184
|
@timeit
|
|
1046
|
-
def cleanup_cassandra_keyspace_details(
|
|
1047
|
-
|
|
1185
|
+
def cleanup_cassandra_keyspace_details(
|
|
1186
|
+
neo4j_session: neo4j.Session,
|
|
1187
|
+
common_job_parameters: Dict,
|
|
1188
|
+
) -> None:
|
|
1189
|
+
GraphJob.from_node_schema(
|
|
1190
|
+
AzureCosmosDBCassandraTableSchema(), common_job_parameters
|
|
1191
|
+
).run(
|
|
1192
|
+
neo4j_session,
|
|
1193
|
+
)
|
|
1194
|
+
GraphJob.from_node_schema(
|
|
1195
|
+
AzureCosmosDBCassandraKeyspaceSchema(), common_job_parameters
|
|
1196
|
+
).run(
|
|
1197
|
+
neo4j_session,
|
|
1198
|
+
)
|
|
1048
1199
|
|
|
1049
1200
|
|
|
1050
1201
|
@timeit
|
|
1051
|
-
def cleanup_mongodb_database_details(
|
|
1052
|
-
|
|
1202
|
+
def cleanup_mongodb_database_details(
|
|
1203
|
+
neo4j_session: neo4j.Session,
|
|
1204
|
+
common_job_parameters: Dict,
|
|
1205
|
+
) -> None:
|
|
1206
|
+
GraphJob.from_node_schema(
|
|
1207
|
+
AzureCosmosDBMongoDBCollectionSchema(), common_job_parameters
|
|
1208
|
+
).run(
|
|
1209
|
+
neo4j_session,
|
|
1210
|
+
)
|
|
1211
|
+
GraphJob.from_node_schema(
|
|
1212
|
+
AzureCosmosDBMongoDBDatabaseSchema(), common_job_parameters
|
|
1213
|
+
).run(
|
|
1214
|
+
neo4j_session,
|
|
1215
|
+
)
|
|
1053
1216
|
|
|
1054
1217
|
|
|
1055
1218
|
@timeit
|
|
1056
|
-
def cleanup_table_resources(
|
|
1057
|
-
|
|
1219
|
+
def cleanup_table_resources(
|
|
1220
|
+
neo4j_session: neo4j.Session,
|
|
1221
|
+
common_job_parameters: Dict,
|
|
1222
|
+
) -> None:
|
|
1223
|
+
GraphJob.from_node_schema(
|
|
1224
|
+
AzureCosmosDBTableResourceSchema(), common_job_parameters
|
|
1225
|
+
).run(
|
|
1226
|
+
neo4j_session,
|
|
1227
|
+
)
|
|
1058
1228
|
|
|
1059
1229
|
|
|
1060
1230
|
@timeit
|
|
1061
1231
|
def sync(
|
|
1062
|
-
|
|
1063
|
-
|
|
1232
|
+
neo4j_session: neo4j.Session,
|
|
1233
|
+
credentials: Credentials,
|
|
1234
|
+
subscription_id: str,
|
|
1235
|
+
sync_tag: int,
|
|
1236
|
+
common_job_parameters: Dict,
|
|
1064
1237
|
) -> None:
|
|
1065
1238
|
logger.info("Syncing Azure CosmosDB for subscription '%s'.", subscription_id)
|
|
1066
1239
|
database_account_list = get_database_account_list(credentials, subscription_id)
|
|
1067
1240
|
database_account_list = transform_database_account_data(database_account_list)
|
|
1068
|
-
load_database_account_data(
|
|
1069
|
-
|
|
1241
|
+
load_database_account_data(
|
|
1242
|
+
neo4j_session,
|
|
1243
|
+
subscription_id,
|
|
1244
|
+
database_account_list,
|
|
1245
|
+
sync_tag,
|
|
1246
|
+
)
|
|
1247
|
+
sync_database_account_data_resources(
|
|
1248
|
+
neo4j_session,
|
|
1249
|
+
subscription_id,
|
|
1250
|
+
database_account_list,
|
|
1251
|
+
sync_tag,
|
|
1252
|
+
)
|
|
1070
1253
|
sync_database_account_details(
|
|
1071
|
-
neo4j_session,
|
|
1254
|
+
neo4j_session,
|
|
1255
|
+
credentials,
|
|
1256
|
+
subscription_id,
|
|
1257
|
+
database_account_list,
|
|
1258
|
+
sync_tag,
|
|
1072
1259
|
common_job_parameters,
|
|
1073
1260
|
)
|
|
1074
1261
|
cleanup_azure_database_accounts(neo4j_session, common_job_parameters)
|