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
|
@@ -11,15 +11,33 @@ from azure.core.exceptions import HttpResponseError
|
|
|
11
11
|
from azure.core.exceptions import ResourceNotFoundError
|
|
12
12
|
from azure.mgmt.storage import StorageManagementClient
|
|
13
13
|
|
|
14
|
-
from .
|
|
15
|
-
from cartography.
|
|
14
|
+
from cartography.client.core.tx import load
|
|
15
|
+
from cartography.graph.job import GraphJob
|
|
16
|
+
from cartography.models.azure.storage.account import AzureStorageAccountSchema
|
|
17
|
+
from cartography.models.azure.storage.blobcontainer import (
|
|
18
|
+
AzureStorageBlobContainerSchema,
|
|
19
|
+
)
|
|
20
|
+
from cartography.models.azure.storage.blobservice import AzureStorageBlobServiceSchema
|
|
21
|
+
from cartography.models.azure.storage.fileservice import AzureStorageFileServiceSchema
|
|
22
|
+
from cartography.models.azure.storage.fileshare import AzureStorageFileShareSchema
|
|
23
|
+
from cartography.models.azure.storage.queue import AzureStorageQueueSchema
|
|
24
|
+
from cartography.models.azure.storage.queueservice import AzureStorageQueueServiceSchema
|
|
25
|
+
from cartography.models.azure.storage.table import AzureStorageTableSchema
|
|
26
|
+
from cartography.models.azure.storage.tableservice import AzureStorageTableServiceSchema
|
|
27
|
+
from cartography.models.azure.tags.storage_tag import AzureStorageTagsSchema
|
|
16
28
|
from cartography.util import timeit
|
|
17
29
|
|
|
30
|
+
from .util.credentials import Credentials
|
|
31
|
+
from .util.tag import transform_tags
|
|
32
|
+
|
|
18
33
|
logger = logging.getLogger(__name__)
|
|
19
34
|
|
|
20
35
|
|
|
21
36
|
@timeit
|
|
22
|
-
def get_client(
|
|
37
|
+
def get_client(
|
|
38
|
+
credentials: Credentials,
|
|
39
|
+
subscription_id: str,
|
|
40
|
+
) -> StorageManagementClient:
|
|
23
41
|
"""
|
|
24
42
|
Getting the Azure Storage client
|
|
25
43
|
"""
|
|
@@ -28,17 +46,24 @@ def get_client(credentials: Credentials, subscription_id: str) -> StorageManagem
|
|
|
28
46
|
|
|
29
47
|
|
|
30
48
|
@timeit
|
|
31
|
-
def get_storage_account_list(
|
|
49
|
+
def get_storage_account_list(
|
|
50
|
+
credentials: Credentials,
|
|
51
|
+
subscription_id: str,
|
|
52
|
+
) -> List[Dict]:
|
|
32
53
|
"""
|
|
33
54
|
Getting the list of storage accounts
|
|
34
55
|
"""
|
|
35
56
|
try:
|
|
36
57
|
client = get_client(credentials, subscription_id)
|
|
37
|
-
storage_account_list = list(
|
|
58
|
+
storage_account_list = list(
|
|
59
|
+
map(lambda x: x.as_dict(), client.storage_accounts.list()),
|
|
60
|
+
)
|
|
38
61
|
|
|
39
62
|
# ClientAuthenticationError and ResourceNotFoundError are subclasses under HttpResponseError
|
|
40
63
|
except ClientAuthenticationError as e:
|
|
41
|
-
logger.warning(
|
|
64
|
+
logger.warning(
|
|
65
|
+
f"Client Authentication Error while retrieving storage accounts - {e}",
|
|
66
|
+
)
|
|
42
67
|
return []
|
|
43
68
|
except ResourceNotFoundError as e:
|
|
44
69
|
logger.warning(f"Storage Account not found error - {e}")
|
|
@@ -48,91 +73,151 @@ def get_storage_account_list(credentials: Credentials, subscription_id: str) ->
|
|
|
48
73
|
return []
|
|
49
74
|
|
|
50
75
|
for storage_account in storage_account_list:
|
|
51
|
-
x = storage_account[
|
|
52
|
-
storage_account[
|
|
76
|
+
x = storage_account["id"].split("/")
|
|
77
|
+
storage_account["resourceGroup"] = x[x.index("resourceGroups") + 1]
|
|
53
78
|
|
|
54
79
|
return storage_account_list
|
|
55
80
|
|
|
56
81
|
|
|
57
82
|
@timeit
|
|
58
83
|
def load_storage_account_data(
|
|
59
|
-
|
|
60
|
-
|
|
84
|
+
neo4j_session: neo4j.Session,
|
|
85
|
+
subscription_id: str,
|
|
86
|
+
storage_account_list: List[Dict],
|
|
87
|
+
azure_update_tag: int,
|
|
88
|
+
) -> None:
|
|
89
|
+
load(
|
|
90
|
+
neo4j_session,
|
|
91
|
+
AzureStorageAccountSchema(),
|
|
92
|
+
storage_account_list,
|
|
93
|
+
lastupdated=azure_update_tag,
|
|
94
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@timeit
|
|
99
|
+
def load_storage_tags(
|
|
100
|
+
neo4j_session: neo4j.Session,
|
|
101
|
+
subscription_id: str,
|
|
102
|
+
storage_accounts: List[Dict],
|
|
103
|
+
update_tag: int,
|
|
61
104
|
) -> None:
|
|
62
105
|
"""
|
|
63
|
-
|
|
64
|
-
"""
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
SET s.lastupdated = $azure_update_tag,
|
|
72
|
-
s.kind = account.kind,
|
|
73
|
-
s.name = account.name,
|
|
74
|
-
s.creationtime = account.creation_time,
|
|
75
|
-
s.hnsenabled = account.is_hns_enabled,
|
|
76
|
-
s.primarylocation = account.primary_location,
|
|
77
|
-
s.secondarylocation = account.secondary_location,
|
|
78
|
-
s.provisioningstate = account.provisioning_state,
|
|
79
|
-
s.statusofprimary = account.status_of_primary,
|
|
80
|
-
s.statusofsecondary = account.status_of_secondary,
|
|
81
|
-
s.supportshttpstrafficonly = account.enable_https_traffic_only
|
|
82
|
-
WITH s
|
|
83
|
-
MATCH (owner:AzureSubscription{id: $AZURE_SUBSCRIPTION_ID})
|
|
84
|
-
MERGE (owner)-[r:RESOURCE]->(s)
|
|
85
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
86
|
-
SET r.lastupdated = $azure_update_tag
|
|
87
|
-
"""
|
|
88
|
-
|
|
89
|
-
neo4j_session.run(
|
|
90
|
-
ingest_storage_account,
|
|
91
|
-
storage_accounts_list=storage_account_list,
|
|
106
|
+
Sync tags for storage accounts.
|
|
107
|
+
"""
|
|
108
|
+
tags = transform_tags(storage_accounts, subscription_id)
|
|
109
|
+
load(
|
|
110
|
+
neo4j_session,
|
|
111
|
+
AzureStorageTagsSchema(),
|
|
112
|
+
tags,
|
|
113
|
+
lastupdated=update_tag,
|
|
92
114
|
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
93
|
-
azure_update_tag=azure_update_tag,
|
|
94
115
|
)
|
|
95
116
|
|
|
96
117
|
|
|
97
118
|
@timeit
|
|
98
119
|
def sync_storage_account_details(
|
|
99
|
-
|
|
100
|
-
|
|
120
|
+
neo4j_session: neo4j.Session,
|
|
121
|
+
credentials: Credentials,
|
|
122
|
+
subscription_id: str,
|
|
123
|
+
storage_account_list: List[Dict],
|
|
124
|
+
sync_tag: int,
|
|
101
125
|
) -> None:
|
|
102
|
-
|
|
103
|
-
|
|
126
|
+
# Get details
|
|
127
|
+
details = get_storage_account_details(
|
|
128
|
+
credentials,
|
|
129
|
+
subscription_id,
|
|
130
|
+
storage_account_list,
|
|
131
|
+
)
|
|
132
|
+
# Transform details
|
|
133
|
+
queue_services, table_services, file_services, blob_services = (
|
|
134
|
+
transform_storage_account_details(
|
|
135
|
+
details,
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
# Load details
|
|
139
|
+
_load_queue_services(neo4j_session, queue_services, subscription_id, sync_tag)
|
|
140
|
+
_load_table_services(neo4j_session, table_services, subscription_id, sync_tag)
|
|
141
|
+
_load_file_services(neo4j_session, file_services, subscription_id, sync_tag)
|
|
142
|
+
_load_blob_services(neo4j_session, blob_services, subscription_id, sync_tag)
|
|
143
|
+
|
|
144
|
+
sync_queue_services_details(
|
|
145
|
+
neo4j_session,
|
|
146
|
+
credentials,
|
|
147
|
+
subscription_id,
|
|
148
|
+
queue_services,
|
|
149
|
+
sync_tag,
|
|
150
|
+
)
|
|
151
|
+
sync_table_services_details(
|
|
152
|
+
neo4j_session,
|
|
153
|
+
credentials,
|
|
154
|
+
subscription_id,
|
|
155
|
+
table_services,
|
|
156
|
+
sync_tag,
|
|
157
|
+
)
|
|
158
|
+
sync_file_services_details(
|
|
159
|
+
neo4j_session,
|
|
160
|
+
credentials,
|
|
161
|
+
subscription_id,
|
|
162
|
+
file_services,
|
|
163
|
+
sync_tag,
|
|
164
|
+
)
|
|
165
|
+
sync_blob_services_details(
|
|
166
|
+
neo4j_session,
|
|
167
|
+
credentials,
|
|
168
|
+
subscription_id,
|
|
169
|
+
blob_services,
|
|
170
|
+
sync_tag,
|
|
171
|
+
)
|
|
104
172
|
|
|
105
173
|
|
|
106
174
|
@timeit
|
|
107
175
|
def get_storage_account_details(
|
|
108
|
-
|
|
176
|
+
credentials: Credentials,
|
|
177
|
+
subscription_id: str,
|
|
178
|
+
storage_account_list: List[Dict],
|
|
109
179
|
) -> Generator[Any, Any, Any]:
|
|
110
180
|
"""
|
|
111
181
|
Iterates over all Storage Accounts to get the different storage services.
|
|
112
182
|
"""
|
|
113
183
|
for storage_account in storage_account_list:
|
|
114
|
-
queue_services = get_queue_services(
|
|
115
|
-
|
|
184
|
+
queue_services = get_queue_services(
|
|
185
|
+
credentials,
|
|
186
|
+
subscription_id,
|
|
187
|
+
storage_account,
|
|
188
|
+
)
|
|
189
|
+
table_services = get_table_services(
|
|
190
|
+
credentials,
|
|
191
|
+
subscription_id,
|
|
192
|
+
storage_account,
|
|
193
|
+
)
|
|
116
194
|
file_services = get_file_services(credentials, subscription_id, storage_account)
|
|
117
195
|
blob_services = get_blob_services(credentials, subscription_id, storage_account)
|
|
118
|
-
yield storage_account[
|
|
119
|
-
|
|
196
|
+
yield storage_account["id"], storage_account["name"], storage_account[
|
|
197
|
+
"resourceGroup"
|
|
120
198
|
], queue_services, table_services, file_services, blob_services
|
|
121
199
|
|
|
122
200
|
|
|
123
201
|
@timeit
|
|
124
|
-
def get_queue_services(
|
|
202
|
+
def get_queue_services(
|
|
203
|
+
credentials: Credentials,
|
|
204
|
+
subscription_id: str,
|
|
205
|
+
storage_account: Dict,
|
|
206
|
+
) -> List[Dict]:
|
|
125
207
|
"""
|
|
126
208
|
Gets the list of queue services.
|
|
127
209
|
"""
|
|
128
210
|
try:
|
|
129
211
|
client = get_client(credentials, subscription_id)
|
|
130
212
|
queue_service_list = client.queue_services.list(
|
|
131
|
-
storage_account[
|
|
132
|
-
|
|
213
|
+
storage_account["resourceGroup"],
|
|
214
|
+
storage_account["name"],
|
|
215
|
+
).as_dict()["value"]
|
|
133
216
|
|
|
134
217
|
except ClientAuthenticationError as e:
|
|
135
|
-
logger.warning(
|
|
218
|
+
logger.warning(
|
|
219
|
+
f"Client Authentication Error while retrieving queue services - {e}",
|
|
220
|
+
)
|
|
136
221
|
return []
|
|
137
222
|
except ResourceNotFoundError as e:
|
|
138
223
|
logger.warning(f"Queue services resource not found error - {e}")
|
|
@@ -145,18 +230,25 @@ def get_queue_services(credentials: Credentials, subscription_id: str, storage_a
|
|
|
145
230
|
|
|
146
231
|
|
|
147
232
|
@timeit
|
|
148
|
-
def get_table_services(
|
|
233
|
+
def get_table_services(
|
|
234
|
+
credentials: Credentials,
|
|
235
|
+
subscription_id: str,
|
|
236
|
+
storage_account: Dict,
|
|
237
|
+
) -> List[Dict]:
|
|
149
238
|
"""
|
|
150
239
|
Gets the list of table services.
|
|
151
240
|
"""
|
|
152
241
|
try:
|
|
153
242
|
client = get_client(credentials, subscription_id)
|
|
154
243
|
table_service_list = client.table_services.list(
|
|
155
|
-
storage_account[
|
|
156
|
-
|
|
244
|
+
storage_account["resourceGroup"],
|
|
245
|
+
storage_account["name"],
|
|
246
|
+
).as_dict()["value"]
|
|
157
247
|
|
|
158
248
|
except ClientAuthenticationError as e:
|
|
159
|
-
logger.warning(
|
|
249
|
+
logger.warning(
|
|
250
|
+
f"Client Authentication Error while retrieving table services - {e}",
|
|
251
|
+
)
|
|
160
252
|
return []
|
|
161
253
|
except ResourceNotFoundError as e:
|
|
162
254
|
logger.warning(f"Table services resource not found error - {e}")
|
|
@@ -169,18 +261,25 @@ def get_table_services(credentials: Credentials, subscription_id: str, storage_a
|
|
|
169
261
|
|
|
170
262
|
|
|
171
263
|
@timeit
|
|
172
|
-
def get_file_services(
|
|
264
|
+
def get_file_services(
|
|
265
|
+
credentials: Credentials,
|
|
266
|
+
subscription_id: str,
|
|
267
|
+
storage_account: Dict,
|
|
268
|
+
) -> List[Dict]:
|
|
173
269
|
"""
|
|
174
270
|
Gets the list of file services.
|
|
175
271
|
"""
|
|
176
272
|
try:
|
|
177
273
|
client = get_client(credentials, subscription_id)
|
|
178
274
|
file_service_list = client.file_services.list(
|
|
179
|
-
storage_account[
|
|
180
|
-
|
|
275
|
+
storage_account["resourceGroup"],
|
|
276
|
+
storage_account["name"],
|
|
277
|
+
).as_dict()["value"]
|
|
181
278
|
|
|
182
279
|
except ClientAuthenticationError as e:
|
|
183
|
-
logger.warning(
|
|
280
|
+
logger.warning(
|
|
281
|
+
f"Client Authentication Error while retrieving file services - {e}",
|
|
282
|
+
)
|
|
184
283
|
return []
|
|
185
284
|
except ResourceNotFoundError as e:
|
|
186
285
|
logger.warning(f"File services resource not found error - {e}")
|
|
@@ -193,7 +292,11 @@ def get_file_services(credentials: Credentials, subscription_id: str, storage_ac
|
|
|
193
292
|
|
|
194
293
|
|
|
195
294
|
@timeit
|
|
196
|
-
def get_blob_services(
|
|
295
|
+
def get_blob_services(
|
|
296
|
+
credentials: Credentials,
|
|
297
|
+
subscription_id: str,
|
|
298
|
+
storage_account: Dict,
|
|
299
|
+
) -> List[Dict]:
|
|
197
300
|
"""
|
|
198
301
|
Gets the list of blob services.
|
|
199
302
|
"""
|
|
@@ -201,15 +304,18 @@ def get_blob_services(credentials: Credentials, subscription_id: str, storage_ac
|
|
|
201
304
|
client = get_client(credentials, subscription_id)
|
|
202
305
|
blob_service_list = list(
|
|
203
306
|
map(
|
|
204
|
-
lambda x: x.as_dict(),
|
|
205
|
-
|
|
206
|
-
storage_account[
|
|
307
|
+
lambda x: x.as_dict(),
|
|
308
|
+
client.blob_services.list(
|
|
309
|
+
storage_account["resourceGroup"],
|
|
310
|
+
storage_account["name"],
|
|
207
311
|
),
|
|
208
312
|
),
|
|
209
313
|
)
|
|
210
314
|
|
|
211
315
|
except ClientAuthenticationError as e:
|
|
212
|
-
logger.warning(
|
|
316
|
+
logger.warning(
|
|
317
|
+
f"Client Authentication Error while retrieving blob services - {e}",
|
|
318
|
+
)
|
|
213
319
|
return []
|
|
214
320
|
except ResourceNotFoundError as e:
|
|
215
321
|
logger.warning(f"Blob services resource not found error - {e}")
|
|
@@ -222,189 +328,155 @@ def get_blob_services(credentials: Credentials, subscription_id: str, storage_ac
|
|
|
222
328
|
|
|
223
329
|
|
|
224
330
|
@timeit
|
|
225
|
-
def
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
) -> None:
|
|
229
|
-
"""
|
|
230
|
-
Create dictionaries for every Azure storage service so we can import them in a single query
|
|
231
|
-
"""
|
|
331
|
+
def transform_storage_account_details(
|
|
332
|
+
storage_account_details: List[Tuple[Any, Any, Any, Any, Any, Any, Any]],
|
|
333
|
+
) -> Tuple[List[Dict], List[Dict], List[Dict], List[Dict]]:
|
|
232
334
|
queue_services: List[Dict] = []
|
|
233
335
|
table_services: List[Dict] = []
|
|
234
336
|
file_services: List[Dict] = []
|
|
235
337
|
blob_services: List[Dict] = []
|
|
236
338
|
|
|
237
|
-
for
|
|
339
|
+
for (
|
|
340
|
+
account_id,
|
|
341
|
+
name,
|
|
342
|
+
resourceGroup,
|
|
343
|
+
queue_service,
|
|
344
|
+
table_service,
|
|
345
|
+
file_service,
|
|
346
|
+
blob_service,
|
|
347
|
+
) in storage_account_details:
|
|
238
348
|
if len(queue_service) > 0:
|
|
239
349
|
for service in queue_service:
|
|
240
|
-
service[
|
|
241
|
-
service[
|
|
242
|
-
service[
|
|
350
|
+
service["storage_account_name"] = name
|
|
351
|
+
service["storage_account_id"] = account_id
|
|
352
|
+
service["resource_group_name"] = resourceGroup
|
|
243
353
|
queue_services.extend(queue_service)
|
|
244
354
|
|
|
245
355
|
if len(table_service) > 0:
|
|
246
356
|
for service in table_service:
|
|
247
|
-
service[
|
|
248
|
-
service[
|
|
249
|
-
service[
|
|
357
|
+
service["storage_account_name"] = name
|
|
358
|
+
service["storage_account_id"] = account_id
|
|
359
|
+
service["resource_group_name"] = resourceGroup
|
|
250
360
|
table_services.extend(table_service)
|
|
251
361
|
|
|
252
362
|
if len(file_service) > 0:
|
|
253
363
|
for service in file_service:
|
|
254
|
-
service[
|
|
255
|
-
service[
|
|
256
|
-
service[
|
|
364
|
+
service["storage_account_name"] = name
|
|
365
|
+
service["storage_account_id"] = account_id
|
|
366
|
+
service["resource_group_name"] = resourceGroup
|
|
257
367
|
file_services.extend(file_service)
|
|
258
368
|
|
|
259
369
|
if len(blob_service) > 0:
|
|
260
370
|
for service in blob_service:
|
|
261
|
-
service[
|
|
262
|
-
service[
|
|
263
|
-
service[
|
|
371
|
+
service["storage_account_name"] = name
|
|
372
|
+
service["storage_account_id"] = account_id
|
|
373
|
+
service["resource_group_name"] = resourceGroup
|
|
264
374
|
blob_services.extend(blob_service)
|
|
265
|
-
|
|
266
|
-
_load_queue_services(neo4j_session, queue_services, update_tag)
|
|
267
|
-
_load_table_services(neo4j_session, table_services, update_tag)
|
|
268
|
-
_load_file_services(neo4j_session, file_services, update_tag)
|
|
269
|
-
_load_blob_services(neo4j_session, blob_services, update_tag)
|
|
270
|
-
|
|
271
|
-
sync_queue_services_details(neo4j_session, credentials, subscription_id, queue_services, update_tag)
|
|
272
|
-
sync_table_services_details(neo4j_session, credentials, subscription_id, table_services, update_tag)
|
|
273
|
-
sync_file_services_details(neo4j_session, credentials, subscription_id, file_services, update_tag)
|
|
274
|
-
sync_blob_services_details(neo4j_session, credentials, subscription_id, blob_services, update_tag)
|
|
375
|
+
return queue_services, table_services, file_services, blob_services
|
|
275
376
|
|
|
276
377
|
|
|
277
378
|
@timeit
|
|
278
379
|
def _load_queue_services(
|
|
279
|
-
|
|
380
|
+
neo4j_session: neo4j.Session,
|
|
381
|
+
queue_services: List[Dict],
|
|
382
|
+
subscription_id: str,
|
|
383
|
+
update_tag: int,
|
|
280
384
|
) -> None:
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
ON CREATE SET qs.firstseen = timestamp(), qs.type = qservice.type
|
|
288
|
-
SET qs.name = qservice.name,
|
|
289
|
-
qs.lastupdated = $azure_update_tag
|
|
290
|
-
WITH qs, qservice
|
|
291
|
-
MATCH (s:AzureStorageAccount{id: qservice.storage_account_id})
|
|
292
|
-
MERGE (s)-[r:USES]->(qs)
|
|
293
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
294
|
-
SET r.lastupdated = $azure_update_tag
|
|
295
|
-
"""
|
|
296
|
-
|
|
297
|
-
neo4j_session.run(
|
|
298
|
-
ingest_queue_services,
|
|
299
|
-
queue_services_list=queue_services,
|
|
300
|
-
azure_update_tag=update_tag,
|
|
385
|
+
load(
|
|
386
|
+
neo4j_session,
|
|
387
|
+
AzureStorageQueueServiceSchema(),
|
|
388
|
+
queue_services,
|
|
389
|
+
lastupdated=update_tag,
|
|
390
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
301
391
|
)
|
|
302
392
|
|
|
303
393
|
|
|
304
394
|
@timeit
|
|
305
395
|
def _load_table_services(
|
|
306
|
-
|
|
396
|
+
neo4j_session: neo4j.Session,
|
|
397
|
+
table_services: List[Dict],
|
|
398
|
+
subscription_id: str,
|
|
399
|
+
update_tag: int,
|
|
307
400
|
) -> None:
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
ON CREATE SET ts.firstseen = timestamp(), ts.type = tservice.type
|
|
315
|
-
SET ts.name = tservice.name,
|
|
316
|
-
ts.lastupdated = $azure_update_tag
|
|
317
|
-
WITH ts, tservice
|
|
318
|
-
MATCH (s:AzureStorageAccount{id: tservice.storage_account_id})
|
|
319
|
-
MERGE (s)-[r:USES]->(ts)
|
|
320
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
321
|
-
SET r.lastupdated = $azure_update_tag
|
|
322
|
-
"""
|
|
323
|
-
|
|
324
|
-
neo4j_session.run(
|
|
325
|
-
ingest_table_services,
|
|
326
|
-
table_services_list=table_services,
|
|
327
|
-
azure_update_tag=update_tag,
|
|
401
|
+
load(
|
|
402
|
+
neo4j_session,
|
|
403
|
+
AzureStorageTableServiceSchema(),
|
|
404
|
+
table_services,
|
|
405
|
+
lastupdated=update_tag,
|
|
406
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
328
407
|
)
|
|
329
408
|
|
|
330
409
|
|
|
331
410
|
@timeit
|
|
332
411
|
def _load_file_services(
|
|
333
|
-
|
|
412
|
+
neo4j_session: neo4j.Session,
|
|
413
|
+
file_services: List[Dict],
|
|
414
|
+
subscription_id: str,
|
|
415
|
+
update_tag: int,
|
|
334
416
|
) -> None:
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
ON CREATE SET fs.firstseen = timestamp(), fs.type = fservice.type
|
|
342
|
-
SET fs.name = fservice.name,
|
|
343
|
-
fs.lastupdated = $azure_update_tag
|
|
344
|
-
WITH fs, fservice
|
|
345
|
-
MATCH (s:AzureStorageAccount{id: fservice.storage_account_id})
|
|
346
|
-
MERGE (s)-[r:USES]->(fs)
|
|
347
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
348
|
-
SET r.lastupdated = $azure_update_tag
|
|
349
|
-
"""
|
|
350
|
-
|
|
351
|
-
neo4j_session.run(
|
|
352
|
-
ingest_file_services,
|
|
353
|
-
file_services_list=file_services,
|
|
354
|
-
azure_update_tag=update_tag,
|
|
417
|
+
load(
|
|
418
|
+
neo4j_session,
|
|
419
|
+
AzureStorageFileServiceSchema(),
|
|
420
|
+
file_services,
|
|
421
|
+
lastupdated=update_tag,
|
|
422
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
355
423
|
)
|
|
356
424
|
|
|
357
425
|
|
|
358
426
|
@timeit
|
|
359
427
|
def _load_blob_services(
|
|
360
|
-
|
|
428
|
+
neo4j_session: neo4j.Session,
|
|
429
|
+
blob_services: List[Dict],
|
|
430
|
+
subscription_id: str,
|
|
431
|
+
update_tag: int,
|
|
361
432
|
) -> None:
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
ON CREATE SET bs.firstseen = timestamp(), bs.type = bservice.type
|
|
369
|
-
SET bs.name = bservice.name,
|
|
370
|
-
bs.lastupdated = $azure_update_tag
|
|
371
|
-
WITH bs, bservice
|
|
372
|
-
MATCH (s:AzureStorageAccount{id: bservice.storage_account_id})
|
|
373
|
-
MERGE (s)-[r:USES]->(bs)
|
|
374
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
375
|
-
SET r.lastupdated = $azure_update_tag
|
|
376
|
-
"""
|
|
377
|
-
|
|
378
|
-
neo4j_session.run(
|
|
379
|
-
ingest_blob_services,
|
|
380
|
-
blob_services_list=blob_services,
|
|
381
|
-
azure_update_tag=update_tag,
|
|
433
|
+
load(
|
|
434
|
+
neo4j_session,
|
|
435
|
+
AzureStorageBlobServiceSchema(),
|
|
436
|
+
blob_services,
|
|
437
|
+
lastupdated=update_tag,
|
|
438
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
382
439
|
)
|
|
383
440
|
|
|
384
441
|
|
|
385
442
|
@timeit
|
|
386
443
|
def sync_queue_services_details(
|
|
387
|
-
|
|
388
|
-
|
|
444
|
+
neo4j_session: neo4j.Session,
|
|
445
|
+
credentials: Credentials,
|
|
446
|
+
subscription_id: str,
|
|
447
|
+
queue_services: List[Dict],
|
|
448
|
+
update_tag: int,
|
|
389
449
|
) -> None:
|
|
390
|
-
queue_services_details = get_queue_services_details(
|
|
391
|
-
|
|
450
|
+
queue_services_details = get_queue_services_details(
|
|
451
|
+
credentials,
|
|
452
|
+
subscription_id,
|
|
453
|
+
queue_services,
|
|
454
|
+
)
|
|
455
|
+
load_queue_services_details(
|
|
456
|
+
neo4j_session, queue_services_details, subscription_id, update_tag
|
|
457
|
+
)
|
|
392
458
|
|
|
393
459
|
|
|
394
460
|
@timeit
|
|
395
461
|
def get_queue_services_details(
|
|
396
|
-
|
|
462
|
+
credentials: Credentials,
|
|
463
|
+
subscription_id: str,
|
|
464
|
+
queue_services: List[Dict],
|
|
397
465
|
) -> Generator[Any, Any, Any]:
|
|
398
466
|
"""
|
|
399
467
|
Returning the queues with their respective queue service id.
|
|
400
468
|
"""
|
|
401
469
|
for queue_service in queue_services:
|
|
402
470
|
queues = get_queues(credentials, subscription_id, queue_service)
|
|
403
|
-
yield queue_service[
|
|
471
|
+
yield queue_service["id"], queues
|
|
404
472
|
|
|
405
473
|
|
|
406
474
|
@timeit
|
|
407
|
-
def get_queues(
|
|
475
|
+
def get_queues(
|
|
476
|
+
credentials: Credentials,
|
|
477
|
+
subscription_id: str,
|
|
478
|
+
queue_service: Dict,
|
|
479
|
+
) -> List[Dict]:
|
|
408
480
|
"""
|
|
409
481
|
Getting the queues from the queue service.
|
|
410
482
|
"""
|
|
@@ -412,9 +484,10 @@ def get_queues(credentials: Credentials, subscription_id: str, queue_service: Di
|
|
|
412
484
|
client = get_client(credentials, subscription_id)
|
|
413
485
|
queues = list(
|
|
414
486
|
map(
|
|
415
|
-
lambda x: x.as_dict(),
|
|
416
|
-
|
|
417
|
-
queue_service[
|
|
487
|
+
lambda x: x.as_dict(),
|
|
488
|
+
client.queue.list(
|
|
489
|
+
queue_service["resource_group_name"],
|
|
490
|
+
queue_service["storage_account_name"],
|
|
418
491
|
),
|
|
419
492
|
),
|
|
420
493
|
)
|
|
@@ -434,7 +507,10 @@ def get_queues(credentials: Credentials, subscription_id: str, queue_service: Di
|
|
|
434
507
|
|
|
435
508
|
@timeit
|
|
436
509
|
def load_queue_services_details(
|
|
437
|
-
|
|
510
|
+
neo4j_session: neo4j.Session,
|
|
511
|
+
details: List[Tuple[Any, Any]],
|
|
512
|
+
subscription_id: str,
|
|
513
|
+
update_tag: int,
|
|
438
514
|
) -> None:
|
|
439
515
|
"""
|
|
440
516
|
Create dictionary for the queue so we can import them in a single query
|
|
@@ -444,60 +520,69 @@ def load_queue_services_details(
|
|
|
444
520
|
for queue_service_id, queue in details:
|
|
445
521
|
if len(queue) > 0:
|
|
446
522
|
for q in queue:
|
|
447
|
-
q[
|
|
523
|
+
q["service_id"] = queue_service_id
|
|
448
524
|
queues.extend(queue)
|
|
449
525
|
|
|
450
|
-
_load_queues(neo4j_session, queues, update_tag)
|
|
526
|
+
_load_queues(neo4j_session, queues, subscription_id, update_tag)
|
|
451
527
|
|
|
452
528
|
|
|
453
529
|
@timeit
|
|
454
|
-
def _load_queues(
|
|
530
|
+
def _load_queues(
|
|
531
|
+
neo4j_session: neo4j.Session,
|
|
532
|
+
queues: List[Dict],
|
|
533
|
+
subscription_id: str,
|
|
534
|
+
update_tag: int,
|
|
535
|
+
) -> None:
|
|
455
536
|
"""
|
|
456
537
|
Ingest Queue details into neo4j.
|
|
457
538
|
"""
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
WITH q, queue
|
|
465
|
-
MATCH (qs:AzureStorageQueueService{id: queue.service_id})
|
|
466
|
-
MERGE (qs)-[r:CONTAINS]->(q)
|
|
467
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
468
|
-
SET r.lastupdated = $azure_update_tag
|
|
469
|
-
"""
|
|
470
|
-
|
|
471
|
-
neo4j_session.run(
|
|
472
|
-
ingest_queues,
|
|
473
|
-
queues_list=queues,
|
|
474
|
-
azure_update_tag=update_tag,
|
|
539
|
+
load(
|
|
540
|
+
neo4j_session,
|
|
541
|
+
AzureStorageQueueSchema(),
|
|
542
|
+
queues,
|
|
543
|
+
lastupdated=update_tag,
|
|
544
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
475
545
|
)
|
|
476
546
|
|
|
477
547
|
|
|
478
548
|
@timeit
|
|
479
549
|
def sync_table_services_details(
|
|
480
|
-
|
|
481
|
-
|
|
550
|
+
neo4j_session: neo4j.Session,
|
|
551
|
+
credentials: Credentials,
|
|
552
|
+
subscription_id: str,
|
|
553
|
+
table_services: List[Dict],
|
|
554
|
+
update_tag: int,
|
|
482
555
|
) -> None:
|
|
483
|
-
table_services_details = get_table_services_details(
|
|
484
|
-
|
|
556
|
+
table_services_details = get_table_services_details(
|
|
557
|
+
credentials,
|
|
558
|
+
subscription_id,
|
|
559
|
+
table_services,
|
|
560
|
+
)
|
|
561
|
+
load_table_services_details(
|
|
562
|
+
neo4j_session, table_services_details, subscription_id, update_tag
|
|
563
|
+
)
|
|
485
564
|
|
|
486
565
|
|
|
487
566
|
@timeit
|
|
488
567
|
def get_table_services_details(
|
|
489
|
-
|
|
568
|
+
credentials: Credentials,
|
|
569
|
+
subscription_id: str,
|
|
570
|
+
table_services: List[Dict],
|
|
490
571
|
) -> Generator[Any, Any, Any]:
|
|
491
572
|
"""
|
|
492
573
|
Returning the tables with their respective table service id.
|
|
493
574
|
"""
|
|
494
575
|
for table_service in table_services:
|
|
495
576
|
tables = get_tables(credentials, subscription_id, table_service)
|
|
496
|
-
yield table_service[
|
|
577
|
+
yield table_service["id"], tables
|
|
497
578
|
|
|
498
579
|
|
|
499
580
|
@timeit
|
|
500
|
-
def get_tables(
|
|
581
|
+
def get_tables(
|
|
582
|
+
credentials: Credentials,
|
|
583
|
+
subscription_id: str,
|
|
584
|
+
table_service: Dict,
|
|
585
|
+
) -> List[Dict]:
|
|
501
586
|
"""
|
|
502
587
|
Getting the tables from the table service.
|
|
503
588
|
"""
|
|
@@ -505,9 +590,10 @@ def get_tables(credentials: Credentials, subscription_id: str, table_service: Di
|
|
|
505
590
|
client = get_client(credentials, subscription_id)
|
|
506
591
|
tables = list(
|
|
507
592
|
map(
|
|
508
|
-
lambda x: x.as_dict(),
|
|
509
|
-
|
|
510
|
-
table_service[
|
|
593
|
+
lambda x: x.as_dict(),
|
|
594
|
+
client.table.list(
|
|
595
|
+
table_service["resource_group_name"],
|
|
596
|
+
table_service["storage_account_name"],
|
|
511
597
|
),
|
|
512
598
|
),
|
|
513
599
|
)
|
|
@@ -527,7 +613,10 @@ def get_tables(credentials: Credentials, subscription_id: str, table_service: Di
|
|
|
527
613
|
|
|
528
614
|
@timeit
|
|
529
615
|
def load_table_services_details(
|
|
530
|
-
|
|
616
|
+
neo4j_session: neo4j.Session,
|
|
617
|
+
details: List[Tuple[Any, Any]],
|
|
618
|
+
subscription_id: str,
|
|
619
|
+
update_tag: int,
|
|
531
620
|
) -> None:
|
|
532
621
|
"""
|
|
533
622
|
Create dictionary for the table so we can import them in a single query
|
|
@@ -537,61 +626,69 @@ def load_table_services_details(
|
|
|
537
626
|
for table_service_id, table in details:
|
|
538
627
|
if len(table) > 0:
|
|
539
628
|
for t in table:
|
|
540
|
-
t[
|
|
629
|
+
t["service_id"] = table_service_id
|
|
541
630
|
tables.extend(table)
|
|
542
631
|
|
|
543
|
-
_load_tables(neo4j_session, tables, update_tag)
|
|
632
|
+
_load_tables(neo4j_session, tables, subscription_id, update_tag)
|
|
544
633
|
|
|
545
634
|
|
|
546
635
|
@timeit
|
|
547
|
-
def _load_tables(
|
|
636
|
+
def _load_tables(
|
|
637
|
+
neo4j_session: neo4j.Session,
|
|
638
|
+
tables: List[Dict],
|
|
639
|
+
subscription_id: str,
|
|
640
|
+
update_tag: int,
|
|
641
|
+
) -> None:
|
|
548
642
|
"""
|
|
549
643
|
Ingest Table details into neo4j.
|
|
550
644
|
"""
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
t.lastupdated = $azure_update_tag
|
|
558
|
-
WITH t, table
|
|
559
|
-
MATCH (ts:AzureStorageTableService{id: table.service_id})
|
|
560
|
-
MERGE (ts)-[r:CONTAINS]->(t)
|
|
561
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
562
|
-
SET r.lastupdated = $azure_update_tag
|
|
563
|
-
"""
|
|
564
|
-
|
|
565
|
-
neo4j_session.run(
|
|
566
|
-
ingest_tables,
|
|
567
|
-
tables_list=tables,
|
|
568
|
-
azure_update_tag=update_tag,
|
|
645
|
+
load(
|
|
646
|
+
neo4j_session,
|
|
647
|
+
AzureStorageTableSchema(),
|
|
648
|
+
tables,
|
|
649
|
+
lastupdated=update_tag,
|
|
650
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
569
651
|
)
|
|
570
652
|
|
|
571
653
|
|
|
572
654
|
@timeit
|
|
573
655
|
def sync_file_services_details(
|
|
574
|
-
|
|
575
|
-
|
|
656
|
+
neo4j_session: neo4j.Session,
|
|
657
|
+
credentials: Credentials,
|
|
658
|
+
subscription_id: str,
|
|
659
|
+
file_services: List[Dict],
|
|
660
|
+
update_tag: int,
|
|
576
661
|
) -> None:
|
|
577
|
-
file_services_details = get_file_services_details(
|
|
578
|
-
|
|
662
|
+
file_services_details = get_file_services_details(
|
|
663
|
+
credentials,
|
|
664
|
+
subscription_id,
|
|
665
|
+
file_services,
|
|
666
|
+
)
|
|
667
|
+
load_file_services_details(
|
|
668
|
+
neo4j_session, file_services_details, subscription_id, update_tag
|
|
669
|
+
)
|
|
579
670
|
|
|
580
671
|
|
|
581
672
|
@timeit
|
|
582
673
|
def get_file_services_details(
|
|
583
|
-
|
|
674
|
+
credentials: Credentials,
|
|
675
|
+
subscription_id: str,
|
|
676
|
+
file_services: List[Dict],
|
|
584
677
|
) -> Generator[Any, Any, Any]:
|
|
585
678
|
"""
|
|
586
679
|
Returning the shares with their respective file service id.
|
|
587
680
|
"""
|
|
588
681
|
for file_service in file_services:
|
|
589
682
|
shares = get_shares(credentials, subscription_id, file_service)
|
|
590
|
-
yield file_service[
|
|
683
|
+
yield file_service["id"], shares
|
|
591
684
|
|
|
592
685
|
|
|
593
686
|
@timeit
|
|
594
|
-
def get_shares(
|
|
687
|
+
def get_shares(
|
|
688
|
+
credentials: Credentials,
|
|
689
|
+
subscription_id: str,
|
|
690
|
+
file_service: Dict,
|
|
691
|
+
) -> List[Dict]:
|
|
595
692
|
"""
|
|
596
693
|
Getting the shares from the file service.
|
|
597
694
|
"""
|
|
@@ -599,9 +696,10 @@ def get_shares(credentials: Credentials, subscription_id: str, file_service: Dic
|
|
|
599
696
|
client = get_client(credentials, subscription_id)
|
|
600
697
|
shares = list(
|
|
601
698
|
map(
|
|
602
|
-
lambda x: x.as_dict(),
|
|
603
|
-
|
|
604
|
-
file_service[
|
|
699
|
+
lambda x: x.as_dict(),
|
|
700
|
+
client.file_shares.list(
|
|
701
|
+
file_service["resource_group_name"],
|
|
702
|
+
file_service["storage_account_name"],
|
|
605
703
|
),
|
|
606
704
|
),
|
|
607
705
|
)
|
|
@@ -621,7 +719,10 @@ def get_shares(credentials: Credentials, subscription_id: str, file_service: Dic
|
|
|
621
719
|
|
|
622
720
|
@timeit
|
|
623
721
|
def load_file_services_details(
|
|
624
|
-
|
|
722
|
+
neo4j_session: neo4j.Session,
|
|
723
|
+
details: List[Tuple[Any, Any]],
|
|
724
|
+
subscription_id: str,
|
|
725
|
+
update_tag: int,
|
|
625
726
|
) -> None:
|
|
626
727
|
"""
|
|
627
728
|
Create dictionary for the shares so we can import them in a single query
|
|
@@ -631,71 +732,73 @@ def load_file_services_details(
|
|
|
631
732
|
for file_service_id, share in details:
|
|
632
733
|
if len(share) > 0:
|
|
633
734
|
for s in share:
|
|
634
|
-
s[
|
|
735
|
+
s["service_id"] = file_service_id
|
|
635
736
|
shares.extend(share)
|
|
636
737
|
|
|
637
|
-
_load_shares(neo4j_session, shares, update_tag)
|
|
738
|
+
_load_shares(neo4j_session, shares, subscription_id, update_tag)
|
|
638
739
|
|
|
639
740
|
|
|
640
741
|
@timeit
|
|
641
|
-
def _load_shares(
|
|
742
|
+
def _load_shares(
|
|
743
|
+
neo4j_session: neo4j.Session,
|
|
744
|
+
shares: List[Dict],
|
|
745
|
+
subscription_id: str,
|
|
746
|
+
update_tag: int,
|
|
747
|
+
) -> None:
|
|
642
748
|
"""
|
|
643
749
|
Ingest Share details into neo4j.
|
|
644
750
|
"""
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
share.lastmodifiedtime = s.last_modified_time,
|
|
652
|
-
share.sharequota = s.share_quota,
|
|
653
|
-
share.accesstier = s.access_tier,
|
|
654
|
-
share.deleted = s.deleted,
|
|
655
|
-
share.accesstierchangetime = s.access_tier_change_time,
|
|
656
|
-
share.accesstierstatus = s.access_tier_status,
|
|
657
|
-
share.deletedtime = s.deleted_time,
|
|
658
|
-
share.enabledprotocols = s.enabled_protocols,
|
|
659
|
-
share.remainingretentiondays = s.remaining_retention_days,
|
|
660
|
-
share.shareusagebytes = s.share_usage_bytes,
|
|
661
|
-
share.version = s.version
|
|
662
|
-
WITH share, s
|
|
663
|
-
MATCH (fs:AzureStorageFileService{id: s.service_id})
|
|
664
|
-
MERGE (fs)-[r:CONTAINS]->(share)
|
|
665
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
666
|
-
SET r.lastupdated = $azure_update_tag
|
|
667
|
-
"""
|
|
668
|
-
|
|
669
|
-
neo4j_session.run(
|
|
670
|
-
ingest_shares,
|
|
671
|
-
shares_list=shares,
|
|
672
|
-
azure_update_tag=update_tag,
|
|
751
|
+
load(
|
|
752
|
+
neo4j_session,
|
|
753
|
+
AzureStorageFileShareSchema(),
|
|
754
|
+
shares,
|
|
755
|
+
lastupdated=update_tag,
|
|
756
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
673
757
|
)
|
|
674
758
|
|
|
675
759
|
|
|
676
760
|
@timeit
|
|
677
761
|
def sync_blob_services_details(
|
|
678
|
-
|
|
679
|
-
|
|
762
|
+
neo4j_session: neo4j.Session,
|
|
763
|
+
credentials: Credentials,
|
|
764
|
+
subscription_id: str,
|
|
765
|
+
blob_services: List[Dict],
|
|
766
|
+
update_tag: int,
|
|
680
767
|
) -> None:
|
|
681
|
-
blob_services_details = get_blob_services_details(
|
|
682
|
-
|
|
768
|
+
blob_services_details = get_blob_services_details(
|
|
769
|
+
credentials,
|
|
770
|
+
subscription_id,
|
|
771
|
+
blob_services,
|
|
772
|
+
)
|
|
773
|
+
load_blob_services_details(
|
|
774
|
+
neo4j_session, blob_services_details, subscription_id, update_tag
|
|
775
|
+
)
|
|
683
776
|
|
|
684
777
|
|
|
685
778
|
@timeit
|
|
686
779
|
def get_blob_services_details(
|
|
687
|
-
|
|
780
|
+
credentials: Credentials,
|
|
781
|
+
subscription_id: str,
|
|
782
|
+
blob_services: List[Dict],
|
|
688
783
|
) -> Generator[Any, Any, Any]:
|
|
689
784
|
"""
|
|
690
785
|
Returning the blob containers with their respective blob service id.
|
|
691
786
|
"""
|
|
692
787
|
for blob_service in blob_services:
|
|
693
|
-
blob_containers = get_blob_containers(
|
|
694
|
-
|
|
788
|
+
blob_containers = get_blob_containers(
|
|
789
|
+
credentials,
|
|
790
|
+
subscription_id,
|
|
791
|
+
blob_service,
|
|
792
|
+
)
|
|
793
|
+
yield blob_service["id"], blob_containers
|
|
695
794
|
|
|
696
795
|
|
|
697
796
|
@timeit
|
|
698
|
-
def get_blob_containers(
|
|
797
|
+
def get_blob_containers(
|
|
798
|
+
credentials: Credentials,
|
|
799
|
+
subscription_id: str,
|
|
800
|
+
blob_service: Dict,
|
|
801
|
+
) -> List[Dict]:
|
|
699
802
|
"""
|
|
700
803
|
Getting the blob containers from the blob service.
|
|
701
804
|
"""
|
|
@@ -705,14 +808,16 @@ def get_blob_containers(credentials: Credentials, subscription_id: str, blob_ser
|
|
|
705
808
|
map(
|
|
706
809
|
lambda x: x.as_dict(),
|
|
707
810
|
client.blob_containers.list(
|
|
708
|
-
blob_service[
|
|
709
|
-
blob_service[
|
|
811
|
+
blob_service["resource_group_name"],
|
|
812
|
+
blob_service["storage_account_name"],
|
|
710
813
|
),
|
|
711
814
|
),
|
|
712
815
|
)
|
|
713
816
|
|
|
714
817
|
except ClientAuthenticationError as e:
|
|
715
|
-
logger.warning(
|
|
818
|
+
logger.warning(
|
|
819
|
+
f"Client Authentication Error while retrieving blob containers - {e}",
|
|
820
|
+
)
|
|
716
821
|
return []
|
|
717
822
|
except ResourceNotFoundError as e:
|
|
718
823
|
logger.warning(f"Blob containers resource not found error - {e}")
|
|
@@ -726,7 +831,10 @@ def get_blob_containers(credentials: Credentials, subscription_id: str, blob_ser
|
|
|
726
831
|
|
|
727
832
|
@timeit
|
|
728
833
|
def load_blob_services_details(
|
|
729
|
-
|
|
834
|
+
neo4j_session: neo4j.Session,
|
|
835
|
+
details: List[Tuple[Any, Any]],
|
|
836
|
+
subscription_id: str,
|
|
837
|
+
update_tag: int,
|
|
730
838
|
) -> None:
|
|
731
839
|
"""
|
|
732
840
|
Create dictionary for the blob containers so we can import them in a single query
|
|
@@ -736,65 +844,89 @@ def load_blob_services_details(
|
|
|
736
844
|
for blob_service_id, container in details:
|
|
737
845
|
if len(container) > 0:
|
|
738
846
|
for c in container:
|
|
739
|
-
c[
|
|
847
|
+
c["service_id"] = blob_service_id
|
|
740
848
|
blob_containers.extend(container)
|
|
741
849
|
|
|
742
|
-
_load_blob_containers(neo4j_session, blob_containers, update_tag)
|
|
850
|
+
_load_blob_containers(neo4j_session, blob_containers, subscription_id, update_tag)
|
|
743
851
|
|
|
744
852
|
|
|
745
853
|
@timeit
|
|
746
854
|
def _load_blob_containers(
|
|
747
|
-
|
|
855
|
+
neo4j_session: neo4j.Session,
|
|
856
|
+
blob_containers: List[Dict],
|
|
857
|
+
subscription_id: str,
|
|
858
|
+
update_tag: int,
|
|
748
859
|
) -> None:
|
|
749
860
|
"""
|
|
750
861
|
Ingest Blob Container details into neo4j.
|
|
751
862
|
"""
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
bc.deleted = blob.deleted,
|
|
759
|
-
bc.deletedtime = blob.deleted_time,
|
|
760
|
-
bc.defaultencryptionscope = blob.default_encryption_scope,
|
|
761
|
-
bc.publicaccess = blob.public_access,
|
|
762
|
-
bc.leasestatus = blob.lease_status,
|
|
763
|
-
bc.leasestate = blob.lease_state,
|
|
764
|
-
bc.lastmodifiedtime = blob.last_modified_time,
|
|
765
|
-
bc.remainingretentiondays = blob.remaining_retention_days,
|
|
766
|
-
bc.version = blob.version,
|
|
767
|
-
bc.hasimmutabilitypolicy = blob.has_immutability_policy,
|
|
768
|
-
bc.haslegalhold = blob.has_legal_hold,
|
|
769
|
-
bc.leaseduration = blob.leaseDuration
|
|
770
|
-
WITH bc, blob
|
|
771
|
-
MATCH (bs:AzureStorageBlobService{id: blob.service_id})
|
|
772
|
-
MERGE (bs)-[r:CONTAINS]->(bc)
|
|
773
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
774
|
-
SET r.lastupdated = $azure_update_tag
|
|
775
|
-
"""
|
|
776
|
-
|
|
777
|
-
neo4j_session.run(
|
|
778
|
-
ingest_blob_containers,
|
|
779
|
-
blob_containers_list=blob_containers,
|
|
780
|
-
azure_update_tag=update_tag,
|
|
863
|
+
load(
|
|
864
|
+
neo4j_session,
|
|
865
|
+
AzureStorageBlobContainerSchema(),
|
|
866
|
+
blob_containers,
|
|
867
|
+
lastupdated=update_tag,
|
|
868
|
+
AZURE_SUBSCRIPTION_ID=subscription_id,
|
|
781
869
|
)
|
|
782
870
|
|
|
783
871
|
|
|
784
872
|
@timeit
|
|
785
873
|
def cleanup_azure_storage_accounts(
|
|
786
|
-
|
|
874
|
+
neo4j_session: neo4j.Session,
|
|
875
|
+
common_job_parameters: Dict,
|
|
787
876
|
) -> None:
|
|
788
|
-
|
|
877
|
+
for node in (
|
|
878
|
+
AzureStorageAccountSchema,
|
|
879
|
+
AzureStorageBlobServiceSchema,
|
|
880
|
+
AzureStorageFileServiceSchema,
|
|
881
|
+
AzureStorageQueueServiceSchema,
|
|
882
|
+
AzureStorageTableServiceSchema,
|
|
883
|
+
AzureStorageFileShareSchema,
|
|
884
|
+
AzureStorageQueueSchema,
|
|
885
|
+
AzureStorageTableSchema,
|
|
886
|
+
AzureStorageBlobContainerSchema,
|
|
887
|
+
):
|
|
888
|
+
GraphJob.from_node_schema(node(), common_job_parameters).run(
|
|
889
|
+
neo4j_session,
|
|
890
|
+
)
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
@timeit
|
|
894
|
+
def cleanup_azure_storage_tags(
|
|
895
|
+
neo4j_session: neo4j.Session,
|
|
896
|
+
common_job_parameters: Dict,
|
|
897
|
+
) -> None:
|
|
898
|
+
"""
|
|
899
|
+
Delete stale Azure Storage Tags that are scoped to the current subscription.
|
|
900
|
+
Uses the sub-resource relationship to only clean tags belonging to this subscription.
|
|
901
|
+
"""
|
|
902
|
+
GraphJob.from_node_schema(AzureStorageTagsSchema(), common_job_parameters).run(
|
|
903
|
+
neo4j_session
|
|
904
|
+
)
|
|
789
905
|
|
|
790
906
|
|
|
791
907
|
@timeit
|
|
792
908
|
def sync(
|
|
793
|
-
|
|
794
|
-
|
|
909
|
+
neo4j_session: neo4j.Session,
|
|
910
|
+
credentials: Credentials,
|
|
911
|
+
subscription_id: str,
|
|
912
|
+
sync_tag: int,
|
|
913
|
+
common_job_parameters: Dict,
|
|
795
914
|
) -> None:
|
|
796
915
|
logger.info("Syncing Azure Storage for subscription '%s'.", subscription_id)
|
|
797
916
|
storage_account_list = get_storage_account_list(credentials, subscription_id)
|
|
798
|
-
load_storage_account_data(
|
|
799
|
-
|
|
917
|
+
load_storage_account_data(
|
|
918
|
+
neo4j_session,
|
|
919
|
+
subscription_id,
|
|
920
|
+
storage_account_list,
|
|
921
|
+
sync_tag,
|
|
922
|
+
)
|
|
923
|
+
load_storage_tags(neo4j_session, subscription_id, storage_account_list, sync_tag)
|
|
924
|
+
sync_storage_account_details(
|
|
925
|
+
neo4j_session,
|
|
926
|
+
credentials,
|
|
927
|
+
subscription_id,
|
|
928
|
+
storage_account_list,
|
|
929
|
+
sync_tag,
|
|
930
|
+
)
|
|
800
931
|
cleanup_azure_storage_accounts(neo4j_session, common_job_parameters)
|
|
932
|
+
cleanup_azure_storage_tags(neo4j_session, common_job_parameters)
|