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
|
@@ -3,6 +3,7 @@ from string import Template
|
|
|
3
3
|
from typing import Dict
|
|
4
4
|
from typing import List
|
|
5
5
|
|
|
6
|
+
from cartography.graph.querybuilder import _asdict_with_validate_relprops
|
|
6
7
|
from cartography.graph.querybuilder import _build_match_clause
|
|
7
8
|
from cartography.graph.querybuilder import rel_present_on_node_schema
|
|
8
9
|
from cartography.models.core.common import PropertyRef
|
|
@@ -15,35 +16,138 @@ from cartography.models.core.relationships import TargetNodeMatcher
|
|
|
15
16
|
def build_cleanup_queries(node_schema: CartographyNodeSchema) -> List[str]:
|
|
16
17
|
"""
|
|
17
18
|
Generates queries to clean up stale nodes and relationships from the given CartographyNodeSchema.
|
|
19
|
+
Properly handles cases where a node schema has a scoped cleanup or not.
|
|
18
20
|
Note that auto-cleanups for a node with no relationships is not currently supported.
|
|
19
|
-
Algorithm:
|
|
20
|
-
1. First delete all stale nodes attached to the node_schema's sub resource
|
|
21
|
-
2. Delete all stale node to sub resource relationships
|
|
22
|
-
- We don't expect this to be very common (never for AWS resources, at least), but in case it is possible for an
|
|
23
|
-
asset to change sub resources, we want to handle it properly.
|
|
24
|
-
3. For all relationships defined on the node schema, delete all stale ones.
|
|
25
21
|
:param node_schema: The given CartographyNodeSchema
|
|
26
22
|
:return: A list of Neo4j queries to clean up nodes and relationships.
|
|
27
23
|
"""
|
|
28
|
-
|
|
24
|
+
# If the node has no relationships, do not delete the node. Leave this behind for the user to manage.
|
|
25
|
+
# Oftentimes these are SyncMetadata nodes.
|
|
26
|
+
if (
|
|
27
|
+
not node_schema.sub_resource_relationship
|
|
28
|
+
and not node_schema.other_relationships
|
|
29
|
+
):
|
|
30
|
+
return []
|
|
31
|
+
|
|
32
|
+
# Case 1 [Standard]: the node has a sub resource and scoped cleanup is true => clean up stale nodes
|
|
33
|
+
# of this type, scoped to the sub resource. Continue on to clean up the other_relationships too.
|
|
34
|
+
if node_schema.sub_resource_relationship and node_schema.scoped_cleanup:
|
|
35
|
+
queries = _build_cleanup_node_and_rel_queries(
|
|
36
|
+
node_schema,
|
|
37
|
+
node_schema.sub_resource_relationship,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Case 2: The node has a sub resource but scoped cleanup is false => this does not make sense
|
|
41
|
+
# because if have a sub resource, we are implying that we are doing scoped cleanup.
|
|
42
|
+
elif node_schema.sub_resource_relationship and not node_schema.scoped_cleanup:
|
|
29
43
|
raise ValueError(
|
|
30
|
-
"
|
|
31
|
-
|
|
44
|
+
f"This is not expected: {node_schema.label} has a sub_resource_relationship but scoped_cleanup=False."
|
|
45
|
+
"Please check the class definition for this node schema. It doesn't make sense for a node to have a "
|
|
46
|
+
"sub resource relationship and an unscoped cleanup. Doing this will cause all stale nodes of this type "
|
|
47
|
+
"to be deleted regardless of the sub resource they are attached to."
|
|
32
48
|
)
|
|
33
49
|
|
|
34
|
-
|
|
50
|
+
# Case 3: The node has no sub resource but scoped cleanup is true => do not delete any nodes, but clean up stale relationships.
|
|
51
|
+
# Return early.
|
|
52
|
+
elif not node_schema.sub_resource_relationship and node_schema.scoped_cleanup:
|
|
53
|
+
queries = []
|
|
54
|
+
other_rels = (
|
|
55
|
+
node_schema.other_relationships.rels
|
|
56
|
+
if node_schema.other_relationships
|
|
57
|
+
else []
|
|
58
|
+
)
|
|
59
|
+
for rel in other_rels:
|
|
60
|
+
query = _build_cleanup_rel_query_no_sub_resource(node_schema, rel)
|
|
61
|
+
queries.append(query)
|
|
62
|
+
return queries
|
|
63
|
+
|
|
64
|
+
# Case 4: The node has no sub resource and scoped cleanup is false => clean up the stale nodes. Continue on to clean up the other_relationships too.
|
|
65
|
+
else:
|
|
66
|
+
queries = [_build_cleanup_node_query_unscoped(node_schema)]
|
|
67
|
+
|
|
35
68
|
if node_schema.other_relationships:
|
|
36
69
|
for rel in node_schema.other_relationships.rels:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
70
|
+
if node_schema.scoped_cleanup:
|
|
71
|
+
# [0] is the delete node query, [1] is the delete relationship query. We only want the latter.
|
|
72
|
+
_, rel_query = _build_cleanup_node_and_rel_queries(node_schema, rel)
|
|
73
|
+
queries.append(rel_query)
|
|
74
|
+
else:
|
|
75
|
+
queries.append(_build_cleanup_rel_queries_unscoped(node_schema, rel))
|
|
76
|
+
|
|
77
|
+
return queries
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _build_cleanup_rel_query_no_sub_resource(
|
|
81
|
+
node_schema: CartographyNodeSchema,
|
|
82
|
+
selected_relationship: CartographyRelSchema,
|
|
83
|
+
) -> str:
|
|
84
|
+
"""
|
|
85
|
+
Helper function to delete stale relationships for node_schemas that have no sub resource relationship defined.
|
|
86
|
+
"""
|
|
87
|
+
if node_schema.sub_resource_relationship:
|
|
88
|
+
raise ValueError(
|
|
89
|
+
f"Expected {node_schema.label} to not exist. "
|
|
90
|
+
"This function is intended for node_schemas without sub_resource_relationships.",
|
|
91
|
+
)
|
|
92
|
+
# Ensure the node is attached to the sub resource and delete the node
|
|
93
|
+
query_template = Template(
|
|
94
|
+
"""
|
|
95
|
+
MATCH (n:$node_label)
|
|
96
|
+
$selected_rel_clause
|
|
97
|
+
WHERE r.lastupdated <> $UPDATE_TAG
|
|
98
|
+
WITH r LIMIT $LIMIT_SIZE
|
|
99
|
+
DELETE r;
|
|
100
|
+
""",
|
|
101
|
+
)
|
|
102
|
+
return query_template.safe_substitute(
|
|
103
|
+
node_label=node_schema.label,
|
|
104
|
+
selected_rel_clause=_build_selected_rel_clause(selected_relationship),
|
|
105
|
+
)
|
|
40
106
|
|
|
41
|
-
|
|
107
|
+
|
|
108
|
+
def _build_match_statement_for_cleanup(node_schema: CartographyNodeSchema) -> str:
|
|
109
|
+
"""
|
|
110
|
+
Helper function to build a MATCH statement for a given node schema for cleanup.
|
|
111
|
+
"""
|
|
112
|
+
if not node_schema.sub_resource_relationship and not node_schema.scoped_cleanup:
|
|
113
|
+
template = Template("MATCH (n:$node_label)")
|
|
114
|
+
return template.safe_substitute(
|
|
115
|
+
node_label=node_schema.label,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# if it has a sub resource relationship defined, we need to match on the sub resource to make sure we only delete
|
|
119
|
+
# nodes that are attached to the sub resource.
|
|
120
|
+
template = Template(
|
|
121
|
+
"MATCH (n:$node_label)$sub_resource_link(:$sub_resource_label{$match_sub_res_clause})"
|
|
122
|
+
)
|
|
123
|
+
sub_resource_link = ""
|
|
124
|
+
sub_resource_label = ""
|
|
125
|
+
match_sub_res_clause = ""
|
|
126
|
+
|
|
127
|
+
if node_schema.sub_resource_relationship:
|
|
128
|
+
# Draw sub resource rel with correct direction
|
|
129
|
+
if node_schema.sub_resource_relationship.direction == LinkDirection.INWARD:
|
|
130
|
+
sub_resource_link_template = Template("<-[s:$SubResourceRelLabel]-")
|
|
131
|
+
else:
|
|
132
|
+
sub_resource_link_template = Template("-[s:$SubResourceRelLabel]->")
|
|
133
|
+
sub_resource_link = sub_resource_link_template.safe_substitute(
|
|
134
|
+
SubResourceRelLabel=node_schema.sub_resource_relationship.rel_label,
|
|
135
|
+
)
|
|
136
|
+
sub_resource_label = node_schema.sub_resource_relationship.target_node_label
|
|
137
|
+
match_sub_res_clause = _build_match_clause(
|
|
138
|
+
node_schema.sub_resource_relationship.target_node_matcher,
|
|
139
|
+
)
|
|
140
|
+
return template.safe_substitute(
|
|
141
|
+
node_label=node_schema.label,
|
|
142
|
+
sub_resource_link=sub_resource_link,
|
|
143
|
+
sub_resource_label=sub_resource_label,
|
|
144
|
+
match_sub_res_clause=match_sub_res_clause,
|
|
145
|
+
)
|
|
42
146
|
|
|
43
147
|
|
|
44
148
|
def _build_cleanup_node_and_rel_queries(
|
|
45
|
-
|
|
46
|
-
|
|
149
|
+
node_schema: CartographyNodeSchema,
|
|
150
|
+
selected_relationship: CartographyRelSchema,
|
|
47
151
|
) -> List[str]:
|
|
48
152
|
"""
|
|
49
153
|
Private function that performs the main string template logic for generating cleanup node and relationship queries.
|
|
@@ -67,15 +171,6 @@ def _build_cleanup_node_and_rel_queries(
|
|
|
67
171
|
"verify the node class definition for the relationships that it has.",
|
|
68
172
|
)
|
|
69
173
|
|
|
70
|
-
# Draw sub resource rel with correct direction
|
|
71
|
-
if node_schema.sub_resource_relationship.direction == LinkDirection.INWARD:
|
|
72
|
-
sub_resource_link_template = Template("<-[s:$SubResourceRelLabel]-")
|
|
73
|
-
else:
|
|
74
|
-
sub_resource_link_template = Template("-[s:$SubResourceRelLabel]->")
|
|
75
|
-
sub_resource_link = sub_resource_link_template.safe_substitute(
|
|
76
|
-
SubResourceRelLabel=node_schema.sub_resource_relationship.rel_label,
|
|
77
|
-
)
|
|
78
|
-
|
|
79
174
|
# The cleanup node query must always be before the cleanup rel query
|
|
80
175
|
delete_action_clauses = [
|
|
81
176
|
"""
|
|
@@ -86,7 +181,9 @@ def _build_cleanup_node_and_rel_queries(
|
|
|
86
181
|
]
|
|
87
182
|
# Now clean up the relationships
|
|
88
183
|
if selected_relationship == node_schema.sub_resource_relationship:
|
|
89
|
-
_validate_target_node_matcher_for_cleanup_job(
|
|
184
|
+
_validate_target_node_matcher_for_cleanup_job(
|
|
185
|
+
node_schema.sub_resource_relationship.target_node_matcher,
|
|
186
|
+
)
|
|
90
187
|
delete_action_clauses.append(
|
|
91
188
|
"""
|
|
92
189
|
WHERE s.lastupdated <> $UPDATE_TAG
|
|
@@ -106,26 +203,99 @@ def _build_cleanup_node_and_rel_queries(
|
|
|
106
203
|
# Ensure the node is attached to the sub resource and delete the node
|
|
107
204
|
query_template = Template(
|
|
108
205
|
"""
|
|
109
|
-
|
|
206
|
+
$match_statement
|
|
110
207
|
$selected_rel_clause
|
|
111
208
|
$delete_action_clause
|
|
112
209
|
""",
|
|
113
210
|
)
|
|
114
211
|
return [
|
|
115
212
|
query_template.safe_substitute(
|
|
116
|
-
|
|
117
|
-
sub_resource_link=sub_resource_link,
|
|
118
|
-
sub_resource_label=node_schema.sub_resource_relationship.target_node_label,
|
|
119
|
-
match_sub_res_clause=_build_match_clause(node_schema.sub_resource_relationship.target_node_matcher),
|
|
213
|
+
match_statement=_build_match_statement_for_cleanup(node_schema),
|
|
120
214
|
selected_rel_clause=(
|
|
121
|
-
""
|
|
215
|
+
""
|
|
216
|
+
if selected_relationship == node_schema.sub_resource_relationship
|
|
122
217
|
else _build_selected_rel_clause(selected_relationship)
|
|
123
218
|
),
|
|
124
219
|
delete_action_clause=delete_action_clause,
|
|
125
|
-
)
|
|
220
|
+
)
|
|
221
|
+
for delete_action_clause in delete_action_clauses
|
|
126
222
|
]
|
|
127
223
|
|
|
128
224
|
|
|
225
|
+
def _build_cleanup_node_query_unscoped(
|
|
226
|
+
node_schema: CartographyNodeSchema,
|
|
227
|
+
) -> str:
|
|
228
|
+
"""
|
|
229
|
+
Generates a cleanup query for a node_schema to allow unscoped cleanup.
|
|
230
|
+
"""
|
|
231
|
+
if node_schema.scoped_cleanup:
|
|
232
|
+
raise ValueError(
|
|
233
|
+
f"_build_cleanup_node_query_for_unscoped_cleanup() failed: '{node_schema.label}' does not have "
|
|
234
|
+
"scoped_cleanup=False, so we cannot generate a query to clean it up. Please verify that the class "
|
|
235
|
+
"definition is what you expect.",
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
# The cleanup node query must always be before the cleanup rel query
|
|
239
|
+
delete_action_clause = """
|
|
240
|
+
WHERE n.lastupdated <> $UPDATE_TAG
|
|
241
|
+
WITH n LIMIT $LIMIT_SIZE
|
|
242
|
+
DETACH DELETE n;
|
|
243
|
+
"""
|
|
244
|
+
|
|
245
|
+
# Ensure the node is attached to the sub resource and delete the node
|
|
246
|
+
query_template = Template(
|
|
247
|
+
"""
|
|
248
|
+
$match_statement
|
|
249
|
+
$delete_action_clause
|
|
250
|
+
""",
|
|
251
|
+
)
|
|
252
|
+
return query_template.safe_substitute(
|
|
253
|
+
match_statement=_build_match_statement_for_cleanup(node_schema),
|
|
254
|
+
delete_action_clause=delete_action_clause,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _build_cleanup_rel_queries_unscoped(
|
|
259
|
+
node_schema: CartographyNodeSchema,
|
|
260
|
+
selected_relationship: CartographyRelSchema,
|
|
261
|
+
) -> str:
|
|
262
|
+
"""
|
|
263
|
+
Generates relationship cleanup query for a node_schema with scoped_cleanup=False.
|
|
264
|
+
"""
|
|
265
|
+
if node_schema.scoped_cleanup:
|
|
266
|
+
raise ValueError(
|
|
267
|
+
f"_build_cleanup_node_and_rel_queries_unscoped() failed: '{node_schema.label}' does not have "
|
|
268
|
+
"scoped_cleanup=False, so we cannot generate a query to clean it up. Please verify that the class "
|
|
269
|
+
"definition is what you expect.",
|
|
270
|
+
)
|
|
271
|
+
if not rel_present_on_node_schema(node_schema, selected_relationship):
|
|
272
|
+
raise ValueError(
|
|
273
|
+
f"_build_cleanup_node_query(): Attempted to build cleanup query for node '{node_schema.label}' and "
|
|
274
|
+
f"relationship {selected_relationship.rel_label} but that relationship is not present on the node. Please "
|
|
275
|
+
"verify the node class definition for the relationships that it has.",
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
# The cleanup node query must always be before the cleanup rel query
|
|
279
|
+
delete_action_clause = """WHERE r.lastupdated <> $UPDATE_TAG
|
|
280
|
+
WITH r LIMIT $LIMIT_SIZE
|
|
281
|
+
DELETE r;
|
|
282
|
+
"""
|
|
283
|
+
|
|
284
|
+
# Ensure the node is attached to the sub resource and delete the node
|
|
285
|
+
query_template = Template(
|
|
286
|
+
"""
|
|
287
|
+
$match_statement
|
|
288
|
+
$selected_rel_clause
|
|
289
|
+
$delete_action_clause
|
|
290
|
+
""",
|
|
291
|
+
)
|
|
292
|
+
return query_template.safe_substitute(
|
|
293
|
+
match_statement=_build_match_statement_for_cleanup(node_schema),
|
|
294
|
+
selected_rel_clause=_build_selected_rel_clause(selected_relationship),
|
|
295
|
+
delete_action_clause=delete_action_clause,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
|
|
129
299
|
def _build_selected_rel_clause(selected_relationship: CartographyRelSchema) -> str:
|
|
130
300
|
"""
|
|
131
301
|
Draw selected relationship with correct direction. Returns a string that looks like either
|
|
@@ -136,8 +306,12 @@ def _build_selected_rel_clause(selected_relationship: CartographyRelSchema) -> s
|
|
|
136
306
|
selected_rel_template = Template("<-[r:$SelectedRelLabel]-")
|
|
137
307
|
else:
|
|
138
308
|
selected_rel_template = Template("-[r:$SelectedRelLabel]->")
|
|
139
|
-
selected_rel = selected_rel_template.safe_substitute(
|
|
140
|
-
|
|
309
|
+
selected_rel = selected_rel_template.safe_substitute(
|
|
310
|
+
SelectedRelLabel=selected_relationship.rel_label,
|
|
311
|
+
)
|
|
312
|
+
selected_rel_clause_template = Template(
|
|
313
|
+
"""MATCH (n)$selected_rel(:$other_node_label)""",
|
|
314
|
+
)
|
|
141
315
|
selected_rel_clause = selected_rel_clause_template.safe_substitute(
|
|
142
316
|
selected_rel=selected_rel,
|
|
143
317
|
other_node_label=selected_relationship.target_node_label,
|
|
@@ -161,3 +335,49 @@ def _validate_target_node_matcher_for_cleanup_job(tgm: TargetNodeMatcher):
|
|
|
161
335
|
f"{key} has set_in_kwargs=False, please check by reviewing the full stack trace to know which object"
|
|
162
336
|
f"this message was raised from. Debug information: PropertyRef name = {prop_ref.name}.",
|
|
163
337
|
)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def build_cleanup_query_for_matchlink(rel_schema: CartographyRelSchema) -> str:
|
|
341
|
+
"""
|
|
342
|
+
Generates a cleanup query for a matchlink relationship.
|
|
343
|
+
:param rel_schema: The CartographyRelSchema object to generate a query. This CartographyRelSchema object
|
|
344
|
+
- Must have a source_node_matcher and source_node_label defined
|
|
345
|
+
- Must have a CartographyRelProperties object where _sub_resource_label and _sub_resource_id are defined
|
|
346
|
+
:return: A Neo4j query used to clean up stale matchlink relationships.
|
|
347
|
+
"""
|
|
348
|
+
if not rel_schema.source_node_matcher:
|
|
349
|
+
raise ValueError(
|
|
350
|
+
f"No source node matcher found for {rel_schema.rel_label}; returning empty list."
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
query_template = Template(
|
|
354
|
+
"""
|
|
355
|
+
MATCH (from:$source_node_label)$rel_direction[r:$rel_label]$rel_direction_end(to:$target_node_label)
|
|
356
|
+
WHERE r.lastupdated <> $UPDATE_TAG
|
|
357
|
+
AND r._sub_resource_label = $sub_resource_label
|
|
358
|
+
AND r._sub_resource_id = $sub_resource_id
|
|
359
|
+
WITH r LIMIT $LIMIT_SIZE
|
|
360
|
+
DELETE r;
|
|
361
|
+
"""
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
# Determine which way to point the arrow. INWARD is toward the source, otherwise we go toward the target.
|
|
365
|
+
if rel_schema.direction == LinkDirection.INWARD:
|
|
366
|
+
rel_direction = "<-"
|
|
367
|
+
rel_direction_end = "-"
|
|
368
|
+
else:
|
|
369
|
+
rel_direction = "-"
|
|
370
|
+
rel_direction_end = "->"
|
|
371
|
+
|
|
372
|
+
# Small hack: avoid type-checking errors by converting the rel_schema to a dict.
|
|
373
|
+
rel_props_as_dict = _asdict_with_validate_relprops(rel_schema)
|
|
374
|
+
|
|
375
|
+
return query_template.safe_substitute(
|
|
376
|
+
source_node_label=rel_schema.source_node_label,
|
|
377
|
+
target_node_label=rel_schema.target_node_label,
|
|
378
|
+
rel_label=rel_schema.rel_label,
|
|
379
|
+
rel_direction=rel_direction,
|
|
380
|
+
rel_direction_end=rel_direction_end,
|
|
381
|
+
sub_resource_label=rel_props_as_dict["_sub_resource_label"],
|
|
382
|
+
sub_resource_id=rel_props_as_dict["_sub_resource_id"],
|
|
383
|
+
)
|
cartography/graph/job.py
CHANGED
|
@@ -13,9 +13,11 @@ from typing import Union
|
|
|
13
13
|
import neo4j
|
|
14
14
|
|
|
15
15
|
from cartography.graph.cleanupbuilder import build_cleanup_queries
|
|
16
|
+
from cartography.graph.cleanupbuilder import build_cleanup_query_for_matchlink
|
|
16
17
|
from cartography.graph.statement import get_job_shortname
|
|
17
18
|
from cartography.graph.statement import GraphStatement
|
|
18
19
|
from cartography.models.core.nodes import CartographyNodeSchema
|
|
20
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
19
21
|
|
|
20
22
|
logger = logging.getLogger(__name__)
|
|
21
23
|
|
|
@@ -32,7 +34,7 @@ def _get_identifiers(template: string.Template) -> List[str]:
|
|
|
32
34
|
filter(
|
|
33
35
|
lambda v: v is not None,
|
|
34
36
|
(
|
|
35
|
-
mo.group(
|
|
37
|
+
mo.group("named") or mo.group("braced")
|
|
36
38
|
for mo in template.pattern.finditer(template.template)
|
|
37
39
|
),
|
|
38
40
|
),
|
|
@@ -71,7 +73,12 @@ class GraphJob:
|
|
|
71
73
|
A job that will run against the cartography graph. A job is a sequence of statements which execute sequentially.
|
|
72
74
|
"""
|
|
73
75
|
|
|
74
|
-
def __init__(
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
name: str,
|
|
79
|
+
statements: List[GraphStatement],
|
|
80
|
+
short_name: Optional[str] = None,
|
|
81
|
+
):
|
|
75
82
|
# E.g. "Okta intel module cleanup"
|
|
76
83
|
self.name = name
|
|
77
84
|
self.statements: List[GraphStatement] = statements
|
|
@@ -100,7 +107,11 @@ class GraphJob:
|
|
|
100
107
|
e,
|
|
101
108
|
)
|
|
102
109
|
raise
|
|
103
|
-
log_msg =
|
|
110
|
+
log_msg = (
|
|
111
|
+
f"Finished job {self.short_name}"
|
|
112
|
+
if self.short_name
|
|
113
|
+
else f"Finished job {self.name}"
|
|
114
|
+
)
|
|
104
115
|
logger.info(log_msg)
|
|
105
116
|
|
|
106
117
|
def as_dict(self) -> Dict:
|
|
@@ -114,43 +125,55 @@ class GraphJob:
|
|
|
114
125
|
}
|
|
115
126
|
|
|
116
127
|
@classmethod
|
|
117
|
-
def from_json(
|
|
128
|
+
def from_json(
|
|
129
|
+
cls, blob: Union[str, dict], short_name: Optional[str] = None
|
|
130
|
+
) -> "GraphJob":
|
|
118
131
|
"""
|
|
119
|
-
Create a job from a JSON blob.
|
|
132
|
+
Create a job from a JSON dict or blob.
|
|
120
133
|
"""
|
|
121
|
-
data
|
|
134
|
+
data = json.loads(blob) if isinstance(blob, str) else blob
|
|
122
135
|
statements = _get_statements_from_json(data, short_name)
|
|
123
136
|
name = data["name"]
|
|
124
137
|
return cls(name, statements, short_name)
|
|
125
138
|
|
|
126
139
|
@classmethod
|
|
127
140
|
def from_node_schema(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
141
|
+
cls,
|
|
142
|
+
node_schema: CartographyNodeSchema,
|
|
143
|
+
parameters: Dict[str, Any],
|
|
144
|
+
iterationsize: int = 100,
|
|
145
|
+
) -> "GraphJob":
|
|
132
146
|
"""
|
|
133
147
|
Create a cleanup job from a CartographyNodeSchema object.
|
|
134
148
|
For a given node, the fields used in the node_schema.sub_resource_relationship.target_node_node_matcher.keys()
|
|
135
149
|
must be provided as keys and values in the params dict.
|
|
150
|
+
:param iterationsize: The number of items to process in each iteration. Defaults to 100.
|
|
136
151
|
"""
|
|
137
152
|
queries: List[str] = build_cleanup_queries(node_schema)
|
|
138
153
|
|
|
139
154
|
expected_param_keys: Set[str] = get_parameters(queries)
|
|
140
155
|
actual_param_keys: Set[str] = set(parameters.keys())
|
|
141
156
|
# Hacky, but LIMIT_SIZE is specified by default in cartography.graph.statement, so we exclude it from validation
|
|
142
|
-
actual_param_keys.add(
|
|
157
|
+
actual_param_keys.add("LIMIT_SIZE")
|
|
143
158
|
|
|
144
159
|
missing_params: Set[str] = expected_param_keys - actual_param_keys
|
|
145
160
|
|
|
146
161
|
if missing_params:
|
|
147
162
|
raise ValueError(
|
|
148
163
|
f'GraphJob is missing the following expected query parameters: "{missing_params}". Please check the '
|
|
149
|
-
f
|
|
164
|
+
f"value passed to `parameters`.",
|
|
150
165
|
)
|
|
151
166
|
|
|
152
167
|
statements: List[GraphStatement] = [
|
|
153
|
-
GraphStatement(
|
|
168
|
+
GraphStatement(
|
|
169
|
+
query,
|
|
170
|
+
parameters=parameters,
|
|
171
|
+
iterative=True,
|
|
172
|
+
iterationsize=iterationsize,
|
|
173
|
+
parent_job_name=node_schema.label,
|
|
174
|
+
parent_job_sequence_num=idx,
|
|
175
|
+
)
|
|
176
|
+
for idx, query in enumerate(queries, start=1)
|
|
154
177
|
]
|
|
155
178
|
|
|
156
179
|
return cls(
|
|
@@ -160,7 +183,49 @@ class GraphJob:
|
|
|
160
183
|
)
|
|
161
184
|
|
|
162
185
|
@classmethod
|
|
163
|
-
def
|
|
186
|
+
def from_matchlink(
|
|
187
|
+
cls,
|
|
188
|
+
rel_schema: CartographyRelSchema,
|
|
189
|
+
sub_resource_label: str,
|
|
190
|
+
sub_resource_id: str,
|
|
191
|
+
update_tag: int,
|
|
192
|
+
iterationsize: int = 100,
|
|
193
|
+
) -> "GraphJob":
|
|
194
|
+
"""
|
|
195
|
+
Create a cleanup job from a CartographyRelSchema object (specifically, a MatchLink).
|
|
196
|
+
This is used for cleaning up stale links between nodes created by load_rels(). Do not use for other purposes.
|
|
197
|
+
|
|
198
|
+
Other notes:
|
|
199
|
+
- For a given rel_schema, the fields used in the rel_schema.properties._sub_resource_label.name and
|
|
200
|
+
rel_schema.properties._sub_resource_id.name must be provided as keys and values in the params dict.
|
|
201
|
+
- The rel_schema must have a source_node_matcher and target_node_matcher.
|
|
202
|
+
:param iterationsize: The number of items to process in each iteration. Defaults to 100.
|
|
203
|
+
"""
|
|
204
|
+
cleanup_link_query = build_cleanup_query_for_matchlink(rel_schema)
|
|
205
|
+
logger.debug(f"Cleanup query: {cleanup_link_query}")
|
|
206
|
+
|
|
207
|
+
parameters = {
|
|
208
|
+
"UPDATE_TAG": update_tag,
|
|
209
|
+
"_sub_resource_label": sub_resource_label,
|
|
210
|
+
"_sub_resource_id": sub_resource_id,
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
statement = GraphStatement(
|
|
214
|
+
cleanup_link_query,
|
|
215
|
+
parameters=parameters,
|
|
216
|
+
iterative=True,
|
|
217
|
+
iterationsize=iterationsize,
|
|
218
|
+
parent_job_name=rel_schema.rel_label,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
return cls(
|
|
222
|
+
f"Cleanup {rel_schema.rel_label} between {rel_schema.source_node_label} and {rel_schema.target_node_label}",
|
|
223
|
+
[statement],
|
|
224
|
+
rel_schema.rel_label,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
@classmethod
|
|
228
|
+
def from_json_file(cls, file_path: Union[str, Path]) -> "GraphJob":
|
|
164
229
|
"""
|
|
165
230
|
Create a job from a JSON file.
|
|
166
231
|
"""
|
|
@@ -168,16 +233,23 @@ class GraphJob:
|
|
|
168
233
|
data: Dict = json.load(j_file)
|
|
169
234
|
|
|
170
235
|
job_shortname: str = get_job_shortname(file_path)
|
|
171
|
-
statements: List[GraphStatement] = _get_statements_from_json(
|
|
236
|
+
statements: List[GraphStatement] = _get_statements_from_json(
|
|
237
|
+
data,
|
|
238
|
+
job_shortname,
|
|
239
|
+
)
|
|
172
240
|
name: str = data["name"]
|
|
173
241
|
return cls(name, statements, job_shortname)
|
|
174
242
|
|
|
175
243
|
@classmethod
|
|
176
244
|
def run_from_json(
|
|
177
|
-
cls,
|
|
245
|
+
cls,
|
|
246
|
+
neo4j_session: neo4j.Session,
|
|
247
|
+
blob: Union[str, dict],
|
|
248
|
+
parameters: Dict,
|
|
249
|
+
short_name: Optional[str] = None,
|
|
178
250
|
) -> None:
|
|
179
251
|
"""
|
|
180
|
-
Run a job from a JSON blob. This will deserialize the job and execute all statements sequentially.
|
|
252
|
+
Run a job from a JSON dict or blob. This will deserialize the job and execute all statements sequentially.
|
|
181
253
|
"""
|
|
182
254
|
if not parameters:
|
|
183
255
|
parameters = {}
|
|
@@ -187,7 +259,12 @@ class GraphJob:
|
|
|
187
259
|
job.run(neo4j_session)
|
|
188
260
|
|
|
189
261
|
@classmethod
|
|
190
|
-
def run_from_json_file(
|
|
262
|
+
def run_from_json_file(
|
|
263
|
+
cls,
|
|
264
|
+
file_path: Union[str, Path],
|
|
265
|
+
neo4j_session: neo4j.Session,
|
|
266
|
+
parameters: Dict,
|
|
267
|
+
) -> None:
|
|
191
268
|
"""
|
|
192
269
|
Run a job from a JSON file. This will deserialize the job and execute all statements sequentially.
|
|
193
270
|
"""
|
|
@@ -200,14 +277,21 @@ class GraphJob:
|
|
|
200
277
|
job.run(neo4j_session)
|
|
201
278
|
|
|
202
279
|
|
|
203
|
-
def _get_statements_from_json(
|
|
280
|
+
def _get_statements_from_json(
|
|
281
|
+
blob: Dict,
|
|
282
|
+
short_job_name: Optional[str] = None,
|
|
283
|
+
) -> List[GraphStatement]:
|
|
204
284
|
"""
|
|
205
285
|
Deserialize all statements from the JSON blob.
|
|
206
286
|
"""
|
|
207
287
|
statements: List[GraphStatement] = []
|
|
208
288
|
for i, statement_data in enumerate(blob["statements"]):
|
|
209
289
|
# i+1 to make it 1-based and not 0-based to help with log readability
|
|
210
|
-
statement: GraphStatement = GraphStatement.create_from_json(
|
|
290
|
+
statement: GraphStatement = GraphStatement.create_from_json(
|
|
291
|
+
statement_data,
|
|
292
|
+
short_job_name,
|
|
293
|
+
i + 1,
|
|
294
|
+
)
|
|
211
295
|
statements.append(statement)
|
|
212
296
|
|
|
213
297
|
return statements
|