cartography 0.104.0rc2__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/_version.py +16 -3
- cartography/cli.py +466 -5
- cartography/client/aws/__init__.py +19 -0
- cartography/client/aws/ecr.py +51 -0
- cartography/client/core/tx.py +357 -8
- cartography/config.py +153 -0
- cartography/data/azure_permission_relationships.yaml +20 -0
- cartography/data/gcp_permission_relationships.yaml +21 -0
- cartography/data/indexes.cypher +0 -186
- cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
- cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
- cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
- cartography/data/jobs/cleanup/github_repos_cleanup.json +2 -0
- cartography/driftdetect/cli.py +3 -2
- cartography/graph/cleanupbuilder.py +198 -41
- cartography/graph/job.py +54 -6
- cartography/graph/querybuilder.py +528 -27
- cartography/graph/statement.py +5 -1
- 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/aws/__init__.py +24 -9
- cartography/intel/aws/acm.py +124 -0
- cartography/intel/aws/apigateway.py +253 -22
- cartography/intel/aws/apigatewayv2.py +116 -0
- cartography/intel/aws/cloudtrail.py +17 -39
- cartography/intel/aws/cloudtrail_management_events.py +962 -0
- cartography/intel/aws/cloudwatch.py +150 -4
- cartography/intel/aws/codebuild.py +132 -0
- cartography/intel/aws/cognito.py +201 -0
- cartography/intel/aws/config.py +7 -3
- cartography/intel/aws/ec2/elastic_ip_addresses.py +3 -1
- cartography/intel/aws/ec2/instances.py +25 -1
- cartography/intel/aws/ec2/internet_gateways.py +4 -2
- cartography/intel/aws/ec2/load_balancer_v2s.py +11 -5
- cartography/intel/aws/ec2/network_interfaces.py +5 -1
- cartography/intel/aws/ec2/reserved_instances.py +3 -1
- cartography/intel/aws/ec2/security_groups.py +140 -122
- cartography/intel/aws/ec2/snapshots.py +47 -84
- cartography/intel/aws/ec2/subnets.py +37 -63
- cartography/intel/aws/ec2/tgw.py +11 -5
- cartography/intel/aws/ec2/volumes.py +1 -1
- cartography/intel/aws/ec2/vpc.py +140 -124
- cartography/intel/aws/ec2/vpc_peerings.py +262 -125
- cartography/intel/aws/ecr.py +269 -98
- cartography/intel/aws/ecr_image_layers.py +923 -0
- cartography/intel/aws/ecs.py +251 -380
- cartography/intel/aws/efs.py +179 -11
- cartography/intel/aws/elasticache.py +102 -79
- cartography/intel/aws/elasticsearch.py +13 -4
- 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 +750 -493
- cartography/intel/aws/identitycenter.py +605 -83
- cartography/intel/aws/inspector.py +221 -105
- cartography/intel/aws/kms.py +173 -201
- cartography/intel/aws/lambda_function.py +272 -189
- cartography/intel/aws/organizations.py +10 -9
- cartography/intel/aws/permission_relationships.py +10 -20
- cartography/intel/aws/rds.py +337 -446
- cartography/intel/aws/redshift.py +9 -4
- cartography/intel/aws/resourcegroupstaggingapi.py +78 -19
- cartography/intel/aws/resources.py +18 -0
- cartography/intel/aws/route53.py +386 -332
- cartography/intel/aws/s3.py +322 -14
- cartography/intel/aws/secretsmanager.py +81 -49
- cartography/intel/aws/securityhub.py +3 -1
- cartography/intel/aws/sns.py +62 -2
- cartography/intel/aws/sqs.py +36 -90
- cartography/intel/aws/ssm.py +3 -5
- cartography/intel/azure/__init__.py +202 -48
- cartography/intel/azure/aks.py +175 -0
- cartography/intel/azure/app_service.py +105 -0
- cartography/intel/azure/compute.py +59 -112
- cartography/intel/azure/container_instances.py +95 -0
- cartography/intel/azure/cosmosdb.py +222 -361
- 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 +145 -292
- cartography/intel/azure/storage.py +185 -262
- cartography/intel/azure/subscription.py +21 -43
- cartography/intel/azure/tenant.py +39 -30
- cartography/intel/azure/util/common.py +13 -0
- cartography/intel/azure/util/credentials.py +49 -174
- cartography/intel/azure/util/tag.py +41 -0
- cartography/intel/create_indexes.py +2 -1
- cartography/intel/crowdstrike/spotlight.py +5 -2
- cartography/intel/dns.py +5 -2
- cartography/intel/entra/__init__.py +100 -1
- 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 +48 -24
- cartography/intel/entra/service_principals.py +217 -0
- cartography/intel/entra/users.py +105 -57
- cartography/intel/gcp/__init__.py +334 -396
- 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 +128 -119
- 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 +83 -169
- cartography/intel/gcp/gke.py +72 -113
- cartography/intel/gcp/iam.py +111 -91
- cartography/intel/gcp/permission_relationships.py +394 -0
- cartography/intel/gcp/policy_bindings.py +225 -0
- cartography/intel/gcp/storage.py +75 -159
- cartography/intel/github/__init__.py +62 -25
- cartography/intel/github/commits.py +423 -0
- cartography/intel/github/repos.py +463 -85
- cartography/intel/github/teams.py +3 -3
- cartography/intel/github/users.py +5 -0
- cartography/intel/github/util.py +12 -0
- 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 +17 -9
- cartography/intel/gsuite/groups.py +291 -0
- cartography/intel/gsuite/users.py +142 -0
- cartography/intel/jamf/computers.py +7 -1
- 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 +59 -57
- cartography/intel/kubernetes/pods.py +168 -75
- cartography/intel/kubernetes/rbac.py +597 -0
- cartography/intel/kubernetes/secrets.py +95 -45
- cartography/intel/kubernetes/services.py +131 -67
- cartography/intel/kubernetes/util.py +142 -14
- cartography/intel/oci/iam.py +23 -9
- cartography/intel/oci/organizations.py +3 -1
- cartography/intel/oci/utils.py +28 -5
- cartography/intel/okta/applications.py +15 -5
- cartography/intel/okta/awssaml.py +14 -10
- cartography/intel/okta/factors.py +3 -1
- cartography/intel/okta/groups.py +5 -2
- cartography/intel/okta/organization.py +3 -1
- cartography/intel/okta/origins.py +3 -1
- cartography/intel/okta/roles.py +5 -2
- cartography/intel/okta/users.py +10 -2
- 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/pagerduty/escalation_policies.py +13 -6
- cartography/intel/pagerduty/schedules.py +9 -4
- cartography/intel/pagerduty/services.py +7 -3
- cartography/intel/pagerduty/teams.py +5 -2
- cartography/intel/pagerduty/users.py +3 -1
- cartography/intel/pagerduty/vendors.py +3 -1
- 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/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/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/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/apikey.py +4 -0
- cartography/models/anthropic/user.py +4 -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/apigatewaydeployment.py +74 -0
- cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
- cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
- cartography/models/aws/apigatewayv2/__init__.py +0 -0
- cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
- cartography/models/aws/cloudtrail/management_events.py +153 -0
- cartography/models/aws/cloudtrail/trail.py +45 -0
- cartography/models/aws/cloudwatch/log_metric_filter.py +79 -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/tables.py +2 -0
- cartography/models/aws/ec2/instances.py +25 -1
- cartography/models/aws/ec2/networkinterfaces.py +4 -0
- cartography/models/aws/ec2/security_group_rules.py +109 -0
- cartography/models/aws/ec2/security_groups.py +90 -0
- cartography/models/aws/ec2/snapshots.py +58 -0
- cartography/models/aws/ec2/subnet_instance.py +2 -0
- cartography/models/aws/ec2/subnet_networkinterface.py +2 -0
- cartography/models/aws/ec2/subnets.py +65 -0
- cartography/models/aws/ec2/volumes.py +20 -0
- 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/access_point.py +77 -0
- cartography/models/aws/efs/file_system.py +60 -0
- cartography/models/aws/efs/mount_target.py +29 -2
- 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/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/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/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/awsidentitycenter.py +1 -0
- cartography/models/aws/identitycenter/awspermissionset.py +70 -0
- cartography/models/aws/identitycenter/awssogroup.py +70 -0
- cartography/models/aws/identitycenter/awsssouser.py +49 -9
- cartography/models/aws/inspector/findings.py +37 -0
- cartography/models/aws/inspector/packages.py +1 -31
- 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/notification.py +24 -0
- cartography/models/aws/secretsmanager/secret.py +106 -0
- cartography/models/aws/secretsmanager/secret_version.py +0 -2
- 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/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 +1 -1
- cartography/models/cloudflare/member.py +4 -0
- cartography/models/core/common.py +1 -0
- cartography/models/core/nodes.py +15 -2
- cartography/models/core/relationships.py +44 -0
- cartography/models/crowdstrike/hosts.py +1 -1
- cartography/models/digitalocean/droplet.py +2 -0
- cartography/models/duo/endpoint.py +1 -1
- cartography/models/duo/phone.py +2 -2
- cartography/models/duo/user.py +4 -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/service_principal.py +104 -0
- cartography/models/entra/user.py +42 -51
- 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 +3 -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/users.py +10 -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 +1 -2
- 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/user.py +4 -0
- 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/adminapikey.py +4 -0
- cartography/models/openai/apikey.py +4 -0
- cartography/models/openai/user.py +4 -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/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/asset.py +2 -0
- cartography/models/snipeit/user.py +4 -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/device.py +2 -1
- cartography/models/tailscale/user.py +6 -1
- 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/sync.py +25 -5
- cartography/util.py +101 -31
- {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/METADATA +61 -22
- cartography-0.123.0.dist-info/RECORD +856 -0
- {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
- 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_ec2_security_groupinfo_cleanup.json +0 -24
- cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +0 -16
- 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/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/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/gcp/crm.py +0 -355
- cartography/intel/gsuite/api.py +0 -342
- cartography-0.104.0rc2.dist-info/RECORD +0 -455
- /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
- /cartography/models/aws/{apigateway.py → apigateway/apigateway.py} +0 -0
- /cartography/models/aws/{apigatewaycertificate.py → apigateway/apigatewaycertificate.py} +0 -0
- /cartography/models/aws/{apigatewayresource.py → apigateway/apigatewayresource.py} +0 -0
- /cartography/models/aws/{apigatewaystage.py → apigateway/apigatewaystage.py} +0 -0
- {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/WHEEL +0 -0
- {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Dict
|
|
3
|
+
from typing import List
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
import neo4j
|
|
7
|
+
from google.auth.credentials import Credentials as GoogleCredentials
|
|
8
|
+
from google.cloud import resourcemanager_v3
|
|
9
|
+
|
|
10
|
+
from cartography.client.core.tx import load
|
|
11
|
+
from cartography.models.gcp.crm.projects import GCPProjectSchema
|
|
12
|
+
from cartography.util import timeit
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@timeit
|
|
18
|
+
def get_gcp_projects(
|
|
19
|
+
org_resource_name: str,
|
|
20
|
+
folders: List[Dict],
|
|
21
|
+
credentials: Optional[GoogleCredentials] = None,
|
|
22
|
+
) -> List[Dict]:
|
|
23
|
+
"""
|
|
24
|
+
Return list of ACTIVE GCP projects under the specified organization
|
|
25
|
+
and within the specified folders.
|
|
26
|
+
:param org_resource_name: Full organization resource name (e.g., "organizations/123456789012")
|
|
27
|
+
:param folders: List of folder dictionaries containing 'name' field with full resource names
|
|
28
|
+
"""
|
|
29
|
+
folder_names = [folder["name"] for folder in folders] if folders else []
|
|
30
|
+
# Build list of parent resources to check (org and all folders)
|
|
31
|
+
parents = set([org_resource_name] + folder_names)
|
|
32
|
+
results: List[Dict] = []
|
|
33
|
+
for parent in parents:
|
|
34
|
+
client = resourcemanager_v3.ProjectsClient(credentials=credentials)
|
|
35
|
+
for proj in client.list_projects(parent=parent):
|
|
36
|
+
# list_projects returns ACTIVE projects by default
|
|
37
|
+
name_field = proj.name # "projects/<number>"
|
|
38
|
+
project_number = name_field.split("/")[-1] if name_field else None
|
|
39
|
+
project_parent = proj.parent
|
|
40
|
+
results.append(
|
|
41
|
+
{
|
|
42
|
+
"projectId": getattr(proj, "project_id", None),
|
|
43
|
+
"projectNumber": project_number,
|
|
44
|
+
"name": getattr(proj, "display_name", None),
|
|
45
|
+
"lifecycleState": proj.state.name,
|
|
46
|
+
"parent": project_parent,
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
return results
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@timeit
|
|
53
|
+
def transform_gcp_projects(data: List[Dict]) -> List[Dict]:
|
|
54
|
+
"""
|
|
55
|
+
Transform GCP project data to add parent_org or parent_folder fields based on parent type.
|
|
56
|
+
|
|
57
|
+
:param data: List of project dicts
|
|
58
|
+
:return: List of transformed project dicts with parent_org and parent_folder fields
|
|
59
|
+
"""
|
|
60
|
+
for project in data:
|
|
61
|
+
project["parent_org"] = None
|
|
62
|
+
project["parent_folder"] = None
|
|
63
|
+
|
|
64
|
+
# Set parent fields based on parent type
|
|
65
|
+
if project["parent"].startswith("organizations"):
|
|
66
|
+
project["parent_org"] = project["parent"]
|
|
67
|
+
elif project["parent"].startswith("folders"):
|
|
68
|
+
project["parent_folder"] = project["parent"]
|
|
69
|
+
else:
|
|
70
|
+
logger.warning(
|
|
71
|
+
f"Project {project['projectId']} has unexpected parent type: {project['parent']}"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return data
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@timeit
|
|
78
|
+
def load_gcp_projects(
|
|
79
|
+
neo4j_session: neo4j.Session,
|
|
80
|
+
data: List[Dict],
|
|
81
|
+
gcp_update_tag: int,
|
|
82
|
+
org_resource_name: str,
|
|
83
|
+
) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Load GCP projects into the graph.
|
|
86
|
+
:param org_resource_name: Full organization resource name (e.g., "organizations/123456789012")
|
|
87
|
+
"""
|
|
88
|
+
transformed_data = transform_gcp_projects(data)
|
|
89
|
+
load(
|
|
90
|
+
neo4j_session,
|
|
91
|
+
GCPProjectSchema(),
|
|
92
|
+
transformed_data,
|
|
93
|
+
lastupdated=gcp_update_tag,
|
|
94
|
+
ORG_RESOURCE_NAME=org_resource_name,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@timeit
|
|
99
|
+
def sync_gcp_projects(
|
|
100
|
+
neo4j_session: neo4j.Session,
|
|
101
|
+
org_resource_name: str,
|
|
102
|
+
folders: List[Dict],
|
|
103
|
+
gcp_update_tag: int,
|
|
104
|
+
common_job_parameters: Dict,
|
|
105
|
+
credentials: Optional[GoogleCredentials] = None,
|
|
106
|
+
) -> List[Dict]:
|
|
107
|
+
"""
|
|
108
|
+
Get and sync GCP project data to Neo4j.
|
|
109
|
+
:param org_resource_name: Full organization resource name (e.g., "organizations/123456789012")
|
|
110
|
+
:param folders: List of folder dictionaries containing 'name' field with full resource names
|
|
111
|
+
:return: List of projects synced
|
|
112
|
+
"""
|
|
113
|
+
logger.debug("Syncing GCP projects")
|
|
114
|
+
projects = get_gcp_projects(
|
|
115
|
+
org_resource_name,
|
|
116
|
+
folders,
|
|
117
|
+
credentials=credentials,
|
|
118
|
+
)
|
|
119
|
+
load_gcp_projects(neo4j_session, projects, gcp_update_tag, org_resource_name)
|
|
120
|
+
return projects
|
cartography/intel/gcp/dns.py
CHANGED
|
@@ -7,28 +7,20 @@ import neo4j
|
|
|
7
7
|
from googleapiclient.discovery import HttpError
|
|
8
8
|
from googleapiclient.discovery import Resource
|
|
9
9
|
|
|
10
|
-
from cartography.
|
|
10
|
+
from cartography.client.core.tx import load
|
|
11
|
+
from cartography.graph.job import GraphJob
|
|
12
|
+
from cartography.models.gcp.dns import GCPDNSZoneSchema
|
|
13
|
+
from cartography.models.gcp.dns import GCPRecordSetSchema
|
|
11
14
|
from cartography.util import timeit
|
|
12
15
|
|
|
13
16
|
logger = logging.getLogger(__name__)
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
@timeit
|
|
17
|
-
def get_dns_zones(dns: Resource, project_id: str) -> List[
|
|
18
|
-
"""
|
|
19
|
-
Returns a list of DNS zones within the given project.
|
|
20
|
-
|
|
21
|
-
:type dns: The GCP DNS resource object
|
|
22
|
-
:param dns: The DNS resource object created by googleapiclient.discovery.build()
|
|
23
|
-
|
|
24
|
-
:type project_id: str
|
|
25
|
-
:param project_id: Current Google Project Id
|
|
26
|
-
|
|
27
|
-
:rtype: list
|
|
28
|
-
:return: List of DNS zones
|
|
29
|
-
"""
|
|
20
|
+
def get_dns_zones(dns: Resource, project_id: str) -> List[Dict]:
|
|
21
|
+
"""Returns a list of DNS zones within the given project."""
|
|
30
22
|
try:
|
|
31
|
-
zones = []
|
|
23
|
+
zones: List[Dict] = []
|
|
32
24
|
request = dns.managedZones().list(project=project_id)
|
|
33
25
|
while request is not None:
|
|
34
26
|
response = request.execute()
|
|
@@ -47,40 +39,22 @@ def get_dns_zones(dns: Resource, project_id: str) -> List[Resource]:
|
|
|
47
39
|
):
|
|
48
40
|
logger.warning(
|
|
49
41
|
(
|
|
50
|
-
"Could not retrieve DNS zones on project %s due to permissions issues.
|
|
42
|
+
"Could not retrieve DNS zones on project %s due to permissions issues. "
|
|
43
|
+
"Code: %s, Message: %s"
|
|
51
44
|
),
|
|
52
45
|
project_id,
|
|
53
46
|
err["code"],
|
|
54
47
|
err["message"],
|
|
55
48
|
)
|
|
56
49
|
return []
|
|
57
|
-
|
|
58
|
-
raise
|
|
50
|
+
raise
|
|
59
51
|
|
|
60
52
|
|
|
61
53
|
@timeit
|
|
62
|
-
def get_dns_rrs(
|
|
63
|
-
|
|
64
|
-
dns_zones: List[Dict],
|
|
65
|
-
project_id: str,
|
|
66
|
-
) -> List[Resource]:
|
|
67
|
-
"""
|
|
68
|
-
Returns a list of DNS Resource Record Sets within the given project.
|
|
69
|
-
|
|
70
|
-
:type dns: The GCP DNS resource object
|
|
71
|
-
:param dns: The DNS resource object created by googleapiclient.discovery.build()
|
|
72
|
-
|
|
73
|
-
:type dns_zones: list
|
|
74
|
-
:param dns_zones: List of DNS zones for the project
|
|
75
|
-
|
|
76
|
-
:type project_id: str
|
|
77
|
-
:param project_id: Current Google Project Id
|
|
78
|
-
|
|
79
|
-
:rtype: list
|
|
80
|
-
:return: List of Resource Record Sets
|
|
81
|
-
"""
|
|
54
|
+
def get_dns_rrs(dns: Resource, dns_zones: List[Dict], project_id: str) -> List[Dict]:
|
|
55
|
+
"""Returns a list of DNS Resource Record Sets within the given project."""
|
|
82
56
|
try:
|
|
83
|
-
rrs: List[
|
|
57
|
+
rrs: List[Dict] = []
|
|
84
58
|
for zone in dns_zones:
|
|
85
59
|
request = dns.resourceRecordSets().list(
|
|
86
60
|
project=project_id,
|
|
@@ -104,16 +78,54 @@ def get_dns_rrs(
|
|
|
104
78
|
):
|
|
105
79
|
logger.warning(
|
|
106
80
|
(
|
|
107
|
-
"Could not retrieve DNS RRS on project %s due to permissions issues.
|
|
81
|
+
"Could not retrieve DNS RRS on project %s due to permissions issues. "
|
|
82
|
+
"Code: %s, Message: %s"
|
|
108
83
|
),
|
|
109
84
|
project_id,
|
|
110
85
|
err["code"],
|
|
111
86
|
err["message"],
|
|
112
87
|
)
|
|
113
88
|
return []
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
89
|
+
raise
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@timeit
|
|
93
|
+
def transform_dns_zones(dns_zones: List[Dict]) -> List[Dict]:
|
|
94
|
+
"""Transform raw DNS zone responses into Neo4j-ready dicts."""
|
|
95
|
+
zones: List[Dict] = []
|
|
96
|
+
for z in dns_zones:
|
|
97
|
+
zones.append(
|
|
98
|
+
{
|
|
99
|
+
"id": z["id"],
|
|
100
|
+
"name": z.get("name"),
|
|
101
|
+
"dns_name": z.get("dnsName"),
|
|
102
|
+
"description": z.get("description"),
|
|
103
|
+
"visibility": z.get("visibility"),
|
|
104
|
+
"kind": z.get("kind"),
|
|
105
|
+
"nameservers": z.get("nameServers"),
|
|
106
|
+
"created_at": z.get("creationTime"),
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
return zones
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@timeit
|
|
113
|
+
def transform_dns_rrs(dns_rrs: List[Dict]) -> List[Dict]:
|
|
114
|
+
"""Transform raw DNS record set responses into Neo4j-ready dicts."""
|
|
115
|
+
records: List[Dict] = []
|
|
116
|
+
for r in dns_rrs:
|
|
117
|
+
records.append(
|
|
118
|
+
{
|
|
119
|
+
# Compose a unique ID to avoid collisions across types and zones
|
|
120
|
+
"id": f"{r['name']}|{r.get('type')}|{r.get('zone')}",
|
|
121
|
+
"name": r["name"],
|
|
122
|
+
"type": r.get("type"),
|
|
123
|
+
"ttl": r.get("ttl"),
|
|
124
|
+
"data": r.get("rrdatas"),
|
|
125
|
+
"zone_id": r.get("zone"),
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
return records
|
|
117
129
|
|
|
118
130
|
|
|
119
131
|
@timeit
|
|
@@ -123,102 +135,30 @@ def load_dns_zones(
|
|
|
123
135
|
project_id: str,
|
|
124
136
|
gcp_update_tag: int,
|
|
125
137
|
) -> None:
|
|
126
|
-
"""
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
:param dns_resp: A DNS response object from the GKE API
|
|
134
|
-
|
|
135
|
-
:type project_id: str
|
|
136
|
-
:param project_id: Current Google Project Id
|
|
137
|
-
|
|
138
|
-
:type gcp_update_tag: timestamp
|
|
139
|
-
:param gcp_update_tag: The timestamp value to set our new Neo4j nodes with
|
|
140
|
-
|
|
141
|
-
:rtype: NoneType
|
|
142
|
-
:return: Nothing
|
|
143
|
-
"""
|
|
144
|
-
|
|
145
|
-
ingest_records = """
|
|
146
|
-
UNWIND $records as record
|
|
147
|
-
MERGE(zone:GCPDNSZone{id:record.id})
|
|
148
|
-
ON CREATE SET
|
|
149
|
-
zone.firstseen = timestamp(),
|
|
150
|
-
zone.created_at = record.creationTime
|
|
151
|
-
SET
|
|
152
|
-
zone.name = record.name,
|
|
153
|
-
zone.dns_name = record.dnsName,
|
|
154
|
-
zone.description = record.description,
|
|
155
|
-
zone.visibility = record.visibility,
|
|
156
|
-
zone.kind = record.kind,
|
|
157
|
-
zone.nameservers = record.nameServers,
|
|
158
|
-
zone.lastupdated = $gcp_update_tag
|
|
159
|
-
WITH zone
|
|
160
|
-
MATCH (owner:GCPProject{id:$ProjectId})
|
|
161
|
-
MERGE (owner)-[r:RESOURCE]->(zone)
|
|
162
|
-
ON CREATE SET
|
|
163
|
-
r.firstseen = timestamp(),
|
|
164
|
-
r.lastupdated = $gcp_update_tag
|
|
165
|
-
"""
|
|
166
|
-
neo4j_session.run(
|
|
167
|
-
ingest_records,
|
|
168
|
-
records=dns_zones,
|
|
169
|
-
ProjectId=project_id,
|
|
170
|
-
gcp_update_tag=gcp_update_tag,
|
|
138
|
+
"""Ingest GCP DNS Zones into Neo4j."""
|
|
139
|
+
load(
|
|
140
|
+
neo4j_session,
|
|
141
|
+
GCPDNSZoneSchema(),
|
|
142
|
+
dns_zones,
|
|
143
|
+
lastupdated=gcp_update_tag,
|
|
144
|
+
PROJECT_ID=project_id,
|
|
171
145
|
)
|
|
172
146
|
|
|
173
147
|
|
|
174
148
|
@timeit
|
|
175
149
|
def load_rrs(
|
|
176
150
|
neo4j_session: neo4j.Session,
|
|
177
|
-
dns_rrs: List[
|
|
151
|
+
dns_rrs: List[Dict],
|
|
178
152
|
project_id: str,
|
|
179
153
|
gcp_update_tag: int,
|
|
180
154
|
) -> None:
|
|
181
|
-
"""
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
:param dns_rrs: A list of RRS
|
|
189
|
-
|
|
190
|
-
:type project_id: str
|
|
191
|
-
:param project_id: Current Google Project Id
|
|
192
|
-
|
|
193
|
-
:type gcp_update_tag: timestamp
|
|
194
|
-
:param gcp_update_tag: The timestamp value to set our new Neo4j nodes with
|
|
195
|
-
|
|
196
|
-
:rtype: NoneType
|
|
197
|
-
:return: Nothing
|
|
198
|
-
"""
|
|
199
|
-
|
|
200
|
-
ingest_records = """
|
|
201
|
-
UNWIND $records as record
|
|
202
|
-
MERGE(rrs:GCPRecordSet{id:record.name})
|
|
203
|
-
ON CREATE SET
|
|
204
|
-
rrs.firstseen = timestamp()
|
|
205
|
-
SET
|
|
206
|
-
rrs.name = record.name,
|
|
207
|
-
rrs.type = record.type,
|
|
208
|
-
rrs.ttl = record.ttl,
|
|
209
|
-
rrs.data = record.rrdatas,
|
|
210
|
-
rrs.lastupdated = $gcp_update_tag
|
|
211
|
-
WITH rrs, record
|
|
212
|
-
MATCH (zone:GCPDNSZone{id:record.zone})
|
|
213
|
-
MERGE (zone)-[r:HAS_RECORD]->(rrs)
|
|
214
|
-
ON CREATE SET
|
|
215
|
-
r.firstseen = timestamp(),
|
|
216
|
-
r.lastupdated = $gcp_update_tag
|
|
217
|
-
"""
|
|
218
|
-
neo4j_session.run(
|
|
219
|
-
ingest_records,
|
|
220
|
-
records=dns_rrs,
|
|
221
|
-
gcp_update_tag=gcp_update_tag,
|
|
155
|
+
"""Ingest GCP DNS Resource Record Sets into Neo4j."""
|
|
156
|
+
load(
|
|
157
|
+
neo4j_session,
|
|
158
|
+
GCPRecordSetSchema(),
|
|
159
|
+
dns_rrs,
|
|
160
|
+
lastupdated=gcp_update_tag,
|
|
161
|
+
PROJECT_ID=project_id,
|
|
222
162
|
)
|
|
223
163
|
|
|
224
164
|
|
|
@@ -227,19 +167,14 @@ def cleanup_dns_records(
|
|
|
227
167
|
neo4j_session: neo4j.Session,
|
|
228
168
|
common_job_parameters: Dict,
|
|
229
169
|
) -> None:
|
|
230
|
-
"""
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
:rtype: NoneType
|
|
240
|
-
:return: Nothing
|
|
241
|
-
"""
|
|
242
|
-
run_cleanup_job("gcp_dns_cleanup.json", neo4j_session, common_job_parameters)
|
|
170
|
+
"""Delete out-of-date GCP DNS Zones and Record Sets nodes and relationships."""
|
|
171
|
+
# Record sets depend on zones, so clean them up first.
|
|
172
|
+
GraphJob.from_node_schema(GCPRecordSetSchema(), common_job_parameters).run(
|
|
173
|
+
neo4j_session,
|
|
174
|
+
)
|
|
175
|
+
GraphJob.from_node_schema(GCPDNSZoneSchema(), common_job_parameters).run(
|
|
176
|
+
neo4j_session,
|
|
177
|
+
)
|
|
243
178
|
|
|
244
179
|
|
|
245
180
|
@timeit
|
|
@@ -250,33 +185,12 @@ def sync(
|
|
|
250
185
|
gcp_update_tag: int,
|
|
251
186
|
common_job_parameters: Dict,
|
|
252
187
|
) -> None:
|
|
253
|
-
"""
|
|
254
|
-
Get GCP DNS Zones and Resource Record Sets using the DNS resource object, ingest to Neo4j, and clean up old data.
|
|
255
|
-
|
|
256
|
-
:type neo4j_session: The Neo4j session object
|
|
257
|
-
:param neo4j_session: The Neo4j session
|
|
258
|
-
|
|
259
|
-
:type dns: The DNS resource object created by googleapiclient.discovery.build()
|
|
260
|
-
:param dns: The GCP DNS resource object
|
|
261
|
-
|
|
262
|
-
:type project_id: str
|
|
263
|
-
:param project_id: The project ID of the corresponding project
|
|
264
|
-
|
|
265
|
-
:type gcp_update_tag: timestamp
|
|
266
|
-
:param gcp_update_tag: The timestamp value to set our new Neo4j nodes with
|
|
267
|
-
|
|
268
|
-
:type common_job_parameters: dict
|
|
269
|
-
:param common_job_parameters: Dictionary of other job parameters to pass to Neo4j
|
|
270
|
-
|
|
271
|
-
:rtype: NoneType
|
|
272
|
-
:return: Nothing
|
|
273
|
-
"""
|
|
188
|
+
"""Get GCP DNS Zones and Record Sets, load them into Neo4j, and clean up old data."""
|
|
274
189
|
logger.info("Syncing DNS records for project %s.", project_id)
|
|
275
|
-
|
|
276
|
-
dns_zones =
|
|
190
|
+
dns_zones_resp = get_dns_zones(dns, project_id)
|
|
191
|
+
dns_zones = transform_dns_zones(dns_zones_resp)
|
|
277
192
|
load_dns_zones(neo4j_session, dns_zones, project_id, gcp_update_tag)
|
|
278
|
-
|
|
279
|
-
dns_rrs =
|
|
193
|
+
dns_rrs_resp = get_dns_rrs(dns, dns_zones_resp, project_id)
|
|
194
|
+
dns_rrs = transform_dns_rrs(dns_rrs_resp)
|
|
280
195
|
load_rrs(neo4j_session, dns_rrs, project_id, gcp_update_tag)
|
|
281
|
-
# TODO scope the cleanup to the current project - https://github.com/cartography-cncf/cartography/issues/381
|
|
282
196
|
cleanup_dns_records(neo4j_session, common_job_parameters)
|
cartography/intel/gcp/gke.py
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
|
+
from typing import Any
|
|
3
4
|
from typing import Dict
|
|
5
|
+
from typing import List
|
|
4
6
|
|
|
5
7
|
import neo4j
|
|
6
8
|
from googleapiclient.discovery import HttpError
|
|
7
9
|
from googleapiclient.discovery import Resource
|
|
8
10
|
|
|
9
|
-
from cartography.
|
|
11
|
+
from cartography.client.core.tx import load
|
|
12
|
+
from cartography.graph.job import GraphJob
|
|
13
|
+
from cartography.models.gcp.gke import GCPGKEClusterSchema
|
|
10
14
|
from cartography.util import timeit
|
|
11
15
|
|
|
12
16
|
logger = logging.getLogger(__name__)
|
|
@@ -56,105 +60,20 @@ def load_gke_clusters(
|
|
|
56
60
|
gcp_update_tag: int,
|
|
57
61
|
) -> None:
|
|
58
62
|
"""
|
|
59
|
-
Ingest GCP GKE
|
|
60
|
-
|
|
61
|
-
:type neo4j_session: Neo4j session object
|
|
62
|
-
:param neo4j session: The Neo4j session object
|
|
63
|
-
|
|
64
|
-
:type cluster_resp: Dict
|
|
65
|
-
:param cluster_resp: A cluster response object from the GKE API
|
|
66
|
-
|
|
67
|
-
:type gcp_update_tag: timestamp
|
|
68
|
-
:param gcp_update_tag: The timestamp value to set our new Neo4j nodes with
|
|
69
|
-
|
|
70
|
-
:rtype: NoneType
|
|
71
|
-
:return: Nothing
|
|
63
|
+
Ingest GCP GKE clusters using the data model loader.
|
|
72
64
|
"""
|
|
65
|
+
clusters: List[Dict[str, Any]] = transform_gke_clusters(cluster_resp)
|
|
73
66
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
cluster.monitoring_service = $ClusterMonitoringService,
|
|
85
|
-
cluster.network = $ClusterNetwork,
|
|
86
|
-
cluster.subnetwork = $ClusterSubnetwork,
|
|
87
|
-
cluster.cluster_ipv4cidr = $ClusterIPv4Cidr,
|
|
88
|
-
cluster.zone = $ClusterZone,
|
|
89
|
-
cluster.location = $ClusterLocation,
|
|
90
|
-
cluster.endpoint = $ClusterEndpoint,
|
|
91
|
-
cluster.initial_version = $ClusterInitialVersion,
|
|
92
|
-
cluster.current_master_version = $ClusterMasterVersion,
|
|
93
|
-
cluster.status = $ClusterStatus,
|
|
94
|
-
cluster.services_ipv4cidr = $ClusterServicesIPv4Cidr,
|
|
95
|
-
cluster.database_encryption = $ClusterDatabaseEncryption,
|
|
96
|
-
cluster.network_policy = $ClusterNetworkPolicy,
|
|
97
|
-
cluster.master_authorized_networks = $ClusterMasterAuthorizedNetworks,
|
|
98
|
-
cluster.legacy_abac = $ClusterAbac,
|
|
99
|
-
cluster.shielded_nodes = $ClusterShieldedNodes,
|
|
100
|
-
cluster.private_nodes = $ClusterPrivateNodes,
|
|
101
|
-
cluster.private_endpoint_enabled = $ClusterPrivateEndpointEnabled,
|
|
102
|
-
cluster.private_endpoint = $ClusterPrivateEndpoint,
|
|
103
|
-
cluster.public_endpoint = $ClusterPublicEndpoint,
|
|
104
|
-
cluster.masterauth_username = $ClusterMasterUsername,
|
|
105
|
-
cluster.masterauth_password = $ClusterMasterPassword
|
|
106
|
-
WITH cluster
|
|
107
|
-
MATCH (owner:GCPProject{id:$ProjectId})
|
|
108
|
-
MERGE (owner)-[r:RESOURCE]->(cluster)
|
|
109
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
110
|
-
SET r.lastupdated = $gcp_update_tag
|
|
111
|
-
"""
|
|
112
|
-
for cluster in cluster_resp.get("clusters", []):
|
|
113
|
-
neo4j_session.run(
|
|
114
|
-
query,
|
|
115
|
-
ProjectId=project_id,
|
|
116
|
-
ClusterSelfLink=cluster["selfLink"],
|
|
117
|
-
ClusterCreateTime=cluster["createTime"],
|
|
118
|
-
ClusterName=cluster["name"],
|
|
119
|
-
ClusterDescription=cluster.get("description"),
|
|
120
|
-
ClusterLoggingService=cluster.get("loggingService"),
|
|
121
|
-
ClusterMonitoringService=cluster.get("monitoringService"),
|
|
122
|
-
ClusterNetwork=cluster.get("network"),
|
|
123
|
-
ClusterSubnetwork=cluster.get("subnetwork"),
|
|
124
|
-
ClusterIPv4Cidr=cluster.get("clusterIpv4Cidr"),
|
|
125
|
-
ClusterZone=cluster.get("zone"),
|
|
126
|
-
ClusterLocation=cluster.get("location"),
|
|
127
|
-
ClusterEndpoint=cluster.get("endpoint"),
|
|
128
|
-
ClusterInitialVersion=cluster.get("initialClusterVersion"),
|
|
129
|
-
ClusterMasterVersion=cluster.get("currentMasterVersion"),
|
|
130
|
-
ClusterStatus=cluster.get("status"),
|
|
131
|
-
ClusterServicesIPv4Cidr=cluster.get("servicesIpv4Cidr"),
|
|
132
|
-
ClusterDatabaseEncryption=cluster.get("databaseEncryption", {}).get(
|
|
133
|
-
"state",
|
|
134
|
-
),
|
|
135
|
-
ClusterNetworkPolicy=_process_network_policy(cluster),
|
|
136
|
-
ClusterMasterAuthorizedNetworks=cluster.get(
|
|
137
|
-
"masterAuthorizedNetworksConfig",
|
|
138
|
-
{},
|
|
139
|
-
).get("enabled"),
|
|
140
|
-
ClusterAbac=cluster.get("legacyAbac", {}).get("enabled"),
|
|
141
|
-
ClusterShieldedNodes=cluster.get("shieldedNodes", {}).get("enabled"),
|
|
142
|
-
ClusterPrivateNodes=cluster.get("privateClusterConfig", {}).get(
|
|
143
|
-
"enablePrivateNodes",
|
|
144
|
-
),
|
|
145
|
-
ClusterPrivateEndpointEnabled=cluster.get("privateClusterConfig", {}).get(
|
|
146
|
-
"enablePrivateEndpoint",
|
|
147
|
-
),
|
|
148
|
-
ClusterPrivateEndpoint=cluster.get("privateClusterConfig", {}).get(
|
|
149
|
-
"privateEndpoint",
|
|
150
|
-
),
|
|
151
|
-
ClusterPublicEndpoint=cluster.get("privateClusterConfig", {}).get(
|
|
152
|
-
"publicEndpoint",
|
|
153
|
-
),
|
|
154
|
-
ClusterMasterUsername=cluster.get("masterAuth", {}).get("username"),
|
|
155
|
-
ClusterMasterPassword=cluster.get("masterAuth", {}).get("password"),
|
|
156
|
-
gcp_update_tag=gcp_update_tag,
|
|
157
|
-
)
|
|
67
|
+
if not clusters:
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
load(
|
|
71
|
+
neo4j_session,
|
|
72
|
+
GCPGKEClusterSchema(),
|
|
73
|
+
clusters,
|
|
74
|
+
lastupdated=gcp_update_tag,
|
|
75
|
+
PROJECT_ID=project_id,
|
|
76
|
+
)
|
|
158
77
|
|
|
159
78
|
|
|
160
79
|
def _process_network_policy(cluster: Dict) -> bool:
|
|
@@ -175,21 +94,10 @@ def cleanup_gke_clusters(
|
|
|
175
94
|
common_job_parameters: Dict,
|
|
176
95
|
) -> None:
|
|
177
96
|
"""
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
:type neo4j_session: The Neo4j session object
|
|
181
|
-
:param neo4j_session: The Neo4j session
|
|
182
|
-
|
|
183
|
-
:type common_job_parameters: dict
|
|
184
|
-
:param common_job_parameters: Dictionary of other job parameters to pass to Neo4j
|
|
185
|
-
|
|
186
|
-
:rtype: NoneType
|
|
187
|
-
:return: Nothing
|
|
97
|
+
Scoped cleanup for GKE clusters based on the project sub-resource relationship.
|
|
188
98
|
"""
|
|
189
|
-
|
|
190
|
-
"gcp_gke_cluster_cleanup.json",
|
|
99
|
+
GraphJob.from_node_schema(GCPGKEClusterSchema(), common_job_parameters).run(
|
|
191
100
|
neo4j_session,
|
|
192
|
-
common_job_parameters,
|
|
193
101
|
)
|
|
194
102
|
|
|
195
103
|
|
|
@@ -222,8 +130,59 @@ def sync_gke_clusters(
|
|
|
222
130
|
:rtype: NoneType
|
|
223
131
|
:return: Nothing
|
|
224
132
|
"""
|
|
225
|
-
logger.info("Syncing
|
|
133
|
+
logger.info("Syncing GKE clusters for project %s.", project_id)
|
|
226
134
|
gke_res = get_gke_clusters(container, project_id)
|
|
227
135
|
load_gke_clusters(neo4j_session, gke_res, project_id, gcp_update_tag)
|
|
228
|
-
# TODO scope the cleanup to the current project - https://github.com/cartography-cncf/cartography/issues/381
|
|
229
136
|
cleanup_gke_clusters(neo4j_session, common_job_parameters)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def transform_gke_clusters(api_result: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
140
|
+
"""
|
|
141
|
+
Transform GKE API response into a list of dicts suitable for the data model loader.
|
|
142
|
+
"""
|
|
143
|
+
result: List[Dict[str, Any]] = []
|
|
144
|
+
for c in api_result.get("clusters", []):
|
|
145
|
+
transformed: Dict[str, Any] = {
|
|
146
|
+
# Required fields
|
|
147
|
+
"id": c["selfLink"],
|
|
148
|
+
"self_link": c["selfLink"],
|
|
149
|
+
"name": c["name"],
|
|
150
|
+
"created_at": c.get("createTime"),
|
|
151
|
+
# Optional fields
|
|
152
|
+
"description": c.get("description"),
|
|
153
|
+
"logging_service": c.get("loggingService"),
|
|
154
|
+
"monitoring_service": c.get("monitoringService"),
|
|
155
|
+
"network": c.get("network"),
|
|
156
|
+
"subnetwork": c.get("subnetwork"),
|
|
157
|
+
"cluster_ipv4cidr": c.get("clusterIpv4Cidr"),
|
|
158
|
+
"zone": c.get("zone"),
|
|
159
|
+
"location": c.get("location"),
|
|
160
|
+
"endpoint": c.get("endpoint"),
|
|
161
|
+
"initial_version": c.get("initialClusterVersion"),
|
|
162
|
+
"current_master_version": c.get("currentMasterVersion"),
|
|
163
|
+
"status": c.get("status"),
|
|
164
|
+
"services_ipv4cidr": c.get("servicesIpv4Cidr"),
|
|
165
|
+
"database_encryption": (c.get("databaseEncryption", {}) or {}).get("state"),
|
|
166
|
+
"network_policy": _process_network_policy(c),
|
|
167
|
+
"master_authorized_networks": (
|
|
168
|
+
c.get("masterAuthorizedNetworksConfig", {}) or {}
|
|
169
|
+
).get("enabled"),
|
|
170
|
+
"legacy_abac": (c.get("legacyAbac", {}) or {}).get("enabled"),
|
|
171
|
+
"shielded_nodes": (c.get("shieldedNodes", {}) or {}).get("enabled"),
|
|
172
|
+
"private_nodes": (c.get("privateClusterConfig", {}) or {}).get(
|
|
173
|
+
"enablePrivateNodes"
|
|
174
|
+
),
|
|
175
|
+
"private_endpoint_enabled": (c.get("privateClusterConfig", {}) or {}).get(
|
|
176
|
+
"enablePrivateEndpoint"
|
|
177
|
+
),
|
|
178
|
+
"private_endpoint": (c.get("privateClusterConfig", {}) or {}).get(
|
|
179
|
+
"privateEndpoint"
|
|
180
|
+
),
|
|
181
|
+
"public_endpoint": (c.get("privateClusterConfig", {}) or {}).get(
|
|
182
|
+
"publicEndpoint"
|
|
183
|
+
),
|
|
184
|
+
"masterauth_username": (c.get("masterAuth", {}) or {}).get("username"),
|
|
185
|
+
"masterauth_password": (c.get("masterAuth", {}) or {}).get("password"),
|
|
186
|
+
}
|
|
187
|
+
result.append(transformed)
|
|
188
|
+
return result
|