Full Code of GoogleCloudPlatform/gcpdiag for AI

main bcb1d5d39e45 cached
2970 files
19.9 MB
5.4M tokens
5649 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (21,470K chars total). Download the full file to get everything.
Repository: GoogleCloudPlatform/gcpdiag
Branch: main
Commit: bcb1d5d39e45
Files: 2970
Total size: 19.9 MB

Directory structure:
gitextract_sa7cb22i/

├── .bumpversion.cfg
├── .coveragerc
├── .devcontainer/
│   ├── README.md
│   └── devcontainer.json
├── .gitallowed
├── .github/
│   └── workflows/
│       ├── code-analysis.yml
│       ├── scorecard.yml
│       └── test.yml
├── .gitignore
├── .isort.cfg
├── .pre-commit-config.yaml
├── .pylint-dictionary.txt
├── .pylintrc
├── .safety-policy.yml
├── .style.yapf
├── .vscode/
│   ├── extensions.json
│   └── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── PRIVACY.md
├── Pipfile
├── README.md
├── bin/
│   ├── changelog_generator.py
│   ├── curl-wrap.sh
│   ├── gcpdiag
│   ├── gcpdiag-dockerized
│   ├── gcpdiag-mocked
│   ├── generate_steps.py
│   ├── json-cleaner
│   ├── pipenv-dockerized
│   ├── precommit-gke-eol-file.sh
│   ├── precommit-required-files
│   ├── precommit-required-files-wrapper
│   ├── precommit-todo-annotations
│   ├── runbook-starter-code-generator
│   ├── steps_table.md
│   ├── templates/
│   │   ├── diagnostic-tree.jinja
│   │   ├── python-file.py.tpl
│   │   ├── runbook-starter-code.py.tpl
│   │   ├── runbook-test.py.tpl
│   │   └── steps.jinja
│   └── terraform
├── cookiecutter-gcpdiag-rule/
│   ├── cookiecutter.json
│   ├── cookiecutter_runner.py
│   ├── hooks/
│   │   └── post_gen_project.py
│   └── {{cookiecutter.__name}}/
│       ├── gcpdiag/
│       │   └── lint/
│       │       └── {{cookiecutter.product}}/
│       │           └── {{cookiecutter.severity.lower()}}_{{cookiecutter.year}}_{{cookiecutter.number}}_{{cookiecutter.__name}}.py
│       └── website/
│           └── content/
│               └── en/
│                   └── rules/
│                       └── {{cookiecutter.product}}/
│                           └── {{cookiecutter.severity}}/
│                               └── {{cookiecutter.year}}_{{cookiecutter.number}}.md
├── docker/
│   ├── gcpdiag/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── entrypoint.sh
│   ├── hugo/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── README.md
│   ├── pipenv-python-3.12/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── entrypoint.sh
│   ├── pipenv-python-3.7/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── entrypoint.sh
│   └── pipenv-python-3.9/
│       ├── Dockerfile
│       ├── Makefile
│       └── entrypoint.sh
├── gcpdiag/
│   ├── __init__.py
│   ├── async_queries/
│   │   ├── __init__.py
│   │   ├── api/
│   │   │   ├── __init__.py
│   │   │   ├── api.py
│   │   │   ├── api_slowtest.py
│   │   │   ├── constant_time_retry_strategy.py
│   │   │   ├── default_random.py
│   │   │   ├── exponential_random_retry_strategy.py
│   │   │   ├── exponential_random_retry_strategy_test.py
│   │   │   ├── gcpdiag_creds.py
│   │   │   ├── get_api.py
│   │   │   ├── sleeper.py
│   │   │   └── test_webserver.py
│   │   ├── dataproc/
│   │   │   ├── __init__.py
│   │   │   ├── dataproc.py
│   │   │   └── dataproc_test.py
│   │   ├── project/
│   │   │   ├── __init__.py
│   │   │   ├── get_project.py
│   │   │   └── project.py
│   │   ├── project_regions.py
│   │   ├── project_regions_test.py
│   │   ├── py.typed
│   │   └── utils/
│   │       ├── __init__.py
│   │       ├── fake_api.py
│   │       ├── loader.py
│   │       └── protocols.py
│   ├── caching.py
│   ├── caching_test.py
│   ├── config.py
│   ├── config_test.py
│   ├── context.py
│   ├── executor.py
│   ├── executor_test.py
│   ├── hooks.py
│   ├── lint/
│   │   ├── __init__.py
│   │   ├── apigee/
│   │   │   ├── __init__.py
│   │   │   ├── apigee_rules_snapshot_test.py
│   │   │   ├── err_2022_001_p4sa_perm.py
│   │   │   ├── err_2022_002_p4sa_kms_key_perm.py
│   │   │   ├── err_2023_001_vpc_peering_created.py
│   │   │   ├── err_2023_002_routing_with_mig.py
│   │   │   ├── err_2023_003_pga_on_mig_subnet.py
│   │   │   ├── err_2023_004_p4nsa_perm.py
│   │   │   ├── err_2023_005_fw_rule_xlb_to_mig.py
│   │   │   ├── err_2023_006_multiple_migs_for_multiple_regions.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   └── WARN_2022_002.txt
│   │   │   ├── warn_2021_001_empty_env.py
│   │   │   ├── warn_2022_001_env_groups_created.py
│   │   │   └── warn_2022_002_env_not_attached.py
│   │   ├── asm/
│   │   │   ├── __init__.py
│   │   │   ├── asm_rules_snapshot_test.py
│   │   │   ├── err_2023_001_traffic_4xx.py
│   │   │   ├── err_2023_002_traffic_5xx.py
│   │   │   ├── err_2024_001_secret_not_found.py
│   │   │   ├── err_2024_002_istiod_resource_issues.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2025_001.txt
│   │   │   │   └── WARN_2025_002.txt
│   │   │   ├── warn_2023_001_grpc_reset.py
│   │   │   ├── warn_2024_001_webhook.py
│   │   │   ├── warn_2025_001_delayedconnect111.py
│   │   │   └── warn_2025_002_protocolerror.py
│   │   ├── bigquery/
│   │   │   ├── __init__.py
│   │   │   ├── bigquery_rules_snapshot_test.py
│   │   │   ├── err_2022_001_concurrent_dml_updates.py
│   │   │   ├── err_2022_002_response_too_large.py
│   │   │   ├── err_2022_003_permission_denied_drive_credentials.py
│   │   │   ├── err_2022_004_exceeded_limit_shuffle.py
│   │   │   ├── err_2023_001_job_not_found_error.py
│   │   │   ├── err_2023_002_dataset_not_found.py
│   │   │   ├── err_2023_003_resource_exceeded.py
│   │   │   ├── err_2023_004_concurrent_dml.py
│   │   │   ├── err_2023_005_outdated_credentials_for_scheduled_queries.py
│   │   │   ├── err_2023_006_bigquery_policy_do_not_belong_to_user.py
│   │   │   ├── err_2023_007_data_transfer_service_agent_does_not_exist.py
│   │   │   ├── err_2023_008_user_not_authorized_to_perform_this_action.py
│   │   │   ├── err_2023_009_not_consistent_with_destination_dataset.py
│   │   │   ├── err_2024_001_query_too_complex.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── ERR_2022_004.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── ERR_2023_007.txt
│   │   │   │   ├── ERR_2023_008.txt
│   │   │   │   ├── ERR_2023_009.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2022_004.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   ├── WARN_2024_003.txt
│   │   │   │   ├── WARN_2024_004.txt
│   │   │   │   ├── WARN_2024_005.txt
│   │   │   │   └── WARN_2024_006.txt
│   │   │   ├── warn_2022_001_exceeded_rate_limits.py
│   │   │   ├── warn_2022_002_column_level_security.py
│   │   │   ├── warn_2022_003_copy_job_quota.py
│   │   │   ├── warn_2022_004_cross_region_copy_job_quota.py
│   │   │   ├── warn_2023_001_query_job_timed_out.py
│   │   │   ├── warn_2023_002_wildcard_tables_query.py
│   │   │   ├── warn_2023_003_too_many_output_column.py
│   │   │   ├── warn_2023_004_bigquery_kms_errors.py
│   │   │   ├── warn_2024_001_imports_or_query_appends_per_table.py
│   │   │   ├── warn_2024_002_invalid_external_connection.py
│   │   │   ├── warn_2024_003_too_many_concurrent_api_requests.py
│   │   │   ├── warn_2024_004_too_many_concurrent_queries.py
│   │   │   ├── warn_2024_005_exceeded_partition_modifications.py
│   │   │   └── warn_2024_006_tabledata_list_bytes_exceeded.py
│   │   ├── billing/
│   │   │   ├── __init__.py
│   │   │   ├── billing_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   └── WARN_2022_003.txt
│   │   │   ├── warn_2022_001_project_billing_enabled.py
│   │   │   ├── warn_2022_002_stray_billing_accounts.py
│   │   │   └── warn_2022_003_cost_anomalies.py
│   │   ├── cloudrun/
│   │   │   ├── __init__.py
│   │   │   ├── cloud_rules_snapshot_test.py
│   │   │   ├── err_2022_001_missing_cloudrun_serviceagent_role.py
│   │   │   └── snapshots/
│   │   │       └── ERR_2022_001.txt
│   │   ├── cloudsql/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_public_ip.py
│   │   │   ├── bp_2023_002_automated_backup.py
│   │   │   ├── bp_2023_003_log_output_flag.py
│   │   │   ├── bp_ext_2023_001_maint_window.py
│   │   │   ├── bp_ext_2023_002_del_protection.py
│   │   │   ├── bp_ext_2023_003_auto_storage_increases.py
│   │   │   ├── bp_ext_2023_004_sla.py
│   │   │   ├── cloudsql_rules_snapshot_test.py
│   │   │   ├── err_2023_001_instance_in_suspended.py
│   │   │   ├── sec_2023_001_public_acess.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2023_002.txt
│   │   │   │   ├── BP_2023_003.txt
│   │   │   │   ├── BP_EXT_2023_001.txt
│   │   │   │   ├── BP_EXT_2023_002.txt
│   │   │   │   ├── BP_EXT_2023_003.txt
│   │   │   │   ├── BP_EXT_2023_004.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── SEC_2023_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   └── WARN_2023_003.txt
│   │   │   ├── warn_2022_001_docker_bridge_network.py
│   │   │   ├── warn_2023_002_high_cpu_usage.py
│   │   │   └── warn_2023_003_high_mem_usage.py
│   │   ├── command.py
│   │   ├── command_test.py
│   │   ├── composer/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_debug_logging_level.py
│   │   │   ├── bp_2023_002_parallelism.py
│   │   │   ├── bp_2023_003_statsd.py
│   │   │   ├── bp_ext_2023_001_number_of_schedulers.py
│   │   │   ├── bp_ext_2023_002_xss_vulnerable_versions.py
│   │   │   ├── composer_rules_snapshot_test.py
│   │   │   ├── err_2022_001_composer_p4sa_permissions.py
│   │   │   ├── err_2022_002_composer_sa_permissions.py
│   │   │   ├── err_2023_001_composer_not_in_error_state.py
│   │   │   ├── err_2023_002_verify_ip_range.py
│   │   │   ├── err_2023_003_dag_timeout_killing.py
│   │   │   ├── err_2023_004_zombie_detection.py
│   │   │   ├── err_2023_005_environment_delete_fail_nat_config.py
│   │   │   ├── err_2024_001_no_error_surfaced.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2023_002.txt
│   │   │   │   ├── BP_2023_003.txt
│   │   │   │   ├── BP_EXT_2023_001.txt
│   │   │   │   ├── BP_EXT_2023_002.txt
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2023_005.txt
│   │   │   │   ├── WARN_2023_006.txt
│   │   │   │   ├── WARN_2023_007.txt
│   │   │   │   ├── WARN_2023_008.txt
│   │   │   │   ├── WARN_2023_009.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   └── WARN_2024_003.txt
│   │   │   ├── warn_2022_001_composer2_p4sa_permissions.py
│   │   │   ├── warn_2022_002_fluentd_pod_crashloop.py
│   │   │   ├── warn_2022_003_total_dag_parse_time.py
│   │   │   ├── warn_2023_001_kerberos_support.py
│   │   │   ├── warn_2023_002_task_sigkill.py
│   │   │   ├── warn_2023_003_task_fail_resource_pressure.py
│   │   │   ├── warn_2023_004_high_database_cpu_usage.py
│   │   │   ├── warn_2023_005_environment_is_consistently_healthy.py
│   │   │   ├── warn_2023_006_schedulers_are_healthy.py
│   │   │   ├── warn_2023_007_high_scheduler_cpu_usage.py
│   │   │   ├── warn_2023_008_composer_airflow_db_is_healthy.py
│   │   │   ├── warn_2023_009_composer_intermittent_task_failure_issue.py
│   │   │   ├── warn_2024_001_low_scheduler_cpu_usuage.py
│   │   │   ├── warn_2024_002_worker_pod_eviction.py
│   │   │   └── warn_2024_003_composer_api_disabled.py
│   │   ├── dataflow/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_dataflow_supported_sdk_version_check.py
│   │   │   ├── dataflow_rules_snapshot_test.py
│   │   │   ├── err_2023_001_dataflow_sa_perm_check.py
│   │   │   ├── err_2023_002_dataflow_ip_space_exhausted.py
│   │   │   ├── err_2023_003_dataflow_subnet_format_check.py
│   │   │   ├── err_2023_004_dataflow_org_policy_violated.py
│   │   │   ├── err_2023_005_dataflow_credential_perm_issue.py
│   │   │   ├── err_2023_006_dataflow_private_google_access_check.py
│   │   │   ├── err_2023_007_dataflow_missing_firewall_issue.py
│   │   │   ├── err_2023_008_dataflow_sa_worker_perm_check.py
│   │   │   ├── err_2023_009_splunk_err_invalid_cert.py
│   │   │   ├── err_2023_010_bq_streaming_insert_missing_field.py
│   │   │   ├── err_2023_011_bq_streaming_insert_mismatch_column.py
│   │   │   ├── err_2023_012_dataflow_spanner_oom.py
│   │   │   ├── err_2023_013_dataflow_spanner_deadline_exceeded.py
│   │   │   ├── err_2024_001_dataflow_gce_quotas.py
│   │   │   ├── err_2024_002_dataflow_key_commit.py
│   │   │   ├── err_2024_003_dataflow_write_truncate_unbounded.py
│   │   │   ├── err_2024_004_missing_gcs_permission_temp_bucket.py
│   │   │   ├── err_2024_005_dataflow_not_creating_pubsub_subscription.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── ERR_2023_007.txt
│   │   │   │   ├── ERR_2023_008.txt
│   │   │   │   ├── ERR_2023_009.txt
│   │   │   │   ├── ERR_2023_010.txt
│   │   │   │   ├── ERR_2023_011.txt
│   │   │   │   ├── ERR_2023_012.txt
│   │   │   │   ├── ERR_2023_013.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── ERR_2024_003.txt
│   │   │   │   ├── ERR_2024_004.txt
│   │   │   │   ├── ERR_2024_005.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2023_006.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   └── WARN_2024_002.txt
│   │   │   ├── warn_2023_001_dataflow_hot_key.py
│   │   │   ├── warn_2023_003_dataflow_worker_logs_throttled.py
│   │   │   ├── warn_2023_004_dataflow_stuck_at_draining.py
│   │   │   ├── warn_2023_006_dataflow_stuck_at_cancelling.py
│   │   │   ├── warn_2024_001_dataflow_operation_ongoing.py
│   │   │   └── warn_2024_002_dataflow_streaming_appliance_commit_failed.py
│   │   ├── datafusion/
│   │   │   ├── __init__.py
│   │   │   ├── datafusion_rules_snapshot_test.py
│   │   │   ├── err_2022_001_connectivity_dataproc_vms.py
│   │   │   ├── err_2022_002_shared_vpc_ip_range.py
│   │   │   ├── err_2022_003_private_peering.py
│   │   │   ├── err_2022_004_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2022_005_host_vpc_permissions.py
│   │   │   ├── err_2022_006_private_google_access.py
│   │   │   ├── err_2022_007_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2022_008_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2022_009_cloud_dataproc_sa_permissions.py
│   │   │   ├── err_2022_010_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2022_011_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2024_001_delete_operation_failing.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── ERR_2022_004.txt
│   │   │   │   ├── ERR_2022_005.txt
│   │   │   │   ├── ERR_2022_006.txt
│   │   │   │   ├── ERR_2022_007.txt
│   │   │   │   ├── ERR_2022_008.txt
│   │   │   │   ├── ERR_2022_009.txt
│   │   │   │   ├── ERR_2022_010.txt
│   │   │   │   ├── ERR_2022_011.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   ├── WARN_2024_003.txt
│   │   │   │   ├── WARN_2024_004.txt
│   │   │   │   └── WARN_2024_005.txt
│   │   │   ├── warn_2024_001_data_fusion_version.py
│   │   │   ├── warn_2024_002_instance_state_running.py
│   │   │   ├── warn_2024_003_cluster_scaling_down_disabled.py
│   │   │   ├── warn_2024_004_datafusion_dataproc_compatabillity.py
│   │   │   └── warn_2024_005_datafusion_dataproc_compatability_preference.py
│   │   ├── dataproc/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2021_001_logging_enabled.py
│   │   │   ├── bp_2022_001_monitoring_enabled.py
│   │   │   ├── bp_2022_098_another_dummy_async_rule.py
│   │   │   ├── bp_2022_099_dummy_async_rule.py
│   │   │   ├── dataproc_rules_snapshot_test.py
│   │   │   ├── err_2022_002_image_versions.py
│   │   │   ├── err_2022_002_image_versions_test.py
│   │   │   ├── err_2022_003_dataproc_sa_permissions.py
│   │   │   ├── err_2022_004_dpgce_connectivity.py
│   │   │   ├── err_2023_001_initialization_action_timeout.py
│   │   │   ├── err_2023_002_orphaned_yarn_application.py
│   │   │   ├── err_2023_003_dataproc_permission.py
│   │   │   ├── err_2023_004_dataproc_firewall_issue.py
│   │   │   ├── err_2023_005_dataproc_quota.py
│   │   │   ├── err_2023_006_shared_vpc_permission.py
│   │   │   ├── err_2023_007_cluster_creation_stockout.py
│   │   │   ├── err_2023_008_bad_dirs.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2021_001.txt
│   │   │   │   ├── BP_2022_001.txt
│   │   │   │   ├── BP_2022_098.txt
│   │   │   │   ├── BP_2022_099.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── ERR_2022_004.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── ERR_2023_007.txt
│   │   │   │   ├── ERR_2023_008.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2022_004.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   └── WARN_2024_002.txt
│   │   │   ├── warn_2021_001_cluster_status_running.py
│   │   │   ├── warn_2022_001_cluster_local_ssd_failed_stop.py
│   │   │   ├── warn_2022_002_job_throttling_rate_limit.py
│   │   │   ├── warn_2022_003_sa_permissions.py
│   │   │   ├── warn_2022_004_cluster_status_running_async.py
│   │   │   ├── warn_2023_001_job_throttling_too_many.py
│   │   │   ├── warn_2023_002_high_system_memory_usage.py
│   │   │   ├── warn_2024_001_safemode.py
│   │   │   └── warn_2024_002_hdfs_write_issue.py
│   │   ├── gae/
│   │   │   ├── __init__.py
│   │   │   ├── err_2023_001_appengine_vpc_connector_policy.py
│   │   │   ├── err_2023_002_appengine_vpc_connector_subnet_overlap.py
│   │   │   ├── err_2025_001_gae_default_service_account_is_deleted.py
│   │   │   ├── gae_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2025_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   └── WARN_2022_002.txt
│   │   │   ├── warn_2022_001_appengine_standard_deprecated_runtimes.py
│   │   │   └── warn_2022_002_appengine_flexible_deprecated_runtimes.py
│   │   ├── gcb/
│   │   │   ├── __init__.py
│   │   │   ├── err_2022_001_missing_cloudbuild_editor_role.py
│   │   │   ├── err_2022_002_build_failed_whithout_artifact_registry_permission.py
│   │   │   ├── err_2022_003_build_failed_with_logs_bucket_retention_policy.py
│   │   │   ├── err_2022_004_missing_cloudbuild_service_agent_role.py
│   │   │   ├── gcb_rules_snapshot_test.py
│   │   │   └── snapshots/
│   │   │       ├── ERR_2022_001.txt
│   │   │       ├── ERR_2022_002.txt
│   │   │       ├── ERR_2022_003.txt
│   │   │       └── ERR_2022_004.txt
│   │   ├── gce/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2021_001_serial_logging_enabled.py
│   │   │   ├── bp_2022_003_unused_boot_disks.py
│   │   │   ├── bp_2023_001_ntp_config.py
│   │   │   ├── bp_2024_001_legacy_monitoring_agent.py
│   │   │   ├── bp_2024_002_legacy_logging_agent.py
│   │   │   ├── bp_ext_2021_003_secure_boot_enabled.py
│   │   │   ├── bp_ext_2022_001_vm_manager_enabled.py
│   │   │   ├── bp_ext_2023_001_gce_scopes.py
│   │   │   ├── bp_ext_2024_001_no_public_ip.py
│   │   │   ├── bp_ext_2024_002_calculate_vm_iops_throughput.py
│   │   │   ├── err_2021_001_mig_scaleup_failed.py
│   │   │   ├── err_2021_002_osconfig_perm.py
│   │   │   ├── err_2021_003_api_service_agent.py
│   │   │   ├── err_2021_004_secure_boot_failed.py
│   │   │   ├── err_2021_005_mount_errors.py
│   │   │   ├── err_2022_001_quota_exceeded.py
│   │   │   ├── err_2022_002_premium_guestos_activation_failed.py
│   │   │   ├── err_2024_001_snapshot_rate_limit.py
│   │   │   ├── err_2024_002_performance.py
│   │   │   ├── err_2024_003_vm_secure_boot_failures.py
│   │   │   ├── err_2024_004_ops_agent.py
│   │   │   ├── gce_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2021_001.txt
│   │   │   │   ├── BP_2022_003.txt
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2024_001.txt
│   │   │   │   ├── BP_2024_002.txt
│   │   │   │   ├── BP_EXT_2021_003.txt
│   │   │   │   ├── BP_EXT_2022_001.txt
│   │   │   │   ├── BP_EXT_2023_001.txt
│   │   │   │   ├── BP_EXT_2024_001.txt
│   │   │   │   ├── BP_EXT_2024_002.txt
│   │   │   │   ├── BP_EXT_2024_003.txt
│   │   │   │   ├── ERR_2021_001.txt
│   │   │   │   ├── ERR_2021_002.txt
│   │   │   │   ├── ERR_2021_003.txt
│   │   │   │   ├── ERR_2021_004.txt
│   │   │   │   ├── ERR_2021_005.txt
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── ERR_2024_003.txt
│   │   │   │   ├── ERR_2024_004.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   ├── WARN_2021_002.txt
│   │   │   │   ├── WARN_2021_003.txt
│   │   │   │   ├── WARN_2021_004.txt
│   │   │   │   ├── WARN_2021_005.txt
│   │   │   │   ├── WARN_2021_006.txt
│   │   │   │   ├── WARN_2021_007.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2022_004.txt
│   │   │   │   ├── WARN_2022_005.txt
│   │   │   │   ├── WARN_2022_006.txt
│   │   │   │   ├── WARN_2022_007.txt
│   │   │   │   ├── WARN_2022_008.txt
│   │   │   │   ├── WARN_2022_009.txt
│   │   │   │   ├── WARN_2022_010.txt
│   │   │   │   ├── WARN_2022_011.txt
│   │   │   │   ├── WARN_2022_012.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   └── WARN_2024_001.txt
│   │   │   ├── utils.py
│   │   │   ├── utils_test.py
│   │   │   ├── warn_2021_001_logging_perm.py
│   │   │   ├── warn_2021_002_disk_latency.py
│   │   │   ├── warn_2021_003_monitoring_permissions.py
│   │   │   ├── warn_2021_004_disk_full_serial_messages.py
│   │   │   ├── warn_2021_005_out_of_memory.py
│   │   │   ├── warn_2021_006_kernel_panic.py
│   │   │   ├── warn_2021_007_bsod.py
│   │   │   ├── warn_2022_001_iap_tcp_forwarding.py
│   │   │   ├── warn_2022_002_duplicated_named_ports.py
│   │   │   ├── warn_2022_003_vm_instances_quota.py
│   │   │   ├── warn_2022_004_docker_bridge_network.py
│   │   │   ├── warn_2022_005_cpu_quota.py
│   │   │   ├── warn_2022_006_gpu_quota.py
│   │   │   ├── warn_2022_007_cloudsql_admin_scope.py
│   │   │   ├── warn_2022_008_ip_address_quota.py
│   │   │   ├── warn_2022_009_disk_quota.py
│   │   │   ├── warn_2022_010_resource_availability.py
│   │   │   ├── warn_2022_011_valid_sa.py
│   │   │   ├── warn_2022_012_windows_kms.py
│   │   │   ├── warn_2023_001_snapshot_policies_on_unused_disks.py
│   │   │   └── warn_2023_002_airflowtask_oom.py
│   │   ├── gcf/
│   │   │   ├── __init__.py
│   │   │   ├── err_2022_001_missing_cloudfunctions_serviceagent_role.py
│   │   │   ├── err_2022_002_cloudfunctions_org_policy_violation.py
│   │   │   ├── err_2022_003_cloudfunctions_memory_limit_exceeded.py
│   │   │   ├── gcf_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   └── WARN_2021_002.txt
│   │   │   ├── warn_2021_001_cloudfunctions_deprecated_runtimes.py
│   │   │   └── warn_2021_002_cloudfunctions_request_aborted.py
│   │   ├── gcs/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2022_001_bucket_access_uniform.py
│   │   │   ├── gcs_rules_snapshot_test.py
│   │   │   └── snapshots/
│   │   │       └── BP_2022_001.txt
│   │   ├── gke/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2021_001_cloudops_enabled.py
│   │   │   ├── bp_2022_001_regional_cluster.py
│   │   │   ├── bp_2022_002_unique_subnets.py
│   │   │   ├── bp_2022_003_cluster_eol.py
│   │   │   ├── bp_2022_004_http_load_balancing_disabled.py
│   │   │   ├── bp_2023_001_network_policy_minimum_requirements.py
│   │   │   ├── bp_2023_002_stateful_workloads_not_on_preemptible_node.py
│   │   │   ├── bp_2023_004_vpc_native_cluster.py
│   │   │   ├── bp_2023_005_gateway_crd.py
│   │   │   ├── bp_2025_001_gke_nodelocal_dnscache_enabled.py
│   │   │   ├── bp_ext_2022_001_groups_enabled.py
│   │   │   ├── bp_ext_2023_001_maintenance_window.py
│   │   │   ├── bp_ext_2023_002_private_cluster.py
│   │   │   ├── eol_parser.sh
│   │   │   ├── err_2021_001_logging_perm.py
│   │   │   ├── err_2021_002_monitoring_perm.py
│   │   │   ├── err_2021_003_kms_key_enabled.py
│   │   │   ├── err_2021_004_node_connection_apiserver.py
│   │   │   ├── err_2021_005_node_connection_storage.py
│   │   │   ├── err_2021_006_scaleup_failed.py
│   │   │   ├── err_2021_007_gke_sa.py
│   │   │   ├── err_2021_008_api_service_agent.py
│   │   │   ├── err_2021_009_nodepool_version_skew.py
│   │   │   ├── err_2021_010_internal_forwarding_rule_limits.py
│   │   │   ├── err_2021_011_ip_masq_not_reporting_errors.py
│   │   │   ├── err_2021_012_np_sa_enabled.py
│   │   │   ├── err_2021_013_connectivity_cluster_rules.py
│   │   │   ├── err_2021_014_connectivity_master.py
│   │   │   ├── err_2021_015_connectivity_vms.py
│   │   │   ├── err_2022_001_connectivity_pod_to_pod.py
│   │   │   ├── err_2022_002_private_google_access.py
│   │   │   ├── err_2022_003_ingress_healthcheck.py
│   │   │   ├── err_2023_001_containerfilesystem_quota.py
│   │   │   ├── err_2023_002_private_routes_based.py
│   │   │   ├── err_2023_003_containerd_bad_config_file.py
│   │   │   ├── err_2023_004_ingress_config.py
│   │   │   ├── err_2023_005_gke_cni_issue.py
│   │   │   ├── err_2023_006_gw_controller_annotation_error.py
│   │   │   ├── err_2023_007_gw_controller_http_route_misconfig.py
│   │   │   ├── err_2023_008_crashloopbackoff.py
│   │   │   ├── err_2023_009_missing_cpu_req.py
│   │   │   ├── err_2023_010_nodelocal_timeout.py
│   │   │   ├── err_2023_011_wi_pod_ip_not_found.py
│   │   │   ├── err_2023_012_missing_mem_request.py
│   │   │   ├── err_2024_001_psa_violoations.py
│   │   │   ├── err_2024_002_webhook_failure_no_endpoint.py
│   │   │   ├── err_2024_003_default_node_serviceaccount_perm.py
│   │   │   ├── err_2025_001_serial_port_logging.py
│   │   │   ├── gke_rules_snapshot_test.py
│   │   │   ├── sec_2021_001_np_uses_default_sa.py
│   │   │   ├── sec_2023_001_worload_id.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2021_001.txt
│   │   │   │   ├── BP_2022_001.txt
│   │   │   │   ├── BP_2022_002.txt
│   │   │   │   ├── BP_2022_003.txt
│   │   │   │   ├── BP_2022_004.txt
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2023_002.txt
│   │   │   │   ├── BP_2023_004.txt
│   │   │   │   ├── BP_2023_005.txt
│   │   │   │   ├── BP_2025_001.txt
│   │   │   │   ├── BP_EXT_2022_001.txt
│   │   │   │   ├── BP_EXT_2023_001.txt
│   │   │   │   ├── BP_EXT_2023_002.txt
│   │   │   │   ├── ERR_2021_001.txt
│   │   │   │   ├── ERR_2021_002.txt
│   │   │   │   ├── ERR_2021_003.txt
│   │   │   │   ├── ERR_2021_004.txt
│   │   │   │   ├── ERR_2021_005.txt
│   │   │   │   ├── ERR_2021_006.txt
│   │   │   │   ├── ERR_2021_007.txt
│   │   │   │   ├── ERR_2021_008.txt
│   │   │   │   ├── ERR_2021_009.txt
│   │   │   │   ├── ERR_2021_010.txt
│   │   │   │   ├── ERR_2021_011.txt
│   │   │   │   ├── ERR_2021_012.txt
│   │   │   │   ├── ERR_2021_013.txt
│   │   │   │   ├── ERR_2021_014.txt
│   │   │   │   ├── ERR_2021_015.txt
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── ERR_2023_007.txt
│   │   │   │   ├── ERR_2023_008.txt
│   │   │   │   ├── ERR_2023_009.txt
│   │   │   │   ├── ERR_2023_010.txt
│   │   │   │   ├── ERR_2023_011.txt
│   │   │   │   ├── ERR_2023_012.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── ERR_2024_003.txt
│   │   │   │   ├── ERR_2025_001.txt
│   │   │   │   ├── SEC_2021_001.txt
│   │   │   │   ├── SEC_2023_001.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   ├── WARN_2021_002.txt
│   │   │   │   ├── WARN_2021_003.txt
│   │   │   │   ├── WARN_2021_004.txt
│   │   │   │   ├── WARN_2021_005.txt
│   │   │   │   ├── WARN_2021_006.txt
│   │   │   │   ├── WARN_2021_007.txt
│   │   │   │   ├── WARN_2021_008.txt
│   │   │   │   ├── WARN_2021_009.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2022_004.txt
│   │   │   │   ├── WARN_2022_005.txt
│   │   │   │   ├── WARN_2022_006.txt
│   │   │   │   ├── WARN_2022_007.txt
│   │   │   │   ├── WARN_2022_008.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   ├── WARN_2024_003.txt
│   │   │   │   ├── WARN_2024_004.txt
│   │   │   │   ├── WARN_2024_005.txt
│   │   │   │   ├── WARN_2024_007.txt
│   │   │   │   └── WARN_2025_001.txt
│   │   │   ├── util.py
│   │   │   ├── warn_2021_001_cluster_version.py
│   │   │   ├── warn_2021_002_nodes_version.py
│   │   │   ├── warn_2021_003_pod_cidr_cluster_size.py
│   │   │   ├── warn_2021_004_system_workloads_stable.py
│   │   │   ├── warn_2021_005_disk_latency.py
│   │   │   ├── warn_2021_006_node_conntrack_full.py
│   │   │   ├── warn_2021_007_disk_full.py
│   │   │   ├── warn_2021_008_gke_istio_incompatible_versions.py
│   │   │   ├── warn_2021_009_node_deprecated_image_types.py
│   │   │   ├── warn_2022_001_wi_with_regional_cluster.py
│   │   │   ├── warn_2022_002_md_concealment.py
│   │   │   ├── warn_2022_003_firewall_rules_permission.py
│   │   │   ├── warn_2022_004_logging_api_disabled.py
│   │   │   ├── warn_2022_005_nvdia_gpu.py
│   │   │   ├── warn_2022_006_nap_node_image_types.py
│   │   │   ├── warn_2022_007_storage_scope.py
│   │   │   ├── warn_2022_008_dns_lookup_timeout_intra_node_visibility.py
│   │   │   ├── warn_2023_001_containerfilesystem_scope.py
│   │   │   ├── warn_2023_002_metadata_server_timeout.py
│   │   │   ├── warn_2023_003_monitoring_api_disabled.py
│   │   │   ├── warn_2023_004_too_few_pods_per_node.py
│   │   │   ├── warn_2024_001_cluster_nap_limits_prevent_autoscaling.py
│   │   │   ├── warn_2024_002_ksa_exceed.py
│   │   │   ├── warn_2024_003_ingress_svc_notfound.py
│   │   │   ├── warn_2024_004_ingress_backendcrd.py
│   │   │   ├── warn_2024_005_ingress_servicetype.py
│   │   │   ├── warn_2024_007_loadbalancer_ipv6_no_internal_range.py
│   │   │   └── warn_2025_001_loadbalancer_ipv6_no_external_range.py
│   │   ├── iam/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_auto_grant_editor_role_default_sa.py
│   │   │   ├── iam_rules_snapshot_test.py
│   │   │   ├── sec_2021_001_sa_permissions.py
│   │   │   ├── sec_2024_001_unused_sa.py
│   │   │   └── snapshots/
│   │   │       ├── BP_2023_001.txt
│   │   │       ├── SEC_2021_001.txt
│   │   │       └── SEC_2024_001.txt
│   │   ├── interconnect/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_high_availability.py
│   │   │   ├── interconnect_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   └── WARN_2025_001.txt
│   │   │   ├── warn_2023_001_legacy_dataplane.py
│   │   │   ├── warn_2023_002_defunct_attachment.py
│   │   │   ├── warn_2023_003_link_maintenance.py
│   │   │   └── warn_2025_001_check_interconnect_mtu.py
│   │   ├── lb/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2022_001_lbpolicy_for_sessionaffinity.py
│   │   │   ├── bp_2023_001_cloudcdn_for_lb_backend_services.py
│   │   │   ├── bp_2023_002_healthcheck_logging_for_backend_services.py
│   │   │   ├── bp_2024_001_sessionaffinity_for_lb_backendservices.py
│   │   │   ├── bp_2024_002_global_access_for_regional_ilb.py
│   │   │   ├── bp_2025_001_protocol_for_lb_backendservices.py
│   │   │   ├── bp_2025_002_timeout_sec_for_lb_backendservices.py
│   │   │   ├── bp_2025_003_connection_draining_backend_services.py
│   │   │   ├── lb_rules_snapshot_test.py
│   │   │   └── snapshots/
│   │   │       ├── BP_2022_001.txt
│   │   │       ├── BP_2023_001.txt
│   │   │       ├── BP_2023_002.txt
│   │   │       ├── BP_2024_001.txt
│   │   │       ├── BP_2024_002.txt
│   │   │       ├── BP_2025_001.txt
│   │   │       ├── BP_2025_002.txt
│   │   │       └── BP_2025_003.txt
│   │   ├── lint_rule_repository_test.py
│   │   ├── looker/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2025_001_get_all_instances.py
│   │   │   ├── bp_2025_002_lsp_high_intensity_queries_bq.py
│   │   │   ├── bp_2025_003_get_all_lags_operations.py
│   │   │   ├── looker_rules_snapshot_test.py
│   │   │   └── snapshots/
│   │   │       ├── BP_2025_001.txt
│   │   │       ├── BP_2025_002.txt
│   │   │       └── BP_2025_003.txt
│   │   ├── notebooks/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_enable_report_system_health.py
│   │   │   ├── bp_2023_002_instances_upgrade_available.py
│   │   │   ├── bp_2023_003_runtimes_upgrade_available.py
│   │   │   ├── bp_2023_004_runtime_idle_shutdown.py
│   │   │   ├── err_2023_001_instances_health_state.py
│   │   │   ├── err_2023_002_create_notebook_compute_subnetworks_permissions_missing.py
│   │   │   ├── err_2023_003_create_notebook_permissions_missing.py
│   │   │   ├── err_2023_004_runtimes_health_state.py
│   │   │   ├── err_2024_001_executor_explicit_project_permissions.py
│   │   │   ├── notebooks_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2023_002.txt
│   │   │   │   ├── BP_2023_003.txt
│   │   │   │   ├── BP_2023_004.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   └── WARN_2023_003.txt
│   │   │   ├── warn_2023_001_notebooks_oom.py
│   │   │   ├── warn_2023_002_data_disk_utilization.py
│   │   │   └── warn_2023_003_boot_disk_utilization.py
│   │   ├── output/
│   │   │   ├── __init__.py
│   │   │   ├── api_output.py
│   │   │   ├── base_output.py
│   │   │   ├── csv_output.py
│   │   │   ├── json_output.py
│   │   │   └── terminal_output.py
│   │   ├── pubsub/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2024_001_ouma_less_one_day.py
│   │   │   ├── err_2024_001_bq_subscription_table_not_found.py
│   │   │   ├── err_2024_002_vpc_sc_new_subs_create_policy_violated.py
│   │   │   ├── err_2024_003_snapshot_creation_fails.py
│   │   │   ├── err_2025_001_push_service_agent_permission.py
│   │   │   ├── pubsub_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2024_001.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── ERR_2024_003.txt
│   │   │   │   ├── ERR_2025_001.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2023_005.txt
│   │   │   │   ├── WARN_2023_006.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   └── WARN_2024_003.txt
│   │   │   ├── warn_2023_001_detached_subscription_exists.py
│   │   │   ├── warn_2023_002_bq_subscription_has_dlq_topic.py
│   │   │   ├── warn_2023_003_topic_atleastone_sub.py
│   │   │   ├── warn_2023_004_orphaned_subscription_exists.py
│   │   │   ├── warn_2023_005_bq_subscription_permisions.py
│   │   │   ├── warn_2023_006_push_requests_failing.py
│   │   │   ├── warn_2024_001_dead_letter_queues_permissions.py
│   │   │   ├── warn_2024_002_gcs_subscription_permissions.py
│   │   │   └── warn_2024_003_cmek_topic_permissions.py
│   │   ├── snapshot_test_base.py
│   │   ├── tpu/
│   │   │   ├── __init__.py
│   │   │   ├── snapshots/
│   │   │   │   └── WARN_2022_001.txt
│   │   │   ├── tpu_rules_snapshot_test.py
│   │   │   └── warn_2022_001_stockout.py
│   │   ├── vertex/
│   │   │   ├── __init__.py
│   │   │   ├── snapshots/
│   │   │   │   └── WARN_2023_001.txt
│   │   │   ├── vertex_rules_snapshot_test.py
│   │   │   └── warn_2023_001_featurestores_state.py
│   │   └── vpc/
│   │       ├── __init__.py
│   │       ├── bp_2022_001_pga_next_hop.py
│   │       ├── bp_2023_001_public_zone_logging.py
│   │       ├── sec_2023_001_public_zone_dnssec.py
│   │       ├── snapshots/
│   │       │   ├── BP_2022_001.txt
│   │       │   ├── BP_2023_001.txt
│   │       │   ├── SEC_2023_001.txt
│   │       │   ├── WARN_2022_001.txt
│   │       │   ├── WARN_2023_001.txt
│   │       │   ├── WARN_2023_002.txt
│   │       │   └── WARN_2024_001.txt
│   │       ├── vpc_rules_snapshot_test.py
│   │       ├── warn_2022_001_project_level_quota.py
│   │       ├── warn_2023_001_psa_no_export_custom_routes.py
│   │       ├── warn_2023_002_private_zone_attachment.py
│   │       └── warn_2024_001_unused_reserved_ip_addresses.py
│   ├── models.py
│   ├── models_test.py
│   ├── product_list.py
│   ├── queries/
│   │   ├── __init__.py
│   │   ├── apigee.py
│   │   ├── apigee_stub.py
│   │   ├── apigee_test.py
│   │   ├── apis.py
│   │   ├── apis_stub.py
│   │   ├── apis_test.py
│   │   ├── apis_utils.py
│   │   ├── apis_utils_test.py
│   │   ├── artifact_registry.py
│   │   ├── artifact_registry_stub.py
│   │   ├── artifact_registry_test.py
│   │   ├── bigquery.py
│   │   ├── bigquery_stub.py
│   │   ├── bigquery_test.py
│   │   ├── billing.py
│   │   ├── billing_stub.py
│   │   ├── billing_test.py
│   │   ├── cloudasset.py
│   │   ├── cloudasset_stub.py
│   │   ├── cloudasset_test.py
│   │   ├── cloudrun.py
│   │   ├── cloudrun_stub.py
│   │   ├── cloudrun_test.py
│   │   ├── cloudsql.py
│   │   ├── cloudsql_stub.py
│   │   ├── cloudsql_test.py
│   │   ├── composer.py
│   │   ├── composer_stub.py
│   │   ├── composer_test.py
│   │   ├── crm.py
│   │   ├── crm_stub.py
│   │   ├── crm_test.py
│   │   ├── dataflow.py
│   │   ├── dataflow_stub.py
│   │   ├── dataflow_test.py
│   │   ├── datafusion.py
│   │   ├── datafusion_stub.py
│   │   ├── datafusion_test.py
│   │   ├── dataproc.py
│   │   ├── dataproc_stub.py
│   │   ├── dataproc_test.py
│   │   ├── dns.py
│   │   ├── dns_stub.py
│   │   ├── gae.py
│   │   ├── gae_stub.py
│   │   ├── gae_test.py
│   │   ├── gcb.py
│   │   ├── gcb_stub.py
│   │   ├── gcb_test.py
│   │   ├── gce.py
│   │   ├── gce_stub.py
│   │   ├── gce_test.py
│   │   ├── gcf.py
│   │   ├── gcf_stub.py
│   │   ├── gcf_test.py
│   │   ├── gcs.py
│   │   ├── gcs_stub.py
│   │   ├── gcs_test.py
│   │   ├── generic_api/
│   │   │   ├── api_build/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── api.py
│   │   │   │   ├── api_unittest.py
│   │   │   │   ├── generic_api_stub.py
│   │   │   │   ├── get_generic.py
│   │   │   │   └── service_factory.py
│   │   │   └── datafusion/
│   │   │       ├── __init__.py
│   │   │       ├── datafusion.py
│   │   │       ├── datafusion_stub.py
│   │   │       └── datafusion_test.py
│   │   ├── gke.py
│   │   ├── gke_stub.py
│   │   ├── gke_test.py
│   │   ├── iam.py
│   │   ├── iam_stub.py
│   │   ├── iam_test.py
│   │   ├── interconnect.py
│   │   ├── interconnect_stub.py
│   │   ├── interconnect_test.py
│   │   ├── kms.py
│   │   ├── kms_stub.py
│   │   ├── kms_test.py
│   │   ├── kubectl.py
│   │   ├── kubectl_stub.py
│   │   ├── lb.py
│   │   ├── lb_stub.py
│   │   ├── lb_test.py
│   │   ├── logs.py
│   │   ├── logs_helper/
│   │   │   ├── __init__.py
│   │   │   ├── logs_query.py
│   │   │   ├── logs_query_test.py
│   │   │   ├── search_exprs.py
│   │   │   └── search_exprs_test.py
│   │   ├── logs_stub.py
│   │   ├── logs_test.py
│   │   ├── looker.py
│   │   ├── looker_stub.py
│   │   ├── looker_test.py
│   │   ├── monitoring.py
│   │   ├── monitoring_stub.py
│   │   ├── monitoring_test.py
│   │   ├── network.py
│   │   ├── network_stub.py
│   │   ├── network_test.py
│   │   ├── networkmanagement.py
│   │   ├── networkmanagement_stub.py
│   │   ├── notebooks.py
│   │   ├── notebooks_stub.py
│   │   ├── notebooks_test.py
│   │   ├── orgpolicy.py
│   │   ├── orgpolicy_test.py
│   │   ├── osconfig.py
│   │   ├── osconfig_stub.py
│   │   ├── osconfig_test.py
│   │   ├── pubsub.py
│   │   ├── pubsub_stub.py
│   │   ├── pubsub_test.py
│   │   ├── quotas.py
│   │   ├── recommender_stub.py
│   │   ├── vertex.py
│   │   ├── vertex_stub.py
│   │   ├── vertex_test.py
│   │   ├── vpn.py
│   │   ├── vpn_stub.py
│   │   ├── vpn_test.py
│   │   ├── web.py
│   │   ├── web_stub.py
│   │   └── web_test.py
│   ├── rule_classes.py
│   ├── runbook/
│   │   ├── __init__.py
│   │   ├── bigquery/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── failed_query.py
│   │   │   ├── failed_query_test.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── failed_query.txt
│   │   │   └── templates/
│   │   │       ├── generics.jinja
│   │   │       └── permissions.jinja
│   │   ├── cloudrun/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── service_deployment.py
│   │   │   ├── service_deployment_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── service_deployment.txt
│   │   │   └── templates/
│   │   │       └── service_deployment.jinja
│   │   ├── command.py
│   │   ├── command_test.py
│   │   ├── constants.py
│   │   ├── crm/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   └── templates/
│   │   │       └── orgpolicy.jinja
│   │   ├── dataflow/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── failed_streaming_pipeline.py
│   │   │   ├── failed_streaming_pipeline_test.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── job_permissions.py
│   │   │   ├── job_permissions_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── failed_streaming_pipeline.txt
│   │   │   │   └── job_permissions.txt
│   │   │   └── templates/
│   │   │       ├── generics.jinja
│   │   │       └── permissions.jinja
│   │   ├── dataproc/
│   │   │   ├── __init__.py
│   │   │   ├── cluster_creation.py
│   │   │   ├── cluster_creation_test.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── cluster_creation.txt
│   │   │   │   └── spark_job_failures.txt
│   │   │   ├── spark_job_failures.py
│   │   │   ├── spark_job_failures_test.py
│   │   │   └── templates/
│   │   │       ├── dataproc_attributes.jinja
│   │   │       ├── job.jinja
│   │   │       ├── logs_related.jinja
│   │   │       ├── network.jinja
│   │   │       └── permissions.jinja
│   │   ├── exceptions.py
│   │   ├── flags.py
│   │   ├── gce/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── disk_performance_benchmark/
│   │   │   │   ├── a-family.json
│   │   │   │   ├── c-family.json
│   │   │   │   ├── e-family.json
│   │   │   │   ├── f-family.json
│   │   │   │   ├── g-family.json
│   │   │   │   ├── h-family.json
│   │   │   │   ├── limits_per_gb.json
│   │   │   │   ├── m-family.json
│   │   │   │   ├── n-family.json
│   │   │   │   ├── t-family.json
│   │   │   │   └── z-family.json
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── guestos_bootup.py
│   │   │   ├── guestos_bootup_test.py
│   │   │   ├── ops_agent.py
│   │   │   ├── ops_agent_test.py
│   │   │   ├── serial_log_analyzer.py
│   │   │   ├── serial_log_analyzer_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── guestos_bootup.txt
│   │   │   │   ├── ops_agent.txt
│   │   │   │   ├── serial_log_analyzer.txt
│   │   │   │   ├── ssh.txt
│   │   │   │   ├── vm_creation.txt
│   │   │   │   ├── vm_performance.txt
│   │   │   │   └── vm_termination.txt
│   │   │   ├── ssh.py
│   │   │   ├── ssh_test.py
│   │   │   ├── templates/
│   │   │   │   ├── generics.jinja
│   │   │   │   ├── instance_property.jinja
│   │   │   │   ├── mig_autoscaling.jinja
│   │   │   │   ├── permissions.jinja
│   │   │   │   ├── vm_attributes.jinja
│   │   │   │   ├── vm_creation.jinja
│   │   │   │   ├── vm_metadata.jinja
│   │   │   │   ├── vm_ops.jinja
│   │   │   │   ├── vm_performance.jinja
│   │   │   │   ├── vm_serial_log.jinja
│   │   │   │   ├── vm_termination.jinja
│   │   │   │   └── vpc_connectivity.jinja
│   │   │   ├── util/
│   │   │   │   ├── __init__.py
│   │   │   │   └── util_test.py
│   │   │   ├── vm_creation.py
│   │   │   ├── vm_creation_test.py
│   │   │   ├── vm_performance.py
│   │   │   ├── vm_performance_test.py
│   │   │   ├── vm_termination.py
│   │   │   └── vm_termination_test.py
│   │   ├── gcf/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── failed_deployments.py
│   │   │   ├── failed_deployments_test.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── failed_deployments.txt
│   │   │   └── templates/
│   │   │       └── failed_deployments.jinja
│   │   ├── gcp/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   └── templates/
│   │   │       ├── api.jinja
│   │   │       └── resource_attribute.jinja
│   │   ├── gke/
│   │   │   ├── __init__.py
│   │   │   ├── cluster_autoscaler.py
│   │   │   ├── cluster_autoscaler_test.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── gke_ip_masq_standard.py
│   │   │   ├── gke_ip_masq_standard_test.py
│   │   │   ├── image_pull.py
│   │   │   ├── image_pull_test.py
│   │   │   ├── ip_exhaustion.py
│   │   │   ├── ip_exhaustion_test.py
│   │   │   ├── logs.py
│   │   │   ├── logs_test.py
│   │   │   ├── monitoring_configuration.py
│   │   │   ├── monitoring_configuration_test.py
│   │   │   ├── node_auto_repair.py
│   │   │   ├── node_auto_repair_test.py
│   │   │   ├── node_bootstrapping.py
│   │   │   ├── node_bootstrapping_test.py
│   │   │   ├── node_unavailability.py
│   │   │   ├── node_unavailability_test.py
│   │   │   ├── resource_quotas.py
│   │   │   ├── resource_quotas_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── cluster_autoscaler.txt
│   │   │   │   ├── gke_ip_masq_standard.txt
│   │   │   │   ├── image_pull.txt
│   │   │   │   ├── ip_exhaustion.txt
│   │   │   │   ├── logs.txt
│   │   │   │   ├── monitoring_configuration.txt
│   │   │   │   ├── node_auto_repair.txt
│   │   │   │   ├── node_bootstrapping.txt
│   │   │   │   ├── node_unavailability.txt
│   │   │   │   └── resource_quotas.txt
│   │   │   └── templates/
│   │   │       ├── clusterautoscaler.jinja
│   │   │       ├── imagepull.jinja
│   │   │       ├── ipexhaustion.jinja
│   │   │       ├── ipmasq_standard.jinja
│   │   │       ├── logs.jinja
│   │   │       ├── monitoring_configuration.jinja
│   │   │       ├── nodeautorepair.jinja
│   │   │       ├── nodebootstrapping.jinja
│   │   │       ├── nodeunavailability.jinja
│   │   │       └── resourcequotas.jinja
│   │   ├── iam/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   └── templates/
│   │   │       ├── permissions.jinja
│   │   │       └── service_account.jinja
│   │   ├── interconnect/
│   │   │   ├── __init__.py
│   │   │   ├── bgp_down_flap.py
│   │   │   ├── bgp_down_flap_test.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── bgp_down_flap.txt
│   │   │   └── templates/
│   │   │       └── bgp_down_flap.jinja
│   │   ├── lb/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── latency.py
│   │   │   ├── latency_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── latency.txt
│   │   │   │   ├── ssl_certificates.txt
│   │   │   │   └── unhealthy_backends.txt
│   │   │   ├── ssl_certificates.py
│   │   │   ├── ssl_certificates_test.py
│   │   │   ├── templates/
│   │   │   │   ├── latency.jinja
│   │   │   │   ├── ssl_certificates.jinja
│   │   │   │   └── unhealthy_backends.jinja
│   │   │   ├── unhealthy_backends.py
│   │   │   └── unhealthy_backends_test.py
│   │   ├── logs/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   └── templates/
│   │   │       └── logging.jinja
│   │   ├── monitoring/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   └── templates/
│   │   │       └── metrics.jinja
│   │   ├── nat/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── out_of_resources.py
│   │   │   ├── out_of_resources_test.py
│   │   │   ├── public_nat_ip_allocation_failed.py
│   │   │   ├── public_nat_ip_allocation_failed_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── public_nat_ip_allocation_failed.txt
│   │   │   ├── templates/
│   │   │   │   ├── nat_ip_allocation_failed.jinja
│   │   │   │   └── nat_out_of_resources.jinja
│   │   │   ├── utils.py
│   │   │   └── utils_test.py
│   │   ├── op.py
│   │   ├── op_test.py
│   │   ├── output/
│   │   │   ├── __init__.py
│   │   │   ├── api_output.py
│   │   │   ├── base_output.py
│   │   │   └── terminal_output.py
│   │   ├── pubsub/
│   │   │   ├── __init__.py
│   │   │   ├── bigquery_subscription_delivery.py
│   │   │   ├── bigquery_subscription_delivery_test.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── gcs_subscription_delivery.py
│   │   │   ├── gcs_subscription_delivery_test.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── pull_subscription_delivery.py
│   │   │   ├── pull_subscription_delivery_test.py
│   │   │   ├── push_subscription_delivery.py
│   │   │   ├── push_subscription_delivery_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── bigquery_subscription_delivery.txt
│   │   │   │   ├── gcs_subscription_delivery.txt
│   │   │   │   ├── pull_subscription_delivery.txt
│   │   │   │   └── push_subscription_delivery.txt
│   │   │   └── templates/
│   │   │       └── generics.jinja
│   │   ├── report.py
│   │   ├── report_test.py
│   │   ├── runbook_test.py
│   │   ├── snapshot_test_base.py
│   │   ├── util.py
│   │   ├── util_test.py
│   │   ├── vertex/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── workbench_instance_stuck_in_provisioning.txt
│   │   │   ├── templates/
│   │   │   │   ├── workbench_compute.jinja
│   │   │   │   ├── workbench_container.jinja
│   │   │   │   ├── workbench_environment_version.jinja
│   │   │   │   ├── workbench_images.jinja
│   │   │   │   ├── workbench_ip.jinja
│   │   │   │   ├── workbench_jupyter_port.jinja
│   │   │   │   ├── workbench_jupyter_space.jinja
│   │   │   │   ├── workbench_scripts.jinja
│   │   │   │   ├── workbench_state.jinja
│   │   │   │   └── workbench_system_logs.jinja
│   │   │   ├── workbench_instance_stuck_in_provisioning.py
│   │   │   └── workbench_instance_stuck_in_provisioning_test.py
│   │   ├── vpc/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── vm_external_ip_connectivity.txt
│   │   │   ├── templates/
│   │   │   │   ├── rca.jinja
│   │   │   │   └── vm_external_ip_connectivity.jinja
│   │   │   ├── util.py
│   │   │   ├── vm_external_ip_connectivity.py
│   │   │   └── vm_external_ip_connectivity_test.py
│   │   └── vpn/
│   │       ├── __init__.py
│   │       ├── constants.py
│   │       ├── flags.py
│   │       ├── generalized_steps.py
│   │       ├── generalized_steps_test.py
│   │       ├── snapshots/
│   │       │   └── vpn_tunnel_check.txt
│   │       ├── templates/
│   │       │   └── vpn_check.jinja
│   │       ├── vpn_tunnel_check.py
│   │       └── vpn_tunnel_check_test.py
│   ├── search/
│   │   ├── __init__.py
│   │   ├── command.py
│   │   ├── command_test.py
│   │   ├── util.py
│   │   └── util_test.py
│   ├── types.py
│   ├── types_test.py
│   ├── utils.py
│   └── utils_test.py
├── pyinstaller/
│   ├── hook-gcpdiag.lint.py
│   ├── hook-gcpdiag.queries.py
│   ├── hook-gcpdiag.runbook.py
│   └── hook-googleapiclient.model.py
├── pyinstaller.spec
├── requirements.in
├── requirements.txt
├── test-data/
│   ├── Makefile.inc
│   ├── README.md
│   ├── apigee1/
│   │   ├── Makefile
│   │   ├── apigee1.tf
│   │   ├── json-dumps/
│   │   │   ├── apigee-envgroups-attachments-empty.json
│   │   │   ├── apigee-envgroups-gcpdiag-demo-envgroup-1-attachments.json
│   │   │   ├── apigee-envgroups.json
│   │   │   ├── apigee-instances-gcpdiag-apigee1-inst1-aaaa-attachments.json
│   │   │   ├── apigee-instances.json
│   │   │   ├── apigee-key.json
│   │   │   ├── apigee-organization.json
│   │   │   ├── apigee-organizations.json
│   │   │   ├── compute-effective-firewalls-apigee-network.json
│   │   │   ├── compute-migs-us-central1.json
│   │   │   ├── compute-network-apigee-network.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-apigee-subnetwork.json
│   │   │   ├── compute-templates.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── kms-key-iam-policy.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── bigquery1/
│   │   ├── Makefile
│   │   ├── job.tf
│   │   ├── json-dumps/
│   │   │   ├── ancestor.json
│   │   │   ├── bigquery-failed-job.json
│   │   │   ├── iam-policy.json
│   │   │   ├── job_get_invalid-region_id.json
│   │   │   ├── job_get_us_IS.json
│   │   │   ├── job_get_us_csv.json
│   │   │   ├── job_get_us_duplicate.json
│   │   │   ├── job_get_us_error.json
│   │   │   ├── job_get_us_errors.json
│   │   │   ├── job_get_us_job.json
│   │   │   ├── job_get_us_job1.json
│   │   │   ├── job_get_us_job2.json
│   │   │   ├── job_get_us_notfound.json
│   │   │   ├── job_get_us_running.json
│   │   │   ├── job_get_us_success.json
│   │   │   ├── job_get_us_unknown.json
│   │   │   ├── job_results_us_IS_.json
│   │   │   ├── job_results_us_mockresult1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── billing1/
│   │   ├── Makefile
│   │   └── json-dumps/
│   │       ├── all_billing_account_projects.json
│   │       ├── all_billing_accounts.json
│   │       ├── billing_account.json
│   │       ├── cost_insights.json
│   │       ├── project.json
│   │       ├── project_billing_info.json
│   │       ├── projects.json
│   │       └── services.json
│   ├── cloudasset1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── project.json
│   │   │   ├── search-all-resources-us-central1.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variable.tf
│   ├── cloudrun1/
│   │   ├── Makefile
│   │   ├── cloudrun1.tf
│   │   ├── json-dumps/
│   │   │   ├── cloudrun_services.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── locations.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── cloudrun2/
│   │   ├── Makefile
│   │   ├── artifact_registry.tf
│   │   ├── build_configs/
│   │   │   └── deploy_run_with_bad_container/
│   │   │       ├── Dockerfile
│   │   │       └── cloudbuild.yaml
│   │   ├── cloud_run.tf
│   │   ├── json-dumps/
│   │   │   ├── cloudrun_services.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── locations.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── cloudsql1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── cloudsql-instances.json
│   │   │   ├── iam-policy.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── sql1.tf
│   │   └── variables.tf
│   ├── composer1/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── composer-env1.tf
│   │   ├── composer-env2.tf
│   │   ├── json-dumps/
│   │   │   ├── composer-environments-us-central1.json
│   │   │   ├── compute-regions.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-account-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── provider.tf
│   │   └── variables.tf
│   ├── dataflow1/
│   │   ├── Makefile
│   │   ├── bucket.tf
│   │   ├── job.tf
│   │   ├── json-dumps/
│   │   │   ├── dataflow-jobs-aggregated.json
│   │   │   ├── dataflow-jobs-us-central1-2024-06-19_09_43_07-14927685200167458422.json
│   │   │   ├── dataflow-jobs-us-central1-streaming.json
│   │   │   ├── dataflow-jobs-us-central1.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── log-exclusions.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── streaming_job.tf
│   │   └── variables.tf
│   ├── datafusion1/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── datafusion.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-subnetworks-us-central1.json
│   │   │   ├── datafusion-default-application-pipeline1-preferences.json
│   │   │   ├── datafusion-default-applications.json
│   │   │   ├── datafusion-default-namespace-preferences.json
│   │   │   ├── datafusion-default-user-compute-profile.json
│   │   │   ├── datafusion-instances.json
│   │   │   ├── datafusion-instances1.json
│   │   │   ├── datafusion-system-compute-profile.json
│   │   │   ├── datafusion-system-preferences.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-account-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── namespaces.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── dataproc1/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── dataproc_cluster.tf
│   │   ├── job.tf
│   │   ├── json-dumps/
│   │   │   ├── autoscaling-policy.json
│   │   │   ├── compute-instances-us-central1-a.json
│   │   │   ├── compute-instances-us-central1-b.json
│   │   │   ├── compute-instances-us-central1-c.json
│   │   │   ├── compute-instances-us-central1-f.json
│   │   │   ├── compute-network-test-bad-network.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── connectivity-test.json
│   │   │   ├── dataproc-clusters-us-central1.json
│   │   │   ├── dataproc-job-failed.json
│   │   │   ├── dataproc-job-success.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── network.tf
│   │   ├── project.tf
│   │   ├── provider.tf
│   │   └── variables.tf
│   ├── dataproc2/
│   │   └── json-dumps/
│   │       ├── logging-entries-1.json
│   │       ├── project.json
│   │       └── services.json
│   ├── dataproc3/
│   │   └── json-dumps/
│   │       ├── logging-entries-1.json
│   │       ├── project.json
│   │       └── services.json
│   ├── fw-policy/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── firewall.tf
│   │   ├── fw-policy.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-migs-europe-west2-b.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-zones.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-custom.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-custom.arEnforceImmutableTags.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── org-constraints.json
│   │   │   ├── org-policies.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── org-policy.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gaes1/
│   │   ├── Makefile
│   │   ├── gaes1-bucket-object.tf
│   │   ├── gaes1-bucket.tf
│   │   ├── gaes1.tf
│   │   ├── json-dumps/
│   │   │   ├── appengine_services.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   ├── services.json
│   │   │   └── versions.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gcb1/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── artifact_registry.tf
│   │   ├── buckets.tf
│   │   ├── build_configs/
│   │   │   ├── .gitignore
│   │   │   ├── cloudbuild1.yaml.tpl
│   │   │   ├── cloudbuild2.yaml.tpl
│   │   │   ├── cloudbuild3.yaml.tpl
│   │   │   └── cloudbuild4.yaml.tpl
│   │   ├── build_configs.tf
│   │   ├── json-dumps/
│   │   │   ├── artifact-registry-policy.json
│   │   │   ├── artifact-registry-project-settings.json
│   │   │   ├── bucket-gcpdiag-gcb1-bucket1-aaaa.json
│   │   │   ├── cloudbuild-empty.json
│   │   │   ├── cloudbuild-triggers.json
│   │   │   ├── cloudbuild-us-central1.json
│   │   │   ├── cloudbuild.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── service_accounts.tf
│   │   ├── source_repository.tf
│   │   ├── trigger.tf
│   │   └── variables.tf
│   ├── gce-image-license/
│   │   ├── Makefile
│   │   └── json-dumps/
│   │       ├── centos-cloud-licenses.json
│   │       ├── cos-cloud-licenses.json
│   │       ├── debian-cloud-licenses.json
│   │       ├── fedora-cloud-licenses.json
│   │       ├── fedora-coreos-cloud-licenses.json
│   │       ├── opensuse-cloud-licenses.json
│   │       ├── rhel-cloud-licenses.json
│   │       ├── rhel-sap-cloud-licenses.json
│   │       ├── rocky-linux-cloud-licenses.json
│   │       ├── suse-cloud-licenses.json
│   │       ├── suse-sap-cloud-licenses.json
│   │       ├── ubuntu-os-cloud-licenses.json
│   │       ├── ubuntu-os-pro-cloud-licenses.json
│   │       ├── windows-cloud-licenses.json
│   │       └── windows-sql-cloud-licenses.json
│   ├── gce1/
│   │   ├── Makefile
│   │   ├── gce1.tf
│   │   ├── gce2.tf
│   │   ├── gke.tf
│   │   ├── healthchecks.tf
│   │   ├── ig1.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west1-b.json
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-europe-west4-a.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-igs-aggregated.json
│   │   │   ├── compute-igs-europe-west1-b.json
│   │   │   ├── compute-igs-europe-west2-b.json
│   │   │   ├── compute-igs-europe-west4-a.json
│   │   │   ├── compute-igs-europe-west4-b.json
│   │   │   ├── compute-instances-aggregated.json
│   │   │   ├── compute-instances-europe-west1-b-2.json
│   │   │   ├── compute-instances-europe-west1-b.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-europe-west4-a-2.json
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-instances-europe-west4-b.json
│   │   │   ├── compute-licenses.json
│   │   │   ├── compute-migs-aggregated.json
│   │   │   ├── compute-migs-europe-west1-b.json
│   │   │   ├── compute-migs-europe-west2-b.json
│   │   │   ├── compute-migs-europe-west4-a.json
│   │   │   ├── compute-negs-empty.json
│   │   │   ├── compute-negs-europe-west1-b.json
│   │   │   ├── compute-negs-europe-west4-b.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-routes.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-serial-port-output-1010101010.json
│   │   │   ├── compute-serial-port-output-1010101011.json
│   │   │   ├── compute-subnetwork-policy.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-templates.json
│   │   │   ├── compute-zones.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── mig.tf
│   │   ├── neg1.tf
│   │   ├── project.tf
│   │   ├── terraform
│   │   └── variables.tf
│   ├── gce2/
│   │   ├── Makefile
│   │   ├── gce_faulty_ssh.tf
│   │   ├── gce_valid_ssh.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west1-b.json
│   │   │   ├── compute-disks-europe-west2-a.json
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-europe-west4-a.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-igs-europe-west1-b.json
│   │   │   ├── compute-igs-europe-west2-b.json
│   │   │   ├── compute-igs-europe-west4-a.json
│   │   │   ├── compute-instances-europe-west1-b-2.json
│   │   │   ├── compute-instances-europe-west1-b.json
│   │   │   ├── compute-instances-europe-west2-a.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-europe-west4-a-2.json
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-licenses.json
│   │   │   ├── compute-migs-europe-west1-b.json
│   │   │   ├── compute-migs-europe-west2-b.json
│   │   │   ├── compute-migs-europe-west4-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-routes.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-serial-port-output-1010101010.json
│   │   │   ├── compute-serial-port-output-1010101011.json
│   │   │   ├── compute-serial-port-output-faulty-linux-ssh.json
│   │   │   ├── compute-serial-port-output-faulty-windows-ssh.json
│   │   │   ├── compute-serial-port-output-valid-linux-ssh.json
│   │   │   ├── compute-serial-port-output-valid-windows-ssh.json
│   │   │   ├── compute-subnetwork-policy.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-templates.json
│   │   │   ├── compute-zones.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gce3/
│   │   ├── Makefile
│   │   ├── faulty-opsagent.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-europe-west2-a.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-zones.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-custom.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── orgpolicy.tf
│   │   ├── project.tf
│   │   ├── terraform
│   │   ├── variables.tf
│   │   └── working-opsagent.tf
│   ├── gce4/
│   │   ├── Makefile
│   │   ├── gce_faulty_ssh.tf
│   │   ├── gce_valid_ssh.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west1-b.json
│   │   │   ├── compute-disks-europe-west2-a.json
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-europe-west4-a.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-igs-europe-west1-b.json
│   │   │   ├── compute-igs-europe-west2-b.json
│   │   │   ├── compute-igs-europe-west4-a.json
│   │   │   ├── compute-instances-europe-west1-b-2.json
│   │   │   ├── compute-instances-europe-west1-b.json
│   │   │   ├── compute-instances-europe-west2-a.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-europe-west4-a-2.json
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-licenses.json
│   │   │   ├── compute-migs-europe-west1-b.json
│   │   │   ├── compute-migs-europe-west2-b.json
│   │   │   ├── compute-migs-europe-west4-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-routes.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-serial-port-output-1010101010.json
│   │   │   ├── compute-serial-port-output-1010101011.json
│   │   │   ├── compute-serial-port-output-faulty-linux-ssh.json
│   │   │   ├── compute-serial-port-output-faulty-windows-ssh.json
│   │   │   ├── compute-serial-port-output-valid-linux-ssh.json
│   │   │   ├── compute-serial-port-output-valid-windows-ssh.json
│   │   │   ├── compute-subnetwork-policy.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-templates.json
│   │   │   ├── compute-zones.json
│   │   │   ├── global-operations.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gce5/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-us-central1-c.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-aggregated.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-us-central1-c.json
│   │   │   ├── compute-migs-aggregated.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-zones.json
│   │   │   ├── global-operations.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── main.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gce6/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-us-central1-c.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-aggregated.json
│   │   │   ├── compute-instances-us-central1-c.json
│   │   │   ├── compute-migs-aggregated.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── global-operations.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── main.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gcf1/
│   │   ├── .gitignore
│   │   ├── Makefile
│   │   ├── gcf1.tf
│   │   ├── json-dumps/
│   │   │   ├── cloudfunctions-empty.json
│   │   │   ├── cloudfunctions-us-central1.json
│   │   │   ├── cloudfunctions.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── sample-code/
│   │   │   ├── main.py
│   │   │   └── requirements.txt
│   │   └── variables.tf
│   ├── gcf2/
│   │   ├── .gitignore
│   │   ├── Makefile
│   │   ├── gcf2.tf
│   │   ├── json-dumps/
│   │   │   ├── cloudfunctions-empty.json
│   │   │   ├── cloudfunctions-europe-west2.json
│   │   │   ├── cloudfunctions.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── sourcecode/
│   │   │   ├── memalloc.py
│   │   │   └── requirements.txt
│   │   └── variables.tf
│   ├── gcs1/
│   │   ├── Makefile
│   │   ├── gcs1.tf
│   │   ├── json-dumps/
│   │   │   ├── bucket-gcpdiag-gcs1bucket2-aaaa.json
│   │   │   ├── bucket-roles.json
│   │   │   ├── project.json
│   │   │   ├── services.json
│   │   │   └── storage.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gke1/
│   │   ├── Makefile
│   │   ├── firewall.tf.old
│   │   ├── gke1.tf
│   │   ├── gke2.tf
│   │   ├── gke3.tf
│   │   ├── gke4.tf
│   │   ├── gke5.tf
│   │   ├── gke6.tf
│   │   ├── json-dumps/
│   │   │   ├── backendServices.json
│   │   │   ├── compute-addresses.json
│   │   │   ├── compute-disks-europe-west1-b.json
│   │   │   ├── compute-disks-europe-west4-a.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-igs-empty.json
│   │   │   ├── compute-instances-aggregated.json
│   │   │   ├── compute-instances-empty.json
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-interconnect1.json
│   │   │   ├── compute-interconnect2.json
│   │   │   ├── compute-interconnect3.json
│   │   │   ├── compute-interconnect4.json
│   │   │   ├── compute-interconnects.json
│   │   │   ├── compute-migs-aggregated.json
│   │   │   ├── compute-migs-empty.json
│   │   │   ├── compute-migs-europe-west4-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-routers-europe-west4.json
│   │   │   ├── compute-routers-us-east4.json
│   │   │   ├── compute-routers-us-west2.json
│   │   │   ├── compute-subnetwork-policy.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-templates.json
│   │   │   ├── compute-zones.json
│   │   │   ├── container-clusters.json
│   │   │   ├── container-kubectl.json
│   │   │   ├── container-server-config-europe-west4-a.json
│   │   │   ├── container-server-config-europe-west4.json
│   │   │   ├── forwardingRules.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-custom.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-account-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── instances.json
│   │   │   ├── interconnect-attachment1.json
│   │   │   ├── interconnect-attachments.json
│   │   │   ├── kms-key-destroyed.json
│   │   │   ├── kms-key-disabled.json
│   │   │   ├── kms-key-enabled.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-custom.arEnforceImmutableTags.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── org-constraints.json
│   │   │   ├── org-policies.json
│   │   │   ├── project.json
│   │   │   ├── services.json
│   │   │   ├── subscriptions.json
│   │   │   └── topics.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gke2/
│   │   ├── Makefile
│   │   └── json-dumps/
│   │       ├── compute-disks-empty.json
│   │       ├── compute-disks-europe-west10-a.json
│   │       ├── compute-disks-europe-west2-b.json
│   │       ├── compute-effective-firewalls-default.json
│   │       ├── compute-igs-empty.json
│   │       ├── compute-igs-europe-west2-b.json
│   │       ├── compute-instances-empty.json
│   │       ├── compute-instances-europe-west10-a.json
│   │       ├── compute-instances-europe-west2-b.json
│   │       ├── compute-interconnects.json
│   │       ├── compute-migs-empty.json
│   │       ├── compute-migs-europe-west10-a.json
│   │       ├── compute-migs-europe-west2-b.json
│   │       ├── compute-network-default.json
│   │       ├── compute-project.json
│   │       ├── compute-regions.json
│   │       ├── compute-routers-europe-west4.json
│   │       ├── compute-subnetwork-policy.json
│   │       ├── compute-subnetworks-aggregated.json
│   │       ├── compute-templates.json
│   │       ├── compute-zones.json
│   │       ├── container-clusters.json
│   │       ├── container-server-config-europe-west10-a.json
│   │       ├── container-server-config-europe-west10.json
│   │       ├── iam-policy.json
│   │       ├── iam-roles-custom.json
│   │       ├── iam-roles-get.json
│   │       ├── iam-service-account-policy.json
│   │       ├── iam-service-accounts.json
│   │       ├── logging-entries-1.json
│   │       ├── monitoring-query.json
│   │       ├── project.json
│   │       └── services.json
│   ├── gke3/
│   │   ├── Makefile
│   │   ├── cluster-1.tf
│   │   ├── json-dumps/
│   │   │   ├── container-cluster-cluster-1.json
│   │   │   ├── container-clusters.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── logging-entries-2.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── network.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gke4/
│   │   ├── Makefile
│   │   ├── cluster.tf
│   │   ├── json-dumps/
│   │   │   ├── container-clusters.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── iam1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── org-constraints.json
│   │   │   ├── org-policies.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── interconnect1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-interconnects.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-routers-routerStatus-dummy-router1.json
│   │   │   ├── compute-routers-routerStatus-dummy-router11.json
│   │   │   ├── compute-routers-routerStatus-dummy-router2.json
│   │   │   ├── compute-routers-routerStatus-dummy-router3.json
│   │   │   ├── compute-routers-us-central1.json
│   │   │   ├── compute-routers-us-east4.json
│   │   │   ├── compute-routers-us-west2.json
│   │   │   ├── interconnect-attachments.json
│   │   │   ├── logging-entries-1.json
│   │   │   └── project.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── lb1/
│   │   ├── Makefile
│   │   ├── http-lb-mig.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-aggregated-backendServices.json
│   │   │   ├── compute-aggregated-forwardingRules.json
│   │   │   ├── compute-backendServices.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── healthChecks.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── lb2/
│   │   ├── Makefile
│   │   ├── http-lb-mig.tf
│   │   ├── json-dumps/
│   │   │   ├── backendService-web-backend-service-get-health-instanceGroups-lb-backend-example-us-east1-b.json
│   │   │   ├── compute-aggregated-backendServices.json
│   │   │   ├── compute-aggregated-forwardingRules.json
│   │   │   ├── compute-backendServices-europe-west4.json
│   │   │   ├── compute-igs-aggregated.json
│   │   │   ├── compute-igs-us-east1-b.json
│   │   │   ├── compute-instances-europe-west4-b.json
│   │   │   ├── compute-instances-us-east1-b.json
│   │   │   ├── compute-negs-europe-west4-b.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-serial-port-output-neg-vm.json
│   │   │   ├── compute-serial-port-output-vm-pn3l.json
│   │   │   ├── compute-zones.json
│   │   │   ├── healthChecks.json
│   │   │   ├── lb-insights-europe-west4.json
│   │   │   ├── lb-insights-global.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   ├── regionBackendService-backend-service-2-europe-west4-get-health-networkEndpointGroups-neg1-europe-west4-b.json
│   │   │   ├── regionHealthChecks-europe-west4.json
│   │   │   └── services.json
│   │   ├── passthrough-lb-neg.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── lb3/
│   │   ├── Makefile
│   │   ├── certs.tf
│   │   ├── https-lb.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-aggregated-backendServices.json
│   │   │   ├── compute-aggregated-forwardingRules.json
│   │   │   ├── compute-aggregated-targetHttpsProxies.json
│   │   │   ├── compute-sslCertificates.json
│   │   │   ├── compute-targetHttpsProxies.json
│   │   │   ├── compute-targetSslProxies.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── ssl-lb.tf
│   │   ├── update_ip.py
│   │   └── variables.tf
│   ├── looker1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── logging-entries-1.json
│   │   │   ├── looker-instances.json
│   │   │   ├── looker.json
│   │   │   ├── operation.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── nat1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-instances-us-central1-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-nat-vpc-network.json
│   │   │   ├── compute-network-nat_vpc_network.json
│   │   │   ├── compute-routers-europe-west4.json
│   │   │   ├── compute-routers-natIpInfo-public-nat-cloud-router.json
│   │   │   ├── compute-routers-natMappingInfo-public-nat-cloud-router.json
│   │   │   ├── compute-routers-natMappingInfo-public_nat_cloud_router.json
│   │   │   ├── compute-routers-routerStatus-public-nat-cloud-router.json
│   │   │   ├── compute-routers-routerStatus-public_nat_cloud_router.json
│   │   │   ├── compute-routers-us-central1.json
│   │   │   ├── monitoring-query-nat-allocation-failed.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── public-cloud-nat.tf
│   │   └── variables.tf
│   ├── notebooks1/
│   │   ├── Makefile
│   │   ├── instances1.tf
│   │   ├── json-dumps/
│   │   │   ├── health-state.json
│   │   │   ├── instances.json
│   │   │   ├── is-upgradeable.json
│   │   │   ├── project.json
│   │   │   ├── runtimes.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── runtimes1.tf
│   │   └── variables.tf
│   ├── notebooks2/
│   │   ├── Makefile
│   │   ├── instance_ok.tf
│   │   ├── instance_provisioning_stuck.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-instances-disks-us-west1-a.json
│   │   │   ├── compute-instances-us-west1-a.json
│   │   │   ├── compute-serial-port-output-notebooks2instance-ok.json
│   │   │   ├── compute-serial-port-output-notebooks2instance-provisioning-stuck.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── notebooks2instance-ok-check-upgradability.json
│   │   │   ├── notebooks2instance-provisioning-stuck-check-upgradability.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── project.json
│   │   │   ├── services.json
│   │   │   └── workbench-instances.json
│   │   ├── network.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── osconfig1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── inventories.json
│   │   │   ├── inventory.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── pubsub1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── bq-subscription.json
│   │   │   ├── bucket-roles.json
│   │   │   ├── gcs-subscription.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   ├── pull-subscription.json
│   │   │   ├── services.json
│   │   │   ├── subscriptions-iam.json
│   │   │   ├── subscriptions.json
│   │   │   ├── topic-iam.json
│   │   │   └── topics.json
│   │   ├── project.tf
│   │   ├── pubsub1.tf
│   │   └── variables.tf
│   ├── tpu1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── vertex1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── featurestores.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── variables.tf
│   │   └── vertex1.tf
│   ├── vpc1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-addresses.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── vpc2/
│   │   ├── Makefile
│   │   ├── external_connectivity_private_instance_faulty.tf
│   │   ├── external_connectivity_private_instance_valid.tf
│   │   ├── external_connectivity_public_instance_faulty.tf
│   │   ├── external_connectivity_public_instance_valid.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-us-central1-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-routes.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-zones.json
│   │   │   ├── connectivity-test.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── monitoring-query-instance-dropped-received-packets-count.json
│   │   │   ├── monitoring-query-nat-allocation-failed.json
│   │   │   ├── monitoring-query-nat-dropped-received-packets-count.json
│   │   │   ├── monitoring-query-nat-dropped-sent-packets-count.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── network.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── vpn/
│   │   └── json-dumps/
│   │       ├── compute-project.json
│   │       ├── logging-entries-1.json
│   │       ├── monitoring-query.json
│   │       ├── project.json
│   │       ├── vpn-tunnel-1.json
│   │       └── vpn-tunnel-down.json
│   └── web/
│       ├── Makefile
│       └── static/
│           ├── cloud-google-com-data-fusion-docs-concepts-configure-clusters
│           ├── cloud-google-com-data-fusion-docs-support-version-support-policy
│           └── cloud-google-com-kubernetes-engine-docs-release-schedule
└── website/
    ├── api_render.py
    ├── archetypes/
    │   └── default.md
    ├── assets/
    │   ├── pdoc_templates/
    │   │   ├── frame.html.jinja2
    │   │   └── module.html.jinja2
    │   └── scss/
    │       └── _variables_project.scss
    ├── config.toml
    ├── content/
    │   └── en/
    │       ├── _index.html
    │       ├── docs/
    │       │   ├── _index.md
    │       │   ├── authentication.md
    │       │   ├── development/
    │       │   │   ├── _index.md
    │       │   │   ├── architecture.md
    │       │   │   └── environment.md
    │       │   ├── running.md
    │       │   └── usage.md
    │       ├── privacy.md
    │       ├── rules/
    │       │   ├── _index.md
    │       │   ├── apigee/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   └── 2023_006.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   └── 2022_002.md
    │       │   │   └── _index.md
    │       │   ├── asm/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2025_001.md
    │       │   │   │   └── 2025_002.md
    │       │   │   └── _index.md
    │       │   ├── bigquery/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   ├── 2023_008.md
    │       │   │   │   ├── 2023_009.md
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   ├── 2024_004.md
    │       │   │   │   ├── 2024_005.md
    │       │   │   │   └── 2024_006.md
    │       │   │   └── _index.md
    │       │   ├── billing/
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   └── 2022_003.md
    │       │   │   └── _index.md
    │       │   ├── cloudrun/
    │       │   │   ├── ERR/
    │       │   │   │   └── 2022_001.md
    │       │   │   └── _index.md
    │       │   ├── cloudsql/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2023_003.md
    │       │   │   ├── BP_EXT/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   └── 2023_004.md
    │       │   │   ├── ERR/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── SEC/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2023_003.md
    │       │   │   └── _index.md
    │       │   ├── composer/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2023_003.md
    │       │   │   ├── BP_EXT/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   └── 2023_002.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   ├── 2023_008.md
    │       │   │   │   ├── 2023_009.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   └── 2024_003.md
    │       │   │   └── _index.md
    │       │   ├── dataflow/
    │       │   │   ├── BP/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   ├── 2023_008.md
    │       │   │   │   ├── 2023_009.md
    │       │   │   │   ├── 2023_010.md
    │       │   │   │   ├── 2023_011.md
    │       │   │   │   ├── 2023_012.md
    │       │   │   │   ├── 2023_013.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   ├── 2024_004.md
    │       │   │   │   └── 2024_005.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   └── _index.md
    │       │   ├── datafusion/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2022_005.md
    │       │   │   │   ├── 2022_006.md
    │       │   │   │   ├── 2022_007.md
    │       │   │   │   ├── 2022_008.md
    │       │   │   │   ├── 2022_009.md
    │       │   │   │   ├── 2022_010.md
    │       │   │   │   ├── 2022_011.md
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   ├── 2024_004.md
    │       │   │   │   └── 2024_005.md
    │       │   │   └── _index.md
    │       │   ├── dataproc/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_098.md
    │       │   │   │   └── 2022_099.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   └── 2023_008.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   └── _index.md
    │       │   ├── gae/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2025_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   └── 2022_002.md
    │       │   │   └── _index.md
    │       │   ├── gcb/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   └── 2022_004.md
    │       │   │   └── _index.md
    │       │   ├── gce/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   ├── BP_EXT/
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2021_002.md
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2021_004.md
    │       │   │   │   ├── 2021_005.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   └── 2024_004.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2021_002.md
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2021_004.md
    │       │   │   │   ├── 2021_005.md
    │       │   │   │   ├── 2021_006.md
    │       │   │   │   ├── 2021_007.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2022_005.md
    │       │   │   │   ├── 2022_006.md
    │       │   │   │   ├── 2022_007.md
    │       │   │   │   ├── 2022_008.md
    │       │   │   │   ├── 2022_009.md
    │       │   │   │   ├── 2022_010.md
    │       │   │   │   ├── 2022_011.md
    │       │   │   │   ├── 2022_012.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   └── 2023_002.md
    │       │   │   └── _index.md
    │       │   ├── gcf/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   └── 2022_003.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   └── 2021_002.md
    │       │   │   └── _index.md
    │       │   ├── gcs/
    │       │   │   ├── BP/
    │       │   │   │   └── 2022_001.md
    │       │   │   └── _index.md
    │       │   ├── gke/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   └── 2025_001.md
    │       │   │   ├── BP_EXT/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   └── 2023_002.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2021_002.md
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2021_004.md
    │       │   │   │   ├── 2021_005.md
    │       │   │   │   ├── 2021_006.md
    │       │   │   │   ├── 2021_007.md
    │       │   │   │   ├── 2021_008.md
    │       │   │   │   ├── 2021_009.md
    │       │   │   │   ├── 2021_010.md
    │       │   │   │   ├── 2021_011.md
    │       │   │   │   ├── 2021_012.md
    │       │   │   │   ├── 2021_013.md
    │       │   │   │   ├── 2021_014.md
    │       │   │   │   ├── 2021_015.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   ├── 2023_008.md
    │       │   │   │   ├── 2023_009.md
    │       │   │   │   ├── 2023_010.md
    │       │   │   │   ├── 2023_011.md
    │       │   │   │   ├── 2023_012.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   └── 2025_001.md
    │       │   │   ├── SEC/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2021_002.md
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2021_004.md
    │       │   │   │   ├── 2021_005.md
    │       │   │   │   ├── 2021_006.md
    │       │   │   │   ├── 2021_007.md
    │       │   │   │   ├── 2021_008.md
    │       │   │   │   ├── 2021_009.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2022_005.md
    │       │   │   │   ├── 2022_006.md
    │       │   │   │   ├── 2022_007.md
    │       │   │   │   ├── 2022_008.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   ├── 2024_004.md
    │       │   │   │   ├── 2024_005.md
    │       │   │   │   ├── 2024_007.md
    │       │   │   │   └── 2025_001.md
    │       │   │   └── _index.md
    │       │   ├── iam/
    │       │   │   ├── BP/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── SEC/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   └── 2024_001.md
    │       │   │   └── _index.md
    │       │   ├── interconnect/
    │       │   │   ├── BP/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   └── 2025_001.md
    │       │   │   └── _index.md
    │       │   ├── lb/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2025_001.md
    │       │   │   │   ├── 2025_002.md
    │       │   │   │   └── 2025_003.md
    │       │   │   └── _index.md
    │       │   ├── looker/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2025_001.md
    │       │   │   │   ├── 2025_002.md
    │       │   │   │   └── 2025_003.md
    │       │   │   └── _index.md
    │       │   ├── notebooks/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   └── 2023_004.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2023_003.md
    │       │   │   └── _index.md
    │       │   ├── pubsub/
    │       │   │   ├── BP/
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   └── 2025_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   └── 2024_003.md
    │       │   │   └── _index.md
    │       │   ├── tpu/
    │       │   │   ├── WARN/
    │       │   │   │   └── 2022_001.md
    │       │   │   └── _index.md
    │       │   ├── vertex/
    │       │   │   ├── WARN/
    │       │   │   │   └── 2023_001.md
    │       │   │   └── _index.md
    │       │   └── vpc/
    │       │       ├── BP/
    │       │       │   ├── 2022_001.md
    │       │       │   └── 2023_001.md
    │       │       ├── SEC/
    │       │       │   └── 2023_001.md
    │       │       ├── WARN/
    │       │       │   ├── 2022_001.md
    │       │       │   ├── 2023_001.md
    │       │       │   ├── 2023_002.md
    │       │       │   └── 2024_001.md
    │       │       └── _index.md
    │       ├── runbook/
    │       │   ├── _index.md
    │       │   ├── diagnostic-trees/
    │       │   │   ├── _index.md
    │       │   │   ├── bigquery/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── failed-query.md
    │       │   │   ├── cloudrun/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── service-deployment.md
    │       │   │   ├── dataflow/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── failed-streaming-pipeline.md
    │       │   │   │   └── job-permissions.md
    │       │   │   ├── dataproc/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── cluster-creation.md
    │       │   │   │   └── spark-job-failures.md
    │       │   │   ├── gce/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── guestos-bootup.md
    │       │   │   │   ├── ops-agent.md
    │       │   │   │   ├── serial-log-analyzer.md
    │       │   │   │   ├── ssh.md
    │       │   │   │   ├── vm-creation.md
    │       │   │   │   ├── vm-performance.md
    │       │   │   │   └── vm-termination.md
    │       │   │   ├── gcf/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── failed-deployments.md
    │       │   │   ├── gke/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── cluster-autoscaler.md
    │       │   │   │   ├── gke-ip-masq-standard.md
    │       │   │   │   ├── image-pull.md
    │       │   │   │   ├── ip-exhaustion.md
    │       │   │   │   ├── logs.md
    │       │   │   │   ├── monitoring-configuration.md
    │       │   │   │   ├── node-auto-repair.md
    │       │   │   │   ├── node-bootstrapping.md
    │       │   │   │   ├── node-unavailability.md
    │       │   │   │   └── resource-quotas.md
    │       │   │   ├── interconnect/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── bgp-down-flap.md
    │       │   │   ├── lb/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── latency.md
    │       │   │   │   ├── ssl-certificates.md
    │       │   │   │   └── unhealthy-backends.md
    │       │   │   ├── nat/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── public-nat-ip-allocation-failed.md
    │       │   │   ├── pubsub/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── bigquery-subscription-delivery.md
    │       │   │   │   ├── gcs-subscription-delivery.md
    │       │   │   │   ├── pull-subscription-delivery.md
    │       │   │   │   └── push-subscription-delivery.md
    │       │   │   ├── vertex/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── workbench-instance-stuck-in-provisioning.md
    │       │   │   ├── vpc/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── vm-external-ip-connectivity.md
    │       │   │   └── vpn/
    │       │   │       ├── _index.md
    │       │   │       └── vpn-tunnel-check.md
    │       │   └── steps/
    │       │       ├── _index.md
    │       │       ├── bigquery/
    │       │       │   ├── _index.md
    │       │       │   ├── big-query-end.md
    │       │       │   ├── big-query-error-identification.md
    │       │       │   ├── big-query-failed-query-start.md
    │       │       │   ├── big-query-job-exists.md
    │       │       │   ├── check-bq-job-has-error.md
    │       │       │   ├── check-bq-job-has-failed.md
    │       │       │   ├── check-permissions.md
    │       │       │   ├── confirm-bq-job-is-done.md
    │       │       │   └── run-permission-checks.md
    │       │       ├── cloudrun/
    │       │       │   ├── _index.md
    │       │       │   ├── container-failed-to-start-step.md
    │       │       │   ├── image-was-not-found-step.md
    │       │       │   ├── no-permission-for-image-step.md
    │       │       │   ├── service-deployment-code-step.md
    │       │       │   └── service-deployment-start.md
    │       │       ├── crm/
    │       │       │   ├── _index.md
    │       │       │   └── org-policy-check.md
    │       │       ├── dataflow/
    │       │       │   ├── _index.md
    │       │       │   ├── dataflow-permissions-end.md
    │       │       │   ├── dataflow-resource-permissions.md
    │       │       │   ├── dataflow-user-account-permissions.md
    │       │       │   ├── dataflow-worker-service-account-permissions.md
    │       │       │   ├── failed-streaming-pipeline-end.md
    │       │       │   ├── failed-streaming-pipeline-start.md
    │       │       │   ├── job-graph-is-constructed.md
    │       │       │   ├── job-is-streaming.md
    │       │       │   ├── job-logs-visible.md
    │       │       │   ├── job-state.md
    │       │       │   └── valid-sdk.md
    │       │       ├── dataproc/
    │       │       │   ├── _index.md
    │       │       │   ├── check-autoscaling-policy.md
    │       │       │   ├── check-bq-connector.md
    │       │       │   ├── check-cluster-network-connectivity.md
    │       │       │   ├── check-cluster-network.md
    │       │       │   ├── check-cluster-quota.md
    │       │       │   ├── check-cluster-stock-out.md
    │       │       │   ├── check-cluster-version.md
    │       │       │   ├── check-gc-pause.md
    │       │       │   ├── check-gcs-connector.md
    │       │       │   ├── check-if-job-failed.md
    │       │       │   ├── check-init-script-failure.md
    │       │       │   ├── check-job-throttling.md
    │       │       │   ├── check-killing-orphaned-application.md
    │       │       │   ├── check-logs-exist.md
    │       │       │   ├── check-master-oom.md
    │       │       │   ├── check-permissions.md
    │       │       │   ├── check-port-exhaustion.md
    │       │       │   ├── check-preemptible.md
    │       │       │   ├── check-private-google-access.md
    │       │       │   ├── check-python-import-failure.md
    │       │       │   ├── check-shared-vpc-roles.md
    │       │       │   ├── check-shuffle-failures.md
    │       │       │   ├── check-shuffle-service-kill.md
    │       │       │   ├── check-stackdriver-setting.md
    │       │       │   ├── check-sw-preemption.md
    │       │       │   ├── check-task-not-found.md
    │       │       │   ├── check-worker-disk-usage-issue.md
    │       │       │   ├── check-worker-oom.md
    │       │       │   ├── check-yarn-runtime-exception.md
    │       │       │   ├── cluster-creation-end.md
    │       │       │   ├── cluster-creation-quota.md
    │       │       │   ├── cluster-creation-start.md
    │       │       │   ├── cluster-creation-stockout.md
    │       │       │   ├── cluster-details-dependency-gateway.md
    │       │       │   ├── cluster-details.md
    │       │       │   ├── cluster-exists.md
    │       │       │   ├── cluster-in-error.md
    │       │       │   ├── data-proc-cluster-exists.md
    │       │       │   ├── internal-ip-gateway.md
    │       │       │   ├── job-details-dependency-gateway.md
    │       │       │   ├── job-exists.md
    │       │       │   ├── job-start.md
    │       │       │   ├── service-account-exists.md
    │       │       │   └── spark-job-end.md
    │       │       ├── gce/
    │       │       │   ├── _index.md
    │       │       │   ├── analysing-serial-logs-end.md
    │       │       │   ├── check-live-migrations.md
    │       │       │   ├── check-serial-port-logging.md
    │       │       │   ├── cloud-init-checks.md
    │       │       │   ├── compute-cluster-manager-termination.md
    │       │       │   ├── cpu-overcommitment-check.md
    │       │       │   ├── disk-avg-io-latency-check.md
    │       │       │   ├── disk-health-check.md
    │       │       │   ├── disk-iops-throughput-utilisation-checks.md
    │       │       │   ├── gce-firewall-allows-ssh.md
    │       │       │   ├── gce-iam-policy-check.md
    │       │       │   ├── gce-log-check.md
    │       │       │   ├── gce-vpc-connectivity-check.md
    │       │       │   ├── gcp-ssh-permissions.md
    │       │       │   ├── guest-os-issued-shutdown.md
    │       │       │   ├── guestos-bootup-start.md
    │       │       │   ├── high-vm-cpu-utilization.md
    │       │       │   ├── high-vm-disk-utilization.md
    │       │       │   ├── high-vm-memory-utilization.md
    │       │       │   ├── host-error.md
    │       │       │   ├── instance-property-check.md
    │       │       │   ├── investigate-guest-os-issued-shutdown.md
    │       │       │   ├── investigate-logging-monitoring.md
    │       │       │   ├── investigate-vm-creation-log-failure.md
    │       │       │   ├── linux-guest-os-checks.md
    │       │       │   ├── managed-instance-group-recreation.md
    │       │       │   ├── mig-autoscaling-policy-check.md
    │       │       │   ├── multiple-termination-check.md
    │       │       │   ├── number-of-terminations.md
    │       │       │   ├── ops-agent-end.md
    │       │       │   ├── ops-agent-start.md
    │       │       │   ├── os-login-status-check.md
    │       │       │   ├── posix-user-has-valid-ssh-key-check.md
    │       │       │   ├── preemptible-instance.md
    │       │       │   ├── scheduled-stop-policy.md
    │       │       │   ├── serial-log-analyzer-start.md
    │       │       │   ├── shielded-vm-integrity-failure.md
    │       │       │   ├── single-termination-check.md
    │       │       │   ├── ssh-end.md
    │       │       │   ├── ssh-in-browser-check.md
    │       │       │   ├── ssh-start.md
    │       │       │   ├── stop-operation-gateway.md
    │       │       │   ├── terminate-on-host-maintenance.md
    │       │       │   ├── termination-operation-type.md
    │       │       │   ├── user-or-service-account-initiated-stop.md
    │       │       │   ├── vm-duplicate-ssh-keys-check.md
    │       │       │   ├── vm-guest-os-type.md
    │       │       │   ├── vm-has-a-service-account.md
    │       │       │   ├── vm-has-ops-agent.md
    │       │       │   ├── vm-lifecycle-state.md
    │       │       │   ├── vm-metadata-check.md
    │       │       │   ├── vm-performance-checks.md
    │       │       │   ├── vm-performance-end.md
    │       │       │   ├── vm-performance-start.md
    │       │       │   ├── vm-scope.md
    │       │       │   ├── vm-serial-logs-check.md
    │       │       │   ├── vm-termination-end.md
    │       │       │   ├── vm-termination-start.md
    │       │       │   ├── vm-termination-type.md
    │       │       │   └── windows-guest-os-checks.md
    │       │       ├── gcf/
    │       │       │   ├── _index.md
    │       │       │   ├── default-service-account-check.md
    │       │       │   ├── failed-deployment-end-step.md
    │       │       │   ├── failed-deployments-start.md
    │       │       │   ├── function-global-scope-check.md
    │       │       │   ├── location-constraint-check.md
    │       │       │   └── user-service-account-check.md
    │       │       ├── gcp/
    │       │       │   ├── _index.md
    │       │       │   ├── human-task.md
    │       │       │   ├── resource-attribute-check.md
    │       │       │   └── service-api-status-check.md
    │       │       ├── gcpdiag/
    │       │       │   ├── _index.md
    │       │       │   ├── end-step.md
    │       │       │   └── start-step.md
    │       │       ├── gke/
    │       │       │   ├── _index.md
    │       │       │   ├── api-enabled.md
    │       │       │   ├── ca-disabled-annotation.md
    │       │       │   ├── ca-failed-to-evict-pods.md
    │       │       │   ├── ca-instance-timeout.md
    │       │       │   ├── ca-ip-space-exhausted.md
    │       │       │   ├── ca-min-resource-limit-exceeded.md
    │       │       │   ├── ca-min-size-reached.md
    │       │       │   ├── ca-no-place-to-move-pods.md
    │       │       │   ├── ca-not-safe-to-evict-annotation.md
    │       │       │   ├── ca-out-of-resources.md
    │       │       │   ├── ca-pod-controller-not-found.md
    │       │       │   ├── ca-pod-kube-system-unmovable.md
    │       │       │   ├── ca-pod-not-enough-pdb.md
    │       │       │   ├── ca-pod-unexpected-error.md
    │       │       │   ├── ca-pods-not-backed-by-controller.md
    │       │       │   ├── ca-quota-exceeded.md
    │       │       │   ├── ca-service-account-deleted.md
    │       │       │   ├── check-config-map.md
    │       │       │   ├── check-daemon-set.md
    │       │       │   ├── check-destination-ip.md
    │       │       │   ├── check-node-ip.md
    │       │       │   ├── check-pod-ip.md
    │       │       │   ├── cluster-autoscaler-end.md
    │       │       │   ├── cluster-autoscaler-start.md
    │       │       │   ├── cluster-level-logging-enabled.md
    │       │       │   ├── cluster-level-monitoring-configuration-enabled.md
    │       │       │   ├── cluster-version.md
    │       │       │   ├── gke-ip-masq-standard-end.md
    │       │       │   ├── gke-ip-masq-standard-start.md
    │       │       │   ├── image-connection-timeout-restricted-private.md
    │       │       │   ├── image-connection-timeout.md
    │       │       │   ├── image-dns-issue.md
    │       │       │   ├── image-forbidden.md
    │       │       │   ├── image-not-found-insufficient-scope.md
    │       │       │   ├── image-not-found.md
    │       │       │   ├── image-pull-end.md
    │       │       │   ├── image-pull-start.md
    │       │       │   ├── ip-exhaustion-end.md
    │       │       │   ├── ip-exhaustion-start.md
    │       │       │   ├── live-migration.md
    │       │       │   ├── logging-api-enabled.md
    │       │       │   ├── logging-write-api-quota-exceeded.md
    │       │       │   ├── logs-end.md
    │       │       │   ├── logs-start.md
    │       │       │   ├── monitoring-api-configuration-enabled.md
    │       │       │   ├── monitoring-configuration-end.md
    │       │       │   ├── monitoring-configuration-start.md
    │       │       │   ├── node-auto-repair-end.md
    │       │       │   ├── node-auto-repair-start.md
    │       │       │   ├── node-bootstrapping-end.md
    │       │       │   ├── node-bootstrapping-start.md
    │       │       │   ├── node-disk-full.md
    │       │       │   ├── node-insert-check.md
    │       │       │   ├── node-ip-range-exhaustion.md
    │       │       │   ├── node-not-ready.md
    │       │       │   ├── node-pool-cloud-logging-access-scope.md
    │       │       │   ├── node-pool-cloud-monitoring-access-scope-configuration.md
    │       │       │   ├── node-pool-scope.md
    │       │       │   ├── node-pool-upgrade.md
    │       │       │   ├── node-registration-success.md
    │       │       │   ├── node-removed-by-autoscaler.md
    │       │       │   ├── node-unavailability-end.md
    │       │       │   ├── node-unavailability-start.md
    │       │       │   ├── nodeproblem.md
    │       │       │   ├── pod-ip-range-exhaustion.md
    │       │       │   ├── preemption-condition.md
    │       │       │   ├── resource-quota-exceeded.md
    │       │       │   ├── resource-quotas-end.md
    │       │       │   ├── resource-quotas-start.md
    │       │       │   ├── service-account-logging-permission.md
    │       │       │   ├── service-account-monitoring-permission-configuration.md
    │       │       │   ├── service-account-permission.md
    │       │       │   ├── unallocatable-gpu.md
    │       │       │   └── unallocatable-tpu.md
    │       │       ├── iam/
    │       │       │   ├── _index.md
    │       │       │   ├── iam-policy-check.md
    │       │       │   └── vm-has-an-active-service-account.md
    │       │       ├── interconnect/
    │       │       │   ├── _index.md
    │       │       │   ├── bgp-down-flap-end.md
    │       │       │   ├── bgp-down-flap-start.md
    │       │       │   ├── check-bgp-down.md
    │       │       │   ├── check-bgp-flap.md
    │       │       │   ├── check-cloud-router-maintenance.md
    │       │       │   └── check-interconnect-maintenance.md
    │       │       ├── lb/
    │       │       │   ├── _index.md
    │       │       │   ├── analyze-certificate-status.md
    │       │       │   ├── analyze-domain-statuses.md
    │       │       │   ├── analyze-failed-caa-check.md
    │       │       │   ├── analyze-failed-not-visible-domains.md
    │       │       │   ├── analyze-latest-health-check-log.md
    │       │       │   ├── analyze-provisioning-domains.md
    │       │       │   ├── analyze-rate-limited-domains.md
    │       │       │   ├── analyze-timeout-health-check-log.md
    │       │       │   ├── analyze-unhealthy-health-check-log.md
    │       │       │   ├── analyze-unknown-health-check-log.md
    │       │       │   ├── check-certificate-attachment.md
    │       │       │   ├── check-past-health-check-success.md
    │       │       │   ├── check-provisioning-time.md
    │       │       │   ├── check-vm-performance.md
    │       │       │   ├── latency-end.md
    │       │       │   ├── lb-backend-latency-check.md
    │       │       │   ├── lb-error-rate-check.md
    │       │       │   ├── lb-latency-start.md
    │       │       │   ├── lb-request-count-check.md
    │       │       │   ├── ssl-certificates-end.md
    │       │       │   ├── ssl-certificates-start.md
    │       │       │   ├── unhealthy-backends-end.md
    │       │       │   ├── unhealthy-backends-start.md
    │       │       │   ├── validate-backend-service-port-configuration.md
    │       │       │   ├── validate-backend-service-protocol-configuration.md
    │       │       │   ├── verify-dns-records.md
    │       │       │   ├── verify-firewall-rules.md
    │       │       │   ├── verify-forwarding-rules-port.md
    │       │       │   ├── verify-health-check-logging-enabled.md
    │       │       │   └── verify-no-certificate-map-conflict.md
    │       │       ├── logs/
    │       │       │   ├── _index.md
    │       │       │   ├── check-issue-log-entry.md
    │       │       │   └── logs-check.md
    │       │       ├── monitoring/
    │       │       │   ├── _index.md
    │       │       │   └── time-series-check.md
    │       │       ├── nat/
    │       │       │   ├── _index.md
    │       │       │   ├── nat-allocation-failed-check.md
    │       │       │   ├── nat-dropped-received-packet-check.md
    │       │       │   ├── nat-ip-allocation-auto-only.md
    │       │       │   ├── nat-ip-allocation-failed-end.md
    │       │       │   ├── nat-ip-allocation-failed-start.md
    │       │       │   ├── nat-ip-allocation-manual-only.md
    │       │       │   ├── nat-ip-allocation-method-check.md
    │       │       │   ├── nat-ip-exhaustion-check.md
    │       │       │   └── nat-resource-exhaustion-check.md
    │       │       ├── pubsub/
    │       │       │   ├── _index.md
    │       │       │   ├── active-subscription.md
    │       │       │   ├── big-query-table-existence-check.md
    │       │       │   ├── big-query-writer-permission-check.md
    │       │       │   ├── check-gcs-bucket.md
    │       │       │   ├── check-service-account-permissions.md
    │       │       │   ├── dead-letter-topic-permissions.md
    │       │       │   ├── dead-letter-topic.md
    │       │       │   ├── end-step.md
    │       │       │   ├── gcs-subscription-delivery-end.md
    │       │       │   ├── gcs-subscription-delivery-start.md
    │       │       │   ├── gcs-subscription-existence-check.md
    │       │       │   ├── investigate-bq-push-errors.md
    │       │       │   ├── pubsub-quotas.md
    │       │       │   ├── pull-rate.md
    │       │       │   ├── pull-subscription-delivery-end.md
    │       │       │   ├── pull-subscription-delivery-start.md
    │       │       │   ├── push-subscription-delivery-end.md
    │       │       │   ├── push-subscription-delivery-start.md
    │       │       │   ├── push_subscription_delivery-end.md
    │       │       │   ├── response-code-step.md
    │       │       │   ├── start-step.md
    │       │       │   ├── subscription-existence-check.md
    │       │       │   ├── subscription-status-check.md
    │       │       │   ├── throughput-qualification.md
    │       │       │   └── vpc-sc-step.md
    │       │       ├── vertex/
    │       │       │   ├── _index.md
    │       │       │   ├── check-workbench-instance-compute-engine-ssh.md
    │       │       │   ├── check-workbench-instance-custom-scripts.md
    │       │       │   ├── check-workbench-instance-external-ip-disabled.md
    │       │       │   ├── check-workbench-instance-is-using-latest-env-version.md
    │       │       │   ├── check-workbench-instance-jupyter-space.md
    │       │       │   ├── check-workbench-instance-performance.md
    │       │       │   ├── check-workbench-instance-syslogs-jupyter-running-on-port-8080.md
    │       │       │   ├── check-workbench-instance-using-custom-container.md
    │       │       │   ├── check-workbench-instance-using-official-image.md
    │       │       │   ├── decision-check-workbench-instance-system-logging.md
    │       │       │   ├── workbench-instance-stuck-in-provisioning-end.md
    │       │       │   └── workbench-instance-stuck-in-provisioning-start.md
    │       │       ├── vpc/
    │       │       │   ├── _index.md
    │       │       │   ├── external-interface-check.md
    │       │       │   ├── internal-interface-check.md
    │       │       │   ├── vm-external-ip-connectivity-end.md
    │       │       │   ├── vm-external-ip-connectivity-start.md
    │       │       │   ├── vm-external-ip-connectivity-test.md
    │       │       │   ├── vm-has-external-ip.md
    │       │       │   ├── vpc-firewall-check.md
    │       │       │   └── vpc-route-check.md
    │       │       └── vpn/
    │       │           ├── _index.md
    │       │           ├── tunnel-down-status-reason.md
    │       │           ├── tunnel-packets-drop-check.md
    │       │           ├── tunnel-packets-utilization-check.md
    │       │           ├── vpn-tunnel-check-end.md
    │       │           └── vpn-tunnel-status.md
    │       └── search.md
    ├── go.mod
    ├── go.sum
    ├── hugo.sh
    ├── i18n/
    │   └── en.toml
    └── layouts/
        ├── 404.html
        ├── docs/
        │   └── baseof.html
        ├── partials/
        │   ├── navbar.html
        │   └── page-meta-links.html
        └── shortcodes/
            └── blocks/
                ├── cover.html
                ├── feature.html
                └── section.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .bumpversion.cfg
================================================
[bumpversion]
current_version = 0.81-test
parse = (?P<major>\d+)\.(?P<minor>\d+)(-(?P<release>.*))?
message = Bump version: {current_version} -> {new_version}
serialize = 
	{major}.{minor}-{release}
	{major}.{minor}

[bumpversion:part:release]
optional_value = release
values = 
	test
	release

[bumpversion:file:gcpdiag/config.py]
search = VERSION = '{current_version}'
replace = VERSION = '{new_version}'


================================================
FILE: .coveragerc
================================================
[run]
omit =
    *_test.py
    *_stub.py


================================================
FILE: .devcontainer/README.md
================================================
# Remote Container

[Remote Container](https://code.visualstudio.com/docs/remote/containers) (aka Development Container)
enables development fully inside a container, which allows for reproducible environments.
Besides allowing for an easier getting started experience, the environment can be rebuild with
`git reset --hard` and a container rebuild.

## Setup

### Requirements

Install the requirements on a Linux host:

1. Install podman on the machine with `apt-get install podman -y`
    1. Ensure you follow all the instructions for correct setup of podman on Debian-like distros.
    Please consult any public (or internal) documentation for the setup
2. Link podman as docker executable to avoid any overseen issues `ln -s /usr/bin/podman /usr/bin/docker`
3. Clone the repository in a folder of your choice on your host

### Open on a Workstation

To open the project in a remote container please follow the official
[documentation](https://code.visualstudio.com/docs/remote/containers#_open-an-existing-workspace-in-a-container)
or the short-listed steps:

1. Ensure you have [VS Code](https://code.visualstudio.com/) installed
2. Ensure the [Remote - Container](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
    extension is installed in VS Code
3. Open the source code folder in VS Code and click the pop-up "Reopen in Container"
    - If the pop-up does not show up by default, please consult the
    [documentation](https://code.visualstudio.com/docs/remote/containers#_open-an-existing-workspace-in-a-container)

### Open on a Remote Instance via SSH

The advantage of development via SSH (especially from non-Linux workstations) are a local UI renderer (VS Code),
without having to rely on graphical remoting protocols such as Chrome Remote Desktop.
Additionally, it gives the power of any possible instance and still has a local UX even though the code execution happens in the Cloud.

For more details please consult the
[documentation](https://code.visualstudio.com/remote/advancedcontainers/develop-remote-host#_connect-using-the-remote-ssh-extension-recommended)
or the following short-listed steps:

1. Ensure you have [VS Code](https://code.visualstudio.com/) installed locally
2. Ensure the [Remote - Container](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) &
    [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh)
    extensions are installed in VS Code
3. Connect to the remote machine via SSH following the
    [documentation](https://code.visualstudio.com/remote/advancedcontainers/develop-remote-host#_connect-using-the-remote-ssh-extension-recommended)
4. Open the container on the remote similar to a local [workstation setup](#open-on-a-workstation)
   - If any issue occurs please consult the
      [documentation](https://code.visualstudio.com/remote/advancedcontainers/develop-remote-host)

The `git push` operation will need to be executed over SSH connection on the host (not in the container).

## Known Issues

- On the first start it might happen that VS Code does not correctly pick up the `pipenv` venv
  - As a workaround, restarting the container might help. Otherwise, please follow the
    [documentation](https://code.visualstudio.com/remote/advancedcontainers/develop-remote-host#_connect-using-the-remote-ssh-extension-recommended)
    to manually select an interpreter

- On the first start it might happen that VS Code does not correctly source the `pipenv` venv for new terminals
  - As a workaround, restarting the container might help.
    Otherwise, please execute `pipenv shell` manually

## Limitations

- `git commit` needs to be run in the container to allow correct execution of git hooks
- `git push` needs to be run on the host for authentication (especially in Google internal environments)

## Possible future improvements

- [ ] Install a Python linter (i.e. pylint) in the container to enable it by default for all developers
- [ ] Install a Python formatter in the container to enable it by default for all developers


================================================
FILE: .devcontainer/devcontainer.json
================================================
{
	"name": "gcpdiag",
	"image": "us-docker.pkg.dev/gcpdiag-dist/common/gcpdiag-pipenv-python-3.12:0.87", // Using our current test image - "latest"/"stable" tags do not exist at the moment
	// Use the following snippet for building the image locally and not pulling it from the remote
	//"build": {
	//	"dockerfile": "../docker/pipenv-python-3.12/Dockerfile",
	//	"context": "../docker/pipenv-python-3.12",
	//	"args": {}
	//},
	"customizations": {
		"vscode": {
			"settings": {
				"python.defaultInterpreterPath": "/usr/local/bin/python",
				"python.linting.enabled": true,
				"python.linting.pylintEnabled": true,
				"python.envFile": "${workspaceFolder}/.devcontainer/.env" // Forcing some specific env settings for debugging any dynamic python file - normal env vars are not correctly picked up
			},
			"extensions": [
				"ms-python.python",
				"ms-python.vscode-pylance"
			]
		}
	},
	"remoteEnv": {
		"PYTHONPATH": "/workspace" // required for bin/gcpdiag to correctly locate the modules / duplication of the .env file - no other workaround found
	},
	"onCreateCommand": "PATH=$HOME/.local/bin:$PATH && pipenv install --dev", // We need to execute the commands very early to allow VS Code (-extensions) to correctly pick up the pipenv venv
	"postCreateCommand": "pipenv run pre-commit install",
	"remoteUser": "root",
	// Podman specific settings
	"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,Z",
	"workspaceFolder": "/workspace",
	//"runArgs": [
	//	"--userns=keep-id"	// Causes issue with uid mappings on host, which we need for git to work properly - files are owned by random uids due to the uid mapping
	//],
	"containerUser": "root"
}


================================================
FILE: .gitallowed
================================================
gcpdiag/queries/client_secrets.json
website/content/en/docs/authentication.md


================================================
FILE: .github/workflows/code-analysis.yml
================================================
name: Code analysis
on:
  pull_request:
  push:

# Declare default permissions as Read only.
permissions: read-all

env:
  PIPENV_VENV_IN_PROJECT: enabled
jobs:
  pre-commit:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
      # Required for actions/cache to save and restore caches
      actions: write
    steps:
    - name: Install Graphviz
      run: sudo apt-get install -y graphviz

    - name: Install Ruby
      run: |
        sudo apt-get install -y ruby

    - name: Checkout repository
      uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 #v4

    - name: Set up Python
      id: setup-python
      uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 #v5
      with:
        python-version: 3.12

    - name: Set up Terraform
      uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
      with:
        terraform_version: 1.0.6

    - name: Install pipenv
      run: python -m pip install --require-hashes -r requirements.txt

    - name: Restore pipenv cache
      id: cache-pipenv
      uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4
      with:
        path: ./.venv
        key: codeanaysis-${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-pipenv-${{ hashFiles('Pipfile.lock') }}

    - name: Install dependencies
      if: steps.cache-pipenv.outputs.cache-hit != 'true'
      run: pipenv install --deploy --dev

    - name: Run pre-commit
      uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1


================================================
FILE: .github/workflows/scorecard.yml
================================================
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.

name: Scorecard supply-chain security
on:
  # For Branch-Protection check. Only the default branch is supported. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
  branch_protection_rule:
  # To guarantee Maintained check is occasionally updated. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
  schedule:
    - cron: '33 12 * * 0'
  push:
    branches: [ "main" ]

# Declare default permissions as read only.
permissions: read-all

jobs:
  analysis:
    name: Scorecard analysis
    runs-on: ubuntu-latest
    permissions:
      # Needed to upload the results to code-scanning dashboard.
      security-events: write
      # Needed to publish results and get a badge (see publish_results below).
      id-token: write


    steps:
      - name: "Checkout code"
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
        with:
          persist-credentials: false

      - name: "Run analysis"
        uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
        with:
          results_file: gcpdiag-scorecard-results.sarif
          results_format: sarif

          # Public repositories:
          #   - Publish results to OpenSSF REST API for easy access by consumers
          #   - Allows the repository to include the Scorecard badge.
          #   - See https://github.com/ossf/scorecard-action#publishing-results.
          publish_results: true

      # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
      # format to the repository Actions tab.
      - name: "Upload artifact"
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        with:
          name: gcpdiag-scorecard-results
          path: gcpdiag-scorecard-results.sarif
          retention-days: 5

      # Upload the results to GitHub's code scanning dashboard (optional).
      # Commenting out will disable upload of results to your repo's Code Scanning dashboard
      - name: "Upload to code-scanning"
        uses: github/codeql-action/upload-sarif@df559355d593797519d70b90fc8edd5db049e7a2 # v3
        with:
          sarif_file: gcpdiag-scorecard-results.sarif


================================================
FILE: .github/workflows/test.yml
================================================
name: Test
on:
  pull_request:
  push:

# Declare default permissions as read only.
permissions: read-all

env:
  PIPENV_VENV_IN_PROJECT: enabled
jobs:
  make-test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
      # Required for actions/cache to save and restore caches
      actions: write
    steps:
    - name: Checkout repository
      uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 #v4

    - name: Set up Python
      id: setup-python
      uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 #v5
      with:
        python-version: 3.12

    - name: Install pipenv
      run:  python -m pip install --require-hashes --no-deps -r requirements.txt

    - name: Restore pipenv cache
      id: cache-pipenv
      uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4
      with:
        path: ./.venv
        key: test-${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-pipenv-${{ hashFiles('Pipfile.lock') }}

    - name: Install dependencies
      if: steps.cache-pipenv.outputs.cache-hit != 'true'
      run: pipenv install --deploy --dev

    - name: Run make test
      run: pipenv run make test

    # The gcpdiag.dev website is no longer on github pages, but it's still good to build it in an action to find errors.
    - name: Hugo build
      run: |
        docker run --rm \
          --user "$(id -u):$(id -g)" \
          -e HUGO_CACHEDIR=/src/.hugo_cache \
          -v "${{ github.workspace }}/website:/src" \
          -w /src \
          us-docker.pkg.dev/gcpdiag-dist/common/gcpdiag-hugo:0.3 \
          build


================================================
FILE: .gitignore
================================================
.coverage
dist
.pipenv-dockerized
*.pyc
__pycache__
.terraform
terraform.tfstate
terraform.tfstate.backup
terraform.tfstate.*.backup
.terraform.tfstate.lock.info
.venv
*.lock.hcl
.pyinstaller.build
.*.swp
website/public
website/resources
crash.*.log
gcpdiag-config
gcpdiag/testpsa.py
.vscode/launch.json
**/.DS_STORE
venv/


================================================
FILE: .isort.cfg
================================================
[settings]
profile=


================================================
FILE: .pre-commit-config.yaml
================================================
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

exclude: '/snapshots/'
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v5.0.0
  hooks:
  - id: check-added-large-files
    args: ['--maxkb=600']
  - id: check-ast
  - id: check-case-conflict
  - id: check-executables-have-shebangs
  - id: check-merge-conflict
  - id: check-toml
  - id: check-vcs-permalinks
  - id: check-yaml
  - id: detect-private-key
  - id: end-of-file-fixer
  - id: mixed-line-ending
  - id: trailing-whitespace
    exclude: .bumpversion.cfg

- repo: https://github.com/asottile/pyupgrade
  rev: v2.29.0
  hooks:
  - id: pyupgrade
    args: [--py36-plus]

- repo: https://github.com/codespell-project/codespell
  rev: v2.3.0
  hooks:
  - id: codespell
    exclude: (^test-data/.*|^.*_test\.py$|^.*_unittest\.py$|^.*\.lock$|^pyinstaller/.*$|^.*\.spec$|^website/content/en/runbook/.*$|^gcpdiag/lint/snapshots/.*$|^gcpdiag/runbook/snapshots/.*$)

- repo: https://github.com/pre-commit/mirrors-mypy
  rev: v1.2.0
  hooks:
  - id: mypy
    exclude: bin/gcpdiag
    args: ['--ignore-missing-imports', '--scripts-are-modules',
      '--implicit-optional', '--no-namespace-packages', '--install-types',
      '--non-interactive']

- repo: https://github.com/timothycrosley/isort
  rev: 5.12.0
  hooks:
  - id: isort

- repo: https://github.com/google/yapf
  rev: v0.40.2
  hooks:
  - id: yapf

- repo: https://github.com/pylint-dev/pylint
  rev: v3.3.1
  hooks:
  - id: pylint

- repo: https://github.com/antonbabenko/pre-commit-terraform
  rev: v1.96.1
  hooks:
  - id: terraform_fmt
  - id: terraform_validate

- repo: local
  hooks:
  - id: gcpdiag-custom-rule
    name: Check that there are required files for each lint rule
    entry: ./bin/precommit-required-files-wrapper lint
    language: script
    files: ^gcpdiag/lint/[^/]+/(bp|warn|err|sec)_.*.py
    exclude: .*_test.py
- repo: local
  hooks:
  - id: gcpdiag-custom-runbook-rule
    name: Check and generate runbook docs
    entry: ./bin/precommit-required-files-wrapper runbook
    language: script
    files: ^gcpdiag/runbook/[^/]+/.*.py
    exclude: >
      .*_test.py|
      ^gcpdiag/runbook/(output|report)|
      ^gcpdiag/runbook/[^/]+/snapshots/|
      ^gcpdiag/runbook/[^/]+/(constants|command|flags|util).py|
      ^gcpdiag/runbook/(constants|command|flags|exceptions|report|util).py
- repo: local
  hooks:
  - id: todo-annotations
    name: Check presence of "TODO:" comments
    entry: ./bin/precommit-todo-annotations
    language: script
- repo: https://github.com/markdownlint/markdownlint
  rev: v0.13.0
  hooks:
  - id: markdownlint
    files: \.(jinja)$
    entry: mdl --rules MD034


================================================
FILE: .pylint-dictionary.txt
================================================
ack
aiohttp
aiplatform
allowedPolicyMemberDomains
api
apigee
Apigee
Apigee's
ApigeeX
apis
APIs
apiserver
APIState
args
Args
argv
ASM
async
asyncio
atleast
attr
auth
autoscaler
Autoscaler
autoscaling
Autoscaling
autoscalingpolicy
backend
Backend
backends
balancer
Balancer
balancers
behaviour
BFD
bigquery
Bigquery
bigquerydatatransfer
bool
boolen
bootable
BQ
byol
camelcase
cb
CDF
CDN
cgroup
Chrony
cidr
cli
cloudaudit
cloudbuild
cloudfunctions
cloudrun
cloudsql
CLUSTERHASH
CLUSTERNAME
CNI
computeProfiles
config
configs
conntrack
containerd
coroutine
Crashloopbackoff
CRD
crm
CRM
Crypto
CryptoKey
CSV
daemonset
dataflow
Dataflow
datafusion
Datafusion
dataplane
Dataplane
dataproc
Dataproc
DataTime
datatypes
datetime
dateutil
debian
decrypt
Decrypter
deque
dev
DiagnosticTree
dicts
diskcache
DLQ
dml
DML
dns
DNS
docstring
DT
Ee
EFI
eg
elif
Enablement
Encrypter
endstep
Enum
env
environmentId
envs
eol
EOL
eval
exampledagname
failureInfo
featurestore
featurestores
Featurestores
filesystem
filesystems
fluentd
formater
formatter
frozenset
functon
fw
gae
GAE
gcb
gce
GCE
gcf
GCF
gcfs
gcloud
gcp
GCP
GcpApiError
gcpbackendpolicies
gcpdiag
gcpdiag's
gcpgatewaypolicies
gcr
GCR
gcs
GCS
Generatlized
getIamPolicy
gke
GKE
GKE's
GKEs
GLB
Globals
googleapiclient
googleapis
gserviceaccount
gzip
healthcheck
healthcheckpolicies
HEC
hostname
HPA
http
Http
HttpError
iam
IAM
IAP
iff
IInvestigates
iLB
inlined
inlining
instanceId
instantiation
intranode
io
ip
IPAddrOrNet
ips
IPs
isclose
istio
Istio
istiod
Iterable
Jinja
json
jupyter
Jupyter
Jupyterlab
Kerberos
Keybased
keyname
keyvalue
kms
KMS
KSA
kube
kubeclt
kubeconfig
kubectl
Kubectl
Kubelet
kubernetes
Kubernetes
kwargs
lifecycle
linters
LintRuleRepository
linux
listPolicy
liveness
LLC
loadbalancing
locationId
LogsQuery
logWriter
lse
masq
maxPartittions
metaclass
Metaclass
metricWriter
mig
migs
MIG's
MIGs
misconfiguration
misconfigurations
misconfigured
MQL
myapp
mysql
namespace
namespaces
nat
Negsignal
networkmanagement
nic
nodepool
nodepools
notpresent
NTP
OAuth
occuring
ok
onboarding
onload
OOM
organizationAdmin
os
osconfig
OSS
ouma
overlayfs
Paramaters
parens
parseable
partitionSizeBytes
PCollection
PCollections
Peerings
performnce
permisssion
PGA
php
PID
pre
precommit
preemptible
prefetch
Prefetch
programmatically
projectId
ProjectPolicy
PSA
pubsub
Pubsub
pvpanic
py
pyinstaller
RDP
recommender
recommened
regexes
repo
Repor
repr
req
requireShieldedVm
resourcemanager
retryable
ru
runbook
runbook's
runbooks
runnable
runtimeId
runtimes
sa
Safemode
SA's
SAs
scaleup
scheduler's
schedulers
SDK
Serverless
serviceaccounts
serviceAgent
serviceId
servicenetworking
shouldnot
SIGKILL
skanzhelev
SLA
SLO
Splunk
SSD
SSL
stackdriver
Stackdriver
stateful
Stateful
Statsd
StatsD
stderr
stdout
stockout
str
stringification
subagent
subagents
subclassed
subclasses
submodules
subnet
Subnet
subnets
subnetwork
Subnetwork
subnetworks
subpackages
subprocess
subqueries
supernet
sys
syslog
syslogs
systemd
targetResources
TBD
TCP
Terraform
testfiles
testproject
testuser
timeframe
tmp
tmux
toml
TP
TPC
TPU
Truthy
Typcial
udp
UDP
UI
unacked
Unacked
undeliverable
unhandled
unittest
unknowd
untrusted
updateing
upgradability
upgradable
uptime
Uptime
uri
URI
url
URLMap
urls
useExternalIp
usuage
util
Util
utils
verifications
vm
VM
vmCanIpForward
vmExternalIpAccess
VM's
VMs
vpc
VPC
VpcFirewallRule
webhook
whitespaces
worklaods
writeable
XLB
XSS
xz
yaml
Yaml


================================================
FILE: .pylintrc
================================================
# This Pylint rcfile contains a best-effort configuration to uphold the
# best-practices and style described in the Google Python style guide:
#   https://google.github.io/styleguide/pyguide.html
#
# Its canonical open-source location is:
#   https://google.github.io/styleguide/pylintrc

[MASTER]

# Add files or directories. They should be base names, not
# paths.
ignore=third_party

# Files or directories matching the regex patterns are skipped. The regex
# matches against base names, not paths.
ignore-patterns=

# Add files or directories matching the regex patterns to the ignore-list.
# The regex matches against paths.
ignore-paths=cookiecutter-gcpdiag-rule/.*

# Pickle collected data for later comparisons.
persistent=no

# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=

# Use multiple processes to speed up Pylint.
jobs=4

# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no


[MESSAGES CONTROL]

# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
#enable=

# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=abstract-method,
        apply-builtin,
        arguments-differ,
        attribute-defined-outside-init,
        backtick,
        bad-option-value,
        basestring-builtin,
        buffer-builtin,
        c-extension-no-member,
        consider-using-enumerate,
        cmp-builtin,
        cmp-method,
        coerce-builtin,
        coerce-method,
        consider-using-f-string,
        delslice-method,
        div-method,
        duplicate-code,
        eq-without-hash,
        execfile-builtin,
        file-builtin,
        filter-builtin-not-iterating,
        fixme,
        getslice-method,
        global-statement,
        hex-method,
        idiv-method,
        implicit-str-concat-in-sequence,
        import-error,
        import-self,
        import-star-module-level,
        inconsistent-return-statements,
        input-builtin,
        intern-builtin,
        invalid-str-codec,
        locally-disabled,
        long-builtin,
        long-suffix,
        map-builtin-not-iterating,
        misplaced-comparison-constant,
        missing-function-docstring,
        metaclass-assignment,
        next-method-called,
        next-method-defined,
        no-absolute-import,
        no-else-break,
        no-else-continue,
        no-else-raise,
        no-else-return,
        no-init,  # added
        no-member,
        no-name-in-module,
        no-self-use,
        nonzero-method,
        oct-method,
        old-division,
        old-ne-operator,
        old-octal-literal,
        old-raise-syntax,
        parameter-unpacking,
        print-statement,
        raising-string,
        range-builtin-not-iterating,
        raw_input-builtin,
        rdiv-method,
        reduce-builtin,
        relative-import,
        reload-builtin,
        round-builtin,
        setslice-method,
        signature-differs,
	spelling,
        standarderror-builtin,
        suppressed-message,
        sys-max-int,
        too-few-public-methods,
        too-many-ancestors,
        too-many-arguments,
        too-many-boolean-expressions,
        too-many-branches,
        too-many-instance-attributes,
        too-many-locals,
        too-many-nested-blocks,
        too-many-public-methods,
        too-many-return-statements,
        too-many-statements,
        trailing-newlines,
        unichr-builtin,
        unicode-builtin,
        unnecessary-pass,
        unpacking-in-except,
        useless-else-on-loop,
        useless-object-inheritance,
        useless-suppression,
        using-cmp-argument,
        wrong-import-order,
        xrange-builtin,
        zip-builtin-not-iterating,


[REPORTS]

# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text

# Tells whether to display a full report or only the messages
reports=no

# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)

# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=


[BASIC]

# Good variable names which should always be accepted, separated by a comma
good-names=main,_

# Bad variable names which should always be refused, separated by a comma
bad-names=

# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=

# Include a hint for the correct naming format with invalid-name
include-naming-hint=no

# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl

# Regular expression matching correct function names
function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$

# Regular expression matching correct variable names
variable-rgx=^[a-z][a-z0-9_]*$

# Regular expression matching correct constant names
const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$

# Regular expression matching correct attribute names
attr-rgx=^_{0,2}[a-z][a-z0-9_]*$

# Regular expression matching correct argument names
argument-rgx=^[a-z][a-z0-9_]*$

# Regular expression matching correct class attribute names
class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$

# Regular expression matching correct inline iteration names
inlinevar-rgx=^[a-z][a-z0-9_]*$

# Regular expression matching correct class names
class-rgx=^_?[A-Z][a-zA-Z0-9]*$

# Regular expression matching correct module names
module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$

# Regular expression matching correct method names
method-rgx=(?x)^(?:(?P<exempt>_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$

# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$

# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=10


[TYPECHECK]

# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager

# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes

# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=

# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local

# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=


[FORMAT]

# Maximum number of characters on a single line.
max-line-length=100

# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt
# lines made too long by directives to pytype.

# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=(?x)(
  ^\s*(\#\ )?<?https?://\S+>?$|
  ^\s*(from\s+\S+\s+)?import\s+.+$)

# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=yes

# Maximum number of lines in a module
max-module-lines=99999

# String used as indentation unit.  The internal Google style guide mandates 2
# spaces.  Google's externally-published style guide says 4, consistent with
# PEP 8.  Here, we use 2 spaces, for conformity with many open-sourced Google
# projects (like TensorFlow).
indent-string='  '

# Number of spaces of indent required inside a hanging  or continued line.
indent-after-paren=4

# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=


[MISCELLANEOUS]

# List of note tags to take in consideration, separated by a comma.
notes=TODO


[STRING]

# This flag controls whether inconsistent-quotes generates a warning when the
# character used as a quote delimiter is used inconsistently within a module.
check-quote-consistency=yes


[VARIABLES]

# Tells whether we should check for unused import in __init__ files.
init-import=no

# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)

# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=

# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb

# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools


[LOGGING]

# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging,absl.logging,tensorflow.io.logging


[SIMILARITIES]

# Minimum lines number of a similarity.
min-similarity-lines=4

# Ignore comments when computing similarities.
ignore-comments=yes

# Ignore docstrings when computing similarities.
ignore-docstrings=yes

# Ignore imports when computing similarities.
ignore-imports=no


[SPELLING]
# run with "make spelling" or a command like:
#  pip install PyEnchant
#  pylint --disable all --enable spelling --spelling-dict en_US gcpdiag
#
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=

# List of comma separated words that should not be checked.
spelling-ignore-words=

# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=.pylint-dictionary.txt

# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no


[IMPORTS]

# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,
                   TERMIOS,
                   Bastion,
                   rexec,
                   sets

# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=

# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=

# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=

# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=

# Force import order to recognize a module as part of a third party library.
known-third-party=enchant, absl

# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no


[CLASSES]

# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
                      __new__,
                      setUp

# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,
                  _fields,
                  _replace,
                  _source,
                  _make

# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls,
                            class_

# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs


[EXCEPTIONS]

# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=builtins.StandardError,
                       builtins.Exception,
                       builtins.BaseException

[DESIGN]
# Increase allowed positional arguments from default (5)
max-positional-arguments=8


================================================
FILE: .safety-policy.yml
================================================
security:
  ignore-vulnerabilities:
    # Waiting for upstream fix for CVE-2025-69872 in diskcache
    "86338":


================================================
FILE: .style.yapf
================================================
[style]
based_on_style = google
indent_width = 2


================================================
FILE: .vscode/extensions.json
================================================
{
  "recommendations": [
    "ms-python.pylint",
    "ms-python.mypy-type-checker",
    "eeyore.yapf"
  ]
}


================================================
FILE: .vscode/settings.json
================================================
{
    "editor.formatOnSave": true,
    "editor.insertSpaces": true,
    "editor.tabSize": 2,
    "files.insertFinalNewline": true,
    "files.trimTrailingWhitespace": true,
    "[python]": {
        "editor.defaultFormatter": "eeyore.yapf",
        "editor.codeActionsOnSave": {
            "source.organizeImports": "always"
        },
    },
    "pylint.severity": {
        "refactor": "Warning",
    },
    "mypy-type-checker.args": [
        "--follow-imports=silent",
        "--ignore-missing-imports",
        "--show-column-numbers",
        "--no-pretty",
        "--scripts-are-modules"
    ],
    "python.terminal.activateEnvInCurrentTerminal": true,
    "python.testing.pytestArgs": [
        "gcpdiag"
    ],
    "python.testing.unittestEnabled": false,
    "python.testing.pytestEnabled": true,
}


================================================
FILE: CHANGELOG.md
================================================

# Changelog

## 0.79 (2025-05-27)

### New Lints

- lb/bp/2025\_003: new rule: lint rule for best practices for load balancer backend service connection draining setting.
- lb/bp/2025\_002: new rule: Lint rule for backend service timeout best practice on load balancer.
- interconnect/warn/2025\_001: interconnect rule: check interconnect MTU mismatch

### New Runbooks

- interconnect/bgp-down-flap: interconnect BGP down flap runbook
- gce/vm-creation: \[New Runbook\] GCE VM Creation runbook
- gce/guestos-boot-up: \[New Runbook\] Guest OS boot-up issues

### New Queries

- orgpolicy.\_get\_available\_org\_constraints: list all the org constraints available for a particular resource. Args: resource\_id: The resource ID. resource\_type: The resource type (project or organization). Returns: A list of available org policy constraints. Raises: utils.GcpApiError: on API errors.
- billing.get\_billing\_info: Get Billing Information for a project, caching the result.
- orgpolicy.get\_all\_project\_org\_policies: list all the org policies set for a particular resource. Args: project\_id: The project ID. Returns: A dictionary of PolicyConstraint objects, keyed by constraint name. Raises: utils.GcpApiError: on API errors.
- network.get\_router\_by\_name

### New Features

- Implement \--test-release flag in gcpdiag docker
- Improved output message quality for all runbooks.
- Add Bundle execution usage details to internal \+ external docs
- Adding exceptions in constructing API endpoints for different services.
- Add markdownlint precommit and graphviz dependencies
- Add ossf scorecard Github Action and update pre-commit hooks

### Fixes

- Update `job_id` parameter.
- Update service name parameter.
- Update output messages for interconnect and dataproc runbooks.
- Update `cluster_name` parameter.
- Disambiguate `name` parameter for GKE and GCF runbooks; fix GCF failed deployments template bug.
- Update dataflow/dataproc jinja templates.
- \[Bundles\] Fix missing `runbook_name` error.
- \[gcpdiag runbook cli\] Fix missing json report error.
- Fix missing import errors.
- Fix `report.run_start_time` error.
- Update pipenv to use the latest version to fix import errors.
- Update Github Actions workflow to use a newer python version to fix tests.
- Create exception for missing runbook parameters.
- Update `README.md`.
- Fix dataproc runbook parameter bug.
- Improve Runbooks Response handling.
- Use the diagnostic engines runbook loader for tests.
- Update ops agent onboarding parameters.
- Update artifact config.
- Update artifact upload version.
- Use scope instead of region wording in the unhealthy backends runbook.
- Fix ossf scorecard action filename in config; re-enable pylint now that sub dependency setuptools is fixed ([https://github.com/pypa/setuptools/issues/4892\#issuecomment-2740696126](https://github.com/pypa/setuptools/issues/4892#issuecomment-2740696126)).
- Migrate info logs to debug logs for messages with PII / SPII.
- Disable py lint.
- Deprecate unused gh-pages github action ([https://github.com/GoogleCloudPlatform/gcpdiag/actions/runs/13902316282/job/38976483921](https://github.com/GoogleCloudPlatform/gcpdiag/actions/runs/13902316282/job/38976483921)).
- Improve the message when HC logs are not enabled.
- github: Bump jinja2 from 3.1.5 to 3.1.6.

## 0.78 (2025-03-04)

#### New Lints

gke/warn/2025\_001: new rule: GKE external LB services are successfully created without encountering IP allocation failures due to external IPv6 subnet configurations.
asm/warn/2025\_002: new rule: Upstream connection established successfully with no protocol errors
asm/warn/2025\_001: new rule: ASM: Envoy doesn't report connection failure
gke/err/2025\_001: GKE cluster complies with the serial port logging organization policy.

#### New Runbooks

gcf/failed-deployments: Cloud Run Functions runbook to assist users to check reasons for failed deployments of Gen2 cloud functions
nat/public-nat-ip-allocation-failed: public nat ip allocation failed runbook
dataproc/spark-job-failures: Dataproc Spark Job Runbook
lb/latency: new runbook: Load Balancer Latency v1

#### New Queries

gce.get\_global\_operations: Returns global operations object in the given project id.
cloudasset.search\_all\_resources: Searches all cloud asset inventory in the project.
lb.get\_load\_balancer\_type\_name: Returns a human-readable name for the given load balancer type.
dataproc.list\_auto\_scaling\_policies: Lists all autoscaling policies in the given project and region.

### New Features

pre-commit codespell check eliminate typos in the repositories
Step class attributes interpolation in step names
Check deprecated parameters in runbooks
Migrate repository to python 3.12
output/api\_output.py: implement api output module
Create threading.local() in op.py for data isolation.

#### Fixes

Update gke/err/2024\_003 to check for `container.defaultNodeServiceAccount` role
Update formatting/style of all runbooks.
fix runbook functionality to properly detect pod IP exhaustion and node IP exhaustion
Explicitly handle HTTP 401 errors - Add step_error for exceptions caused by GcpApiError - Handle edge case where
Improve error handling for iam.roles()

## 0.77 (2024-11-13)

#### New Lint Rules

- gke/err/2024\_002: gke webhook failure endpoints not available
- gke/warn/2024\_007: GKE cluster in a dual-stack with external IPv6 access

#### New Runbooks

- lb/ssl-certificate: Runbook for troubleshooting LB SSL certificates issues
- gke/node-unavailablity: Identifies the reasons for a GKE node being unavailable

#### New Queries

- gke.get\_cluster: Retrieve a single GKE cluster using its project, region, and cluster name.
- dns.find\_dns\_records: Resolves DNS records for a given domain and returns a set of IP addresses.
- lb.get\_ssl\_certifcate: Returns object matching certificate name and region
- lb.get\_target\_https\_proxies: Retrieves the list of all TargetHttpProxy resources, regional and global, available to the specified project.
- lb.get\_forwarding\_rule: Returns the specified ForwardingRule resource.

#### Enhancements

- Functionality to auto suggest correct runbook names for misspelled runbooks
- Updated docker images to ubuntu:24.04 (python 3.12)
- Updated devcontainer to python 3.12
- Migrated crm queries from v1 to v3
- gce/vm-performance: Added PD performance health check
- gce/vm-performance: Implemented disk average\_io\_latency check
- Removed apis\_utils.batch\_execute\_all call from orgpolicy query
- Enabled gcpdiag.dev page indexing
- Reduced API retries to 3 attempts
- Improved START\_TIME\_UTC inconsistency & Error parsing date string fix
- pubsub/pull-subscription-delivery: removed cold cache checks
- Add functionality to disable query caching for edge cases
- Improve error handling within gcpdiag library to raise errors for handling rather than exiting.

#### Fixes

- lb.get\_backend\_service: Improved calls to fetch global backend
- Added project_id parameters for the runbook tests without  valid project ids

#### Deprecation

- Flag `--project`: Full deprecation in **runbook command** to allow multiple project ids/numbers to be specified via `--parameter`

## 0.76 (2024-10-1)

#### New Lint Rules

- dataproc/warn/2024\_005: Investigates if Data Fusion version is compatible with Dataproc version from the CDAP Preferences settings

#### New Runbooks

- pubsub/pull-subscription-delivery: Investigates common Cloud Pub/Sub pull delivery issues related to delivery latency, quotas, pull rate and throughput rate

#### New Queries

- pubsub.get\_subscription: Retrieves a single pubsub subscription resource
- apis.is\_all\_enabled: Check if a list of services are enabled on a given project
- gke.get\_release\_schedule: Fetch GKE cluster release schedule

#### Enhancements

- `make new-rule`: A make rule with a [cookiecutter](https://www.cookiecutter.io/) recipe to generate new lint rule templates
- gce.get\_gce\_public\_images: Improved gce\_stub query to correctly fetch all image licenses during test.
- Runbooks metrics generation for Google Internal Users
- New flag `--reason`: argument primarily used by Google internal users to specify rational for executing the tool
- Bundles: A runbook feature to allow execution of a collection of steps
- Runbook operation (op.add_metadata) to create or retrieve metadata related to steps

#### Fixes

- Enforce explicit parameter configuration in gce generalized steps.
- dataflow/dataflow-permission: Refactored runbook to `dataflow/job-permission`
- dataflow/bp/2024\_002: Fixed resource filtering bug for forwarding rule (internal LB)
- gce/vm-performance: Fixed disk performance benchmark lookup

#### Deprecation

- apis\_utils.batch\_list\_all: Replaced by apis\utils.multi\_list\_all
- Flag `--project`: Soft deprecation in **runbook command** to allow multiple project ids/numbers to be specified via `--parameter`
- Deprecated pre-commit hook gke-eol-file

## 0.75 (2024-9-2)

#### New Lint Rules

- bigquery/WARN/2024\_005: Checks BigQuery table does not exceed number of partition modifications
  to a column partitioned table
- bigquery/WARN/2024\_006: Checks BigQuery job does not exceed tabledata.list bytes
  per second per project
- dataflow/ERR/2024\_006: Checks Dataflow job does not fail during execution due
  to resource exhaustion in zone
- datafusion/WARN\_2024\_004: Checks Data Fusion version is compatible with Dataproc
  version from the corresponding compute profiles
- gke/WARN/2024\_003: Checks Ingress traffic is successful if service is correctly mapped
- gke/WARN/2024\_004: Checks Ingress is successful if backendconfig crd is correctly mapped
- gke/WARN/2024\_005: Checks GKE Ingress successfully routes external traffic to NodePort service
- gce/BP_EXT/2024\_002: Calculate a GCE VM's IOPS and Throughput Limits

#### New Runbooks

- lb/unhealthy-backends: Diagnose Unhealthy Backends of a Load Balancer
- gke/resource-quota: Diagnose quota related issues related to gke clusters.
- gce/vm-performance: Diagnose GCE VM performance
- gke/image-pull: Diagnose Image Pull Failures related GKE clusters.
- gke/node-auto-repair: RCA Node auto-repaired incidents
- gke/gke-ip-masq-standard: Diagnose IP Masquerading issues on GKE clusters
- dataflow/dataflow-permission: Diagnose Permission required for cluster creation and operation

#### New Query

- lb.get\_backend\_service: Fetch instances matching compute backend service name and/or region
- lb.get\_backend\_service_health: Fetch compute backend service health data
- generic\_api/datafusion: Re-implementation of how to call and test generic apis

#### Enhancements

- cloudrun/service-deployment: 2 additional checks for image not found and image permissions failure
- bigquery/WARN/2022\_001: Updated lint rule  diagnostic steps documentation
- Implement ignorecase for input parameters
- gce/ssh and gce/serial-log-analyzer: Include Auth failure checks in  runbooks
- Updated GKE version End of Life tracker
- New API Stub for Recommender API

#### Fixes

- gce/vm-termination: Made vm name and zone mandatory fields
- Updated dependencies:
  - aiohttp: 3.9.5 -> 3.10.3
  - attrs: 23.2.0 -> 24.2.0
  - cachetools: 5.3.3 -> 5.4.0
  - certifi: 2024.6.2 -> 2024.7.4
  - exceptiongroup: 1.2.1 -> 1.2.2
  - google-api-python-client: 2.134.0 -> 2.141.0
  - google-auth: 2.30.0 -> 2.33.0
  - google-auth-oauthlib: 1.2.0 -> 1.2.1
  - importlib-resources: 6.4.0 -> 6.4.2
  - protobuf: 5.27.2 -> 5.27.3
  - pyyaml: 6.0.1 -> 6.0.2
  - soupsieve: 2.5 -> 2.6
- Fix lint output and GCE query functions for multi-region resources
- Removed deprecated option skip\_delete from TF code

## 0.74 (2024-7-10)

#### Fixes

- Re-roll of v0.72 after correcting pip module issue with the docker image build

#### New Lint Rule

datafusion/warn\_2024\_002 Data Fusion instance is in a running state

#### New Runbook

dataproc/cluster\_creation Dataproc cluster creation diagnostic tree

## 0.73 (2024-7-8)

#### New Feature

- Added search command to scale the docstrings for lint rules or runbooks to
  match keywords
- added runbook check step outcome: step\_ok, step\_failed, etc.
- Added a zonal endpoint in osconfig library. It returns inventories for all VMs under a certain zone

#### Fixes

- Create runbook report regardless of the number of failed steps
- Improve introductory error message for new runbooks
- Update lint command API return value for display of resources in each rule
- General spelling corrections
- Add documentation for runbook operator methods
- Remove unneeded google path reference in loading template block contenta
- Update runbook name validation
- Handle when gcloud command is not installed when running runbook generator
- Allow to query logs for each test data separately in logs\_stub
- Update GKE EOL date
- Relax constraints on location of end steps in runbook
- Update pip dependencies; security fix for pdoc
- Added monitoring to the list of supported products runbook steps
- generic\_api/datafusion apis.make\_request() re-implementation
- Update and improve runbook error handling

#### New Lint Rule

- gke/err\_2024\_001\_psa\_violations Checking for no Pod Security Admission violations in the project
- bigquery/warn\_2024\_002\_invalid\_external\_connection BigQuery external
  connection with Cloud SQL does not fail
- pubsub/err\_2024\_003\_snapshot\_creation\_fails snapshot creation fails if
  backlog is too old
- pubsub/err\_2024\_002\_vpc\_sc\_new\_subs\_create\_policy\_violated check for
  pubsub error due to organization policy
- bigquery/warn\_2024\_0003 BigQuery job does not fail due to Maximum API requests per user per method exceeded

#### New Runbook

- gce/ops\_agent Ops Agent Onboarding runbook
- gcp/serial\_log\_analyzer runbook to analyse known issues logged into Serial Console logs
- vertex/workbench\_instance\_stuck\_in\_provisioning Runbook to Troubleshoot Issue: Vertex AI Workbench Instance Stuck in Provisioning State
- cloudrun/service\_deployment Cloud Run deployment runbook
- gke/ip\_exhaustion gke ip exhaustion runbook
- dataflow/failed\_streaming\_pipeline Diagnostic checks for failed Dataflow Streaming Pipelines
- nat/out\_of\_resources vm external ip connectivity runbook

## 0.72 (2024-5-30)

#### Fixes

- update pyinstaller to include runbook command and templates in x20 binary
  build
- Update pylint configuration files
- Update GKE EOL file
- fix case sensitive runbook bug with bool value interpretation
- Revert "new rule: datafusion\_cdap\_api\_call\_implementation"
- Revert "new rule:check scale down disabled for the compute profiles in the
  datafusion instance
- Update pipenv dependencies.
- pipenv upgrade idna and aiohttp per reported security vulnerabilities
- Removed cloud resource manager dependency from gce/bp\_2024\_001 and
  gce/bp\_2024\_002 Rules. Improved error reporting.
- default universe\_domain, credentials for runbook API, handle template path
  for runbook from API service
- fix title for BP\_EXT/2024\_001.md conflict with BP/2024\_001.md
- GCE lint legacy monitoring and agent: Report ok when VM manager (os config
  API) does not detect legacy agent packages on the GCE VM.

#### New Features

- added spell check and corrections of existing misspelled words

#### New Runbook

- new runbook: GKE logs
- new runbook: GKE cluster autoscaler

#### New Lint Rule

- dataflow/err\_2024\_004\_missing\_gce\_permission\_temp\_bucket The Dataflow
  job has the necessary GCS permissions for the temporary bucket
- gce/err\_2024\_003\_dataflow\_write\_truncate\_unbounded streaming dataflow
  jobs are not using write\_truncate when working with unbounded pcollections
- gce/err\_2024\_004\_ops\_agent In additional to access scope and iam roles,
  the monitoring API and logging API should also be enabled on the project, for
  Ops Agent to send metrics and logs respectively.
- gce/err\_2024\_004\_ops\_agent The rules verifies that the Ops Agent is
  installed on a GCE VM and is sending logs and metrics to gcloud backend.
- gke/warn\_2024\_002\_ksa\_exceeded GKE KSA exceeded 3000 in WI enabled
  clusters.

## 0.71 (2024-4-17)

#### New lint rules

- datafusion/err\_2024\_001\_delete\_operation\_failing datafusion
  deletion operation
- gce/err\_2024\_003\_vm\_secure\_boot\_failures GCE Lint rule for boot
  failures for Shielded VM
- gce/bp\_2024\_001\_legacy\_monitoring\_agent GCE Legacy Monitoring Agent
  is not installed
- gce/bp\_2024\_002\_legacy\_logging\_agent GCE Legacy Logging Agent is not
  be installed
- gce/bp\_ext\_2024\_001\_no\_public\_ip.py GCE SSH in Browser: SSH Button
  Disabled
- pubsub/bp\_2024\_001\_ouma\_less\_one\_day Oldest Unacked Message Age
  Value less than 24 hours
- bigquery/err\_2024\_001\_query\_too\_complex query is too complex
- bigquery/warn\_2024\_001\_imports\_or\_query\_appends\_per\_table table
  exceeds limit for imports or query appends

#### New query

- osconfig

  "OS management tools that can be used for patch management, patch compliance,
  and configuration management on VM instances."
    <https://cloud.google.com/compute/docs/osconfig/rest>

#### New runbook

- gce/vm\_termination assist investigating underlying reasons behind
  termination or reboot
- gke/cluster\_autoscaler GKE Cluster autoscaler error messages check

#### New features

- Add cache bypass option for runbook steps
- Add runbook starter code generator; updates to code generator
- Add API for runbook command

#### Fixes

- Add mock data for datafusion API testing
- Correct runbook documentation generation output
- Improve runbook operator functions usage
- Add dataflow and other components to supported runbook component list
- Remove duplicate vm\_termination.py script
- Add jinja templates to docker image on cloud shell
- correct argv passed for parsing in runbook command
- Adding pipenv and git checks to help beginners get started easily on runbook
  generator
- update idna pipenv CVE-2024-3651 Moderate severity
- SSH runbook enhancements
- runbook fixes - catch missing template errors, include project id when no
  parameters

## 0.70 (2024-3-27)

#### New lint rules

- pubsub/ERR\_2024\_001 bq subscription table not found
- composer/WARN\_2024\_001 low scheduler cpu usage
- datafusion/WARN\_2024\_001 data fusion version
- composer/WARN\_2024\_002 worker pod eviction
- gce/ERR\_2024\_002 performance
- notebooks/ERR\_2024\_001 executor explicit project permissions
- dataflow/WARN\_2024\_001 dataflow operation ongoing
- dataflow/ERR\_2024\_001 dataflow gce quotas
- dataflow/WARN\_2024\_002 dataflow streaming appliance commit failed
- dataflow/ERR\_2024\_002 dataflow key commit
- gke/WARN\_2024\_001 cluster nap limits prevent autoscaling

#### New query

- datafusion\_cdap API query implementation - provides CDAP profile metadata

#### Fixes

- Updated pipenv packages, Pipenv.lock dependencies
- Updated github action workflow versions to stop warnings about node v10 and v10
- Refactor Runbook: Implemented a modular, class-based design to facilitate a
  more configurable method for tree construction.

## 0.69 (2024-2-21)

#### New feature

- add universe\_domain for Trusted Partner Client (TPC)

#### New rules

- asm/WARN\_2024\_001 Webhook failed
- lb/BP\_2024\_002 Check if global access is on for the regional iLB
- pubsub/WARN\_2024\_003 Pub/Sub rule: CMEK - Topic Permissions
- dataproc/WARN\_2024\_001 dataproc check hdfs safemode status
- dataproc/WARN\_2024\_002 dataproc hdfs write issues
- gce/ERR\_2024\_001 GCE rule:Snapshot creation rate limit
- lb/BP\_2024\_001 session affinity enabled on load balancer
- pubsub/WARN\_2024\_002 GCS subscription has the apt permissions
- dataflow/ERR\_2023\_010 missing required field
- pubsub/WARN\_2024\_001 DLQ Subscription has apt permissions

#### Fixes

- Update Pull Request and Merge to only run when an update was committed
- Creating a github action Workflow to automatically update the gke/eol.yaml file
- Update gke/eol.yaml file

## 0.68 (2024-1-17)

#### New Rules

- gke/bp\_2023\_002 Gke cluster is a private cluster
- composer/err\_2023\_002 Use allowed IP ranges to create Private IP Cluster
- compoer/err\_2023\_004 DAG is detected as zombie
- composer/err\_2023\_003 DAG timeout issue
- composer/err\_2023\_005 Check NAT config for environment deletion fail
- bigquery/err\_2023\_009 BigQuery job not failed due to Schedule query with multiple DML
- gce/warn\_2023\_002 Serial logs don’t contain out-of-memory message due to airflow task run
- dataflow/err\_2023\_011 Streaming insert mismatch column type
- dataflow/err\_2023\_012 Spanner OOM
- dataflow/err\_2023\_013 Spanner deadline error
- pubsub/warn\_2023\_006 Pubsub push subscriptions have no push errors
- dataproc/err\_2023\_008 Dataproc cluster disk space issues check and web page
- composer/err\_2024\_001 Composer not failed due to 'no error was surfaced' error
- lb/bp\_2023\_002 check that logging is enabled on health checks for load balancer backend
  services
- vpc/warn\_2024\_001 Check Unused Reserved IP addresses
- iam/sec\_2024\_001 Detect unused service accounts

#### New module

- Add billing module query and lint rules

#### Fixes

- Skip notebook instances query if API is not enabled
- Update MD formatting for gke/WARN/2023\_004.md
- Update conflicting credentials import name
- Updating EOL rule snapshot to match new schedule
- Update gke eol.yaml
- add str repr of RuleModule for more info in exceptions loading rules
- fixed bug in billing change 1673236 - added checks for correct permissions
- fixed bug in change id 2113602 - updated condition for check NAT config rule

#### Features and Improvements

- Improved report generation for runbook
- refactor lint.command.run to return a dict when run from API service
- Add set\_credentials() method
- Clear credentials used in API service after request
- Updated gke eol.yaml
- Added the id label to filter the Dataflow jobs using the job i

## 0.67 (2023-11-17)

#### Fixes

- Updating GKE EOL file and snapshot
- Rewording message triggering internal leak test

#### New Command and Rules

- Runbook POC with ssh runbook and terraform scripts

#### New rules

- GKE cluster has workload identity enabled
- Splunk job uses valid certificate

## 0.66 (2023-10-13)

#### Fixes

- Handle app failure when project policy contains cross-project service accounts
- Update the version skew for modern versions of Kubernetes. <https://kubernetes.io/blog/2023/08/15/kubernetes-v1-28-release/#changes-to-supported-skew-between-control-plane-and-node-versions>
- Updating working and typos in multiple files
- Update gke test snapshot.
- added content in md file for rule apigee\_err\_2023\_003

#### New rules

- bigquery/ERR/2023\_008: user not authorized to perform this action
- pubsub/WARN/2023\_005: bigquery subscription has apt permissions
- asm/ERR/2023\_001, asm/ERR/2023\_002: Anthos Service mesh
- gke/BP/2022\_003: Make GKE EOL detection more robust and less hardcoded
- gke/WARN/2023\_004: Add a check for too low `maxPodsPerNode` number
- gke/ERR/2023\_012: missing memory request for hpa
- bigquery/ERR/2023\_006: bigquery policy does not belong to user
- pubsub/WARN/2023\_00[14]: no subscription without attached topic
- composer/WARN/2023\_009: Cloud Composer Intermittent Task Failure during Scheduling

#### New module

- Anthos Service mash

## 0.65 (2023-09-18)

#### New rules

- apigee/ERR/2023\_006: Multiple migs for multiple regions
- vertex/WARN/2023\_001: New product: Vertex AI / new rule: check featurestores state
- pubsub/WARN/2023\_001: Check that the project does not have a detached subscription
- gke/ERR/2023\_011: GKE Metadata Server isn’t reporting errors for pod IP not found
- dataflow/WARN/2023\_006: Dataflow job stuck in canceling state for more than half hour
- vpc/WARN/2023\_001: Private service access not exporting custom routes
- interconnect/WARN/2023\_001: Interconnect attachment is not using dataplane v1
- interconnect/WARN/2023\_002: Checking if the VLAN attachment is in a non functional state
- pubsub/WARN/2023\_003: Topic has at least one attached subscription
- bigquery/ERR/2023\_007: Data Transfer Service Agent exists and has the required roles
- bigquery/WARN/2023\_002: BigQuery subscriptions have deadletter topic attached
- dataproc/ERR/2023\_007: Enough resources in region for dataproc cluster creation
- interconnect/WARN/2023\_003: Interconnect link is under maintenance

#### Fixes

- Account for GKE zones in vpc/WARN/2023\_002
- Refactor GCE label reference
- Update pipenv
- Fix typing Union in notebooks
- Add prefetch\_rule to notebooks rules
- Use more descriptive name for get-subscriptions method and account for deleted topics

## 0.64 (2023-08-14)

#### New rules

- gke/bp\_2023\_005\_gateway\_crd: manually installed gateway crd GKE
- gke/err\_2023\_010\_nodelocal\_timeout: nodelocal dns timeout GKE
- gke/err\_2023\_009\_missing\_cpu\_req: Missing CPU request GKE
- gke/err\_2023\_008\_crashloopbackoff: gke cluster had pods in crashloopbackoff error GKE
- gke/err\_2023\_006\_gw\_controller\_annotation\_error: GKE Gateway controller reporting misconfigured annotations in Gateway resource GKE
- gke/err\_2023\_007\_gw\_controller\_http\_route\_misconfig: GKE Gateway controller reporting invalid HTTPRoute for Gateway GKE
- dataflow/bp\_2023\_001\_dataflow\_supported\_sdk\_version\_check: Dataflow job using supported sdk version dataflow
- cloudsql/warn\_2023\_003\_high\_mem\_usage: Cloud SQL instance's memory usage does not exceed 90%
- cloudsql/bp\_ext\_2023\_003\_auto\_storage\_increases: Cloud SQL instance autoscaling is enabled
- gke/warn\_2023\_003\_monitoring\_api\_disabled: Cloud Monitoring API enabled when GKE monitoring is enabled

#### Fixes

- Remove references to deprecated oauth option in docs b/281956212
- Update diagram titles to remove “gcp doctor” reference
- Fix wrong cloudsql/WARN/2023\_003 MQL query cloudsql (external submission)
- gcs/bp\_2022\_001\_bucket\_access\_uniform: skip cloud build and dataproc buckets issue/61 b/293951741
- gce/warn\_2022\_001\_iap\_tcp\_forwarding: skip check for dataproc cluster vm instances
- gce/bp\_2021\_001\_serial\_logging\_enabled: skip check for dataproc cluster vm instances
- gke/bp\_2022\_003\_cluster\_eol: end of life version list dates updated

## 0.63 (2023-07-10)

#### Fixes

- Fix futures timeout error.

## 0.62 (2023-07-10)

#### New rules

- cloudsql/SEC/2023\_001: Cloud SQL is not publicly accessible (github #73)
- dataproc/ERR/2023\_002: Orphaned YARN application
- dataflow/ERR/2023\_007: Streaming Dataflow doesn't report being stuck because of firewall rules

#### Fixes

- Fix GCE API being erroneously required to run gcpdiag
- Fix locking issues in multi-threaded code
- Improve caching of API exceptions

## 0.61 (2023-06-30)

#### Fixes

- Fix attribute error on dnssec API call

## 0.60 (2023-06-29)

#### New rules

- apigee/ERR/2023\_003: Private Google Access (PGA) for subnet of Managed Instance Group is enabled
- apigee/ERR/2023\_004: Service Networking API is enabled and SA account has the required role
- apigee/ERR/2023\_005: External Load Balancer (XLB) is able to connect to the MIG
- bigquery/ERR/2023\_001: Jobs called via the API are all found
- bigquery/ERR/2023\_002: BigQuery hasn't reported any unknown datasets
- bigquery/ERR/2023\_003: BigQuery query job do not encounter resource exceeded error
- bigquery/ERR/2023\_004: BigQuery query job do not encounter dml concurrency issue
- bigquery/ERR/2023\_005: Scheduled query not failing due to outdated credentials
- bigquery/WARN/2023\_003: BigQuery query job does not fail with too many output columns error
- bigquery/WARN/2023\_004: BigQuery CMEK-related operations do not fail due to missing permissions
- bigquery/WARN/2023\_005: No errors querying wildcard tables
- cloudsql/BP/2023\_001: Cloud SQL is not assigned Public IP (github #65)
- cloudsql/BP/2023\_002: Cloud SQL is configured with automated backup
- cloudsql/BP\_EXT/2023\_001: Cloud SQL is defined with Maintenance Window as any (github #67)
- cloudsql/BP\_EXT/2023\_002: Cloud SQL is configured with Deletion Protection (github #68)
- cloudsql/BP\_EXT/2023\_003: Cloud SQL enables automatic storage increases feature
- cloudsql/BP\_EXT/2023\_004: Cloud SQL instance is covered by the SLA
- cloudsql/ERR/2023\_001: Cloud SQL instance should not be in SUSPENDED state
- cloudsql/WARN/2023\_001: Cloud SQL instance's log_output flag is not configured as TABLE
- cloudsql/WARN/2023\_002: Cloud SQL instance's avg CPU utilization is not over 98% for 6 hours
- cloudsql/WARN/2023\_003: Cloud SQL instance's memory usage does not exceed 90%
- composer/BP/2023\_001: Cloud Composer logging level is set to INFO
- composer/BP/2023\_002: Cloud Composer's worker concurrency is not limited by parallelism
- composer/BP/2023\_003: Cloud Composer does not override the StatsD configurations
- composer/BP\_EXT/2023\_001: Cloud Composer has no more than 2 Airflow schedulers
- composer/BP\_EXT/2023\_002: Cloud Composer has higher version than airflow-2.2.3
- composer/ERR/2023\_001: Cloud Composer is not in ERROR state
- composer/WARN/2023\_001: Cloud Composer does not override Kerberos configurations
- composer/WARN/2023\_002: Cloud Composer tasks are not interrupted by SIGKILL
- composer/WARN/2023\_003: Cloud Composer tasks are not failed due to resource pressure
- composer/WARN/2023\_004: Cloud Composer database CPU usage does not exceed 80%
- composer/WARN/2023\_005: Cloud Composer is consistently in healthy state
- composer/WARN/2023\_006: Airflow schedulers are healthy for the last hour
- composer/WARN/2023\_007: Cloud Composer Scheduler CPU limit exceeded
- composer/WARN/2023\_008: Cloud Composer Airflow database is in healthy state
- dataflow/ERR/2023\_001: Dataflow service account has dataflow.serviceAgent role
- dataflow/ERR/2023\_002: Dataflow job does not fail during execution due to IP space exhaustion
- dataflow/ERR/2023\_003: Dataflow job does not fail during execution due to incorrect subnet
- dataflow/ERR/2023\_004: Dataflow job does not fail due to organization policy constraints
- dataflow/ERR/2023\_005: Dataflow job does not fail during execution due credential or permission issue
- dataflow/ERR/2023\_006: Dataflow job fails if Private Google Access is disabled on subnetwork
- dataflow/WARN/2023\_001: Dataflow job does not have a hot key
- dataproc/ERR/2023\_002: No orphaned YARN application found
- dataproc/ERR/2023\_003: Dataproc cluster service account permissions
- dataproc/ERR/2023\_004: Dataproc firewall rules for connectivity between master and worker nodes
- dataproc/ERR/2023\_005: Dataproc cluster has sufficient quota
- dataproc/ERR/2023\_006: DataProc cluster user has networking permissions on host project
- gce/WARN/2023\_001: GCE snapshot policies are defined only for used disks
- gke/ERR/2023\_004: GKE ingresses are well configured
- gke/ERR/2023\_005: Workloads not reporting misconfigured CNI plugins
- iam/BP/2023\_001: Policy constraint 'AutomaticIamGrantsForDefaultServiceAccounts' enforced
- interconnect/BP/2023\_001: VLAN attachments deployed in same metro are in different EADs
- lb/BP/2023\_001: Cloud CDN is enabled on backends for global external load balancers
- notebooks/BP/2023\_001: Vertex AI Workbench instance enables system health report
- notebooks/BP/2023\_003: Vertex AI Workbench runtimes for managed notebooks are up to date
- notebooks/ERR/2023\_002: Vertex AI Workbench account has compute.subnetworks permissions
- notebooks/ERR/2023\_003: Vertex AI Workbench account has permissions to create and use notebooks
- notebooks/ERR/2023\_004: Vertex AI Workbench runtimes for managed notebooks are healthy
- notebooks/WARN/2023\_001: Vertex AI Workbench instance is not being OOMKilled
- notebooks/WARN/2023\_002: Vertex AI Workbench instance is in healthy data disk space status
- notebooks/WARN/2023\_003: Vertex AI Workbench instance is in healthy boot disk space status
- vpc/SEC/2023\_001: DNSSEC is enabled for public zones
- vpc/WARN/2023\_002: Private zone is attached to a VPC

#### Enhancements

- Support for sub project resource filtering (`--name`, `--location`, `--label`)
- Support fetching serial port output logs from Compute API (`--enable-gce-serial-buffer`)
- New product: Cloud Dataflow
- New product: Cloud Interconnect
- Add kubectl query module
- Optimizations for logging based composer rules

#### Fixes

- gke/BP/2022\_003: updated EOL schedule for GKE
- Fix billing project id not set at startup (github #58)
- Fix JSON format with --output=json (github #62)
- Fix GCS uniform bucket access detection (github #69)
- dataproc/WARN/2022\_002: fix attribute lookup error (github #57)
- gke/WARN/2021\_003: update GKE pod cidr rule to report values per pod cidr range

## 0.59 (2023-04-14)

#### New rules

- apigee/ERR/2023\_001: Customer's network is peered to Apigee's network
- apigee/ERR/2023\_002: Network bridge managed instance group is correctly configured
- bigquery/WARN/2022\_003: BigQuery copy job does not exceed the daily copy quota
- bigquery/WARN/2022\_004: BigQuery copy job does not exceed the cross-region daily copy quota
- bigquery/WARN/2023\_001: BigQuery query job does not time out during execution
- composer/WARN/2022\_003: Composer scheduler parses all DAG files without overloading
- datafusion/ERR/2022\_008: Cloud Data Fusion SA has Service Account User permissions on the Dataproc SA
- datafusion/ERR/2022\_009: Cloud Dataproc Service Account has a Cloud Data Fusion Runner role
- datafusion/ERR/2022\_010: Cloud Dataproc Service Account has a Dataproc Worker role
- datafusion/ERR/2022\_011: The Dataproc SA for a CDF instance with version > 6.2.0 has Storage Admin role
- dataproc/ERR/2022\_004: Dataproc on GCE master VM is able to communicate with at least one worker VM
- dataproc/ERR/2023\_001: Dataproc cluster initialization completed by the end of the timeout period
- dataproc/WARN/2022\_004: Cluster should normally spend most of the time in RUNNING state
- dataproc/WARN/2023\_001: Concurrent Job limit was not exceeded
- dataproc/WARN/2023\_002: Master Node System Memory utilization under threshold
- gae/ERR/2023\_001: App Engine: VPC Connector creation failure due to Org Policy
- gae/ERR/2023\_002: App Engine: VPC Connector creation due to subnet overlap
- gcb/ERR/2022\_004: Cloud Build Service Agent has the cloudbuild.serviceAgent role
- gce/BP/2023\_001: GCE Instances follows access scope best practice
- gce/BP/2023\_001: Instance time source is configured with Google NTP server
- gce/ERR/2022\_002: Serial logs don't contain Guest OS activation errors
- gce/WARN/2022\_010: GCE has enough resources available to fulfill requests
- gce/WARN/2022\_011: GCE VM service account is valid
- gce/WARN/2022\_012: Validate if a Microsoft Windows instance is able to activate using GCP PAYG licence
- gke/BP/2023\_001: GKE network policy minimum requirements
- gke/BP/2023\_002: Stateful workloads do not run on preemptible node
- gke/BP/2023\_004: GKE clusters are VPC-native
- gke/BP_EXT/2023\_003: GKE maintenance windows are defined
- gke/ERR/2023\_001: Container File System API quota not exceeded
- gke/ERR/2023\_002: GKE private clusters are VPC-native
- gke/ERR/2023\_003: containerd config.toml is valid
- gke/WARN/2023\_001: Container File System has the required scopes for Image Streaming
- gke/WARN/2023\_002: GKE workload timeout to Compute Engine metadata server
- lb/BP/2022\_001: LocalityLbPolicy compatible with sessionAffinity
- notebooks/ERR/2023\_001: Vertex AI Workbench user-managed notebook instances are healthy
- vpc/BP/2022\_001: Explicit routes for Google APIs if the default route is modified
- vpc/BP/2023\_001: DNS logging is enabled for public zones

#### Enhancements

- New product: Cloud Load Balancing
- New product: Vertex AI Workbench Notebooks
- Experimental asynchronous IO execution (not enabled by default)
- gcb/ERR/2022\_002: Check access to images hosted in gcr.io repositories
- Add support for interconnect API
- Extract project id from email when fetching service accounts instead of using
  wildcard, making IAM service account checks more reliable.
- --project now accepts project numbers in addition to project ids

#### Fixes

- gke/BP/2022\_003: updated EOL schedule for GKE
- Fix 403 error on userinfo API call

## 0.58 (2022-11-08)

#### Deprecation

- Python 3.9+ is required for gcpdiag. Python 3.8 and older versions support is deprecated.
- Deprecated authentication using OAuth (`--auth-oauth`) has been removed.

#### New rules

- apigee/ERR/2022\_002: Verify whether Cloud KMS key is enabled and could be accessed by Apigee Service Agent
- datafusion/ERR/2022\_003: Private Data Fusion instance is peered to the tenant project
- datafusion/ERR/2022\_004: Cloud Data Fusion Service Account has necessary permissions
- datafusion/ERR/2022\_005: Private Data Fusion instance has networking permissions
- datafusion/ERR/2022\_006: Private Google Access enabled for private Data Fusion instance subnetwork
- datafusion/ERR/2022\_007: Cloud Data Fusion Service Account exists at a Project
- gke/BP/2022\_004: GKE clusters should have HTTP load balancing enabled to use GKE ingress

#### Enhancements

- Python dependencies updated

#### Fixes

- gke/ERR/2021\_002: skip if there are no GKE clusters

## 0.57 (2022-09-29)

#### Deprecation

- Default authentication using OAuth (`--auth-oauth`) is now deprecated and Application Default Credentials (`--auth-adc`) will be used instead. Alternatively you can use Service Account private key (`--auth-key FILE`).

#### New rules

- apigee/WARN/2022\_001: Verify whether all environments has been attached to Apigee X instances
- apigee/WARN/2022\_002: Environment groups are created in the Apigee runtime plane
- cloudrun/ERR/2022\_001: Cloud Run service agent has the run.serviceAgent role
- datafusion/ERR/2022\_001: Firewall rules allow for Data Fusion to communicate to Dataproc VMs
- datafusion/ERR/2022\_002: Private Data Fusion instance has valid host VPC IP range
- dataproc/WARN/2022\_001: Dataproc VM Service Account has necessary permissions
- dataproc/WARN/2022\_002: Job rate limit was not exceeded
- gcf/ERR/2022\_002: Cloud Function deployment failure due to Resource Location Constraint
- gcf/ERR/2022\_003: Function invocation interrupted due to memory limit exceeded
- gke/WARN/2022/\_008: GKE connectivity: possible dns timeout in some gke versions
- gke/WARN/2022\_007: GKE nodes need Storage API access scope to retrieve build artifacts
- gke/WARN/2022\_008: GKE connectivity: possible dns timeout in some gke versions

#### Enhancements

- New product: Cloud Run
- New product: Data Fusion

#### Fixes

- gcf/WARN/2021\_002: Added check for MATCH_STR
- gcs/BP/2022\_001: KeyError: 'iamConfiguration'
- gke/ERR/2022\_003: unhandled exception
- gke/WARN/2022\_005: Incorrectly report missing "nvidia-driver-installer" daemonset
- iam/SEC/2021\_001: unhandled exception

## 0.56 (2022-07-18)

#### New rules

- bigquery/ERR/2022\_001: BigQuery is not exceeding rate limits
- bigquery/ERR/2022\_001: BigQuery jobs not failing due to concurrent DML updates on the same table
- bigquery/ERR/2022\_002: BigQuery jobs are not failing due to results being larger than the maximum response size
- bigquery/ERR/2022\_003: BigQuery jobs are not failing while accessing data in Drive due to a permission issue
- bigquery/ERR/2022\_004: BigQuery jobs are not failing due to shuffle operation resources exceeded
- bigquery/WARN/2022\_002: BigQuery does not violate column level security
- cloudsql/WARN/2022\_001: Docker bridge network should be avoided
- composer/WARN/2022\_002: fluentd pods in Composer environments are not crashing
- dataproc/ERR/2022\_003: Dataproc Service Account permissions
- dataproc/WARN/2022\_001: Dataproc clusters are not failed to stop due to the local SSDs
- gae/WARN/2022\_002: App Engine Flexible versions don't use deprecated runtimes
- gcb/ERR/2022\_002: Cloud Build service account registry permissions
- gcb/ERR/2022\_003: Builds don't fail because of retention policy set on logs bucket
- gce/BP/2022\_003: detect orphaned disks
- gce/ERR/2022\_001: Project limits were not exceeded
- gce/WARN/2022\_004: Cloud SQL Docker bridge network should be avoided
- gce/WARN/2022\_005: GCE CPU quota is not near the limit
- gce/WARN/2022\_006: GCE GPU quota is not near the limit
- gce/WARN/2022\_007: VM has the proper scope to connect using the Cloud SQL Admin API
- gce/WARN/2022\_008: GCE External IP addresses quota is not near the limit
- gce/WARN/2022\_009: GCE disk quota is not near the limit
- gcf/ERR/2022\_001: Cloud Functions service agent has the cloudfunctions.serviceAgent role
- gcf/WARN/2021\_002: Cloud Functions have no scale up issues
- gke/BP\_EXT/2022\_001: Google Groups for RBAC enabled (github #12)
- gke/WARN/2022\_006: GKE NAP nodes use a containerd image
- tpu/WARN/2022\_001: Cloud TPU resource availability
- vpc/WARN/2022\_001: Cross Project Networking Service projects quota is not near the limit

#### Updated rules

- dataproc/ERR/2022\_002: fix os version detection (github #26)
- gke/BP/2022\_003: update GKE EOL schedule
- gke/ERR/2022\_001: fix KeyError exception
- gke/BP/2022\_002: skip legacy VPC

#### Enhancements

- Add support for multiple output formats (--output=csv, --output=json)
- Better handle CTRL-C signal
- Org policy support
- New product: CloudSQL
- New product: VPC
- Renamed product "GAES" to "GAE" (Google App Engine)
- Publish internal API documentation on <https://gcpdiag.dev/docs/development/api/>
- Update Python dependencies

## 0.55 (2022-04-25)

Version 0.55 was released with the same code as 0.54. The release was used
to facilitate the transition of binaries to another location.

## 0.54 (2022-04-25)

#### New rules

- apigee/ERR/2022_001: Apigee Service Agent permissions

#### Enhancements

- dynamically load gcpdiag lint rules for all products
- support IAM policy retrieval for Artifact Registry
- move gcpdiag release buckets to new location

#### Fixes

- gke/ERR/2022_002: use correct network for shared VPC scenario (#24)
- error out early if service accounts of inspected projects can't be retrieved
- fix docker wrapper script for --config and --auth-key options
- allow to create test projects in an org folder
- ignore more system service accounts (ignore all accounts starting with gcp-sa)

## 0.53 (2022-03-30)

#### New rules

- composer/ERR/2022_001: Composer Service Agent permissions
- composer/ERR/2022_002: Composer Environment Service Account permissions
- composer/WARN/2022_001: Composer Service Agent permissions for Composer 2.x
- gce/BP_EXT/2022_001: GCP project has VM Manager enabled
- gce/WARN/2022_003: GCE VM instances quota is not near the limit
- gke/BP/2022_002: GKE clusters are using unique subnets
- gke/BP/2022_003: GKE cluster is not near to end of life
- gke/WARN/2022_003: GKE service account permissions to manage project firewall rules
- gke/WARN/2022_004: Cloud Logging API enabled when GKE logging is enabled
- gke/WARN/2022_005: NVIDIA GPU device drivers are installed on GKE nodes with GPU

#### Enhancements

- Support IAM policies for service accounts and subnetworks
- Skip rules using logs if Cloud Logging API is disabled
- New option: --logs-query-timeout
- Add support for configuration files
  (see <https://gcpdiag.dev/docs/usage/#configuration-file>)

#### Fixes

- Fix various unhandled exceptions

## 0.52 (2022-02-11)

#### New rules

- dataproc/BP/2022_001: Cloud Monitoring agent is enabled.
- dataproc/ERR/2022_002: Dataproc is not using deprecated images.
- gce/WARN/2022_001: IAP service can connect to SSH/RDP port on instances.
- gce/WARN/2022_002: Instance groups named ports are using unique names.
- gke/ERR/2022_002: GKE nodes of private clusters can access Google APIs and services.
- gke/ERR/2022_003: GKE connectivity: load balancer to node communication (ingress).

#### Updated rules

- gcb/ERR/2022_001: Fix false positive when no build is configured.
- gke/WARN/2021_008: Improve Istio deprecation message

#### Enhancements

- Introduce "extended" rules (BP_EXT, ERR_EXT, etc.), disabled by default
  and which can be enabled with --include-extended.
- Large IAM policy code refactorings in preparation for org-level IAM
  policy support.

#### Fixes

- More API retry fixes.
- Fix --billing-project which had no effect before.
- Fix exception related to GCE instance scopes.

## 0.51 (2022-01-21)

#### Fixes

- Update Python dependencies, and add 'packaging', missing in the docker image.

## 0.50 (2022-01-21)

#### New rules

- gcb/ERR/2022_001: The Cloud Build logs do not report permission issues
- gce/BP/2021_002: GCE nodes have an up to date ops agent
- gce/BP/2021_003: Secure Boot is enabled
- gce/ERR/2021_004: Serial logs don’t contain Secure Boot errors
- gce/ERR/2021_005: Serial logs don't contain mount error messages
- gce/WARN/2021_005: Serial logs don't contain out-of-memory messages
- gce/WARN/2021_006: Serial logs don't contain "Kernel panic" messages
- gce/WARN/2021_007: Serial logs don't contain "BSOD" messages
- gcs/BP/2022_001: Buckets are using uniform access
- gke/BP/2022_001: GKE clusters are regional
- gke/ERR/2022_001: GKE connectivity: pod to pod communication
- gke/WARN/2022_001: GKE clusters with workload identity are regional
- gke/WARN/2022_002: GKE metadata concealment is not in use

#### Updated rules

- gcf/WARN/2021_001: add one more deprecated runtime Nodejs6 (github #17)

#### Enhancements

- New product: App Engine Standard
- New product: Cloud Build
- New product: Cloud Pub/Sub
- New product: Cloud Storage

#### Fixes

- Verify early that IAM API is enabled
- Catch API errors in prefetch_rule
- Disable italic in Cloud Shell
- Implement retry logic for batch API failures

## 0.49 (2021-12-20)

#### New / updated rules

- dataproc/BP/2021_001: Dataproc Job driver logs are enabled
- composer/WARN/2021_001: Composer environment status is running (b/207615409)
- gke/ERR/2021_013: GKE cluster firewall rules are configured. (b/210407018)
- gke/ERR/2021_014: GKE masters of can reach the nodes. (b/210407018)
- gke/ERR/2021_015: GKE connectivity: node to pod communication. (b/210407018)
- gce/WARN/2021_001: verify logging access scopes (b/210711351)
- gce/WARN/2021_003: verify monitoring access scopes (b/210711351)

#### Enhancements

- New product: Cloud Composer (b/207615409)
- Simplify API testing by using ephemeral projects (b/207484323)
- gcpdiag.sh wrapper script now verifies the minimum version of current script
- Add support for client-side firewall connectivity tests (b/210407018)

#### Fixes

## 0.48 (2021-11-15)

#### New rules

- apigee/WARN/2021_001: Every env. group has at least one env. (b/193733957)
- dataproc/WARN/2021_001: Dataproc cluster is in RUNNING state (b/204850980)

#### Enhancements

- Use OAuth authentication by default (b/195908593)
- New product: Dataproc (b/204850980)
- New product: Apigee (b/193733957)

#### Fixes

- Fix GitHub actions with newest pipenv

## 0.47 (2021-11-01)

#### New rules

- gce/WARN/2021_004: check serial output for 'disk full' messages (b/193383069)

#### Enhancements

- Add podman support in wrapper script

#### Fixes

- Fix gcf KeyError when API enabled but no functions defined (b/204516746)

## 0.46 (2021-10-27)

#### New rules

- gce/WARN/2021_003: gce service account monitoring permissions (b/199277342)
- gcf/WARN/2021_001: cloud functions deprecated runtimes
- gke/WARN/2021_009: deprecated node image types (b/202405661)

#### Enhancements

- New website! <https://gcpdiag.dev>
- Rule documentation permalinks added to lint output (b/191612825)
- Added --include and --exclude arguments to filter rules to run (b/183490284)

## 0.45 (2021-10-08)

#### Enhancements

- Use --auth-adc by default for all non-google.com users (b/202488675)

## 0.44 (2021-10-07)

#### New rules

- gke/ERR/2021_009: gke cluster and node pool version skew (b/200559114)
- gke/ERR/2021_010: clusters are not facing ILB quota issues (b/193382041)
- gke/ERR/2021_011: ip-masq-agent errors (b/199480284)
- iam/SEC/2021_001: no service account has owner role (b/201526416)

#### Enhancements

- Improve error message for --auth-adc authentication errors (b/202091830)
- Suggest gcloud command if CRM API is not enabled
- Use --auth-adc by default in Cloud Shell (b/201996404)
- Improve output with hidden items
- Update docker image to python:3.9-slim

#### Fixes

- Make the docker wrapper macos-compatible (GH-10)
- Exclude fleet workload identities from SA disabled check (b/201631248)


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of
experience, education, socioeconomic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

*   Using welcoming and inclusive language
*   Being respectful of differing viewpoints and experiences
*   Gracefully accepting constructive criticism
*   Focusing on what is best for the community
*   Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

*   The use of sexualized language or imagery and unwelcome sexual attention or
    advances
*   Trolling, insulting/derogatory comments, and personal or political attacks
*   Public or private harassment
*   Publishing others' private information, such as a physical or electronic
    address, without explicit permission
*   Other conduct which could reasonably be considered inappropriate in a
    professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

This Code of Conduct also applies outside the project spaces when the Project
Steward has a reasonable belief that an individual's behavior may have a
negative impact on the project or its community.

## Conflict Resolution

We do not believe that all conflict is bad; healthy debate and disagreement
often yield positive results. However, it is never okay to be disrespectful or
to engage in behavior that violates the project’s code of conduct.

If you see someone violating the code of conduct, you are encouraged to address
the behavior directly with those involved. Many issues can be resolved quickly
and easily, and this gives people more control over the outcome of their
dispute. If you are unable to resolve the matter for any reason, or if the
behavior is threatening or harassing, report it. We are dedicated to providing
an environment where participants feel welcome and safe.

Reports should be directed to David Schweikert <dwes@google.com>, the
Project Steward(s) for gcpdiag. It is the Project Steward’s duty to
receive and address reported violations of the code of conduct. They will then
work with a committee consisting of representatives from the Open Source
Programs Office and the Google Open Source Strategy team. If for any reason you
are uncomfortable reaching out to the Project Steward, please email
opensource@google.com.

We will investigate every complaint, but you may not receive a direct response.
We will use our discretion in determining when and how to follow up on reported
incidents, which may range from not taking action to permanent expulsion from
the project and project-sponsored spaces. We will notify the accused of the
report and provide them an opportunity to discuss it before any action is taken.
The identity of the reporter will be omitted from the details of the report
supplied to the accused. In potentially harmful situations, such as ongoing
harassment or threats to anyone's safety, we may take action without notice.

## Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html


================================================
FILE: CONTRIBUTING.md
================================================
# How to Contribute

We'd love to accept your patches and contributions to this project. There are
just a few small guidelines you need to follow.

## Contributor License Agreement

Contributions to this project must be accompanied by a Contributor License
Agreement (CLA). You (or your employer) retain the copyright to your
contribution; this simply gives us permission to use and redistribute your
contributions as part of the project. Head over to
<https://cla.developers.google.com/> to see your current agreements on file or
to sign a new one.

You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.

## Code Reviews

All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.

## Community Guidelines

This project follows
[Google's Open Source Community Guidelines](https://opensource.google/conduct/).


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: Makefile
================================================
VERSION=$(shell sed -n 's/^current_version\s*=\s*//p' <.bumpversion.cfg)
DIST_NAME=gcpdiag-$(VERSION)
SHELL=/bin/bash

.PHONY: test coverage-report version build bump-version tarfile release runbook-docs runbook-starter-code spelling

# Comprehensive environment check.
check-environment:
	@command -v pipenv >/dev/null 2>&1 || { echo >&2 "ERROR: pipenv is not installed. Please run 'pip install pipenv' and try again."; exit 1; }
	@if [ -z "$$(pipenv --venv)" ]; then \
		echo "Pipenv environment not created. Please run 'pipenv install --dev'."; \
		exit 1; \
	fi
	@pipenv check || { \
		REQUIRED_PYTHON_VERSION=$$(sed -n 's/^python_version\s*=\s*"\(.*\)"/\\1/p' < Pipfile); \
		echo >&2 "ERROR: Pipenv check failed. Your Python version might be incorrect."; \
		echo >&2 "Please run 'pipenv --rm && pipenv --python $$REQUIRED_PYTHON_VERSION install --dev' to fix this."; \
		exit 1; \
	}

test: check-environment
	pipenv run pytest -o log_level=DEBUG --cov-config=.coveragerc --cov=gcpdiag --forked

coverage-report:
	pipenv run pytest --cov-config=.coveragerc --cov=gcpdiag --forked --cov-report html --cov-report term-missing
	@echo ""
	@echo "To view the report, run the following command in your terminal:"
	@echo "python3 -m http.server 8080"
	@echo "Then open http://localhost:8080/htmlcov/ in your browser."

test_async_api:
	python -m unittest gcpdiag.async_queries.api.api_slowtest

test-mocked:
	# run gcpdiag-mocked and verify that the exit status is what we expect
	bin/gcpdiag-mocked lint --auth-adc --project=gcpdiag-gke1-aaaa; \
	  EXIT_CODE=$$?; \
	  if [ $$EXIT_CODE != 2 ]; then echo "incorrect exit code $$EXIT_CODE" >&2; exit 1; fi; \
	  exit 0

spelling:
	 pip install -U PyEnchant; pylint --disable all --enable spelling --spelling-dict en_US gcpdiag

snapshots:
	pytest --snapshot-update --forked -v -v

gke-eol-file:
	./gcpdiag/lint/gke/eol_parser.sh > gcpdiag/lint/gke/eol.yaml

version:
	@echo $(VERSION)

build:
	rm -f dist/gcpdiag
	pyinstaller --workpath=.pyinstaller.build pyinstaller.spec

bump-version:
	bumpversion --commit minor

new-rule:
	python cookiecutter-gcpdiag-rule/cookiecutter_runner.py

tarfile:
	# TODO: replace with something based on setuptools?
	rm -rf dist-tmp
	mkdir -p dist-tmp/$(DIST_NAME)/bin
	cp Pipfile Pipfile.lock README.md dist-tmp/$(DIST_NAME)
	cp bin/gcpdiag dist-tmp/$(DIST_NAME)/bin
	chmod +x dist-tmp/$(DIST_NAME)/bin/gcpdiag
	cp --parents gcpdiag/queries/client_secrets.json dist-tmp/$(DIST_NAME)
	find gcpdiag -name '*.py' -exec cp --parents '{}' dist-tmp/$(DIST_NAME) ';'
	find gcpdiag -name '*.jinja' -exec cp --parents '{}' dist-tmp/$(DIST_NAME) ';'
	find gcpdiag/runbook/gce/disk_performance_benchmark -name '*.json' -exec cp --parents '{}' dist-tmp/$(DIST_NAME) ';'
	chmod -R a+rX dist-tmp
	mkdir -p dist
	tar -C dist-tmp -czf dist/gcpdiag-$(VERSION).tar.gz --owner=0 --group=0 gcpdiag-$(VERSION)
	rm -rf dist-tmp

release:
	# Make sure we are using the latest submitted code.
	git fetch
	git checkout origin/master
	# Remove '-test' in the version.
	# Note: this will fail if we have already a release tag, in which case
	# you should first increase the minor version with a code review.
	bumpversion --commit --tag --tag-message "Release v{new_version}" release
	# Push to the release branch and tag the release.
	# Note: We want ff-only because otherwise the commit ids will be different
	# between master and release, and that causes problems with tags
	# (and in particular the version tag pointing to a commit in the release
	# branch, so that git describe doesn't work correctly in master, which
	# itself disrupts the creation of tags in GitHub by Copybara),
	# If this fails, you probably should force-push from master to the
	# release branch. The release branch is only used to kick off releases
	# in Kokoro.
	git merge --ff-only origin/release
	git push origin HEAD:release
	git push --tags
	# increment the version (and add back '-test')
	bumpversion --commit minor
	git push origin HEAD:refs/for/master

runbook-docs:
  # Help developers generate and update docs before actually running full precommit
	pre-commit run gcpdiag-custom-runbook-rule

runbook-starter-code:
	@[ "$(name)" ] || (echo "name is not set. Usage: make $@ name=product/runbook-id" && false)
	@PYTHON=`which python3 || which python`;\
	if [ -z "$$PYTHON" ]; then \
		echo "Python is not installed or not found in PATH"; \
		exit 1; \
	fi;\
	echo "Using Python at $$PYTHON"; \
	$$PYTHON bin/runbook-starter-code-generator py_path=$$PYTHON name=$(name) prepenv=$(prepenv)


================================================
FILE: PRIVACY.md
================================================
See: https://gcpdiag.dev/privacy


================================================
FILE: Pipfile
================================================
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"

[requires]
python_version = "3.12"

[packages]
aiohttp = "*"
appdirs = "*"
boltons = "*"
blessings = "*"
dataclasses = "==0.6"
diskcache = "*"
dnspython = "*"
google-api-python-client = "*"
google-auth-oauthlib = "*"
importlib-resources = "*"
jinja2 = ">=3.0.0"
packaging = "==23.*"
python-dateutil = "*"
pyyaml = "*"
ratelimit = "*"
six = "==1.16.0"
# Python 3.7 compatibility
typing-extensions = "*"
# Python 3.9 compatibility
exceptiongroup = "*"
beautifulsoup4 = "*"
async-timeout = "*"
bs4 = "*"

[dev-packages]
absl-py = "*"
astunparse = "*"
bump2version = "*"
coverage = "*"
dnspython = "*"
importlib-metadata = "*"
isort = "==5.12.0"
mypy = "*"
pdoc = "*"
pre-commit = "*"
pyinstaller = "*"
pytest = "*"
pytest-cov = "*"
pytest-forked = "*"
pytest-snapshot = "*"
yapf = "*"
pylint = "*"
# for vim:
# pip install 'python-language-server[yapf,pyflakes,mccabe]'
safety = "*"
types-pyyaml = "*"
cookiecutter = "*"


================================================
FILE: README.md
================================================
# gcpdiag - Diagnostics for Google Cloud Platform

[![code analysis badge](https://github.com/GoogleCloudPlatform/gcpdiag/actions/workflows/code-analysis.yml/badge.svg?branch=main&event=push)](https://github.com/GoogleCloudPlatform/gcpdiag/actions/workflows/code-analysis.yml?query=branch%3Amain+event%3Apush)
[![test badge](https://github.com/GoogleCloudPlatform/gcpdiag/actions/workflows/test.yml/badge.svg?branch=main&event=push)](https://github.com/GoogleCloudPlatform/gcpdiag/actions/workflows/test.yml?query=branch%3Amain+event%3Apush)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/GoogleCloudPlatform/gcpdiag/badge)](https://scorecard.dev/viewer/?uri=github.com/GoogleCloudPlatform/gcpdiag)


**gcpdiag** is a command-line diagnostics tool for GCP customers. It finds and
helps to fix common issues in Google Cloud Platform projects. It is used to test
projects against a wide range of best practices and frequent mistakes, based on
the troubleshooting experience of the Google Cloud Support team.

gcpdiag is open-source and contributions are welcome! Note that this is not an
officially supported Google product, but a community effort. The Google Cloud
Support team maintains this code and we do our best to avoid causing any
problems in your projects, but we give no guarantees to that end.

<img src="docs/gcpdiag-demo-2021-10-01.gif" alt="gcpdiag demo" width="800"/>

## Installation

You can run gcpdiag using a shell wrapper that starts gcpdiag in a Docker
container. This should work on any machine with Docker or Podman installed,
including Cloud Shell.

```
curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag
chmod +x gcpdiag
./gcpdiag lint --project=MYPROJECT
```

## Usage

Currently gcpdiag mainly supports subcommand: `lint` and `Runbooks`, which is
used to run diagnostics on one or more GCP projects.

### LINT

```
usage:

gcpdiag lint --project P [OPTIONS]
gcpdiag lint --project P [--name faulty-vm --location us-central1-a --label key:value]

Run diagnostics in GCP projects.

optional arguments:
  -h, --help            show this help message and exit
  --auth-adc            Authenticate using Application Default Credentials (default)
  --auth-key FILE       Authenticate using a service account private key file
  --project P           Project ID of project to inspect
  --name n [n ...]      Resource Name(s) to inspect (e.g.: bastion-host,prod-*)
  --location R [R ...]  Valid GCP region/zone to scope inspection (e.g.: us-central1-a,us-central1)
  --label key:value     One or more resource labels as key-value pair(s) to scope inspection
                        (e.g.:  env:prod, type:frontend or env=prod type=frontend)
  --billing-project P   Project used for billing/quota of API calls done by gcpdiag (default is the inspected project, requires
                        'serviceusage.services.use' permission)
  --show-skipped        Show skipped rules
  --hide-ok             Hide rules with result OK
  --enable-gce-serial-buffer
                        Fetch serial port one output directly from the Compute API. Use this flag when not exporting
                        serial port output to cloud logging.
  --include INCLUDE     Include rule pattern (e.g.: `gke`, `gke/*/2021*`). Multiple pattern can be specified (comma separated, or with multiple
                        arguments)
  --exclude EXCLUDE     Exclude rule pattern (e.g.: `BP`, `*/*/2022*`)
  --include-extended    Include extended rules. Additional rules might generate false positives (default: False)
  -v, --verbose         Increase log verbosity
  --within-days D       How far back to search logs and metrics (default: 3 days)
  --config FILE         Read configuration from FILE
  --logging-ratelimit-requests R
                        Configure rate limit for logging queries (default: 60)
  --logging-ratelimit-period-seconds S
                        Configure rate limit period for logging queries (default: 60 seconds)
  --logging-page-size P
                        Configure page size for logging queries (default: 500)
  --logging-fetch-max-entries E
                        Configure max entries to fetch by logging queries (default: 10000)
  --logging-fetch-max-time-seconds S
                        Configure timeout for logging queries (default: 120 seconds)
  --output FORMATTER    Format output as one of [terminal, json, csv] (default: terminal)
  --test-release        Runs the latest gcpdiag test release. (e.g.: --test-release=staging)
```

#### RUNBOOK

```
usage:

gcpdiag runbook --project=project_id -p "param_name=param_value" [OPTIONS]

example:
gcpdiag runbook gce/ssh --project "project_id" -p "name=vm-id" -p "zone=us-central1-a"

optional arguments:
  -h, --help                              show this help message and exit
  --auth-adc                              Authenticate using Application Default Credentials
  --auth-key FILE                         Authenticate using a service account private key file
  --billing-project P                     Project used for billing/quota of API calls done by
                                          gcpdiag (default is the inspected project, requires 'serviceusage.services.use' permission)
  -v                                      Increase log verbosity
  --test-release                          Runs the latest gcpdiag test release. (e.g.: --test-release=staging)

  Descriptions for Logging Options logging-related options:
  --logging-ratelimit-requests R`:        rate limit for API requests.
  --logging-ratelimit-period-seconds S`:  period in seconds for the API rate limit.
  --logging-page-size P`:                 page size for API requests.
  --logging-fetch-max-entries E`:         maximum number of entries to fetch.
  --logging-fetch-max-time-seconds S`:    maximum time in seconds to fetch logs.
```

##### BUNDLE

Create a YAML file to execute a "bundle" of individual runbook steps. This YAML
file allows you to define multiple bundles, each containing specific parameters
and steps to execute.

***Ex: test.yaml***

```
- bundle:
  # Define the parameters that will be used in the steps.
  parameter:
    project_id: "project_name"
    zone: "zone_name"
    instance_name: "instance_name"
  # Define the steps that will be executed.
  steps:
    - gcpdiag.runbook.gce.generalized_steps.VmLifecycleState
    - gcpdiag.runbook.gce.ops_agent.VmHasAServiceAccount
    - gcpdiag.runbook.gce.ssh.PosixUserHasValidSshKeyCheck

- bundle:
  # Define the parameters that will be used in the steps.
  parameter:
    project_id: "project_name"
    principal: "project_name@appspot.gserviceaccount.com"
  # Define the steps that will be executed.
  steps:
    - gcpdiag.runbook.iam.generalized_steps.IamPolicyCheck
    - gcpdiag.runbook.gcf.failed_deployments.DefaultServiceAccountCheck
```

In this example, two bundles are defined:

*   The first bundle includes parameters for a GCE instance and executes three
    steps related to VM lifecycle, Ops Agent, and SSH key validation.
*   The second bundle includes parameters for a service account and executes two
    steps related to IAM policy and GCF default service account.

***Executing a yaml file :***

```
gcpdiag runbook --bundle-spec  test.yaml
```

## Development

### Coverage Report

To generate a coverage report, run:

```
make coverage-report
```

This will run tests and generate an HTML coverage report. At the end of
the execution, it will give you instructions on how to view the report in your
browser.

## Further Information

See <http://gcpdiag.dev> for more information:

-   [Documentation](https://gcpdiag.dev/docs/)
-   [Lint rule description](https://gcpdiag.dev/rules/)
-   [Runbook description](https://gcpdiag.dev/runbook/)
-   [Development guides](https://gcpdiag.dev/docs/development/)

## Authentication

gcpdiag supports authentication using multiple mechanisms:

1.  Application default credentials

    gcpdiag can use Cloud SDK's
    [Application Default Credentials](https://google-auth.readthedocs.io/en/latest/reference/google.auth.html#google.auth.default).
    This might require that you first run `gcloud auth login --update-adc` to
    update the cached credentials. This is the default in Cloud Shell because in
    that environment, ADC credentials are automatically provisioned.

1.  Service account key

    You can also use the `--auth-key` parameter to specify the
    [private key](https://cloud.google.com/iam/docs/creating-managing-service-account-keys)
    of a service account.

The authenticated principal will need as minimum the following roles granted
(both of them):

-   `Viewer` on the inspected project
-   `Service Usage Consumer` on the project used for billing/quota enforcement,
    which is per default the project being inspected, but can be explicitly set
    using the `--billing-project` option

The Editor and Owner roles include all the required permissions, but if you use
service account authentication (`--auth-key`), we recommend to only grant the
Viewer+Service Usage Consumer on that service account.

## Test Products, Classes, and IDs

Tests are organized by product, class, and ID.

The **product** is the GCP service that is being tested. Examples: GKE or GCE.

The **class** is what kind of test it is, currently we have:

Class name | Description
---------- | -----------------------------------------------
BP         | Best practice, opinionated recommendations
WARN       | Warnings: things that are possibly wrong
ERR        | Errors: things that are very likely to be wrong
SEC        | Potential security issues

The **ID** is currently formatted as YYYY_NNN, where YYYY is the year the test
was written, and NNN is a counter. The ID must be unique per product/class
combination.

Each test also has a **short_description** and a **long_description**. The short
description is a statement about the **good state** that is being verified to be
true (i.e. we don't test for errors, we test for compliance, i.e. an problem not
to be present).

## Adding Support for New GCP Products

When adding lint rules or runbooks for a new GCP product that gcpdiag doesn't
currently support, you need to update the following files to register the new
product modules:

[gcpdiag/product_list.py](https://github.com/GoogleCloudPlatform/gcpdiag/blob/main/gcpdiag/product_list.py):
Add the new product identifier to the central list used by gcpdiag. Update the
list of known products for the runbook code generator script.

[pyinstaller/hook-gcpdiag.runbook.py](https://github.com/GoogleCloudPlatform/gcpdiag/blob/main/pyinstaller/hook-gcpdiag.runbook.py):
Ensure PyInstaller includes the new runbook modules during the build process.

[pyinstaller/hook-gcpdiag.lint.py](https://github.com/GoogleCloudPlatform/gcpdiag/blob/main/pyinstaller/hook-gcpdiag.lint.py):
Ensure PyInstaller includes the new lint rule modules during the build process.

[bin/runbook-starter-code-generator](https://github.com/GoogleCloudPlatform/gcpdiag/blob/main/bin/runbook-starter-code-generator):
Update product set in the starter code generator script.


================================================
FILE: bin/changelog_generator.py
================================================
#!/usr/bin/env python3

# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Changelog Generator"""

import ast
import os
import re
import subprocess
import sys


def lint_name_generator(file_path):
  """Lint name regex generator"""
  parts = file_path.split('/')
  if len(parts) >= 4:
    group3 = parts[3]
    prefix = ''.join(c for c in group3 if c.isalpha() or c == '_').split(
        '__', maxsplit=1)[0]
    numbers = ''.join(
        c for c in group3 if c.isdigit() or c == '_').strip('_').split(
            '__', maxsplit=1)[0]
    return f"{parts[2]}/{prefix}/{numbers.rstrip('_')}"


def find_queries(file, commit):
  """find new queries and respective docstring"""
  if os.path.exists(file):
    with open(file, encoding='utf-8') as f:
      tree = ast.parse(f.read())
    f.close()
    content_changed = subprocess.check_output(
        ['git', 'show', '-p', f'{commit}',
         f'{file}']).decode('utf-8').split('\n')
    i = 0
    for item in content_changed:
      i = i + 1
      if item.startswith('+def '):
        file = file.split('/')[-1].split('.py')[0]
        match = re.search(r'def\s+(.+?)\(', item)
        function_name = ''
        if match:
          function_name = match.group(1)
          message = ''
          for node in ast.walk(tree):
            if isinstance(node, ast.FunctionDef) and node.name == function_name:
              message = ast.get_docstring(node) or 'No Message found'

          final = file + '.' + function_name + ': ' + ' '.join(message.split())
          if final:
            return final
          else:
            return file + ': No function implemented'
  else:
    return file + ': No file found'


def generate_release_notes(old_commit, new_commit, current_version):
  """Generates release notes for version change"""

  commits = subprocess.check_output([
      'git', 'log', '--pretty=format:"%h %s"', '--no-merges',
      f'{old_commit}..{new_commit}'
  ]).decode('utf-8').split('\n')

  commits_dict = {}
  for commit in commits:
    if commit.strip():
      commit_id, commit_msg = commit.strip('"').split(' ', 1)
      commits_dict[commit_id] = commit_msg

  fixes = []
  new_runbooks = []
  new_lints = []
  new_queries = []

  for commit_item in commits_dict.items():
    commit = commit_item[0]
    commit_msg = commit_item[1]
    if commit_msg.startswith('Bump version:'):
      pass
    else:
      try:
        # Get the files changed in this commit
        files_changed = subprocess.check_output(
            ['git', 'show', '--name-status', '--pretty=format:""',
             f'{commit}']).decode('utf-8').split('\n')
        if len(files_changed) > 2:
          files_changed_dict = {}
          for file_info in files_changed:
            if file_info.strip():
              match = re.match(r'([AM])\t(.*)', file_info.strip('"'))
              if match:
                status, filename = match.groups()
                files_changed_dict[filename] = status

          all_files_existed = []
          all_new_files = []
          # Check if all changed files existed before this commit
          for file in files_changed_dict.items():
            if file[1] in ['M', 'T']:
              all_files_existed.append(file[0])
            elif file[1] == 'A':
              all_new_files.append(file[0])

          ignored_files = [
              'utils.py', 'generalized_steps.py', '__init__.py', 'constants.py',
              'flags.py', 'utils_test.py'
          ]

          if all_files_existed and not all_new_files:
            fixes.append(commit_msg)
          else:
            new_runbooks.extend([
                (re.sub(r'gcpdiag/runbook/|_|\.py', '-', f).strip('-') + ': ' +
                 commit_msg)
                for f in all_new_files
                if f.startswith('gcpdiag/runbook/') and f.endswith('.py') and
                f.split('/')[-1] not in ignored_files and
                not f.endswith('_test.py')
            ])
            new_lints.extend([
                (lint_name_generator(f) + ': ' + commit_msg)
                for f in all_new_files
                if f.startswith('gcpdiag/lint/') and f.endswith('.py') and
                f.split('/')[-1] not in ignored_files and
                not f.endswith('_test.py')
            ])
          all_files = all_files_existed + all_new_files
          new_queries.extend([
              find_queries(f, commit)
              for f in all_files
              if f.startswith('gcpdiag/queries/') and f.endswith('.py') and
              f.split('/')[-1] not in ignored_files and
              not f.endswith('_test.py') and not f.endswith('_stub.py')
          ])

      except subprocess.CalledProcessError:
        pass

  new_runbooks = list(dict.fromkeys(new_runbooks))
  new_lints = list(dict.fromkeys(new_lints))
  new_queries = list(dict.fromkeys(new_queries))
  new_queries = list(filter(None, new_queries))

  new_runbooks = [item.replace('_', r'\_') for item in new_runbooks]
  new_lints = [item.replace('_', r'\_') for item in new_lints]
  new_queries = [item.replace('_', r'\_') for item in new_queries]

  # Format release notes
  release_notes = f'\n\n# Release Notes for v{current_version}\n\n'  # Removed tag from title
  if new_lints:
    release_notes += '## New Lints\n\n' + '\n'.join(new_lints) + '\n\n'
  if new_runbooks:
    release_notes += '## New Runbooks\n\n' + '\n'.join(new_runbooks) + '\n\n'
  if new_queries:
    release_notes += '## New Queries\n\n' + '\n'.join(new_queries) + '\n\n'
  if fixes:
    release_notes += '## Fixes\n\n' + '\n'.join(fixes) + '\n\n'
  return release_notes


if __name__ == '__main__':

  with open('gcpdiag/config.py', encoding='utf-8') as fcg:
    for line in fcg:
      if line.startswith('VERSION ='):
        match_var = re.match(r"VERSION = '([\d.]+)", line)
        if match_var:
          current_ver = match_var.group(1)
          previous_version = f'v{float(current_ver) - 0.01}'
        else:
          print('Current version information is missing from gcpdiag/config.py')
          current_ver = input(
              'Please enter the current version e.g 0.77 or 0.76: ')
          if current_ver and re.match(r'^\d+\.\d{2}$', current_ver):
            previous_version = f'v{float(current_ver) - 0.01}'
            break
          else:
            print('No Current Version information found, exiting!!')
            sys.exit(1)

  fcg.close()
  #old_commit_id = "0fc34e64"
  #old_commit_id = 'v0.73'
  old_commit_id = previous_version
  new_commit_id = 'HEAD'
  release_notes_final = generate_release_notes(old_commit_id, new_commit_id,
                                               current_ver)
  print(release_notes_final)


================================================
FILE: bin/curl-wrap.sh
================================================
#!/bin/sh
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# send a curl request with gcloud default app credentials

if [ -z "$ACCESS_TOKEN" ]; then
  ACCESS_TOKEN=$(gcloud auth application-default print-access-token)
fi

exec curl \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "$@"


================================================
FILE: bin/gcpdiag
================================================
#!/usr/bin/env python3

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""gcpdiag main script."""

# pylint: disable=invalid-name

import sys

from gcpdiag import config
from gcpdiag.lint import command as lint_command
from gcpdiag.runbook import command as runbook_command
from gcpdiag.search import command as search_command


def main(argv):
  # A very simple command-line parser to determine what subcommand is called.
  # Proper argument parsing will be done in the subcommands.

  # make sure we always output UTF-8, even if the terminal falls back to ascii
  if sys.version_info >= (3, 7):
    sys.stdout.reconfigure(encoding='utf-8')

  if len(argv) == 1 or argv[1] == '--help' or argv[1] == 'help':
    print_help()
  elif argv[1] == 'version' or argv[1] == '--version':
    print(f'gcpdiag {config.VERSION}\nCopyright 2021 Google LLC')
  elif argv[1] == 'lint':
    # Replace argv[0:1] with only argv[0] so that argparse works correctly.
    sys.argv.pop(0)
    sys.argv[0] = 'gcpdiag lint'
    try:
      lint_command.run(argv)
    except KeyboardInterrupt:
      print(
          '\n[WARNING] KeyboardInterrupt: Application was interrupted (terminated)',
          file=sys.stderr)
      sys.exit(1)
  elif argv[1] == 'runbook':
    # Replace argv[0:1] with only argv[0] so that argparse works correctly.
    sys.argv.pop(0)
    sys.argv[0] = 'gcpdiag runbook'
    try:
      runbook_command.run(argv)
    except KeyboardInterrupt:
      print(
          '\n[WARNING] KeyboardInterrupt: Application was interrupted (terminated)',
          file=sys.stderr)
      sys.exit(1)
  elif argv[1] == 'search':
    # Replace argv[0:1] with only argv[0] so that argparse works correctly.
    sys.argv.pop(0)
    sys.argv[0] = 'gcpdiag search'
    try:
      search_command.run(argv)
    except KeyboardInterrupt:
      print(
          '\n[WARNING] KeyboardInterrupt: Application was interrupted (terminated)',
          file=sys.stderr)
      sys.exit(1)
  else:
    print(f'ERROR: unknown command {argv[1]}. Use --help for help.',
          file=sys.stderr)
    sys.exit(1)


def print_help():
  print("""gcpdiag 🩺 - Diagnostics for Google Cloud Platform

Usage:
        gcpdiag COMMAND [OPTIONS]

Commands:
        help     Print this help text.
        lint     Run diagnostics on GCP projects.
        runbook  Run diagnostics tree to deep dive into GCP issue.
        search   Find gcpdiag rules related to search terms.
        version  Print gcpdiag version.

See: gcpdiag COMMAND --help for command-specific usage.""")


if __name__ == '__main__':
  main(sys.argv)


================================================
FILE: bin/gcpdiag-dockerized
================================================
#!/bin/bash
set -e
THIS_WRAPPER_VERSION=0.11
SUPPORTED_RUNTIME="docker podman"
DEFAULT_OUTPUT_DIR="$HOME/tmp"

# Initialize variables for wrapper arguments
CONFIG_FILE=""
AUTH_KEY=""
TEST_RELEASE=""
REPORT_DIR=""
BUNDLE_SPEC_FILE=""
# Array to hold arguments intended for the gcpdiag command
declare -a gcpdiag_args=()

# Parse arguments, separating wrapper flags from gcpdiag flags
while [[ $# -gt 0 ]]; do
  case "$1" in
    --config=*)
      CONFIG_FILE="${1#*=}"
      gcpdiag_args+=("$1")
      shift # consume argument
      ;;
    --config)
      CONFIG_FILE="$2"
       gcpdiag_args+=("$1" "$2")
      shift 2 # consume flag
      ;;
    --auth-key=*)
      AUTH_KEY="${1#*=}"
      gcpdiag_args+=("$1")
      shift # consume argument
      ;;
    --auth-key)
      AUTH_KEY="$2"
      gcpdiag_args+=("$1" "$2")
      shift 2 # consume flag
      ;;
    --test-release=*)
      TEST_RELEASE="${1#*=}"
      shift # consume argument
      ;;
    --test-release)
       TEST_RELEASE="$2"
       shift 2 # consume flag
      ;;
    --report-dir=*)
      REPORT_DIR="${1#*=}"
      gcpdiag_args+=("$1")
      shift # consume argument
      ;;
    --report-dir)
      REPORT_DIR="$2"
      gcpdiag_args+=("$1" "$2")
      shift 2 # consume flag
      ;;
    --bundle-spec=*)
      BUNDLE_SPEC_FILE="${1#*=}"
      gcpdiag_args+=("$1")
      shift # consume argument
      ;;
    --bundle-spec)
      BUNDLE_SPEC_FILE="$2"
      gcpdiag_args+=("$1" "$2")
      shift 2 # consume flag
      ;;
    *)
      # Assume anything else is an argument for gcpdiag
      gcpdiag_args+=("$1")
      shift # consume argument
      ;;
  esac
done

eval $(curl -sf https://storage.googleapis.com/gcpdiag-dist/release-version|grep -Ei '^\w*=[0-9a-z/\._-]*$')

# Modify image and tag if --test-release was used
if [[ "$TEST_RELEASE" == "staging" ]]; then
  echo "test-release specified: $TEST_RELEASE"
  # Using bash parameter expansion for potentially safer version increment
  if [[ "$DOCKER_IMAGE_VERSION" =~ ^([0-9]+)\.([0-9]+)$ ]]; then
      major="${BASH_REMATCH[1]}"
      minor="${BASH_REMATCH[2]}"
      DOCKER_IMAGE_VERSION="${major}.$((minor + 1))-test"
  else
      echo "Warning: Could not parse DOCKER_IMAGE_VERSION ($DOCKER_IMAGE_VERSION) for incrementing."
      # Fallback or alternative logic might be needed here
      DOCKER_IMAGE_VERSION+="-test" # Simple append as fallback
  fi
  # Using bash parameter expansion for safer replacement
  DOCKER_IMAGE="${DOCKER_IMAGE/release/staging}"
  echo "DOCKER_IMAGE_VERSION: $DOCKER_IMAGE_VERSION"
  echo "DOCKER_IMAGE: $DOCKER_IMAGE"
fi

# Test whether 1st arg is greater than or equal to the 2nd, when compared as version numbers (bash-only)
version_ge () {
  # Note: implementation is rather crude and will treat missing numbers as `0`
  # so e.g. "1" and "1.0.0" compare equal; even worse, "..1" is accepted and
  # less than "0.0.2", and the empty string is equal to "0.0"
  local -a V1=(${1//./ })
  local -a V2=(${2//./ })
  if (( ${#V1[@]} > ${#V2[@]} )); then
    local -i len=${#V1[@]}
  else
    local -i len=${#V2[@]}
  fi
  for i in $(seq 0 ${len}); do
    if (( "${V1[$i]:-0}" < "${V2[$i]:-0}")); then
      return 1  # V1[i] < V2[i]
    fi
  done
  return 0  # V1 >= V2
}

# Test whether a file was provided and exists, then prepare its mount path
# and update its path in gcpdiag_args for the container context.
# The mount path is returned via the global variable MOUNT_RESULT.
handle_mount_path () {
  local FILE="$1"
  MOUNT_RESULT=""

  if [ -n "$FILE" ]; then
    if [ -f "$FILE" ]; then
      if [[ "$FILE" = /* ]]; then
        # absolute path shall be mounted as is
        MOUNT_RESULT="-v $FILE:$FILE"
      else
        # local path need to be mounted inside root folder
        MOUNT_RESULT="-v $PWD/$FILE:/$FILE"
        # We also need to update the path in gcpdiag_args to be absolute
        # so the container finds it at /<file>
        for i in "${!gcpdiag_args[@]}"; do
          if [[ "${gcpdiag_args[$i]}" == "$FILE" ]]; then
            gcpdiag_args[$i]="/$FILE"
            break
          # Handle --arg=file case, ensuring we match the exact value
          elif [[ "${gcpdiag_args[$i]}" == *"=$FILE" ]]; then
            gcpdiag_args[$i]="${gcpdiag_args[$i]%%$FILE*}/$FILE"
            break
          fi
        done
      fi
    else
      return 1
    fi
  fi
  # Success
  return 0
}
# Test whether 1st arg (abs path to mount) was provided and exists, then prepare mount path
# If no custom mount point was provided, create and mount the DEFAULT_OUTPUT_DIR
# that will be used inside container with the same path
handle_mount_dir() {
  local DIR_TO_MOUNT="$1"
  local MOUNT=""

  if [ -z "$DIR_TO_MOUNT" ]; then
    DIR_TO_MOUNT="$DEFAULT_OUTPUT_DIR"

    if [ -z "$DIR_TO_MOUNT" ]; then
      # Return an error code if DIR_TO_MOUNT is empty or does not exist
      return 1
    else
      mkdir -p "$DIR_TO_MOUNT"
    fi
  elif [ ! -d "$DIR_TO_MOUNT" ] && [[ "$DIR_TO_MOUNT" = /* ]]; then
    # Create the directory if it doesn't exist and an absolute path is provided
    mkdir -p "$DIR_TO_MOUNT"
  fi

  # If it's a directory, mount the entire directory
  [ -d "$DIR_TO_MOUNT" ] && MOUNT="-v $DIR_TO_MOUNT:$DIR_TO_MOUNT"
  echo "$MOUNT"
  return 0
}

# Check this script version and compare with the minimum required version
# defined in the release-version file. This allows us to force an upgrade
# of the wrapper script.
if ! version_ge "$THIS_WRAPPER_VERSION" "$WRAPPER_VERSION"; then
  echo
  echo "## ERROR:"
  echo "## This gcpdiag wrapper script is obsolete (version $THIS_WRAPPER_VERSION, minimum required: $WRAPPER_VERSION)."
  echo "## Please update the wrapper script to the latest version as follows:"
  echo
  echo "curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag"
  echo "chmod +x gcpdiag"
  echo
  exit 1
fi

[ -t 0 ] && USE_TTY="-it" || USE_TTY=""

# Ensure necessary host directories exist with correct ownership
mkdir -p "$HOME/.cache/gcpdiag" \
         "$HOME/.cache/gcpdiag-dockerized" \
         "$HOME/.config/gcloud"

# Set RUNTIME based on available container runtime cmd
RUNTIME="" # Initialize RUNTIME
for r in $SUPPORTED_RUNTIME; do
  if command -v "$r" >/dev/null; then
    RUNTIME="$r"
    break
  fi
done

if [ -z "$RUNTIME" ]; then
  echo >&2 "ERROR: No container runtime found - supported: $SUPPORTED_RUNTIME"
  exit 1
fi

# Configure Podman if used
if [ "$RUNTIME" = podman ]; then
  export PODMAN_USERNS=keep-id
fi

# Prepare config file mount
CONFIG_MOUNT=""
MOUNT_RESULT=""
if [ -n "$CONFIG_FILE" ]; then
    if ! handle_mount_path "$CONFIG_FILE"; then
        echo >&2 # Print errors to stderr
        echo >&2 "## ERROR:"
        echo >&2 "## Configuration file: '$CONFIG_FILE' does not exist or is not a regular file!"
        echo >&2
        exit 1
    fi
    CONFIG_MOUNT=$MOUNT_RESULT
fi
# Prepare auth key mount
AUTH_KEY_MOUNT=""
MOUNT_RESULT=""
if [ -n "$AUTH_KEY" ]; then
    if ! handle_mount_path "$AUTH_KEY"; then
        echo >&2 # Print errors to stderr
        echo >&2 "## ERROR:"
        echo >&2 "## Authentication key file: '$AUTH_KEY' does not exist or is not a regular file!"
        echo >&2
        exit 1
    fi
    AUTH_KEY_MOUNT=$MOUNT_RESULT
fi

BUNDLE_SPEC_MOUNT=""
MOUNT_RESULT=""
if [ -n "$BUNDLE_SPEC_FILE" ]; then
    if ! handle_mount_path "$BUNDLE_SPEC_FILE"; then
        echo >&2 # Print errors to stderr
        echo >&2 "## ERROR:"
        echo >&2 "## Bundle spec file: '$BUNDLE_SPEC_FILE' does not exist or is not a regular file!"
        echo >&2
        exit 1
    fi
    BUNDLE_SPEC_MOUNT=$MOUNT_RESULT
fi

# Prepare report dir mount
if ! REPORT_DIR_MOUNT=$(handle_mount_dir "$REPORT_DIR"); then
  echo >&2
  echo >&2 "## ERROR:"
  echo >&2 "## Error creating report dir: $REPORT_DIR"
  echo >&2
  exit 1
fi

# shellcheck disable=SC2086
exec "$RUNTIME" run --rm $USE_TTY \
  --rm \
  -u "$(id -u):$(id -g)" \
  -e "USER=$(id -n -u)" \
  -e "GROUP=$(id -n -g)" \
  -e "SHELL=/bin/bash" \
  -e HOME -e LANG -e GOOGLE_AUTH_TOKEN -e CLOUD_SHELL \
  -v "$HOME/.cache/gcpdiag-dockerized:$HOME/.cache/gcpdiag" \
  -v "$HOME/.config/gcloud:$HOME/.config/gcloud" \
  $CONFIG_MOUNT \
  $AUTH_KEY_MOUNT \
  $BUNDLE_SPEC_MOUNT \
  $REPORT_DIR_MOUNT \
  "$DOCKER_IMAGE:$DOCKER_IMAGE_VERSION" /opt/gcpdiag/bin/gcpdiag "${gcpdiag_args[@]}"


================================================
FILE: bin/gcpdiag-mocked
================================================
#!/usr/bin/env python3

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""gcpdiag test script using data from test-data."""

# pylint: disable=invalid-name

import sys
from unittest import mock

from gcpdiag import config
from gcpdiag.lint import command as lint_command
from gcpdiag.queries import apis_stub, kubectl_stub
from gcpdiag.queries.generic_api.api_build import generic_api_stub


def noop(*args):
  del args
  pass


@mock.patch('gcpdiag.queries.apis.get_api', new=apis_stub.get_api_stub)
@mock.patch('gcpdiag.hooks.post_lint_hook', new=noop)
@mock.patch('gcpdiag.queries.kubectl.verify_auth', new=kubectl_stub.verify_auth)
@mock.patch('gcpdiag.queries.kubectl.check_gke_ingress',
            new=kubectl_stub.check_gke_ingress)
@mock.patch(
    'gcpdiag.queries.generic_api.api_build.get_generic.get_generic_api',
    new=generic_api_stub.get_generic_api_stub,
)
def main(argv):
  # A very simple command-line parser to determine what subcommand is called.
  # Proper argument parsing will be done in the subcommands.

  # make sure we always output UTF-8, even if the terminal falls back to ascii
  if sys.version_info >= (3, 7):
    sys.stdout.reconfigure(encoding='utf-8')

  if len(argv) == 1 or argv[1] == '--help' or argv[1] == 'help':
    print_help()
  elif argv[1] == 'version' or argv[1] == '--version':
    print(f'gcpdiag {config.VERSION}\nCopyright 2021 Google LLC')
  elif argv[1] == 'lint':
    # Replace argv[0:1] with only argv[0] so that argparse works correctly.
    sys.argv.pop(0)
    sys.argv[0] = 'gcpdiag lint'
    lint_command.run(argv)
  else:
    print(f'ERROR: unknown command {argv[1]}. Use --help for help.',
          file=sys.stderr)
    sys.exit(1)


def print_help():
  print("""gcpdiag 🩺 - Diagnostics for Google Cloud Platform

Usage:
        gcpdiag COMMAND [OPTIONS]

Commands:
        help     Print this help text.
        lint     Run diagnostics on GCP projects.
        version  Print gcpdiag version.

See: gcpdiag COMMAND --help for command-specific usage.""")


if __name__ == '__main__':
  main(sys.argv)


================================================
FILE: bin/generate_steps.py
================================================
#!/usr/bin/env python3
"""Generate a markdown table with all gcpdiag runbook steps."""

import importlib
import inspect
import os
import pathlib
import textwrap
from typing import List, Sequence

from absl import app, flags

from gcpdiag import runbook
from gcpdiag.runbook import constants

_URL_BASE_PREFIX = flags.DEFINE_string(
    "url_base_prefix",
    "https://github.com/GoogleCloudPlatform/gcpdiag/tree/main",
    "Base URL prefix for the files in the table.",
)


def fetch_and_list_steps(output_file_path: str, base_url_path: str):
  """Fetches all Step subclasses and generates a Markdown table."""
  table_rows = []
  modules_with_files: List[tuple[str, str]] = []
  for root, _, files in os.walk("gcpdiag/runbook"):
    for file in files:
      if file.endswith(".py") and not file.startswith("__"):
        module_path = os.path.join(root, file)
        # Prepare path for URL
        url_path = module_path.replace("\\", "/")
        file_url = f"{base_url_path}/{url_path}"
        module_path = module_path.replace("/", ".")[:-3]
        modules_with_files.append(
            (module_path, file_url))  # gcpdiag.runbook.nameofrunbook.nameoffile

  rows_data = []
  for module_path, file_url in modules_with_files:
    try:
      module = importlib.import_module(module_path)
      file_name = module_path.split(".")[-1]
    except ImportError:
      continue
    for _, obj in inspect.getmembers(module,
                                     inspect.isclass):  # returns Only class
      if issubclass(obj, runbook.Step) and obj is not runbook.Step:
        try:
          step_instance = obj()  # obj of the Class
          if hasattr(step_instance, "type") and isinstance(
              step_instance.type, constants.StepType):
            step_type = step_instance.type.value
          else:
            step_type = "ERROR: Invalid Step Type"
        except TypeError:
          step_type = "ERROR: Could not instantiate Step"
        step_id = f"google.cloud.{obj.id}"

        rows_data.append({
            "file_name": file_name,
            "file_url": file_url,
            "step_name": obj.__name__,
            "step_type": step_type,
            "step_id": step_id
        })

  # Sort the rows data
  rows_data.sort(key=lambda x: (x["file_name"], x["step_name"]))

  for row in rows_data:
    row_values = {
        "file_name": row["file_name"],
        "file_url": row["file_url"],
        "step_name": row["step_name"],
        "step_type": row["step_type"],
        "step_id": row["step_id"],
    }
    table_rows.append(
        "|[{file_name}]({file_url}) | **{step_name}** | {step_type} |"
        " `{step_id}` |".format(**row_values))

  markdown_table = textwrap.dedent("""
        |Runbook name| **Runbook Step** | stepType | `StepId` |
        |:------------|:----------- |:----------- |:----------- |
    """)
  markdown_table += "\n".join(table_rows)

  # Create the parent directory if it doesn't exist
  pathlib.Path(output_file_path).parent.mkdir(parents=True, exist_ok=True)

  with open(output_file_path, "w", encoding="utf-8") as f:
    f.write(markdown_table)


def main(argv: Sequence[str]) -> None:
  if len(argv) > 1:
    raise app.UsageError("Too many command-line arguments.")
  output_file = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             "steps_table.md")
  base_url = _URL_BASE_PREFIX.value
  fetch_and_list_steps(output_file_path=output_file, base_url_path=base_url)


if __name__ == "__main__":
  app.run(main)


================================================
FILE: bin/json-cleaner
================================================
#!/usr/bin/env python3
"""Development script to strip out any sensitive data from GCP API responses."""

# pylint: disable=invalid-name

import json
import re
import sys

clean_maps = {
    'apigee': {
        '.caCertificate': 'REDACTED',
        '.apigeeProjectId': 'REDACTED',
    },
    'cloudrun': {
        '.services.[].creator': 'REDACTED',
        '.services.[].binaryAuthorization': 'REDACTED'
    },
    'cloudfunctions': {
        '.cloudfunctions.[].sourceToken': 'REDACTED'
    },
    'appengine_versions': {
        '.versions.[].createdBy': 'REDACTED'
    },
    'clusters': {
        '.clusters.[].endpoint': '192.168.1.1',
        '.clusters.[].masterAuth.clusterCaCertificate': 'REDACTED',
    },
    'instances': {
        # not really sensitive, but we don't care about it...
        '.items.[].disks.[].shieldedInstanceInitialState.dbs.[].content':
            'REDACTED',
        '.items.[].disks.[].shieldedInstanceInitialState.dbxs.[].content':
            'REDACTED',
        '.items.[].disks.[].shieldedInstanceInitialState.keks.[].content':
            'REDACTED',
        '.items.[].disks.[].shieldedInstanceInitialState.pk.content':
            'REDACTED',
        '.items.[].fingerprint':
            'REDACTED',
        '.items.[].metadata.fingerprint':
            'REDACTED',
        '.items.[].metadata.items.configure-sh':
            'REDACTED',
        '.items.[].metadata.items.kube-env':
            'REDACTED',
        '.items.[].metadata.items.user-data':
            'REDACTED',
        '.items.[].networkInterfaces.[].fingerprint':
            'REDACTED',
        '.items.[].tags.fingerprint':
            'REDACTED',
    },
    'compute-templates': {
        '.items.[].properties.metadata.fingerprint': 'REDACTED',
        '.items.[].properties.metadata.items.configure-sh': 'REDACTED',
        '.items.[].properties.metadata.items.kube-env': 'REDACTED',
        '.items.[].properties.metadata.items.user-data': 'REDACTED',
    },
    'compute-project': {
        '.commonInstanceMetadata.items.sshKeys': 'REDACTED'
    },
    'compute-network': {
        '.peerings.[].network':
            'https://www.googleapis.com/compute/v1/projects/'
            'REDACTED/global/networks/servicenetworking'
    },
    'service-accounts': {
        '.accounts.[].oauth2ClientId': 'REDACTED'
    },
    'other': {}
}


def traverse_and_clean(path: str, data, clean_map: dict):
  if path in clean_map:
    return clean_map[path]

  if isinstance(data, dict):
    for key in list(data.keys()):
      key_path = path + '.' + key
      data[key] = traverse_and_clean(key_path, data[key], clean_map)
  elif isinstance(data, list):

    for i in range(len(data)):
      # special case: "key", "value" list -> lookup as dict
      if isinstance(data[i], dict) and 'key' in data[i] and 'value' in data[i]:
        key_path = path + '.' + data[i]['key']
        if key_path in clean_map:
          data[i]['value'] = clean_map[key_path]
      else:
        data[i] = traverse_and_clean(path + '.[]', data[i], clean_map)
  elif isinstance(data, str):
    # obfuscate real email addresses
    data = re.sub(r'[a-z]+@google\.com', 'testuser@example.com', data)
  return data


def main():
  data = json.load(sys.stdin)

  if len(sys.argv) != 2:
    print('usage: json-cleaner RESOURCE_TYPE')
    sys.exit(1)

  resource_type = sys.argv[1]
  if resource_type not in clean_maps:
    print('first argument must be one of: ' +
          ', '.join(sorted(clean_maps.keys())),
          file=sys.stderr)
    sys.exit(1)

  # transform using clean_maps
  data = traverse_and_clean('', data, clean_maps[resource_type])
  print(json.dumps(data, indent=2, sort_keys=True))


main()


================================================
FILE: bin/pipenv-dockerized
================================================
#!/bin/bash

if [ "$#" == "0" ]; then
  echo "usage: $0 PYTHON_VERSION COMMAND ARG1 ARG2 ARG3" >&2
  exit 1
fi
PYTHON_VERSION="$1"
IMAGE_TAG="$2"
shift 2

IMAGE="us-docker.pkg.dev/gcpdiag-dist/common/gcpdiag-pipenv-python-${PYTHON_VERSION}:${IMAGE_TAG}"

USE_TTY=""
CWD=$(pwd)
[ -t 0 ] && USE_TTY="-it"

#mkdir -p "$HOME/.cache/pre-commit"
#mkdir -p "$HOME/.cache/pipenv"
#mkdir -p "$HOME/.local/share/virtualenv"
mkdir -p "$HOME/.config/gcloud"
mkdir -p .pipenv-dockerized/venv-$PYTHON_VERSION
mkdir -p .pipenv-dockerized/home
mkdir -p .venv
exec docker run $USE_TTY \
  --rm \
  -u "$(id -u):$(id -g)" \
  -e "USER=$(id -n -u)" \
  -e "GROUP=$(id -n -g)" \
  -e "HOME=$HOME" \
  -e "LANG=$LANG" \
  -e "SHELL=/bin/bash" \
  -e "KOKORO_BUILD_NUMBER=$KOKORO_BUILD_NUMBER" \
  -v "$CWD:$CWD" \
  -v "$HOME/.config/gcloud:$HOME/.config/gcloud" \
  -v "$CWD/.pipenv-dockerized/home:$HOME" \
  -v "$CWD/.pipenv-dockerized/venv-$PYTHON_VERSION:$CWD/.venv" \
  -w "$CWD" \
  $IMAGE pipenv "$@"


================================================
FILE: bin/precommit-gke-eol-file.sh
================================================
#!/bin/sh

# WARNING: This script is deprecated and may be removed in a future release.
# Please use 'gcpdiag/queries/gke.get_release_schedule' instead.

# Checks if gcpdiag/lint/gke/eol.yaml file contains the up to date list of
# GKE Releases with corresponding EOL (end-of-life) dates

if ! ./gcpdiag/lint/gke/eol_parser.sh | diff - gcpdiag/lint/gke/eol.yaml > /dev/null
then
  echo 'GKE eol.yaml file is outdated. Please run `make gke-eol-file` from the top level directory'
  exit 1
fi


================================================
FILE: bin/precommit-required-files
================================================
#!/usr/bin/env python3
"""Verify that the lint rules are documented in the website."""

# pylint: disable=invalid-name

import importlib
import inspect
import os
import pathlib
import re
import subprocess
import sys
import textwrap
from os import path
from typing import List

from jinja2 import TemplateNotFound, UndefinedError

from gcpdiag import lint, runbook
from gcpdiag.product_list import get_product_list
from gcpdiag.rule_classes import get_rule_classes
from gcpdiag.runbook import DiagnosticTree, util

#Lint Rules Doc
WEBSITE_RULES_DIR = 'website/content/en/rules'
LINT_RULES_DIR = 'gcpdiag/lint'
# Runbook Docs
WEBSITE_RUNBOOK_DIR = 'website/content/en/runbook'

# update also pyinstaller/hook-gcpdiag.lint.py
PRODUCTS = get_product_list()

PRODUCTS_EXCEPTIONS = ['gcpdiag', 'gcp']

RULE_CLASSES = get_rule_classes()


def usage():
  print('usage: gcpdiag-website-rules FILE1.py FILE2.py', file=sys.stderr)
  sys.exit(1)


def gen_rule_page(rule, rule_page_path):
  # Create product directory
  try:
    class_dir = pathlib.Path(f'{WEBSITE_RULES_DIR}/{rule.product}')
    class_dir.mkdir()
    with open(class_dir / '_index.md', 'w', encoding='utf-8') as f:
      print(textwrap.dedent(f'''\
          ---
          title: "{rule.product.upper()}"
          linkTitle: "{rule.product}"
          type: docs
          ---
          '''),
            file=f)
  except FileExistsError:
    pass

  # Create rule class directory
  try:
    class_dir = pathlib.Path(
        f'{WEBSITE_RULES_DIR}/{rule.product}/{rule.rule_class}')
    class_dir.mkdir()
  except FileExistsError:
    pass

  with open(rule_page_path, 'w', encoding='utf-8') as f:
    print(textwrap.dedent(f'''\
    ---
    title: "{rule.product}/{rule.rule_class}/{rule.rule_id}"
    linkTitle: "{rule.rule_class}/{rule.rule_id}"
    weight: 1
    type: docs
    description: >
      {rule.short_desc}
    ---

    **Product**: {PRODUCTS[rule.product]}\\
    **Rule class**: {rule.rule_class} - {RULE_CLASSES[str(rule.rule_class)]}

    ### Description
    '''),
          file=f)
    print(rule.long_desc, file=f)
    print(textwrap.dedent('''\

    ### Remediation

    ### Further information'''),
          file=f)


def check_runbook(files):
  """Check runbook files to automatically update or generate docs for DTs and it steps."""
  # Initialize variables to hold the diagnostic tree and in-scope steps.
  inscope_dts: List[DiagnosticTree] = []
  in_scope_steps = {}

  # Process each file path provided.
  for file_path in files:
    # Use regular expression to parse relevant information from the file path.
    match = re.match(r'gcpdiag/runbook/([^/]+)/(.*)\.py', file_path)
    if not match:
      continue

    rule_dir, rule_basename = match.groups()
    rule_module_name = f'gcpdiag.runbook.{rule_dir}.{rule_basename}'
    try:
      module = importlib.import_module(rule_module_name)
    except ImportError:
      continue

    mod_dt_count = 0
    for name, obj in inspect.getmembers(module, inspect.isclass):
      # Handle DiagnosticTree classes.
      if issubclass(
          obj, runbook.DiagnosticTree) and obj is not runbook.DiagnosticTree:
        mod_dt_count += 1
        if mod_dt_count > 1:
          raise RuntimeError(
              f'Multiple Diagnostic Trees found in {file_path}\n'
              f'For readability each Diagnostic Tree should have it own file'
              f'Only keep custom steps for this Diagnostic Tree in the file')
        inscope_dts.append(obj)

      # Store Step classes that have possibly been modified.
      elif issubclass(obj, runbook.Step) and obj is not runbook.Step:
        in_scope_steps[name] = obj

  for dt in inscope_dts:
    gen_dt_rule_and_steps_page(dt(None), in_scope_steps)


def gen_dt_rule_and_steps_page(dt, in_scope_steps):
  """Generate documentation pages for a diagnostic tree and its steps.

  Args:
    dt: The diagnostic tree object to process.
    in_scope_steps: A dictionary of steps that are in scope for documentation.
  """
  if dt.product not in PRODUCTS and dt.product not in PRODUCTS_EXCEPTIONS:
    print(
        f'ERROR: Product "{dt.product}" for Diagnostic Tree '
        f'"{dt.__class__.__name__}" is not defined in the "PRODUCTS" '
        'dictionary.',
        file=sys.stderr)
    print(
        'To resolve this pre-commit error, you must add the new product to '
        '"bin/precommit-required-files.py".',
        file=sys.stderr)
    print(
        'Specifically, update the `PRODUCTS` dictionary in the '
        '`get_product_list()` function.',
        file=sys.stderr)
    print(
        'Example: "your_new_product": "[Your New Product Name]"'
        '(https://cloud.google.com/your-new-product-url)',
        file=sys.stderr)
    sys.exit(1)

  # Expand the full diagnostic tree from the AST nodes.
  # Used to draw graphviz images and document the child steps.
  builder = runbook.ExpandTreeFromAst(dt.__class__)
  expanded_dt = builder.visit_ast_nodes(dt.build_tree)

  # Function to recursively traverse and generate documentation for all steps in the tree.
  def traverse_all_steps(step):
    gen_step_page(step)
    # Remove generated steps from the in_scope_steps dict.
    in_scope_steps.pop(step.__class__.__name__, None)
    for child in step.steps:
      traverse_all_steps(child)

  traverse_all_steps(expanded_dt.start)
  # Generate pages for any remaining steps not directly part of the diagnostic tree.
  for step in in_scope_steps.values():
    gen_step_page(step())

  # Create dt product directory if doesn't exist and sub folder images.
  try:
    dt_dir = pathlib.Path(f'{WEBSITE_RUNBOOK_DIR}/diagnostic-trees')
    # Make both diagnostic-trees
    dt_dir.mkdir(parents=True)
    with open(dt_dir / '_index.md', 'w', encoding='utf-8') as f:
      print(textwrap.dedent('''\
          ---
          title: "Debugging Trees"
          linkTitle: "Debugging Trees"
          type: docs
          weight: 1
          ---
          '''),
            file=f,
            end='')
  except FileExistsError:
    pass

  # Create dt product directory if doesn't exist and sub folder images.
  try:
    product_dt_dir = pathlib.Path(
        f'{WEBSITE_RUNBOOK_DIR}/diagnostic-trees/{dt.product}')
    # Make both diagnostic-trees
    product_dt_dir.mkdir(parents=True)
    with open(product_dt_dir / '_index.md', 'w', encoding='utf-8') as f:
      print(textwrap.dedent(f'''\
          ---
          title: "{dt.product.upper()}"
          linkTitle: "{dt.product}"
          type: docs
          weight: 2
          ---

          All diagnostic tree available in {dt.product}
          '''),
            file=f,
            end='')
  except FileExistsError:
    pass

  try:
    img_dir = pathlib.Path(f'{str(product_dt_dir)}/images')
    img_dir.mkdir(parents=True)
  except FileExistsError:
    pass

  context = {
      'rule': expanded_dt,
      'util': util,
      'title': util.pascal_case_to_title(dt.__class__.__name__),
      'PRODUCTS': PRODUCTS,
      'ROOT_DIR': WEBSITE_RUNBOOK_DIR
  }
  # Render the template with the context
  rendered_content = runbook.util.render_template('bin/templates',
                                                  'diagnostic-tree.jinja',
                                                  context).rstrip('\n')
  dt_path = f'{dt_dir}/{expanded_dt.name}.md'
  md_page_content = ''
  if os.path.exists(dt_path):
    # Check if the content changed.
    md_page_content = runbook.util.render_template(dt_dir,
                                                   f'{expanded_dt.name}.md', {})
  if rendered_content != md_page_content:
    with open(dt_path, 'w', encoding='utf-8') as f:
      f.write(rendered_content)
      f.write('\n')


def gen_step_page(step: runbook.Step):
  """Generates a Markdown page for a given diagnostic step.

  Creates a Markdown file for the specified step in the
  diagnostic process, using a template to render the step's details into a
  human-readable format. It ensures that each step has its own dedicated page.

  Args:
    step (runbook.Step): The diagnostic step instance to generate the page.
  """
  if step.product not in PRODUCTS and step.product not in PRODUCTS_EXCEPTIONS:
    print(
        f'ERROR: Product "{step.product}" for Diagnostic Tree '
        f'"{step.__class__.__name__}" is not defined in the "PRODUCTS" '
        f'dictionary.',
        file=sys.stderr)
    print(
        'To resolve this pre-commit error, you must add the new product to '
        '"bin/precommit-required-files.py".',
        file=sys.stderr)
    print(
        'Specifically, update the `PRODUCTS` dictionary in the '
        '`get_product_list()` function.',
        file=sys.stderr)
    print(
        'Example: "your_new_product": "[Your New Product Name]"'
        '(https://cloud.google.com/your-new-product-url)',
        file=sys.stderr)
    sys.exit(1)  # Exit with an error to prevent further issues

  try:
    steps_dir = pathlib.Path(f'{WEBSITE_RUNBOOK_DIR}/steps')
    steps_dir.mkdir(parents=True)
    with open(steps_dir / '_index.md', 'w', encoding='utf-8') as f:
      print(textwrap.dedent('''\
          ---
          title: "All Steps"
          linkTitle: "steps"
          type: docs
          weight: 1
          ---

          All steps available in the runbook by products
          '''),
            file=f,
            end='')
  except FileExistsError:
    pass

  try:
    product_steps_dir = pathlib.Path(
        f'{WEBSITE_RUNBOOK_DIR}/steps/{step.product}')
    product_steps_dir.mkdir()
    with open(product_steps_dir / '_index.md', 'w', encoding='utf-8') as f:
      print(textwrap.dedent(f'''\
          ---
          title: "{step.product.upper()}"
          linkTitle: "{step.product}"
          type: docs
          weight: 2
          ---

          All steps available in {step.product}
          '''),
            file=f,
            end='')
  except FileExistsError:
    pass

  msgs = {}
  try:
    filepath, block_prefix = step.template.split('::')
    msgs = runbook.util.load_template_block(module_name=step.__module__,
                                            file_name=filepath.strip(),
                                            block_name=block_prefix.strip())
  except UndefinedError as e:
    print(f'Encounted a block error while parsing {e} used in step {step.id}')
  except TemplateNotFound as e:
    print(
        f'Step "{step.id}" is using a non-existent jinja file with the name: {e}'
    )
  except AttributeError as e:
    pass
  except ValueError as e:
    print('Ensure that your template string uses '
          f'the following format "template_file::block_name":{e}')

  context = {'step': step, 'msgs': msgs, 'PRODUCTS': PRODUCTS}
  step_page = f'{product_steps_dir}/{step.doc_file_name}.md'
  rendered_content = runbook.util.render_template('bin/templates/',
                                                  'steps.jinja', context)
  # For some reason there are \n at the end despite striping new line and block lines
  # Many strip it if any still exists at the end.
  rendered_content = rendered_content.rstrip('\n')
  md_page_content = ''

  if os.path.exists(step_page):
    # Check if the content changed.
    md_page_content = runbook.util.render_template(product_steps_dir,
                                                   f'{step.doc_file_name}.md',
                                                   {})

  if rendered_content != md_page_content:
    with open(step_page, 'w', encoding='utf-8') as f:
      f.write(rendered_content)
      f.write('\n')


def check_rule_page(rule):
  rule_page_path = f'{WEBSITE_RULES_DIR}/{rule.product}/{rule.rule_class}/{rule.rule_id}.md'
  # check that rule page exists and is staged
  lsfiles = subprocess.run(['git', 'ls-files', '-s', rule_page_path],
                           stdout=subprocess.PIPE,
                           check=False)
  if len(lsfiles.stdout) > 0:
    return True
  elif path.exists(rule_page_path):
    print(f'rule page not staged: {rule_page_path}', file=sys.stderr)
    return False
  else:
    print(f'generated initial rule page: {rule_page_path}', file=sys.stderr)
    gen_rule_page(rule, rule_page_path)
    return False


def check_rule_snapshot(rule):
  rule_snapshot_path = (f'{LINT_RULES_DIR}/{rule.product}/snapshots/'
                        f'{rule.rule_class}_{rule.rule_id}.txt')

  # check that rule snapshot exists and is staged
  lsfiles = subprocess.run(['git', 'ls-files', '-s', rule_snapshot_path],
                           stdout=subprocess.PIPE,
                           check=False)
  if len(lsfiles.stdout) > 0:
    return True
  elif path.exists(rule_snapshot_path):
    print(f'rule snapshot not staged: {rule_snapshot_path}', file=sys.stderr)
    return False
  else:
    print(
        f'run "make snapshots" to generate rule snapshot: {rule_snapshot_path} ',
        file=sys.stderr)
    return False


def check(files):
  rules_repo = lint.LintRuleRepository()
  seen_rule_ids = {}
  exit_fail = False
  for arg in sorted(files):
    # only process gcpdiag lint rules
    m = re.match(r'gcpdiag/lint/([^/]+)/(.*)\.py', arg)
    if not m:
      continue
    rule_dir = m.group(1)
    rule_basename = m.group(2)
    rule_module_name = f'gcpdiag.lint.{rule_dir}.{rule_basename}'
    try:
      rule = rules_repo.get_rule_by_module_name(rule_module_name)
      # Verify that the rule id is unique
      if str(rule) in seen_rule_ids:
        print(f'ERROR: rule id {str(rule)} is not unique!', file=sys.stderr)
        exit_fail = True
      seen_rule_ids[str(rule)] = 1
      if not check_rule_page(rule):
        exit_fail = True
      if not check_rule_snapshot(rule):
        exit_fail = True
    except lint.NotLintRule:
      continue
  if exit_fail:
    sys.exit(1)


if __name__ == '__main__':
  if len(sys.argv) < 2:
    usage()
  elif sys.argv[1] == 'lint':
    check(sys.argv[2:])
  elif sys.argv[1] == 'runbook':
    check_runbook(sys.argv[2:])


================================================
FILE: bin/precommit-required-files-wrapper
================================================
#!/bin/sh

# wrapper to call precommit-required-files with correct environment set
# (this is particularly problematic in GitHub Actions and I couldn't get
# it to work without this wrapper)

# note: the script assumes to be running in the root directory of the git
# repository

export PATH=$(pipenv --venv)/bin:$PATH
export PYTHONPATH=$(pwd)
python bin/precommit-required-files "$@"


================================================
FILE: bin/precommit-todo-annotations
================================================
#!/bin/sh

# An hook script to verify changes to be committed do not contain
# any 'TODO:' comments.

# To bypass this hook, use the "--no-verify" parameter when committing.

# Redirect output to stderr.
exec 1>&2

# Define colors
RED='\033[0;31m'
NC='\033[0m'

# Define what term will be searched for.
SEARCH_TERM_TODO="TODO:"

# Check for the presence of the SEARCH_TERM in updated files.
if [[ $(git diff --cached | grep -E "^\+" | grep -v '+++ b/' | cut -c 2-) == *$SEARCH_TERM_TODO* ]]
then
	printf "${RED}Error:${NC} Found ${SEARCH_TERM_TODO} in attempted commit.\n"
	printf "Please remove all occurrences of ${SEARCH_TERM_TODO} before committing.\n"
	exit 1
fi


================================================
FILE: bin/runbook-starter-code-generator
================================================
#!/usr/bin/env python3
"""Generate runbook starter code"""

import os
import re
import subprocess
import sys
import textwrap
from datetime import datetime

# update pyinstaller/hook-gcpdiag-runbook.py when adding any new modules
SUPPORTED_PRODUCTS = {
    'apigee', 'billing', 'bigquery', 'cdn', 'cloudrun', 'crm', 'composer',
    'datafusion', 'dataflow', 'dataproc', 'kms', 'gar', 'gke', 'gcb', 'gcf',
    'gae', 'gce', 'iam', 'interconnect', 'gcs', 'lb', 'logs', 'tpu', 'pubsub',
    'sql', 'vertex', 'vpc', 'nat', 'monitoring', 'vpn'
}


def _get_active_gcloud_project():
  """Best effort check to retrieve the project id currently configured on gcloud."""
  try:
    # Run the gcloud command to get the current project
    result = subprocess.run(['gcloud', 'config', 'get-value', 'project'],
                            check=True,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            text=True)
    project_id = result.stdout.strip()
  except (subprocess.CalledProcessError, OSError, FileNotFoundError):
    return None
  else:
    print(
        f'Found project {_color(project_id,"blue")}; will use it arg for `--project`'
    )
    return project_id


def _color(text, color):
  colors = {
      'green': '\033[92m',
      'blue': '\033[94m',
      'magenta': '\033[95m',
      'cyan': '\033[96m',
      'reset': '\033[0m'
  }
  return f"{colors[color]}{text}{colors['reset']}"


def _git_operations(runbook_name):
  try:
    current_branch = _get_current_branch()
    _stash_changes(runbook_name)

    if current_branch not in (runbook_name, 'master'):
      _switch_to_master(current_branch)
      current_branch = _get_current_branch()

    _update_repository(current_branch)

    if current_branch != runbook_name:
      _create_new_or_switch_branch(runbook_name)
      current_branch = _get_current_branch()

    print(
        f'You can run `git stash pop` if you want the stashed changes in branch {runbook_name}'
    )
  except subprocess.CalledProcessError as e:
    print('An error occurred during git operations:')
    print(e)
  except OSError:
    pass


def _get_current_branch():
  result = subprocess.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
                          check=True,
                          text=True,
                          capture_output=True)
  branch = result.stdout.strip()
  print(f'Currently on branch "{branch}"')
  return branch


def _stash_changes(runbook_name):
  try:
    # Attempt to stash changes
    result = subprocess.run([
        'git', 'stash', 'push', '-m',
        f'Auto-stash during {runbook_name} generation'
    ],
                            text=True,
                            capture_output=True,
                            check=True).stdout.strip()
    if 'no local changes to save' in result.lower():
      print('No changes to stash.')
    else:
      print(
          'Detected uncommitted changes in the working directory and stashed them!'
      )

  except subprocess.CalledProcessError as e:
    print('Failed to stash changes:')
    print(e)


def _switch_to_master(current_branch):
  print(
      f'Switching from branch "{current_branch}" to "master" to sync environment.'
  )
  subprocess.run(['git', 'checkout', 'master'],
                 check=True,
                 text=True,
                 capture_output=True).stdout.strip()


def _update_repository(current_branch):
  print(
      f'On "{current_branch}" branch; syncing with remote branch `origin/master`.'
  )
  subprocess.run(['git', 'pull', 'origin', 'master', '--rebase'],
                 check=True,
                 text=True,
                 capture_output=True)
  print('Repository updated with: `git pull origin master --rebase`')


def _create_new_or_switch_branch(runbook_name):
  command = ['git', 'checkout', '-b', runbook_name]
  # First, check if the branch already exists
  existing_branches = subprocess.run(['git', 'branch', '--list', runbook_name],
                                     check=False,
                                     text=True,
                                     capture_output=True).stdout.strip()

  # If the branch already exists, print a message and do not attempt to create it
  if existing_branches:
    print(
        f'Branch "{runbook_name}" already exists. Switching to existing branch')
    command.remove('-b')
  else:
    print(f'Creating new branch "{runbook_name}".')
  try:
    # Attempt to create the branch since it does not exist
    subprocess.run(command, check=True, text=True,
                   capture_output=True).stdout.strip()
  except subprocess.CalledProcessError as e:
    # Handle possible errors during branch creation (e.g., due to local modifications)
    print('Failed to create new branch:')
    print(e)


def check_and_activate_shell(command, py_path, name, prepenv):
  # Check if the VIRTUAL_ENV environment variable is set
  print(_color('\nPreparing your python virtual environment', 'blue'))
  print(_color('=========================================', 'blue'))
  if 'VIRTUAL_ENV' in os.environ:
    print('Virtual environment is already activated. Generating starter code.')
    gen_starter_code({'name': name, 'prepenv': prepenv})
  else:
    # Check current directory and subfolders
    current_directory = os.getcwd()
    if 'gcpdiag' in current_directory and os.path.isdir(
        'gcpdiag') and os.path.isdir('bin'):
      print('Attempting to activate the virtual environment for "gcpdiag".')
      print('Virtual environment activated.')
      gen_starter_code({'name': name, 'prepenv': prepenv})
      if not _activate_virtual_environment():
        print('Failed to activate the venv. Manually run it `pipenv shell`.')
    else:
      print(
          'Not in an appropriate location to activate the virtual environment.')
      print('Current directory:', current_directory)


def _activate_virtual_environment():
  try:
    # Using 'pipenv run' instead of 'pipenv shell' as it's better suited for scripts
    subprocess.run('pipenv shell', shell=True, check=True)
    return True
  except subprocess.CalledProcessError:
    return False


def gen_starter_code(args_: dict):
  # Extract product and Runbook ID
  runbook_name = args_['name']
  parts = runbook_name.split('/')
  product = parts[0]
  id_ = parts[1]

  if product not in SUPPORTED_PRODUCTS:
    print(f"Product '{product}' is not supported yet or registered.", file=sys.stderr)
    print('Please ensure this product is added to all necessary configuration files.', file=sys.stderr)
    print(f'Specifically, you need to update:')
    print(f"  1. The `SUPPORTED_PRODUCTS` set in '{__file__}'", file=sys.stderr)
    print(f"  2. The `PRODUCTS` dictionary in 'bin/precommit-required-files.py'", file=sys.stderr)
    print("Example for `bin/precommit-required-files.py`: 'your_new_product': '[Your New Product Name](https://cloud.google.com/your-new-product-url)'", file=sys.stderr)
    return

  if args_['prepenv']:
    print(_color('\nPreparing your local git repository', 'blue'))
    print(_color('===================================', 'blue'))
    _git_operations(runbook_name)
  dir_path = f'gcpdiag/runbook/{product}'
  filename = id_.replace('-', '_')
  dt_name = re.sub(r'(^|-)([a-z0-9])', lambda match: match.group(2).upper(),
                   id_)

  # Create necessary directories
  os.makedirs(os.path.join(dir_path, 'templates'), exist_ok=True)
  os.makedirs(os.path.join(dir_path, 'snapshots'), exist_ok=True)
  open(os.path.join(dir_path, '__init__.py'), 'a', encoding='utf-8').close()

  file_path = os.path.join(dir_path, f'{filename}.py')
  print(_color('\nGenerating Your Runbook', 'blue'))
  print(_color('=======================', 'blue'))
  if not os.path.exists(file_path):
    # Process the runbook starter code template
    with open('bin/templates/runbook-starter-code.py.tpl',
              'r',
              encoding='utf-8') as template_file:
      template_content = template_file.read()

    template_content = template_content.replace('TreeName', dt_name)
    template_content = template_content.replace('[YEAR]',
                                                str(datetime.now().year))

    with open(file_path, 'w', encoding='utf-8') as output_file:
      output_file.write(template_content)
      print(
          f'Created runbook in {_color(f"{dir_path}/{filename}.py", "magenta")}. Happy Coding! 💻 🚀'
      )
  else:
    print(
        f'{file_path} already exists. Will not be generating starter code for: {runbook_name}'
    )
    print('Verify if runbook already exist')
    print(f'Doc: https://gcpdiag.dev/runbook/diagnostic-trees/{product}/{id_}')
    print(f'File: gcpdiag/runbook/{product}/{id_}.py')

  print(_color('\nVerifying & Generating runbook product files', 'blue'))
  print(_color('============================================', 'blue'))
  # Process additional template files
  for file in [
      'constants', 'flags', 'generalized_steps', 'generalized_steps_test'
  ]:
    file_path = os.path.join(dir_path, f'{file}.py')
    if not os.path.exists(file_path):
      with open('bin/templates/python-file.py.tpl', 'r',
                encoding='utf-8') as template_file:
        content = template_file.read()

      content = content.replace('[YEAR]', str(datetime.now().year))

      with open(file_path, 'w', encoding='utf-8') as output_file:
        output_file.write(content)
        print(f'Created {file_path}.')
      if file in ('constants', 'flags'):
        with open(file_path, 'a', encoding='utf-8') as output_file:
          output_file.write(
              textwrap.dedent(f'''\
                            # pylint: disable=unused-wildcard-import, wildcard-import
                            from gcpdiag.runbook.iam.{file} import *
                            '''))
  print('Ok!')

  print(_color('\nGenerating Test Class', 'blue'))
  print(_color('=====================', 'blue'))
  file_path = os.path.join(dir_path, f'{filename}_test.py')
  if not os.path.exists(file_path):
    # Process the runbook starter code template
    with open('bin/templates/runbook-test.py.tpl', 'r',
              encoding='utf-8') as template_file:
      template_content = template_file.read()

    template_content = template_content.replace('TreeName', dt_name)
    template_content = template_content.replace('PRODUCT', product)
    template_content = template_content.replace('RULE', runbook_name)
    template_content = template_content.replace('[YEAR]',
                                                str(datetime.now().year))

    with open(file_path, 'w', encoding='utf-8') as output_file:
      output_file.write(template_content)
      print(f'Created runbook test in {_color(f"{file_path}", "magenta")}. ✅ 🎉')
  else:
    print(f'Strange, test class {file_path} already exists.')

  print(_color(f'\nHow to run {runbook_name} in local development', 'blue'))
  print(_color('===============================================', 'blue'))
  proj = _get_active_gcloud_project() or 'REPLACE_PROJECT_ID'
  print('Run the runbook in interactive mode')
  print(
      _color(
          f'bin/gcpdiag runbook {runbook_name} -p custom_flag={product} --project={proj}',
          'green'))
  print(
      f'Use {_color("--auto", "magenta")} to run the runbook in a non-interactive mode'
  )
  print(
      _color(
          f'bin/gcpdiag runbook {runbook_name} -p custom_flag={product} --project={proj} --auto',
          'green'))


def _parse_kwargs(argv):
  kwargs = {}
  for arg in argv:
    if '=' in arg:
      key, value = arg.split('=', 1)
      kwargs[key] = value.strip()
  return kwargs


if __name__ == '__main__':
  args = _parse_kwargs(sys.argv[1::])
  args['command'] = sys.argv[1]
  if args.get('prepenv').lower() in ('0', 'n', 'no', 'false', ''):
    args['prepenv'] = False
    gen_starter_code(args)
  elif args.get('prepenv').lower() in ('1', 'y', 'yes', 'true'):
    args['prepenv'] = True
    check_and_activate_shell(**args)
  else:
    print(
        'Usage: python runbook-starter-code-generator name=product/runbook-id prepenv=true'
    )


================================================
FILE: bin/steps_table.md
================================================

|Runbook name| **Runbook Step** | stepType | `StepId` |
|:------------|:----------- |:----------- |:----------- |
|[bgp_down_flap](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/interconnect/bgp_down_flap.py) | **BgpDownFlapEnd** | END | `google.cloud.gcpdiag.runbook.interconnect.bgp_down_flap.BgpDownFlapEnd` |
|[bgp_down_flap](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/interconnect/bgp_down_flap.py) | **BgpDownFlapStart** | START | `google.cloud.gcpdiag.runbook.interconnect.bgp_down_flap.BgpDownFlapStart` |
|[bgp_down_flap](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/interconnect/bgp_down_flap.py) | **CheckBgpDown** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.interconnect.bgp_down_flap.CheckBgpDown` |
|[bgp_down_flap](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/interconnect/bgp_down_flap.py) | **CheckBgpFlap** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.interconnect.bgp_down_flap.CheckBgpFlap` |
|[bgp_down_flap](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/interconnect/bgp_down_flap.py) | **CheckCloudRouterMaintenance** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.interconnect.bgp_down_flap.CheckCloudRouterMaintenance` |
|[bgp_down_flap](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/interconnect/bgp_down_flap.py) | **CheckInterconnectMaintenance** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.interconnect.bgp_down_flap.CheckInterconnectMaintenance` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaDisabledAnnotation** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaDisabledAnnotation` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaFailedToEvictPods** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaFailedToEvictPods` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaInstanceTimeout** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaInstanceTimeout` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaIpSpaceExhausted** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaIpSpaceExhausted` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaMinResourceLimitExceeded** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaMinResourceLimitExceeded` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaMinSizeReached** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaMinSizeReached` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaNoPlaceToMovePods** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaNoPlaceToMovePods` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaNotSafeToEvictAnnotation** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaNotSafeToEvictAnnotation` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaOutOfResources** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaOutOfResources` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaPodControllerNotFound** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaPodControllerNotFound` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaPodKubeSystemUnmovable** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaPodKubeSystemUnmovable` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaPodNotEnoughPdb** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaPodNotEnoughPdb` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaPodUnexpectedError** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaPodUnexpectedError` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaPodsNotBackedByController** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaPodsNotBackedByController` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaQuotaExceeded** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaQuotaExceeded` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **CaServiceAccountDeleted** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.CaServiceAccountDeleted` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **ClusterAutoscalerEnd** | END | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.ClusterAutoscalerEnd` |
|[cluster_autoscaler](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/cluster_autoscaler.py) | **ClusterAutoscalerStart** | START | `google.cloud.gcpdiag.runbook.gke.cluster_autoscaler.ClusterAutoscalerStart` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **CheckClusterNetwork** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.CheckClusterNetwork` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **CheckInitScriptFailure** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.CheckInitScriptFailure` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **CheckPrivateGoogleAccess** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.CheckPrivateGoogleAccess` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **CheckSharedVPCRoles** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.CheckSharedVPCRoles` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **ClusterCreationEnd** | END | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.ClusterCreationEnd` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **ClusterCreationQuota** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.ClusterCreationQuota` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **ClusterCreationStart** | START | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.ClusterCreationStart` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **ClusterCreationStockout** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.ClusterCreationStockout` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **ClusterDetailsDependencyGateway** | GATEWAY | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.ClusterDetailsDependencyGateway` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **InternalIpGateway** | GATEWAY | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.InternalIpGateway` |
|[cluster_creation](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/cluster_creation.py) | **ServiceAccountExists** | GATEWAY | `google.cloud.gcpdiag.runbook.dataproc.cluster_creation.ServiceAccountExists` |
|[failed_deployments](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcf/failed_deployments.py) | **DefaultServiceAccountCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gcf.failed_deployments.DefaultServiceAccountCheck` |
|[failed_deployments](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcf/failed_deployments.py) | **FailedDeploymentEndStep** | END | `google.cloud.gcpdiag.runbook.gcf.failed_deployments.FailedDeploymentEndStep` |
|[failed_deployments](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcf/failed_deployments.py) | **FailedDeploymentsStart** | START | `google.cloud.gcpdiag.runbook.gcf.failed_deployments.FailedDeploymentsStart` |
|[failed_deployments](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcf/failed_deployments.py) | **FunctionGlobalScopeCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gcf.failed_deployments.FunctionGlobalScopeCheck` |
|[failed_deployments](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcf/failed_deployments.py) | **LocationConstraintCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gcf.failed_deployments.LocationConstraintCheck` |
|[failed_deployments](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcf/failed_deployments.py) | **UserServiceAccountCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gcf.failed_deployments.UserServiceAccountCheck` |
|[failed_streaming_pipeline](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataflow/failed_streaming_pipeline.py) | **FailedStreamingPipelineEnd** | END | `google.cloud.gcpdiag.runbook.dataflow.failed_streaming_pipeline.FailedStreamingPipelineEnd` |
|[failed_streaming_pipeline](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataflow/failed_streaming_pipeline.py) | **FailedStreamingPipelineStart** | START | `google.cloud.gcpdiag.runbook.dataflow.failed_streaming_pipeline.FailedStreamingPipelineStart` |
|[failed_streaming_pipeline](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataflow/failed_streaming_pipeline.py) | **JobGraphIsConstructed** | GATEWAY | `google.cloud.gcpdiag.runbook.dataflow.failed_streaming_pipeline.JobGraphIsConstructed` |
|[failed_streaming_pipeline](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataflow/failed_streaming_pipeline.py) | **JobIsStreaming** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataflow.failed_streaming_pipeline.JobIsStreaming` |
|[failed_streaming_pipeline](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataflow/failed_streaming_pipeline.py) | **JobLogsVisible** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataflow.failed_streaming_pipeline.JobLogsVisible` |
|[failed_streaming_pipeline](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataflow/failed_streaming_pipeline.py) | **JobState** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataflow.failed_streaming_pipeline.JobState` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/generalized_steps.py) | **CheckClusterNetworkConnectivity** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataproc.generalized_steps.CheckClusterNetworkConnectivity` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/logs/generalized_steps.py) | **CheckIssueLogEntry** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.logs.generalized_steps.CheckIssueLogEntry` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataproc/generalized_steps.py) | **CheckLogsExist** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataproc.generalized_steps.CheckLogsExist` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vertex/generalized_steps.py) | **CheckWorkbenchInstanceCustomScripts** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.vertex.generalized_steps.CheckWorkbenchInstanceCustomScripts` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vertex/generalized_steps.py) | **CheckWorkbenchInstanceExternalIpDisabled** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.vertex.generalized_steps.CheckWorkbenchInstanceExternalIpDisabled` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vertex/generalized_steps.py) | **CheckWorkbenchInstanceIsUsingLatestEnvVersion** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.vertex.generalized_steps.CheckWorkbenchInstanceIsUsingLatestEnvVersion` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vertex/generalized_steps.py) | **CheckWorkbenchInstancePerformance** | COMPOSITE STEP | `google.cloud.gcpdiag.runbook.vertex.generalized_steps.CheckWorkbenchInstancePerformance` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vertex/generalized_steps.py) | **CheckWorkbenchInstanceSyslogsJupyterRunningOnPort8080** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.vertex.generalized_steps.CheckWorkbenchInstanceSyslogsJupyterRunningOnPort8080` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vertex/generalized_steps.py) | **CheckWorkbenchInstanceUsingOfficialImage** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.vertex.generalized_steps.CheckWorkbenchInstanceUsingOfficialImage` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **GceVpcConnectivityCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.GceVpcConnectivityCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **HighVmCpuUtilization** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.HighVmCpuUtilization` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **HighVmDiskUtilization** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.HighVmDiskUtilization` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **HighVmMemoryUtilization** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.HighVmMemoryUtilization` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcp/generalized_steps.py) | **HumanTask** | MANUAL STEP | `google.cloud.gcpdiag.runbook.gcp.generalized_steps.HumanTask` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/iam/generalized_steps.py) | **IamPolicyCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.iam.generalized_steps.IamPolicyCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/nat/generalized_steps.py) | **NatDroppedReceivedPacketCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.nat.generalized_steps.NatDroppedReceivedPacketCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/nat/generalized_steps.py) | **NatIpExhaustionCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.nat.generalized_steps.NatIpExhaustionCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/nat/generalized_steps.py) | **NatResourceExhaustionCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.nat.generalized_steps.NatResourceExhaustionCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/crm/generalized_steps.py) | **OrgPolicyCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.crm.generalized_steps.OrgPolicyCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/pubsub/generalized_steps.py) | **PubsubQuotas** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.pubsub.generalized_steps.PubsubQuotas` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcp/generalized_steps.py) | **ResourceAttributeCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gcp.generalized_steps.ResourceAttributeCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gcp/generalized_steps.py) | **ServiceApiStatusCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gcp.generalized_steps.ServiceApiStatusCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/monitoring/generalized_steps.py) | **TimeSeriesCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.monitoring.generalized_steps.TimeSeriesCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/dataflow/generalized_steps.py) | **ValidSdk** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.dataflow.generalized_steps.ValidSdk` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vpc/generalized_steps.py) | **VmExternalIpConnectivityTest** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.vpc.generalized_steps.VmExternalIpConnectivityTest` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/iam/generalized_steps.py) | **VmHasAnActiveServiceAccount** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.iam.generalized_steps.VmHasAnActiveServiceAccount` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **VmHasOpsAgent** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.VmHasOpsAgent` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **VmLifecycleState** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.VmLifecycleState` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **VmMetadataCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.VmMetadataCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **VmScope** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.VmScope` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gce/generalized_steps.py) | **VmSerialLogsCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gce.generalized_steps.VmSerialLogsCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vpc/generalized_steps.py) | **VpcFirewallCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.vpc.generalized_steps.VpcFirewallCheck` |
|[generalized_steps](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/vpc/generalized_steps.py) | **VpcRouteCheck** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.vpc.generalized_steps.VpcRouteCheck` |
|[gke_ip_masq_standard](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/gke_ip_masq_standard.py) | **CheckConfigMap** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.gke_ip_masq_standard.CheckConfigMap` |
|[gke_ip_masq_standard](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/gke_ip_masq_standard.py) | **CheckDaemonSet** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.gke_ip_masq_standard.CheckDaemonSet` |
|[gke_ip_masq_standard](https://github.com/GoogleCloudPlatform/gcpdiag/tree/main/gcpdiag/runbook/gke/gke_ip_masq_standard.py) | **CheckDestinationIP** | AUTOMATED STEP | `google.cloud.gcpdiag.runbook.gke.gke_ip_masq_standard.CheckDestina
Download .txt
gitextract_sa7cb22i/

├── .bumpversion.cfg
├── .coveragerc
├── .devcontainer/
│   ├── README.md
│   └── devcontainer.json
├── .gitallowed
├── .github/
│   └── workflows/
│       ├── code-analysis.yml
│       ├── scorecard.yml
│       └── test.yml
├── .gitignore
├── .isort.cfg
├── .pre-commit-config.yaml
├── .pylint-dictionary.txt
├── .pylintrc
├── .safety-policy.yml
├── .style.yapf
├── .vscode/
│   ├── extensions.json
│   └── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── PRIVACY.md
├── Pipfile
├── README.md
├── bin/
│   ├── changelog_generator.py
│   ├── curl-wrap.sh
│   ├── gcpdiag
│   ├── gcpdiag-dockerized
│   ├── gcpdiag-mocked
│   ├── generate_steps.py
│   ├── json-cleaner
│   ├── pipenv-dockerized
│   ├── precommit-gke-eol-file.sh
│   ├── precommit-required-files
│   ├── precommit-required-files-wrapper
│   ├── precommit-todo-annotations
│   ├── runbook-starter-code-generator
│   ├── steps_table.md
│   ├── templates/
│   │   ├── diagnostic-tree.jinja
│   │   ├── python-file.py.tpl
│   │   ├── runbook-starter-code.py.tpl
│   │   ├── runbook-test.py.tpl
│   │   └── steps.jinja
│   └── terraform
├── cookiecutter-gcpdiag-rule/
│   ├── cookiecutter.json
│   ├── cookiecutter_runner.py
│   ├── hooks/
│   │   └── post_gen_project.py
│   └── {{cookiecutter.__name}}/
│       ├── gcpdiag/
│       │   └── lint/
│       │       └── {{cookiecutter.product}}/
│       │           └── {{cookiecutter.severity.lower()}}_{{cookiecutter.year}}_{{cookiecutter.number}}_{{cookiecutter.__name}}.py
│       └── website/
│           └── content/
│               └── en/
│                   └── rules/
│                       └── {{cookiecutter.product}}/
│                           └── {{cookiecutter.severity}}/
│                               └── {{cookiecutter.year}}_{{cookiecutter.number}}.md
├── docker/
│   ├── gcpdiag/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── entrypoint.sh
│   ├── hugo/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── README.md
│   ├── pipenv-python-3.12/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── entrypoint.sh
│   ├── pipenv-python-3.7/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── entrypoint.sh
│   └── pipenv-python-3.9/
│       ├── Dockerfile
│       ├── Makefile
│       └── entrypoint.sh
├── gcpdiag/
│   ├── __init__.py
│   ├── async_queries/
│   │   ├── __init__.py
│   │   ├── api/
│   │   │   ├── __init__.py
│   │   │   ├── api.py
│   │   │   ├── api_slowtest.py
│   │   │   ├── constant_time_retry_strategy.py
│   │   │   ├── default_random.py
│   │   │   ├── exponential_random_retry_strategy.py
│   │   │   ├── exponential_random_retry_strategy_test.py
│   │   │   ├── gcpdiag_creds.py
│   │   │   ├── get_api.py
│   │   │   ├── sleeper.py
│   │   │   └── test_webserver.py
│   │   ├── dataproc/
│   │   │   ├── __init__.py
│   │   │   ├── dataproc.py
│   │   │   └── dataproc_test.py
│   │   ├── project/
│   │   │   ├── __init__.py
│   │   │   ├── get_project.py
│   │   │   └── project.py
│   │   ├── project_regions.py
│   │   ├── project_regions_test.py
│   │   ├── py.typed
│   │   └── utils/
│   │       ├── __init__.py
│   │       ├── fake_api.py
│   │       ├── loader.py
│   │       └── protocols.py
│   ├── caching.py
│   ├── caching_test.py
│   ├── config.py
│   ├── config_test.py
│   ├── context.py
│   ├── executor.py
│   ├── executor_test.py
│   ├── hooks.py
│   ├── lint/
│   │   ├── __init__.py
│   │   ├── apigee/
│   │   │   ├── __init__.py
│   │   │   ├── apigee_rules_snapshot_test.py
│   │   │   ├── err_2022_001_p4sa_perm.py
│   │   │   ├── err_2022_002_p4sa_kms_key_perm.py
│   │   │   ├── err_2023_001_vpc_peering_created.py
│   │   │   ├── err_2023_002_routing_with_mig.py
│   │   │   ├── err_2023_003_pga_on_mig_subnet.py
│   │   │   ├── err_2023_004_p4nsa_perm.py
│   │   │   ├── err_2023_005_fw_rule_xlb_to_mig.py
│   │   │   ├── err_2023_006_multiple_migs_for_multiple_regions.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   └── WARN_2022_002.txt
│   │   │   ├── warn_2021_001_empty_env.py
│   │   │   ├── warn_2022_001_env_groups_created.py
│   │   │   └── warn_2022_002_env_not_attached.py
│   │   ├── asm/
│   │   │   ├── __init__.py
│   │   │   ├── asm_rules_snapshot_test.py
│   │   │   ├── err_2023_001_traffic_4xx.py
│   │   │   ├── err_2023_002_traffic_5xx.py
│   │   │   ├── err_2024_001_secret_not_found.py
│   │   │   ├── err_2024_002_istiod_resource_issues.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2025_001.txt
│   │   │   │   └── WARN_2025_002.txt
│   │   │   ├── warn_2023_001_grpc_reset.py
│   │   │   ├── warn_2024_001_webhook.py
│   │   │   ├── warn_2025_001_delayedconnect111.py
│   │   │   └── warn_2025_002_protocolerror.py
│   │   ├── bigquery/
│   │   │   ├── __init__.py
│   │   │   ├── bigquery_rules_snapshot_test.py
│   │   │   ├── err_2022_001_concurrent_dml_updates.py
│   │   │   ├── err_2022_002_response_too_large.py
│   │   │   ├── err_2022_003_permission_denied_drive_credentials.py
│   │   │   ├── err_2022_004_exceeded_limit_shuffle.py
│   │   │   ├── err_2023_001_job_not_found_error.py
│   │   │   ├── err_2023_002_dataset_not_found.py
│   │   │   ├── err_2023_003_resource_exceeded.py
│   │   │   ├── err_2023_004_concurrent_dml.py
│   │   │   ├── err_2023_005_outdated_credentials_for_scheduled_queries.py
│   │   │   ├── err_2023_006_bigquery_policy_do_not_belong_to_user.py
│   │   │   ├── err_2023_007_data_transfer_service_agent_does_not_exist.py
│   │   │   ├── err_2023_008_user_not_authorized_to_perform_this_action.py
│   │   │   ├── err_2023_009_not_consistent_with_destination_dataset.py
│   │   │   ├── err_2024_001_query_too_complex.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── ERR_2022_004.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── ERR_2023_007.txt
│   │   │   │   ├── ERR_2023_008.txt
│   │   │   │   ├── ERR_2023_009.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2022_004.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   ├── WARN_2024_003.txt
│   │   │   │   ├── WARN_2024_004.txt
│   │   │   │   ├── WARN_2024_005.txt
│   │   │   │   └── WARN_2024_006.txt
│   │   │   ├── warn_2022_001_exceeded_rate_limits.py
│   │   │   ├── warn_2022_002_column_level_security.py
│   │   │   ├── warn_2022_003_copy_job_quota.py
│   │   │   ├── warn_2022_004_cross_region_copy_job_quota.py
│   │   │   ├── warn_2023_001_query_job_timed_out.py
│   │   │   ├── warn_2023_002_wildcard_tables_query.py
│   │   │   ├── warn_2023_003_too_many_output_column.py
│   │   │   ├── warn_2023_004_bigquery_kms_errors.py
│   │   │   ├── warn_2024_001_imports_or_query_appends_per_table.py
│   │   │   ├── warn_2024_002_invalid_external_connection.py
│   │   │   ├── warn_2024_003_too_many_concurrent_api_requests.py
│   │   │   ├── warn_2024_004_too_many_concurrent_queries.py
│   │   │   ├── warn_2024_005_exceeded_partition_modifications.py
│   │   │   └── warn_2024_006_tabledata_list_bytes_exceeded.py
│   │   ├── billing/
│   │   │   ├── __init__.py
│   │   │   ├── billing_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   └── WARN_2022_003.txt
│   │   │   ├── warn_2022_001_project_billing_enabled.py
│   │   │   ├── warn_2022_002_stray_billing_accounts.py
│   │   │   └── warn_2022_003_cost_anomalies.py
│   │   ├── cloudrun/
│   │   │   ├── __init__.py
│   │   │   ├── cloud_rules_snapshot_test.py
│   │   │   ├── err_2022_001_missing_cloudrun_serviceagent_role.py
│   │   │   └── snapshots/
│   │   │       └── ERR_2022_001.txt
│   │   ├── cloudsql/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_public_ip.py
│   │   │   ├── bp_2023_002_automated_backup.py
│   │   │   ├── bp_2023_003_log_output_flag.py
│   │   │   ├── bp_ext_2023_001_maint_window.py
│   │   │   ├── bp_ext_2023_002_del_protection.py
│   │   │   ├── bp_ext_2023_003_auto_storage_increases.py
│   │   │   ├── bp_ext_2023_004_sla.py
│   │   │   ├── cloudsql_rules_snapshot_test.py
│   │   │   ├── err_2023_001_instance_in_suspended.py
│   │   │   ├── sec_2023_001_public_acess.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2023_002.txt
│   │   │   │   ├── BP_2023_003.txt
│   │   │   │   ├── BP_EXT_2023_001.txt
│   │   │   │   ├── BP_EXT_2023_002.txt
│   │   │   │   ├── BP_EXT_2023_003.txt
│   │   │   │   ├── BP_EXT_2023_004.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── SEC_2023_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   └── WARN_2023_003.txt
│   │   │   ├── warn_2022_001_docker_bridge_network.py
│   │   │   ├── warn_2023_002_high_cpu_usage.py
│   │   │   └── warn_2023_003_high_mem_usage.py
│   │   ├── command.py
│   │   ├── command_test.py
│   │   ├── composer/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_debug_logging_level.py
│   │   │   ├── bp_2023_002_parallelism.py
│   │   │   ├── bp_2023_003_statsd.py
│   │   │   ├── bp_ext_2023_001_number_of_schedulers.py
│   │   │   ├── bp_ext_2023_002_xss_vulnerable_versions.py
│   │   │   ├── composer_rules_snapshot_test.py
│   │   │   ├── err_2022_001_composer_p4sa_permissions.py
│   │   │   ├── err_2022_002_composer_sa_permissions.py
│   │   │   ├── err_2023_001_composer_not_in_error_state.py
│   │   │   ├── err_2023_002_verify_ip_range.py
│   │   │   ├── err_2023_003_dag_timeout_killing.py
│   │   │   ├── err_2023_004_zombie_detection.py
│   │   │   ├── err_2023_005_environment_delete_fail_nat_config.py
│   │   │   ├── err_2024_001_no_error_surfaced.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2023_002.txt
│   │   │   │   ├── BP_2023_003.txt
│   │   │   │   ├── BP_EXT_2023_001.txt
│   │   │   │   ├── BP_EXT_2023_002.txt
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2023_005.txt
│   │   │   │   ├── WARN_2023_006.txt
│   │   │   │   ├── WARN_2023_007.txt
│   │   │   │   ├── WARN_2023_008.txt
│   │   │   │   ├── WARN_2023_009.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   └── WARN_2024_003.txt
│   │   │   ├── warn_2022_001_composer2_p4sa_permissions.py
│   │   │   ├── warn_2022_002_fluentd_pod_crashloop.py
│   │   │   ├── warn_2022_003_total_dag_parse_time.py
│   │   │   ├── warn_2023_001_kerberos_support.py
│   │   │   ├── warn_2023_002_task_sigkill.py
│   │   │   ├── warn_2023_003_task_fail_resource_pressure.py
│   │   │   ├── warn_2023_004_high_database_cpu_usage.py
│   │   │   ├── warn_2023_005_environment_is_consistently_healthy.py
│   │   │   ├── warn_2023_006_schedulers_are_healthy.py
│   │   │   ├── warn_2023_007_high_scheduler_cpu_usage.py
│   │   │   ├── warn_2023_008_composer_airflow_db_is_healthy.py
│   │   │   ├── warn_2023_009_composer_intermittent_task_failure_issue.py
│   │   │   ├── warn_2024_001_low_scheduler_cpu_usuage.py
│   │   │   ├── warn_2024_002_worker_pod_eviction.py
│   │   │   └── warn_2024_003_composer_api_disabled.py
│   │   ├── dataflow/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_dataflow_supported_sdk_version_check.py
│   │   │   ├── dataflow_rules_snapshot_test.py
│   │   │   ├── err_2023_001_dataflow_sa_perm_check.py
│   │   │   ├── err_2023_002_dataflow_ip_space_exhausted.py
│   │   │   ├── err_2023_003_dataflow_subnet_format_check.py
│   │   │   ├── err_2023_004_dataflow_org_policy_violated.py
│   │   │   ├── err_2023_005_dataflow_credential_perm_issue.py
│   │   │   ├── err_2023_006_dataflow_private_google_access_check.py
│   │   │   ├── err_2023_007_dataflow_missing_firewall_issue.py
│   │   │   ├── err_2023_008_dataflow_sa_worker_perm_check.py
│   │   │   ├── err_2023_009_splunk_err_invalid_cert.py
│   │   │   ├── err_2023_010_bq_streaming_insert_missing_field.py
│   │   │   ├── err_2023_011_bq_streaming_insert_mismatch_column.py
│   │   │   ├── err_2023_012_dataflow_spanner_oom.py
│   │   │   ├── err_2023_013_dataflow_spanner_deadline_exceeded.py
│   │   │   ├── err_2024_001_dataflow_gce_quotas.py
│   │   │   ├── err_2024_002_dataflow_key_commit.py
│   │   │   ├── err_2024_003_dataflow_write_truncate_unbounded.py
│   │   │   ├── err_2024_004_missing_gcs_permission_temp_bucket.py
│   │   │   ├── err_2024_005_dataflow_not_creating_pubsub_subscription.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── ERR_2023_007.txt
│   │   │   │   ├── ERR_2023_008.txt
│   │   │   │   ├── ERR_2023_009.txt
│   │   │   │   ├── ERR_2023_010.txt
│   │   │   │   ├── ERR_2023_011.txt
│   │   │   │   ├── ERR_2023_012.txt
│   │   │   │   ├── ERR_2023_013.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── ERR_2024_003.txt
│   │   │   │   ├── ERR_2024_004.txt
│   │   │   │   ├── ERR_2024_005.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2023_006.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   └── WARN_2024_002.txt
│   │   │   ├── warn_2023_001_dataflow_hot_key.py
│   │   │   ├── warn_2023_003_dataflow_worker_logs_throttled.py
│   │   │   ├── warn_2023_004_dataflow_stuck_at_draining.py
│   │   │   ├── warn_2023_006_dataflow_stuck_at_cancelling.py
│   │   │   ├── warn_2024_001_dataflow_operation_ongoing.py
│   │   │   └── warn_2024_002_dataflow_streaming_appliance_commit_failed.py
│   │   ├── datafusion/
│   │   │   ├── __init__.py
│   │   │   ├── datafusion_rules_snapshot_test.py
│   │   │   ├── err_2022_001_connectivity_dataproc_vms.py
│   │   │   ├── err_2022_002_shared_vpc_ip_range.py
│   │   │   ├── err_2022_003_private_peering.py
│   │   │   ├── err_2022_004_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2022_005_host_vpc_permissions.py
│   │   │   ├── err_2022_006_private_google_access.py
│   │   │   ├── err_2022_007_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2022_008_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2022_009_cloud_dataproc_sa_permissions.py
│   │   │   ├── err_2022_010_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2022_011_cloud_datafusion_sa_permissions.py
│   │   │   ├── err_2024_001_delete_operation_failing.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── ERR_2022_004.txt
│   │   │   │   ├── ERR_2022_005.txt
│   │   │   │   ├── ERR_2022_006.txt
│   │   │   │   ├── ERR_2022_007.txt
│   │   │   │   ├── ERR_2022_008.txt
│   │   │   │   ├── ERR_2022_009.txt
│   │   │   │   ├── ERR_2022_010.txt
│   │   │   │   ├── ERR_2022_011.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   ├── WARN_2024_003.txt
│   │   │   │   ├── WARN_2024_004.txt
│   │   │   │   └── WARN_2024_005.txt
│   │   │   ├── warn_2024_001_data_fusion_version.py
│   │   │   ├── warn_2024_002_instance_state_running.py
│   │   │   ├── warn_2024_003_cluster_scaling_down_disabled.py
│   │   │   ├── warn_2024_004_datafusion_dataproc_compatabillity.py
│   │   │   └── warn_2024_005_datafusion_dataproc_compatability_preference.py
│   │   ├── dataproc/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2021_001_logging_enabled.py
│   │   │   ├── bp_2022_001_monitoring_enabled.py
│   │   │   ├── bp_2022_098_another_dummy_async_rule.py
│   │   │   ├── bp_2022_099_dummy_async_rule.py
│   │   │   ├── dataproc_rules_snapshot_test.py
│   │   │   ├── err_2022_002_image_versions.py
│   │   │   ├── err_2022_002_image_versions_test.py
│   │   │   ├── err_2022_003_dataproc_sa_permissions.py
│   │   │   ├── err_2022_004_dpgce_connectivity.py
│   │   │   ├── err_2023_001_initialization_action_timeout.py
│   │   │   ├── err_2023_002_orphaned_yarn_application.py
│   │   │   ├── err_2023_003_dataproc_permission.py
│   │   │   ├── err_2023_004_dataproc_firewall_issue.py
│   │   │   ├── err_2023_005_dataproc_quota.py
│   │   │   ├── err_2023_006_shared_vpc_permission.py
│   │   │   ├── err_2023_007_cluster_creation_stockout.py
│   │   │   ├── err_2023_008_bad_dirs.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2021_001.txt
│   │   │   │   ├── BP_2022_001.txt
│   │   │   │   ├── BP_2022_098.txt
│   │   │   │   ├── BP_2022_099.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── ERR_2022_004.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── ERR_2023_007.txt
│   │   │   │   ├── ERR_2023_008.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2022_004.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   └── WARN_2024_002.txt
│   │   │   ├── warn_2021_001_cluster_status_running.py
│   │   │   ├── warn_2022_001_cluster_local_ssd_failed_stop.py
│   │   │   ├── warn_2022_002_job_throttling_rate_limit.py
│   │   │   ├── warn_2022_003_sa_permissions.py
│   │   │   ├── warn_2022_004_cluster_status_running_async.py
│   │   │   ├── warn_2023_001_job_throttling_too_many.py
│   │   │   ├── warn_2023_002_high_system_memory_usage.py
│   │   │   ├── warn_2024_001_safemode.py
│   │   │   └── warn_2024_002_hdfs_write_issue.py
│   │   ├── gae/
│   │   │   ├── __init__.py
│   │   │   ├── err_2023_001_appengine_vpc_connector_policy.py
│   │   │   ├── err_2023_002_appengine_vpc_connector_subnet_overlap.py
│   │   │   ├── err_2025_001_gae_default_service_account_is_deleted.py
│   │   │   ├── gae_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2025_001.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   └── WARN_2022_002.txt
│   │   │   ├── warn_2022_001_appengine_standard_deprecated_runtimes.py
│   │   │   └── warn_2022_002_appengine_flexible_deprecated_runtimes.py
│   │   ├── gcb/
│   │   │   ├── __init__.py
│   │   │   ├── err_2022_001_missing_cloudbuild_editor_role.py
│   │   │   ├── err_2022_002_build_failed_whithout_artifact_registry_permission.py
│   │   │   ├── err_2022_003_build_failed_with_logs_bucket_retention_policy.py
│   │   │   ├── err_2022_004_missing_cloudbuild_service_agent_role.py
│   │   │   ├── gcb_rules_snapshot_test.py
│   │   │   └── snapshots/
│   │   │       ├── ERR_2022_001.txt
│   │   │       ├── ERR_2022_002.txt
│   │   │       ├── ERR_2022_003.txt
│   │   │       └── ERR_2022_004.txt
│   │   ├── gce/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2021_001_serial_logging_enabled.py
│   │   │   ├── bp_2022_003_unused_boot_disks.py
│   │   │   ├── bp_2023_001_ntp_config.py
│   │   │   ├── bp_2024_001_legacy_monitoring_agent.py
│   │   │   ├── bp_2024_002_legacy_logging_agent.py
│   │   │   ├── bp_ext_2021_003_secure_boot_enabled.py
│   │   │   ├── bp_ext_2022_001_vm_manager_enabled.py
│   │   │   ├── bp_ext_2023_001_gce_scopes.py
│   │   │   ├── bp_ext_2024_001_no_public_ip.py
│   │   │   ├── bp_ext_2024_002_calculate_vm_iops_throughput.py
│   │   │   ├── err_2021_001_mig_scaleup_failed.py
│   │   │   ├── err_2021_002_osconfig_perm.py
│   │   │   ├── err_2021_003_api_service_agent.py
│   │   │   ├── err_2021_004_secure_boot_failed.py
│   │   │   ├── err_2021_005_mount_errors.py
│   │   │   ├── err_2022_001_quota_exceeded.py
│   │   │   ├── err_2022_002_premium_guestos_activation_failed.py
│   │   │   ├── err_2024_001_snapshot_rate_limit.py
│   │   │   ├── err_2024_002_performance.py
│   │   │   ├── err_2024_003_vm_secure_boot_failures.py
│   │   │   ├── err_2024_004_ops_agent.py
│   │   │   ├── gce_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2021_001.txt
│   │   │   │   ├── BP_2022_003.txt
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2024_001.txt
│   │   │   │   ├── BP_2024_002.txt
│   │   │   │   ├── BP_EXT_2021_003.txt
│   │   │   │   ├── BP_EXT_2022_001.txt
│   │   │   │   ├── BP_EXT_2023_001.txt
│   │   │   │   ├── BP_EXT_2024_001.txt
│   │   │   │   ├── BP_EXT_2024_002.txt
│   │   │   │   ├── BP_EXT_2024_003.txt
│   │   │   │   ├── ERR_2021_001.txt
│   │   │   │   ├── ERR_2021_002.txt
│   │   │   │   ├── ERR_2021_003.txt
│   │   │   │   ├── ERR_2021_004.txt
│   │   │   │   ├── ERR_2021_005.txt
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── ERR_2024_003.txt
│   │   │   │   ├── ERR_2024_004.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   ├── WARN_2021_002.txt
│   │   │   │   ├── WARN_2021_003.txt
│   │   │   │   ├── WARN_2021_004.txt
│   │   │   │   ├── WARN_2021_005.txt
│   │   │   │   ├── WARN_2021_006.txt
│   │   │   │   ├── WARN_2021_007.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2022_004.txt
│   │   │   │   ├── WARN_2022_005.txt
│   │   │   │   ├── WARN_2022_006.txt
│   │   │   │   ├── WARN_2022_007.txt
│   │   │   │   ├── WARN_2022_008.txt
│   │   │   │   ├── WARN_2022_009.txt
│   │   │   │   ├── WARN_2022_010.txt
│   │   │   │   ├── WARN_2022_011.txt
│   │   │   │   ├── WARN_2022_012.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   └── WARN_2024_001.txt
│   │   │   ├── utils.py
│   │   │   ├── utils_test.py
│   │   │   ├── warn_2021_001_logging_perm.py
│   │   │   ├── warn_2021_002_disk_latency.py
│   │   │   ├── warn_2021_003_monitoring_permissions.py
│   │   │   ├── warn_2021_004_disk_full_serial_messages.py
│   │   │   ├── warn_2021_005_out_of_memory.py
│   │   │   ├── warn_2021_006_kernel_panic.py
│   │   │   ├── warn_2021_007_bsod.py
│   │   │   ├── warn_2022_001_iap_tcp_forwarding.py
│   │   │   ├── warn_2022_002_duplicated_named_ports.py
│   │   │   ├── warn_2022_003_vm_instances_quota.py
│   │   │   ├── warn_2022_004_docker_bridge_network.py
│   │   │   ├── warn_2022_005_cpu_quota.py
│   │   │   ├── warn_2022_006_gpu_quota.py
│   │   │   ├── warn_2022_007_cloudsql_admin_scope.py
│   │   │   ├── warn_2022_008_ip_address_quota.py
│   │   │   ├── warn_2022_009_disk_quota.py
│   │   │   ├── warn_2022_010_resource_availability.py
│   │   │   ├── warn_2022_011_valid_sa.py
│   │   │   ├── warn_2022_012_windows_kms.py
│   │   │   ├── warn_2023_001_snapshot_policies_on_unused_disks.py
│   │   │   └── warn_2023_002_airflowtask_oom.py
│   │   ├── gcf/
│   │   │   ├── __init__.py
│   │   │   ├── err_2022_001_missing_cloudfunctions_serviceagent_role.py
│   │   │   ├── err_2022_002_cloudfunctions_org_policy_violation.py
│   │   │   ├── err_2022_003_cloudfunctions_memory_limit_exceeded.py
│   │   │   ├── gcf_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   └── WARN_2021_002.txt
│   │   │   ├── warn_2021_001_cloudfunctions_deprecated_runtimes.py
│   │   │   └── warn_2021_002_cloudfunctions_request_aborted.py
│   │   ├── gcs/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2022_001_bucket_access_uniform.py
│   │   │   ├── gcs_rules_snapshot_test.py
│   │   │   └── snapshots/
│   │   │       └── BP_2022_001.txt
│   │   ├── gke/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2021_001_cloudops_enabled.py
│   │   │   ├── bp_2022_001_regional_cluster.py
│   │   │   ├── bp_2022_002_unique_subnets.py
│   │   │   ├── bp_2022_003_cluster_eol.py
│   │   │   ├── bp_2022_004_http_load_balancing_disabled.py
│   │   │   ├── bp_2023_001_network_policy_minimum_requirements.py
│   │   │   ├── bp_2023_002_stateful_workloads_not_on_preemptible_node.py
│   │   │   ├── bp_2023_004_vpc_native_cluster.py
│   │   │   ├── bp_2023_005_gateway_crd.py
│   │   │   ├── bp_2025_001_gke_nodelocal_dnscache_enabled.py
│   │   │   ├── bp_ext_2022_001_groups_enabled.py
│   │   │   ├── bp_ext_2023_001_maintenance_window.py
│   │   │   ├── bp_ext_2023_002_private_cluster.py
│   │   │   ├── eol_parser.sh
│   │   │   ├── err_2021_001_logging_perm.py
│   │   │   ├── err_2021_002_monitoring_perm.py
│   │   │   ├── err_2021_003_kms_key_enabled.py
│   │   │   ├── err_2021_004_node_connection_apiserver.py
│   │   │   ├── err_2021_005_node_connection_storage.py
│   │   │   ├── err_2021_006_scaleup_failed.py
│   │   │   ├── err_2021_007_gke_sa.py
│   │   │   ├── err_2021_008_api_service_agent.py
│   │   │   ├── err_2021_009_nodepool_version_skew.py
│   │   │   ├── err_2021_010_internal_forwarding_rule_limits.py
│   │   │   ├── err_2021_011_ip_masq_not_reporting_errors.py
│   │   │   ├── err_2021_012_np_sa_enabled.py
│   │   │   ├── err_2021_013_connectivity_cluster_rules.py
│   │   │   ├── err_2021_014_connectivity_master.py
│   │   │   ├── err_2021_015_connectivity_vms.py
│   │   │   ├── err_2022_001_connectivity_pod_to_pod.py
│   │   │   ├── err_2022_002_private_google_access.py
│   │   │   ├── err_2022_003_ingress_healthcheck.py
│   │   │   ├── err_2023_001_containerfilesystem_quota.py
│   │   │   ├── err_2023_002_private_routes_based.py
│   │   │   ├── err_2023_003_containerd_bad_config_file.py
│   │   │   ├── err_2023_004_ingress_config.py
│   │   │   ├── err_2023_005_gke_cni_issue.py
│   │   │   ├── err_2023_006_gw_controller_annotation_error.py
│   │   │   ├── err_2023_007_gw_controller_http_route_misconfig.py
│   │   │   ├── err_2023_008_crashloopbackoff.py
│   │   │   ├── err_2023_009_missing_cpu_req.py
│   │   │   ├── err_2023_010_nodelocal_timeout.py
│   │   │   ├── err_2023_011_wi_pod_ip_not_found.py
│   │   │   ├── err_2023_012_missing_mem_request.py
│   │   │   ├── err_2024_001_psa_violoations.py
│   │   │   ├── err_2024_002_webhook_failure_no_endpoint.py
│   │   │   ├── err_2024_003_default_node_serviceaccount_perm.py
│   │   │   ├── err_2025_001_serial_port_logging.py
│   │   │   ├── gke_rules_snapshot_test.py
│   │   │   ├── sec_2021_001_np_uses_default_sa.py
│   │   │   ├── sec_2023_001_worload_id.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2021_001.txt
│   │   │   │   ├── BP_2022_001.txt
│   │   │   │   ├── BP_2022_002.txt
│   │   │   │   ├── BP_2022_003.txt
│   │   │   │   ├── BP_2022_004.txt
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2023_002.txt
│   │   │   │   ├── BP_2023_004.txt
│   │   │   │   ├── BP_2023_005.txt
│   │   │   │   ├── BP_2025_001.txt
│   │   │   │   ├── BP_EXT_2022_001.txt
│   │   │   │   ├── BP_EXT_2023_001.txt
│   │   │   │   ├── BP_EXT_2023_002.txt
│   │   │   │   ├── ERR_2021_001.txt
│   │   │   │   ├── ERR_2021_002.txt
│   │   │   │   ├── ERR_2021_003.txt
│   │   │   │   ├── ERR_2021_004.txt
│   │   │   │   ├── ERR_2021_005.txt
│   │   │   │   ├── ERR_2021_006.txt
│   │   │   │   ├── ERR_2021_007.txt
│   │   │   │   ├── ERR_2021_008.txt
│   │   │   │   ├── ERR_2021_009.txt
│   │   │   │   ├── ERR_2021_010.txt
│   │   │   │   ├── ERR_2021_011.txt
│   │   │   │   ├── ERR_2021_012.txt
│   │   │   │   ├── ERR_2021_013.txt
│   │   │   │   ├── ERR_2021_014.txt
│   │   │   │   ├── ERR_2021_015.txt
│   │   │   │   ├── ERR_2022_001.txt
│   │   │   │   ├── ERR_2022_002.txt
│   │   │   │   ├── ERR_2022_003.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2023_005.txt
│   │   │   │   ├── ERR_2023_006.txt
│   │   │   │   ├── ERR_2023_007.txt
│   │   │   │   ├── ERR_2023_008.txt
│   │   │   │   ├── ERR_2023_009.txt
│   │   │   │   ├── ERR_2023_010.txt
│   │   │   │   ├── ERR_2023_011.txt
│   │   │   │   ├── ERR_2023_012.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── ERR_2024_003.txt
│   │   │   │   ├── ERR_2025_001.txt
│   │   │   │   ├── SEC_2021_001.txt
│   │   │   │   ├── SEC_2023_001.txt
│   │   │   │   ├── WARN_2021_001.txt
│   │   │   │   ├── WARN_2021_002.txt
│   │   │   │   ├── WARN_2021_003.txt
│   │   │   │   ├── WARN_2021_004.txt
│   │   │   │   ├── WARN_2021_005.txt
│   │   │   │   ├── WARN_2021_006.txt
│   │   │   │   ├── WARN_2021_007.txt
│   │   │   │   ├── WARN_2021_008.txt
│   │   │   │   ├── WARN_2021_009.txt
│   │   │   │   ├── WARN_2022_001.txt
│   │   │   │   ├── WARN_2022_002.txt
│   │   │   │   ├── WARN_2022_003.txt
│   │   │   │   ├── WARN_2022_004.txt
│   │   │   │   ├── WARN_2022_005.txt
│   │   │   │   ├── WARN_2022_006.txt
│   │   │   │   ├── WARN_2022_007.txt
│   │   │   │   ├── WARN_2022_008.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   ├── WARN_2024_003.txt
│   │   │   │   ├── WARN_2024_004.txt
│   │   │   │   ├── WARN_2024_005.txt
│   │   │   │   ├── WARN_2024_007.txt
│   │   │   │   └── WARN_2025_001.txt
│   │   │   ├── util.py
│   │   │   ├── warn_2021_001_cluster_version.py
│   │   │   ├── warn_2021_002_nodes_version.py
│   │   │   ├── warn_2021_003_pod_cidr_cluster_size.py
│   │   │   ├── warn_2021_004_system_workloads_stable.py
│   │   │   ├── warn_2021_005_disk_latency.py
│   │   │   ├── warn_2021_006_node_conntrack_full.py
│   │   │   ├── warn_2021_007_disk_full.py
│   │   │   ├── warn_2021_008_gke_istio_incompatible_versions.py
│   │   │   ├── warn_2021_009_node_deprecated_image_types.py
│   │   │   ├── warn_2022_001_wi_with_regional_cluster.py
│   │   │   ├── warn_2022_002_md_concealment.py
│   │   │   ├── warn_2022_003_firewall_rules_permission.py
│   │   │   ├── warn_2022_004_logging_api_disabled.py
│   │   │   ├── warn_2022_005_nvdia_gpu.py
│   │   │   ├── warn_2022_006_nap_node_image_types.py
│   │   │   ├── warn_2022_007_storage_scope.py
│   │   │   ├── warn_2022_008_dns_lookup_timeout_intra_node_visibility.py
│   │   │   ├── warn_2023_001_containerfilesystem_scope.py
│   │   │   ├── warn_2023_002_metadata_server_timeout.py
│   │   │   ├── warn_2023_003_monitoring_api_disabled.py
│   │   │   ├── warn_2023_004_too_few_pods_per_node.py
│   │   │   ├── warn_2024_001_cluster_nap_limits_prevent_autoscaling.py
│   │   │   ├── warn_2024_002_ksa_exceed.py
│   │   │   ├── warn_2024_003_ingress_svc_notfound.py
│   │   │   ├── warn_2024_004_ingress_backendcrd.py
│   │   │   ├── warn_2024_005_ingress_servicetype.py
│   │   │   ├── warn_2024_007_loadbalancer_ipv6_no_internal_range.py
│   │   │   └── warn_2025_001_loadbalancer_ipv6_no_external_range.py
│   │   ├── iam/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_auto_grant_editor_role_default_sa.py
│   │   │   ├── iam_rules_snapshot_test.py
│   │   │   ├── sec_2021_001_sa_permissions.py
│   │   │   ├── sec_2024_001_unused_sa.py
│   │   │   └── snapshots/
│   │   │       ├── BP_2023_001.txt
│   │   │       ├── SEC_2021_001.txt
│   │   │       └── SEC_2024_001.txt
│   │   ├── interconnect/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_high_availability.py
│   │   │   ├── interconnect_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   └── WARN_2025_001.txt
│   │   │   ├── warn_2023_001_legacy_dataplane.py
│   │   │   ├── warn_2023_002_defunct_attachment.py
│   │   │   ├── warn_2023_003_link_maintenance.py
│   │   │   └── warn_2025_001_check_interconnect_mtu.py
│   │   ├── lb/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2022_001_lbpolicy_for_sessionaffinity.py
│   │   │   ├── bp_2023_001_cloudcdn_for_lb_backend_services.py
│   │   │   ├── bp_2023_002_healthcheck_logging_for_backend_services.py
│   │   │   ├── bp_2024_001_sessionaffinity_for_lb_backendservices.py
│   │   │   ├── bp_2024_002_global_access_for_regional_ilb.py
│   │   │   ├── bp_2025_001_protocol_for_lb_backendservices.py
│   │   │   ├── bp_2025_002_timeout_sec_for_lb_backendservices.py
│   │   │   ├── bp_2025_003_connection_draining_backend_services.py
│   │   │   ├── lb_rules_snapshot_test.py
│   │   │   └── snapshots/
│   │   │       ├── BP_2022_001.txt
│   │   │       ├── BP_2023_001.txt
│   │   │       ├── BP_2023_002.txt
│   │   │       ├── BP_2024_001.txt
│   │   │       ├── BP_2024_002.txt
│   │   │       ├── BP_2025_001.txt
│   │   │       ├── BP_2025_002.txt
│   │   │       └── BP_2025_003.txt
│   │   ├── lint_rule_repository_test.py
│   │   ├── looker/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2025_001_get_all_instances.py
│   │   │   ├── bp_2025_002_lsp_high_intensity_queries_bq.py
│   │   │   ├── bp_2025_003_get_all_lags_operations.py
│   │   │   ├── looker_rules_snapshot_test.py
│   │   │   └── snapshots/
│   │   │       ├── BP_2025_001.txt
│   │   │       ├── BP_2025_002.txt
│   │   │       └── BP_2025_003.txt
│   │   ├── notebooks/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2023_001_enable_report_system_health.py
│   │   │   ├── bp_2023_002_instances_upgrade_available.py
│   │   │   ├── bp_2023_003_runtimes_upgrade_available.py
│   │   │   ├── bp_2023_004_runtime_idle_shutdown.py
│   │   │   ├── err_2023_001_instances_health_state.py
│   │   │   ├── err_2023_002_create_notebook_compute_subnetworks_permissions_missing.py
│   │   │   ├── err_2023_003_create_notebook_permissions_missing.py
│   │   │   ├── err_2023_004_runtimes_health_state.py
│   │   │   ├── err_2024_001_executor_explicit_project_permissions.py
│   │   │   ├── notebooks_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2023_001.txt
│   │   │   │   ├── BP_2023_002.txt
│   │   │   │   ├── BP_2023_003.txt
│   │   │   │   ├── BP_2023_004.txt
│   │   │   │   ├── ERR_2023_001.txt
│   │   │   │   ├── ERR_2023_002.txt
│   │   │   │   ├── ERR_2023_003.txt
│   │   │   │   ├── ERR_2023_004.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   └── WARN_2023_003.txt
│   │   │   ├── warn_2023_001_notebooks_oom.py
│   │   │   ├── warn_2023_002_data_disk_utilization.py
│   │   │   └── warn_2023_003_boot_disk_utilization.py
│   │   ├── output/
│   │   │   ├── __init__.py
│   │   │   ├── api_output.py
│   │   │   ├── base_output.py
│   │   │   ├── csv_output.py
│   │   │   ├── json_output.py
│   │   │   └── terminal_output.py
│   │   ├── pubsub/
│   │   │   ├── __init__.py
│   │   │   ├── bp_2024_001_ouma_less_one_day.py
│   │   │   ├── err_2024_001_bq_subscription_table_not_found.py
│   │   │   ├── err_2024_002_vpc_sc_new_subs_create_policy_violated.py
│   │   │   ├── err_2024_003_snapshot_creation_fails.py
│   │   │   ├── err_2025_001_push_service_agent_permission.py
│   │   │   ├── pubsub_rules_snapshot_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── BP_2024_001.txt
│   │   │   │   ├── ERR_2024_001.txt
│   │   │   │   ├── ERR_2024_002.txt
│   │   │   │   ├── ERR_2024_003.txt
│   │   │   │   ├── ERR_2025_001.txt
│   │   │   │   ├── WARN_2023_001.txt
│   │   │   │   ├── WARN_2023_002.txt
│   │   │   │   ├── WARN_2023_003.txt
│   │   │   │   ├── WARN_2023_004.txt
│   │   │   │   ├── WARN_2023_005.txt
│   │   │   │   ├── WARN_2023_006.txt
│   │   │   │   ├── WARN_2024_001.txt
│   │   │   │   ├── WARN_2024_002.txt
│   │   │   │   └── WARN_2024_003.txt
│   │   │   ├── warn_2023_001_detached_subscription_exists.py
│   │   │   ├── warn_2023_002_bq_subscription_has_dlq_topic.py
│   │   │   ├── warn_2023_003_topic_atleastone_sub.py
│   │   │   ├── warn_2023_004_orphaned_subscription_exists.py
│   │   │   ├── warn_2023_005_bq_subscription_permisions.py
│   │   │   ├── warn_2023_006_push_requests_failing.py
│   │   │   ├── warn_2024_001_dead_letter_queues_permissions.py
│   │   │   ├── warn_2024_002_gcs_subscription_permissions.py
│   │   │   └── warn_2024_003_cmek_topic_permissions.py
│   │   ├── snapshot_test_base.py
│   │   ├── tpu/
│   │   │   ├── __init__.py
│   │   │   ├── snapshots/
│   │   │   │   └── WARN_2022_001.txt
│   │   │   ├── tpu_rules_snapshot_test.py
│   │   │   └── warn_2022_001_stockout.py
│   │   ├── vertex/
│   │   │   ├── __init__.py
│   │   │   ├── snapshots/
│   │   │   │   └── WARN_2023_001.txt
│   │   │   ├── vertex_rules_snapshot_test.py
│   │   │   └── warn_2023_001_featurestores_state.py
│   │   └── vpc/
│   │       ├── __init__.py
│   │       ├── bp_2022_001_pga_next_hop.py
│   │       ├── bp_2023_001_public_zone_logging.py
│   │       ├── sec_2023_001_public_zone_dnssec.py
│   │       ├── snapshots/
│   │       │   ├── BP_2022_001.txt
│   │       │   ├── BP_2023_001.txt
│   │       │   ├── SEC_2023_001.txt
│   │       │   ├── WARN_2022_001.txt
│   │       │   ├── WARN_2023_001.txt
│   │       │   ├── WARN_2023_002.txt
│   │       │   └── WARN_2024_001.txt
│   │       ├── vpc_rules_snapshot_test.py
│   │       ├── warn_2022_001_project_level_quota.py
│   │       ├── warn_2023_001_psa_no_export_custom_routes.py
│   │       ├── warn_2023_002_private_zone_attachment.py
│   │       └── warn_2024_001_unused_reserved_ip_addresses.py
│   ├── models.py
│   ├── models_test.py
│   ├── product_list.py
│   ├── queries/
│   │   ├── __init__.py
│   │   ├── apigee.py
│   │   ├── apigee_stub.py
│   │   ├── apigee_test.py
│   │   ├── apis.py
│   │   ├── apis_stub.py
│   │   ├── apis_test.py
│   │   ├── apis_utils.py
│   │   ├── apis_utils_test.py
│   │   ├── artifact_registry.py
│   │   ├── artifact_registry_stub.py
│   │   ├── artifact_registry_test.py
│   │   ├── bigquery.py
│   │   ├── bigquery_stub.py
│   │   ├── bigquery_test.py
│   │   ├── billing.py
│   │   ├── billing_stub.py
│   │   ├── billing_test.py
│   │   ├── cloudasset.py
│   │   ├── cloudasset_stub.py
│   │   ├── cloudasset_test.py
│   │   ├── cloudrun.py
│   │   ├── cloudrun_stub.py
│   │   ├── cloudrun_test.py
│   │   ├── cloudsql.py
│   │   ├── cloudsql_stub.py
│   │   ├── cloudsql_test.py
│   │   ├── composer.py
│   │   ├── composer_stub.py
│   │   ├── composer_test.py
│   │   ├── crm.py
│   │   ├── crm_stub.py
│   │   ├── crm_test.py
│   │   ├── dataflow.py
│   │   ├── dataflow_stub.py
│   │   ├── dataflow_test.py
│   │   ├── datafusion.py
│   │   ├── datafusion_stub.py
│   │   ├── datafusion_test.py
│   │   ├── dataproc.py
│   │   ├── dataproc_stub.py
│   │   ├── dataproc_test.py
│   │   ├── dns.py
│   │   ├── dns_stub.py
│   │   ├── gae.py
│   │   ├── gae_stub.py
│   │   ├── gae_test.py
│   │   ├── gcb.py
│   │   ├── gcb_stub.py
│   │   ├── gcb_test.py
│   │   ├── gce.py
│   │   ├── gce_stub.py
│   │   ├── gce_test.py
│   │   ├── gcf.py
│   │   ├── gcf_stub.py
│   │   ├── gcf_test.py
│   │   ├── gcs.py
│   │   ├── gcs_stub.py
│   │   ├── gcs_test.py
│   │   ├── generic_api/
│   │   │   ├── api_build/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── api.py
│   │   │   │   ├── api_unittest.py
│   │   │   │   ├── generic_api_stub.py
│   │   │   │   ├── get_generic.py
│   │   │   │   └── service_factory.py
│   │   │   └── datafusion/
│   │   │       ├── __init__.py
│   │   │       ├── datafusion.py
│   │   │       ├── datafusion_stub.py
│   │   │       └── datafusion_test.py
│   │   ├── gke.py
│   │   ├── gke_stub.py
│   │   ├── gke_test.py
│   │   ├── iam.py
│   │   ├── iam_stub.py
│   │   ├── iam_test.py
│   │   ├── interconnect.py
│   │   ├── interconnect_stub.py
│   │   ├── interconnect_test.py
│   │   ├── kms.py
│   │   ├── kms_stub.py
│   │   ├── kms_test.py
│   │   ├── kubectl.py
│   │   ├── kubectl_stub.py
│   │   ├── lb.py
│   │   ├── lb_stub.py
│   │   ├── lb_test.py
│   │   ├── logs.py
│   │   ├── logs_helper/
│   │   │   ├── __init__.py
│   │   │   ├── logs_query.py
│   │   │   ├── logs_query_test.py
│   │   │   ├── search_exprs.py
│   │   │   └── search_exprs_test.py
│   │   ├── logs_stub.py
│   │   ├── logs_test.py
│   │   ├── looker.py
│   │   ├── looker_stub.py
│   │   ├── looker_test.py
│   │   ├── monitoring.py
│   │   ├── monitoring_stub.py
│   │   ├── monitoring_test.py
│   │   ├── network.py
│   │   ├── network_stub.py
│   │   ├── network_test.py
│   │   ├── networkmanagement.py
│   │   ├── networkmanagement_stub.py
│   │   ├── notebooks.py
│   │   ├── notebooks_stub.py
│   │   ├── notebooks_test.py
│   │   ├── orgpolicy.py
│   │   ├── orgpolicy_test.py
│   │   ├── osconfig.py
│   │   ├── osconfig_stub.py
│   │   ├── osconfig_test.py
│   │   ├── pubsub.py
│   │   ├── pubsub_stub.py
│   │   ├── pubsub_test.py
│   │   ├── quotas.py
│   │   ├── recommender_stub.py
│   │   ├── vertex.py
│   │   ├── vertex_stub.py
│   │   ├── vertex_test.py
│   │   ├── vpn.py
│   │   ├── vpn_stub.py
│   │   ├── vpn_test.py
│   │   ├── web.py
│   │   ├── web_stub.py
│   │   └── web_test.py
│   ├── rule_classes.py
│   ├── runbook/
│   │   ├── __init__.py
│   │   ├── bigquery/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── failed_query.py
│   │   │   ├── failed_query_test.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── failed_query.txt
│   │   │   └── templates/
│   │   │       ├── generics.jinja
│   │   │       └── permissions.jinja
│   │   ├── cloudrun/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── service_deployment.py
│   │   │   ├── service_deployment_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── service_deployment.txt
│   │   │   └── templates/
│   │   │       └── service_deployment.jinja
│   │   ├── command.py
│   │   ├── command_test.py
│   │   ├── constants.py
│   │   ├── crm/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   └── templates/
│   │   │       └── orgpolicy.jinja
│   │   ├── dataflow/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── failed_streaming_pipeline.py
│   │   │   ├── failed_streaming_pipeline_test.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── job_permissions.py
│   │   │   ├── job_permissions_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── failed_streaming_pipeline.txt
│   │   │   │   └── job_permissions.txt
│   │   │   └── templates/
│   │   │       ├── generics.jinja
│   │   │       └── permissions.jinja
│   │   ├── dataproc/
│   │   │   ├── __init__.py
│   │   │   ├── cluster_creation.py
│   │   │   ├── cluster_creation_test.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── cluster_creation.txt
│   │   │   │   └── spark_job_failures.txt
│   │   │   ├── spark_job_failures.py
│   │   │   ├── spark_job_failures_test.py
│   │   │   └── templates/
│   │   │       ├── dataproc_attributes.jinja
│   │   │       ├── job.jinja
│   │   │       ├── logs_related.jinja
│   │   │       ├── network.jinja
│   │   │       └── permissions.jinja
│   │   ├── exceptions.py
│   │   ├── flags.py
│   │   ├── gce/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── disk_performance_benchmark/
│   │   │   │   ├── a-family.json
│   │   │   │   ├── c-family.json
│   │   │   │   ├── e-family.json
│   │   │   │   ├── f-family.json
│   │   │   │   ├── g-family.json
│   │   │   │   ├── h-family.json
│   │   │   │   ├── limits_per_gb.json
│   │   │   │   ├── m-family.json
│   │   │   │   ├── n-family.json
│   │   │   │   ├── t-family.json
│   │   │   │   └── z-family.json
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── guestos_bootup.py
│   │   │   ├── guestos_bootup_test.py
│   │   │   ├── ops_agent.py
│   │   │   ├── ops_agent_test.py
│   │   │   ├── serial_log_analyzer.py
│   │   │   ├── serial_log_analyzer_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── guestos_bootup.txt
│   │   │   │   ├── ops_agent.txt
│   │   │   │   ├── serial_log_analyzer.txt
│   │   │   │   ├── ssh.txt
│   │   │   │   ├── vm_creation.txt
│   │   │   │   ├── vm_performance.txt
│   │   │   │   └── vm_termination.txt
│   │   │   ├── ssh.py
│   │   │   ├── ssh_test.py
│   │   │   ├── templates/
│   │   │   │   ├── generics.jinja
│   │   │   │   ├── instance_property.jinja
│   │   │   │   ├── mig_autoscaling.jinja
│   │   │   │   ├── permissions.jinja
│   │   │   │   ├── vm_attributes.jinja
│   │   │   │   ├── vm_creation.jinja
│   │   │   │   ├── vm_metadata.jinja
│   │   │   │   ├── vm_ops.jinja
│   │   │   │   ├── vm_performance.jinja
│   │   │   │   ├── vm_serial_log.jinja
│   │   │   │   ├── vm_termination.jinja
│   │   │   │   └── vpc_connectivity.jinja
│   │   │   ├── util/
│   │   │   │   ├── __init__.py
│   │   │   │   └── util_test.py
│   │   │   ├── vm_creation.py
│   │   │   ├── vm_creation_test.py
│   │   │   ├── vm_performance.py
│   │   │   ├── vm_performance_test.py
│   │   │   ├── vm_termination.py
│   │   │   └── vm_termination_test.py
│   │   ├── gcf/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── failed_deployments.py
│   │   │   ├── failed_deployments_test.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── failed_deployments.txt
│   │   │   └── templates/
│   │   │       └── failed_deployments.jinja
│   │   ├── gcp/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   └── templates/
│   │   │       ├── api.jinja
│   │   │       └── resource_attribute.jinja
│   │   ├── gke/
│   │   │   ├── __init__.py
│   │   │   ├── cluster_autoscaler.py
│   │   │   ├── cluster_autoscaler_test.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── gke_ip_masq_standard.py
│   │   │   ├── gke_ip_masq_standard_test.py
│   │   │   ├── image_pull.py
│   │   │   ├── image_pull_test.py
│   │   │   ├── ip_exhaustion.py
│   │   │   ├── ip_exhaustion_test.py
│   │   │   ├── logs.py
│   │   │   ├── logs_test.py
│   │   │   ├── monitoring_configuration.py
│   │   │   ├── monitoring_configuration_test.py
│   │   │   ├── node_auto_repair.py
│   │   │   ├── node_auto_repair_test.py
│   │   │   ├── node_bootstrapping.py
│   │   │   ├── node_bootstrapping_test.py
│   │   │   ├── node_unavailability.py
│   │   │   ├── node_unavailability_test.py
│   │   │   ├── resource_quotas.py
│   │   │   ├── resource_quotas_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── cluster_autoscaler.txt
│   │   │   │   ├── gke_ip_masq_standard.txt
│   │   │   │   ├── image_pull.txt
│   │   │   │   ├── ip_exhaustion.txt
│   │   │   │   ├── logs.txt
│   │   │   │   ├── monitoring_configuration.txt
│   │   │   │   ├── node_auto_repair.txt
│   │   │   │   ├── node_bootstrapping.txt
│   │   │   │   ├── node_unavailability.txt
│   │   │   │   └── resource_quotas.txt
│   │   │   └── templates/
│   │   │       ├── clusterautoscaler.jinja
│   │   │       ├── imagepull.jinja
│   │   │       ├── ipexhaustion.jinja
│   │   │       ├── ipmasq_standard.jinja
│   │   │       ├── logs.jinja
│   │   │       ├── monitoring_configuration.jinja
│   │   │       ├── nodeautorepair.jinja
│   │   │       ├── nodebootstrapping.jinja
│   │   │       ├── nodeunavailability.jinja
│   │   │       └── resourcequotas.jinja
│   │   ├── iam/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   └── templates/
│   │   │       ├── permissions.jinja
│   │   │       └── service_account.jinja
│   │   ├── interconnect/
│   │   │   ├── __init__.py
│   │   │   ├── bgp_down_flap.py
│   │   │   ├── bgp_down_flap_test.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── bgp_down_flap.txt
│   │   │   └── templates/
│   │   │       └── bgp_down_flap.jinja
│   │   ├── lb/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── latency.py
│   │   │   ├── latency_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── latency.txt
│   │   │   │   ├── ssl_certificates.txt
│   │   │   │   └── unhealthy_backends.txt
│   │   │   ├── ssl_certificates.py
│   │   │   ├── ssl_certificates_test.py
│   │   │   ├── templates/
│   │   │   │   ├── latency.jinja
│   │   │   │   ├── ssl_certificates.jinja
│   │   │   │   └── unhealthy_backends.jinja
│   │   │   ├── unhealthy_backends.py
│   │   │   └── unhealthy_backends_test.py
│   │   ├── logs/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   └── templates/
│   │   │       └── logging.jinja
│   │   ├── monitoring/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   └── templates/
│   │   │       └── metrics.jinja
│   │   ├── nat/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── out_of_resources.py
│   │   │   ├── out_of_resources_test.py
│   │   │   ├── public_nat_ip_allocation_failed.py
│   │   │   ├── public_nat_ip_allocation_failed_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── public_nat_ip_allocation_failed.txt
│   │   │   ├── templates/
│   │   │   │   ├── nat_ip_allocation_failed.jinja
│   │   │   │   └── nat_out_of_resources.jinja
│   │   │   ├── utils.py
│   │   │   └── utils_test.py
│   │   ├── op.py
│   │   ├── op_test.py
│   │   ├── output/
│   │   │   ├── __init__.py
│   │   │   ├── api_output.py
│   │   │   ├── base_output.py
│   │   │   └── terminal_output.py
│   │   ├── pubsub/
│   │   │   ├── __init__.py
│   │   │   ├── bigquery_subscription_delivery.py
│   │   │   ├── bigquery_subscription_delivery_test.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── gcs_subscription_delivery.py
│   │   │   ├── gcs_subscription_delivery_test.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── pull_subscription_delivery.py
│   │   │   ├── pull_subscription_delivery_test.py
│   │   │   ├── push_subscription_delivery.py
│   │   │   ├── push_subscription_delivery_test.py
│   │   │   ├── snapshots/
│   │   │   │   ├── bigquery_subscription_delivery.txt
│   │   │   │   ├── gcs_subscription_delivery.txt
│   │   │   │   ├── pull_subscription_delivery.txt
│   │   │   │   └── push_subscription_delivery.txt
│   │   │   └── templates/
│   │   │       └── generics.jinja
│   │   ├── report.py
│   │   ├── report_test.py
│   │   ├── runbook_test.py
│   │   ├── snapshot_test_base.py
│   │   ├── util.py
│   │   ├── util_test.py
│   │   ├── vertex/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── workbench_instance_stuck_in_provisioning.txt
│   │   │   ├── templates/
│   │   │   │   ├── workbench_compute.jinja
│   │   │   │   ├── workbench_container.jinja
│   │   │   │   ├── workbench_environment_version.jinja
│   │   │   │   ├── workbench_images.jinja
│   │   │   │   ├── workbench_ip.jinja
│   │   │   │   ├── workbench_jupyter_port.jinja
│   │   │   │   ├── workbench_jupyter_space.jinja
│   │   │   │   ├── workbench_scripts.jinja
│   │   │   │   ├── workbench_state.jinja
│   │   │   │   └── workbench_system_logs.jinja
│   │   │   ├── workbench_instance_stuck_in_provisioning.py
│   │   │   └── workbench_instance_stuck_in_provisioning_test.py
│   │   ├── vpc/
│   │   │   ├── __init__.py
│   │   │   ├── constants.py
│   │   │   ├── flags.py
│   │   │   ├── generalized_steps.py
│   │   │   ├── generalized_steps_test.py
│   │   │   ├── snapshots/
│   │   │   │   └── vm_external_ip_connectivity.txt
│   │   │   ├── templates/
│   │   │   │   ├── rca.jinja
│   │   │   │   └── vm_external_ip_connectivity.jinja
│   │   │   ├── util.py
│   │   │   ├── vm_external_ip_connectivity.py
│   │   │   └── vm_external_ip_connectivity_test.py
│   │   └── vpn/
│   │       ├── __init__.py
│   │       ├── constants.py
│   │       ├── flags.py
│   │       ├── generalized_steps.py
│   │       ├── generalized_steps_test.py
│   │       ├── snapshots/
│   │       │   └── vpn_tunnel_check.txt
│   │       ├── templates/
│   │       │   └── vpn_check.jinja
│   │       ├── vpn_tunnel_check.py
│   │       └── vpn_tunnel_check_test.py
│   ├── search/
│   │   ├── __init__.py
│   │   ├── command.py
│   │   ├── command_test.py
│   │   ├── util.py
│   │   └── util_test.py
│   ├── types.py
│   ├── types_test.py
│   ├── utils.py
│   └── utils_test.py
├── pyinstaller/
│   ├── hook-gcpdiag.lint.py
│   ├── hook-gcpdiag.queries.py
│   ├── hook-gcpdiag.runbook.py
│   └── hook-googleapiclient.model.py
├── pyinstaller.spec
├── requirements.in
├── requirements.txt
├── test-data/
│   ├── Makefile.inc
│   ├── README.md
│   ├── apigee1/
│   │   ├── Makefile
│   │   ├── apigee1.tf
│   │   ├── json-dumps/
│   │   │   ├── apigee-envgroups-attachments-empty.json
│   │   │   ├── apigee-envgroups-gcpdiag-demo-envgroup-1-attachments.json
│   │   │   ├── apigee-envgroups.json
│   │   │   ├── apigee-instances-gcpdiag-apigee1-inst1-aaaa-attachments.json
│   │   │   ├── apigee-instances.json
│   │   │   ├── apigee-key.json
│   │   │   ├── apigee-organization.json
│   │   │   ├── apigee-organizations.json
│   │   │   ├── compute-effective-firewalls-apigee-network.json
│   │   │   ├── compute-migs-us-central1.json
│   │   │   ├── compute-network-apigee-network.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-apigee-subnetwork.json
│   │   │   ├── compute-templates.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── kms-key-iam-policy.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── bigquery1/
│   │   ├── Makefile
│   │   ├── job.tf
│   │   ├── json-dumps/
│   │   │   ├── ancestor.json
│   │   │   ├── bigquery-failed-job.json
│   │   │   ├── iam-policy.json
│   │   │   ├── job_get_invalid-region_id.json
│   │   │   ├── job_get_us_IS.json
│   │   │   ├── job_get_us_csv.json
│   │   │   ├── job_get_us_duplicate.json
│   │   │   ├── job_get_us_error.json
│   │   │   ├── job_get_us_errors.json
│   │   │   ├── job_get_us_job.json
│   │   │   ├── job_get_us_job1.json
│   │   │   ├── job_get_us_job2.json
│   │   │   ├── job_get_us_notfound.json
│   │   │   ├── job_get_us_running.json
│   │   │   ├── job_get_us_success.json
│   │   │   ├── job_get_us_unknown.json
│   │   │   ├── job_results_us_IS_.json
│   │   │   ├── job_results_us_mockresult1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── billing1/
│   │   ├── Makefile
│   │   └── json-dumps/
│   │       ├── all_billing_account_projects.json
│   │       ├── all_billing_accounts.json
│   │       ├── billing_account.json
│   │       ├── cost_insights.json
│   │       ├── project.json
│   │       ├── project_billing_info.json
│   │       ├── projects.json
│   │       └── services.json
│   ├── cloudasset1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── project.json
│   │   │   ├── search-all-resources-us-central1.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variable.tf
│   ├── cloudrun1/
│   │   ├── Makefile
│   │   ├── cloudrun1.tf
│   │   ├── json-dumps/
│   │   │   ├── cloudrun_services.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── locations.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── cloudrun2/
│   │   ├── Makefile
│   │   ├── artifact_registry.tf
│   │   ├── build_configs/
│   │   │   └── deploy_run_with_bad_container/
│   │   │       ├── Dockerfile
│   │   │       └── cloudbuild.yaml
│   │   ├── cloud_run.tf
│   │   ├── json-dumps/
│   │   │   ├── cloudrun_services.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── locations.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── cloudsql1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── cloudsql-instances.json
│   │   │   ├── iam-policy.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── sql1.tf
│   │   └── variables.tf
│   ├── composer1/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── composer-env1.tf
│   │   ├── composer-env2.tf
│   │   ├── json-dumps/
│   │   │   ├── composer-environments-us-central1.json
│   │   │   ├── compute-regions.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-account-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── provider.tf
│   │   └── variables.tf
│   ├── dataflow1/
│   │   ├── Makefile
│   │   ├── bucket.tf
│   │   ├── job.tf
│   │   ├── json-dumps/
│   │   │   ├── dataflow-jobs-aggregated.json
│   │   │   ├── dataflow-jobs-us-central1-2024-06-19_09_43_07-14927685200167458422.json
│   │   │   ├── dataflow-jobs-us-central1-streaming.json
│   │   │   ├── dataflow-jobs-us-central1.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── log-exclusions.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── streaming_job.tf
│   │   └── variables.tf
│   ├── datafusion1/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── datafusion.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-subnetworks-us-central1.json
│   │   │   ├── datafusion-default-application-pipeline1-preferences.json
│   │   │   ├── datafusion-default-applications.json
│   │   │   ├── datafusion-default-namespace-preferences.json
│   │   │   ├── datafusion-default-user-compute-profile.json
│   │   │   ├── datafusion-instances.json
│   │   │   ├── datafusion-instances1.json
│   │   │   ├── datafusion-system-compute-profile.json
│   │   │   ├── datafusion-system-preferences.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-account-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── namespaces.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── dataproc1/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── dataproc_cluster.tf
│   │   ├── job.tf
│   │   ├── json-dumps/
│   │   │   ├── autoscaling-policy.json
│   │   │   ├── compute-instances-us-central1-a.json
│   │   │   ├── compute-instances-us-central1-b.json
│   │   │   ├── compute-instances-us-central1-c.json
│   │   │   ├── compute-instances-us-central1-f.json
│   │   │   ├── compute-network-test-bad-network.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── connectivity-test.json
│   │   │   ├── dataproc-clusters-us-central1.json
│   │   │   ├── dataproc-job-failed.json
│   │   │   ├── dataproc-job-success.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── network.tf
│   │   ├── project.tf
│   │   ├── provider.tf
│   │   └── variables.tf
│   ├── dataproc2/
│   │   └── json-dumps/
│   │       ├── logging-entries-1.json
│   │       ├── project.json
│   │       └── services.json
│   ├── dataproc3/
│   │   └── json-dumps/
│   │       ├── logging-entries-1.json
│   │       ├── project.json
│   │       └── services.json
│   ├── fw-policy/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── firewall.tf
│   │   ├── fw-policy.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-migs-europe-west2-b.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-zones.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-custom.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-custom.arEnforceImmutableTags.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── org-constraints.json
│   │   │   ├── org-policies.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── org-policy.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gaes1/
│   │   ├── Makefile
│   │   ├── gaes1-bucket-object.tf
│   │   ├── gaes1-bucket.tf
│   │   ├── gaes1.tf
│   │   ├── json-dumps/
│   │   │   ├── appengine_services.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   ├── services.json
│   │   │   └── versions.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gcb1/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── artifact_registry.tf
│   │   ├── buckets.tf
│   │   ├── build_configs/
│   │   │   ├── .gitignore
│   │   │   ├── cloudbuild1.yaml.tpl
│   │   │   ├── cloudbuild2.yaml.tpl
│   │   │   ├── cloudbuild3.yaml.tpl
│   │   │   └── cloudbuild4.yaml.tpl
│   │   ├── build_configs.tf
│   │   ├── json-dumps/
│   │   │   ├── artifact-registry-policy.json
│   │   │   ├── artifact-registry-project-settings.json
│   │   │   ├── bucket-gcpdiag-gcb1-bucket1-aaaa.json
│   │   │   ├── cloudbuild-empty.json
│   │   │   ├── cloudbuild-triggers.json
│   │   │   ├── cloudbuild-us-central1.json
│   │   │   ├── cloudbuild.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── service_accounts.tf
│   │   ├── source_repository.tf
│   │   ├── trigger.tf
│   │   └── variables.tf
│   ├── gce-image-license/
│   │   ├── Makefile
│   │   └── json-dumps/
│   │       ├── centos-cloud-licenses.json
│   │       ├── cos-cloud-licenses.json
│   │       ├── debian-cloud-licenses.json
│   │       ├── fedora-cloud-licenses.json
│   │       ├── fedora-coreos-cloud-licenses.json
│   │       ├── opensuse-cloud-licenses.json
│   │       ├── rhel-cloud-licenses.json
│   │       ├── rhel-sap-cloud-licenses.json
│   │       ├── rocky-linux-cloud-licenses.json
│   │       ├── suse-cloud-licenses.json
│   │       ├── suse-sap-cloud-licenses.json
│   │       ├── ubuntu-os-cloud-licenses.json
│   │       ├── ubuntu-os-pro-cloud-licenses.json
│   │       ├── windows-cloud-licenses.json
│   │       └── windows-sql-cloud-licenses.json
│   ├── gce1/
│   │   ├── Makefile
│   │   ├── gce1.tf
│   │   ├── gce2.tf
│   │   ├── gke.tf
│   │   ├── healthchecks.tf
│   │   ├── ig1.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west1-b.json
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-europe-west4-a.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-igs-aggregated.json
│   │   │   ├── compute-igs-europe-west1-b.json
│   │   │   ├── compute-igs-europe-west2-b.json
│   │   │   ├── compute-igs-europe-west4-a.json
│   │   │   ├── compute-igs-europe-west4-b.json
│   │   │   ├── compute-instances-aggregated.json
│   │   │   ├── compute-instances-europe-west1-b-2.json
│   │   │   ├── compute-instances-europe-west1-b.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-europe-west4-a-2.json
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-instances-europe-west4-b.json
│   │   │   ├── compute-licenses.json
│   │   │   ├── compute-migs-aggregated.json
│   │   │   ├── compute-migs-europe-west1-b.json
│   │   │   ├── compute-migs-europe-west2-b.json
│   │   │   ├── compute-migs-europe-west4-a.json
│   │   │   ├── compute-negs-empty.json
│   │   │   ├── compute-negs-europe-west1-b.json
│   │   │   ├── compute-negs-europe-west4-b.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-routes.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-serial-port-output-1010101010.json
│   │   │   ├── compute-serial-port-output-1010101011.json
│   │   │   ├── compute-subnetwork-policy.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-templates.json
│   │   │   ├── compute-zones.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── mig.tf
│   │   ├── neg1.tf
│   │   ├── project.tf
│   │   ├── terraform
│   │   └── variables.tf
│   ├── gce2/
│   │   ├── Makefile
│   │   ├── gce_faulty_ssh.tf
│   │   ├── gce_valid_ssh.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west1-b.json
│   │   │   ├── compute-disks-europe-west2-a.json
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-europe-west4-a.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-igs-europe-west1-b.json
│   │   │   ├── compute-igs-europe-west2-b.json
│   │   │   ├── compute-igs-europe-west4-a.json
│   │   │   ├── compute-instances-europe-west1-b-2.json
│   │   │   ├── compute-instances-europe-west1-b.json
│   │   │   ├── compute-instances-europe-west2-a.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-europe-west4-a-2.json
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-licenses.json
│   │   │   ├── compute-migs-europe-west1-b.json
│   │   │   ├── compute-migs-europe-west2-b.json
│   │   │   ├── compute-migs-europe-west4-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-routes.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-serial-port-output-1010101010.json
│   │   │   ├── compute-serial-port-output-1010101011.json
│   │   │   ├── compute-serial-port-output-faulty-linux-ssh.json
│   │   │   ├── compute-serial-port-output-faulty-windows-ssh.json
│   │   │   ├── compute-serial-port-output-valid-linux-ssh.json
│   │   │   ├── compute-serial-port-output-valid-windows-ssh.json
│   │   │   ├── compute-subnetwork-policy.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-templates.json
│   │   │   ├── compute-zones.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gce3/
│   │   ├── Makefile
│   │   ├── faulty-opsagent.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-europe-west2-a.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-zones.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-custom.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── orgpolicy.tf
│   │   ├── project.tf
│   │   ├── terraform
│   │   ├── variables.tf
│   │   └── working-opsagent.tf
│   ├── gce4/
│   │   ├── Makefile
│   │   ├── gce_faulty_ssh.tf
│   │   ├── gce_valid_ssh.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west1-b.json
│   │   │   ├── compute-disks-europe-west2-a.json
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-europe-west4-a.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-igs-europe-west1-b.json
│   │   │   ├── compute-igs-europe-west2-b.json
│   │   │   ├── compute-igs-europe-west4-a.json
│   │   │   ├── compute-instances-europe-west1-b-2.json
│   │   │   ├── compute-instances-europe-west1-b.json
│   │   │   ├── compute-instances-europe-west2-a.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-europe-west4-a-2.json
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-licenses.json
│   │   │   ├── compute-migs-europe-west1-b.json
│   │   │   ├── compute-migs-europe-west2-b.json
│   │   │   ├── compute-migs-europe-west4-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-routes.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-serial-port-output-1010101010.json
│   │   │   ├── compute-serial-port-output-1010101011.json
│   │   │   ├── compute-serial-port-output-faulty-linux-ssh.json
│   │   │   ├── compute-serial-port-output-faulty-windows-ssh.json
│   │   │   ├── compute-serial-port-output-valid-linux-ssh.json
│   │   │   ├── compute-serial-port-output-valid-windows-ssh.json
│   │   │   ├── compute-subnetwork-policy.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-templates.json
│   │   │   ├── compute-zones.json
│   │   │   ├── global-operations.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gce5/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-us-central1-c.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-aggregated.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-us-central1-c.json
│   │   │   ├── compute-migs-aggregated.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-zones.json
│   │   │   ├── global-operations.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── main.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gce6/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-disks-us-central1-c.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-aggregated.json
│   │   │   ├── compute-instances-us-central1-c.json
│   │   │   ├── compute-migs-aggregated.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── global-operations.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── main.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gcf1/
│   │   ├── .gitignore
│   │   ├── Makefile
│   │   ├── gcf1.tf
│   │   ├── json-dumps/
│   │   │   ├── cloudfunctions-empty.json
│   │   │   ├── cloudfunctions-us-central1.json
│   │   │   ├── cloudfunctions.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── sample-code/
│   │   │   ├── main.py
│   │   │   └── requirements.txt
│   │   └── variables.tf
│   ├── gcf2/
│   │   ├── .gitignore
│   │   ├── Makefile
│   │   ├── gcf2.tf
│   │   ├── json-dumps/
│   │   │   ├── cloudfunctions-empty.json
│   │   │   ├── cloudfunctions-europe-west2.json
│   │   │   ├── cloudfunctions.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── sourcecode/
│   │   │   ├── memalloc.py
│   │   │   └── requirements.txt
│   │   └── variables.tf
│   ├── gcs1/
│   │   ├── Makefile
│   │   ├── gcs1.tf
│   │   ├── json-dumps/
│   │   │   ├── bucket-gcpdiag-gcs1bucket2-aaaa.json
│   │   │   ├── bucket-roles.json
│   │   │   ├── project.json
│   │   │   ├── services.json
│   │   │   └── storage.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gke1/
│   │   ├── Makefile
│   │   ├── firewall.tf.old
│   │   ├── gke1.tf
│   │   ├── gke2.tf
│   │   ├── gke3.tf
│   │   ├── gke4.tf
│   │   ├── gke5.tf
│   │   ├── gke6.tf
│   │   ├── json-dumps/
│   │   │   ├── backendServices.json
│   │   │   ├── compute-addresses.json
│   │   │   ├── compute-disks-europe-west1-b.json
│   │   │   ├── compute-disks-europe-west4-a.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-igs-empty.json
│   │   │   ├── compute-instances-aggregated.json
│   │   │   ├── compute-instances-empty.json
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-interconnect1.json
│   │   │   ├── compute-interconnect2.json
│   │   │   ├── compute-interconnect3.json
│   │   │   ├── compute-interconnect4.json
│   │   │   ├── compute-interconnects.json
│   │   │   ├── compute-migs-aggregated.json
│   │   │   ├── compute-migs-empty.json
│   │   │   ├── compute-migs-europe-west4-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-routers-europe-west4.json
│   │   │   ├── compute-routers-us-east4.json
│   │   │   ├── compute-routers-us-west2.json
│   │   │   ├── compute-subnetwork-policy.json
│   │   │   ├── compute-subnetworks-aggregated.json
│   │   │   ├── compute-subnetworks-europe-west4.json
│   │   │   ├── compute-templates.json
│   │   │   ├── compute-zones.json
│   │   │   ├── container-clusters.json
│   │   │   ├── container-kubectl.json
│   │   │   ├── container-server-config-europe-west4-a.json
│   │   │   ├── container-server-config-europe-west4.json
│   │   │   ├── forwardingRules.json
│   │   │   ├── healthChecks.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-roles-custom.json
│   │   │   ├── iam-roles-get.json
│   │   │   ├── iam-service-account-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── instances.json
│   │   │   ├── interconnect-attachment1.json
│   │   │   ├── interconnect-attachments.json
│   │   │   ├── kms-key-destroyed.json
│   │   │   ├── kms-key-disabled.json
│   │   │   ├── kms-key-enabled.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-custom.arEnforceImmutableTags.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── org-constraints.json
│   │   │   ├── org-policies.json
│   │   │   ├── project.json
│   │   │   ├── services.json
│   │   │   ├── subscriptions.json
│   │   │   └── topics.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gke2/
│   │   ├── Makefile
│   │   └── json-dumps/
│   │       ├── compute-disks-empty.json
│   │       ├── compute-disks-europe-west10-a.json
│   │       ├── compute-disks-europe-west2-b.json
│   │       ├── compute-effective-firewalls-default.json
│   │       ├── compute-igs-empty.json
│   │       ├── compute-igs-europe-west2-b.json
│   │       ├── compute-instances-empty.json
│   │       ├── compute-instances-europe-west10-a.json
│   │       ├── compute-instances-europe-west2-b.json
│   │       ├── compute-interconnects.json
│   │       ├── compute-migs-empty.json
│   │       ├── compute-migs-europe-west10-a.json
│   │       ├── compute-migs-europe-west2-b.json
│   │       ├── compute-network-default.json
│   │       ├── compute-project.json
│   │       ├── compute-regions.json
│   │       ├── compute-routers-europe-west4.json
│   │       ├── compute-subnetwork-policy.json
│   │       ├── compute-subnetworks-aggregated.json
│   │       ├── compute-templates.json
│   │       ├── compute-zones.json
│   │       ├── container-clusters.json
│   │       ├── container-server-config-europe-west10-a.json
│   │       ├── container-server-config-europe-west10.json
│   │       ├── iam-policy.json
│   │       ├── iam-roles-custom.json
│   │       ├── iam-roles-get.json
│   │       ├── iam-service-account-policy.json
│   │       ├── iam-service-accounts.json
│   │       ├── logging-entries-1.json
│   │       ├── monitoring-query.json
│   │       ├── project.json
│   │       └── services.json
│   ├── gke3/
│   │   ├── Makefile
│   │   ├── cluster-1.tf
│   │   ├── json-dumps/
│   │   │   ├── container-cluster-cluster-1.json
│   │   │   ├── container-clusters.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── logging-entries-2.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── network.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── gke4/
│   │   ├── Makefile
│   │   ├── cluster.tf
│   │   ├── json-dumps/
│   │   │   ├── container-clusters.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── iam1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── org-constraints.json
│   │   │   ├── org-policies.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── interconnect1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-interconnects.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-routers-routerStatus-dummy-router1.json
│   │   │   ├── compute-routers-routerStatus-dummy-router11.json
│   │   │   ├── compute-routers-routerStatus-dummy-router2.json
│   │   │   ├── compute-routers-routerStatus-dummy-router3.json
│   │   │   ├── compute-routers-us-central1.json
│   │   │   ├── compute-routers-us-east4.json
│   │   │   ├── compute-routers-us-west2.json
│   │   │   ├── interconnect-attachments.json
│   │   │   ├── logging-entries-1.json
│   │   │   └── project.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── lb1/
│   │   ├── Makefile
│   │   ├── http-lb-mig.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-aggregated-backendServices.json
│   │   │   ├── compute-aggregated-forwardingRules.json
│   │   │   ├── compute-backendServices.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── healthChecks.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── lb2/
│   │   ├── Makefile
│   │   ├── http-lb-mig.tf
│   │   ├── json-dumps/
│   │   │   ├── backendService-web-backend-service-get-health-instanceGroups-lb-backend-example-us-east1-b.json
│   │   │   ├── compute-aggregated-backendServices.json
│   │   │   ├── compute-aggregated-forwardingRules.json
│   │   │   ├── compute-backendServices-europe-west4.json
│   │   │   ├── compute-igs-aggregated.json
│   │   │   ├── compute-igs-us-east1-b.json
│   │   │   ├── compute-instances-europe-west4-b.json
│   │   │   ├── compute-instances-us-east1-b.json
│   │   │   ├── compute-negs-europe-west4-b.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── compute-serial-port-output-neg-vm.json
│   │   │   ├── compute-serial-port-output-vm-pn3l.json
│   │   │   ├── compute-zones.json
│   │   │   ├── healthChecks.json
│   │   │   ├── lb-insights-europe-west4.json
│   │   │   ├── lb-insights-global.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   ├── regionBackendService-backend-service-2-europe-west4-get-health-networkEndpointGroups-neg1-europe-west4-b.json
│   │   │   ├── regionHealthChecks-europe-west4.json
│   │   │   └── services.json
│   │   ├── passthrough-lb-neg.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── lb3/
│   │   ├── Makefile
│   │   ├── certs.tf
│   │   ├── https-lb.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-aggregated-backendServices.json
│   │   │   ├── compute-aggregated-forwardingRules.json
│   │   │   ├── compute-aggregated-targetHttpsProxies.json
│   │   │   ├── compute-sslCertificates.json
│   │   │   ├── compute-targetHttpsProxies.json
│   │   │   ├── compute-targetSslProxies.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── ssl-lb.tf
│   │   ├── update_ip.py
│   │   └── variables.tf
│   ├── looker1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── logging-entries-1.json
│   │   │   ├── looker-instances.json
│   │   │   ├── looker.json
│   │   │   ├── operation.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── nat1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-instances-europe-west4-a.json
│   │   │   ├── compute-instances-us-central1-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-nat-vpc-network.json
│   │   │   ├── compute-network-nat_vpc_network.json
│   │   │   ├── compute-routers-europe-west4.json
│   │   │   ├── compute-routers-natIpInfo-public-nat-cloud-router.json
│   │   │   ├── compute-routers-natMappingInfo-public-nat-cloud-router.json
│   │   │   ├── compute-routers-natMappingInfo-public_nat_cloud_router.json
│   │   │   ├── compute-routers-routerStatus-public-nat-cloud-router.json
│   │   │   ├── compute-routers-routerStatus-public_nat_cloud_router.json
│   │   │   ├── compute-routers-us-central1.json
│   │   │   ├── monitoring-query-nat-allocation-failed.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── public-cloud-nat.tf
│   │   └── variables.tf
│   ├── notebooks1/
│   │   ├── Makefile
│   │   ├── instances1.tf
│   │   ├── json-dumps/
│   │   │   ├── health-state.json
│   │   │   ├── instances.json
│   │   │   ├── is-upgradeable.json
│   │   │   ├── project.json
│   │   │   ├── runtimes.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── runtimes1.tf
│   │   └── variables.tf
│   ├── notebooks2/
│   │   ├── Makefile
│   │   ├── instance_ok.tf
│   │   ├── instance_provisioning_stuck.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-instances-disks-us-west1-a.json
│   │   │   ├── compute-instances-us-west1-a.json
│   │   │   ├── compute-serial-port-output-notebooks2instance-ok.json
│   │   │   ├── compute-serial-port-output-notebooks2instance-provisioning-stuck.json
│   │   │   ├── logging-entries-1.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── notebooks2instance-ok-check-upgradability.json
│   │   │   ├── notebooks2instance-provisioning-stuck-check-upgradability.json
│   │   │   ├── org-constraint-compute.disableSerialPortAccess.json
│   │   │   ├── org-constraint-compute.disableSerialPortLogging.json
│   │   │   ├── org-constraint-compute.disableSshInBrowser.json
│   │   │   ├── org-constraint-compute.requireOsLogin.json
│   │   │   ├── org-constraint-compute.requireShieldedVm.json
│   │   │   ├── org-constraint-iam.automaticIamGrantsForDefaultServiceAccounts.json
│   │   │   ├── org-constraint-iam.disableCrossProjectServiceAccountUsage.json
│   │   │   ├── project.json
│   │   │   ├── services.json
│   │   │   └── workbench-instances.json
│   │   ├── network.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── osconfig1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── inventories.json
│   │   │   ├── inventory.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── pubsub1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── bq-subscription.json
│   │   │   ├── bucket-roles.json
│   │   │   ├── gcs-subscription.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   ├── pull-subscription.json
│   │   │   ├── services.json
│   │   │   ├── subscriptions-iam.json
│   │   │   ├── subscriptions.json
│   │   │   ├── topic-iam.json
│   │   │   └── topics.json
│   │   ├── project.tf
│   │   ├── pubsub1.tf
│   │   └── variables.tf
│   ├── tpu1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── logging-entries-1.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── vertex1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── featurestores.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   ├── variables.tf
│   │   └── vertex1.tf
│   ├── vpc1/
│   │   ├── Makefile
│   │   ├── json-dumps/
│   │   │   ├── compute-addresses.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-regions.json
│   │   │   ├── monitoring-query.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── vpc2/
│   │   ├── Makefile
│   │   ├── external_connectivity_private_instance_faulty.tf
│   │   ├── external_connectivity_private_instance_valid.tf
│   │   ├── external_connectivity_public_instance_faulty.tf
│   │   ├── external_connectivity_public_instance_valid.tf
│   │   ├── json-dumps/
│   │   │   ├── compute-disks-europe-west2-b.json
│   │   │   ├── compute-effective-firewalls-default.json
│   │   │   ├── compute-instances-europe-west2-b.json
│   │   │   ├── compute-instances-us-central1-a.json
│   │   │   ├── compute-network-default.json
│   │   │   ├── compute-network-routes.json
│   │   │   ├── compute-project.json
│   │   │   ├── compute-zones.json
│   │   │   ├── connectivity-test.json
│   │   │   ├── iam-policy.json
│   │   │   ├── iam-service-accounts.json
│   │   │   ├── monitoring-query-instance-dropped-received-packets-count.json
│   │   │   ├── monitoring-query-nat-allocation-failed.json
│   │   │   ├── monitoring-query-nat-dropped-received-packets-count.json
│   │   │   ├── monitoring-query-nat-dropped-sent-packets-count.json
│   │   │   ├── project.json
│   │   │   └── services.json
│   │   ├── network.tf
│   │   ├── project.tf
│   │   └── variables.tf
│   ├── vpn/
│   │   └── json-dumps/
│   │       ├── compute-project.json
│   │       ├── logging-entries-1.json
│   │       ├── monitoring-query.json
│   │       ├── project.json
│   │       ├── vpn-tunnel-1.json
│   │       └── vpn-tunnel-down.json
│   └── web/
│       ├── Makefile
│       └── static/
│           ├── cloud-google-com-data-fusion-docs-concepts-configure-clusters
│           ├── cloud-google-com-data-fusion-docs-support-version-support-policy
│           └── cloud-google-com-kubernetes-engine-docs-release-schedule
└── website/
    ├── api_render.py
    ├── archetypes/
    │   └── default.md
    ├── assets/
    │   ├── pdoc_templates/
    │   │   ├── frame.html.jinja2
    │   │   └── module.html.jinja2
    │   └── scss/
    │       └── _variables_project.scss
    ├── config.toml
    ├── content/
    │   └── en/
    │       ├── _index.html
    │       ├── docs/
    │       │   ├── _index.md
    │       │   ├── authentication.md
    │       │   ├── development/
    │       │   │   ├── _index.md
    │       │   │   ├── architecture.md
    │       │   │   └── environment.md
    │       │   ├── running.md
    │       │   └── usage.md
    │       ├── privacy.md
    │       ├── rules/
    │       │   ├── _index.md
    │       │   ├── apigee/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   └── 2023_006.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   └── 2022_002.md
    │       │   │   └── _index.md
    │       │   ├── asm/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2025_001.md
    │       │   │   │   └── 2025_002.md
    │       │   │   └── _index.md
    │       │   ├── bigquery/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   ├── 2023_008.md
    │       │   │   │   ├── 2023_009.md
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   ├── 2024_004.md
    │       │   │   │   ├── 2024_005.md
    │       │   │   │   └── 2024_006.md
    │       │   │   └── _index.md
    │       │   ├── billing/
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   └── 2022_003.md
    │       │   │   └── _index.md
    │       │   ├── cloudrun/
    │       │   │   ├── ERR/
    │       │   │   │   └── 2022_001.md
    │       │   │   └── _index.md
    │       │   ├── cloudsql/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2023_003.md
    │       │   │   ├── BP_EXT/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   └── 2023_004.md
    │       │   │   ├── ERR/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── SEC/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2023_003.md
    │       │   │   └── _index.md
    │       │   ├── composer/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2023_003.md
    │       │   │   ├── BP_EXT/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   └── 2023_002.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   ├── 2023_008.md
    │       │   │   │   ├── 2023_009.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   └── 2024_003.md
    │       │   │   └── _index.md
    │       │   ├── dataflow/
    │       │   │   ├── BP/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   ├── 2023_008.md
    │       │   │   │   ├── 2023_009.md
    │       │   │   │   ├── 2023_010.md
    │       │   │   │   ├── 2023_011.md
    │       │   │   │   ├── 2023_012.md
    │       │   │   │   ├── 2023_013.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   ├── 2024_004.md
    │       │   │   │   └── 2024_005.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   └── _index.md
    │       │   ├── datafusion/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2022_005.md
    │       │   │   │   ├── 2022_006.md
    │       │   │   │   ├── 2022_007.md
    │       │   │   │   ├── 2022_008.md
    │       │   │   │   ├── 2022_009.md
    │       │   │   │   ├── 2022_010.md
    │       │   │   │   ├── 2022_011.md
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   ├── 2024_004.md
    │       │   │   │   └── 2024_005.md
    │       │   │   └── _index.md
    │       │   ├── dataproc/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_098.md
    │       │   │   │   └── 2022_099.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   └── 2023_008.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   └── _index.md
    │       │   ├── gae/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2025_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   └── 2022_002.md
    │       │   │   └── _index.md
    │       │   ├── gcb/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   └── 2022_004.md
    │       │   │   └── _index.md
    │       │   ├── gce/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   ├── BP_EXT/
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   └── 2024_002.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2021_002.md
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2021_004.md
    │       │   │   │   ├── 2021_005.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   └── 2024_004.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2021_002.md
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2021_004.md
    │       │   │   │   ├── 2021_005.md
    │       │   │   │   ├── 2021_006.md
    │       │   │   │   ├── 2021_007.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2022_005.md
    │       │   │   │   ├── 2022_006.md
    │       │   │   │   ├── 2022_007.md
    │       │   │   │   ├── 2022_008.md
    │       │   │   │   ├── 2022_009.md
    │       │   │   │   ├── 2022_010.md
    │       │   │   │   ├── 2022_011.md
    │       │   │   │   ├── 2022_012.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   └── 2023_002.md
    │       │   │   └── _index.md
    │       │   ├── gcf/
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   └── 2022_003.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   └── 2021_002.md
    │       │   │   └── _index.md
    │       │   ├── gcs/
    │       │   │   ├── BP/
    │       │   │   │   └── 2022_001.md
    │       │   │   └── _index.md
    │       │   ├── gke/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   └── 2025_001.md
    │       │   │   ├── BP_EXT/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   └── 2023_002.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2021_002.md
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2021_004.md
    │       │   │   │   ├── 2021_005.md
    │       │   │   │   ├── 2021_006.md
    │       │   │   │   ├── 2021_007.md
    │       │   │   │   ├── 2021_008.md
    │       │   │   │   ├── 2021_009.md
    │       │   │   │   ├── 2021_010.md
    │       │   │   │   ├── 2021_011.md
    │       │   │   │   ├── 2021_012.md
    │       │   │   │   ├── 2021_013.md
    │       │   │   │   ├── 2021_014.md
    │       │   │   │   ├── 2021_015.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2023_007.md
    │       │   │   │   ├── 2023_008.md
    │       │   │   │   ├── 2023_009.md
    │       │   │   │   ├── 2023_010.md
    │       │   │   │   ├── 2023_011.md
    │       │   │   │   ├── 2023_012.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   └── 2025_001.md
    │       │   │   ├── SEC/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   ├── 2021_002.md
    │       │   │   │   ├── 2021_003.md
    │       │   │   │   ├── 2021_004.md
    │       │   │   │   ├── 2021_005.md
    │       │   │   │   ├── 2021_006.md
    │       │   │   │   ├── 2021_007.md
    │       │   │   │   ├── 2021_008.md
    │       │   │   │   ├── 2021_009.md
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2022_002.md
    │       │   │   │   ├── 2022_003.md
    │       │   │   │   ├── 2022_004.md
    │       │   │   │   ├── 2022_005.md
    │       │   │   │   ├── 2022_006.md
    │       │   │   │   ├── 2022_007.md
    │       │   │   │   ├── 2022_008.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   ├── 2024_004.md
    │       │   │   │   ├── 2024_005.md
    │       │   │   │   ├── 2024_007.md
    │       │   │   │   └── 2025_001.md
    │       │   │   └── _index.md
    │       │   ├── iam/
    │       │   │   ├── BP/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── SEC/
    │       │   │   │   ├── 2021_001.md
    │       │   │   │   └── 2024_001.md
    │       │   │   └── _index.md
    │       │   ├── interconnect/
    │       │   │   ├── BP/
    │       │   │   │   └── 2023_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   └── 2025_001.md
    │       │   │   └── _index.md
    │       │   ├── lb/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2022_001.md
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2025_001.md
    │       │   │   │   ├── 2025_002.md
    │       │   │   │   └── 2025_003.md
    │       │   │   └── _index.md
    │       │   ├── looker/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2025_001.md
    │       │   │   │   ├── 2025_002.md
    │       │   │   │   └── 2025_003.md
    │       │   │   └── _index.md
    │       │   ├── notebooks/
    │       │   │   ├── BP/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   └── 2023_004.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   └── 2023_003.md
    │       │   │   └── _index.md
    │       │   ├── pubsub/
    │       │   │   ├── BP/
    │       │   │   │   └── 2024_001.md
    │       │   │   ├── ERR/
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   ├── 2024_003.md
    │       │   │   │   └── 2025_001.md
    │       │   │   ├── WARN/
    │       │   │   │   ├── 2023_001.md
    │       │   │   │   ├── 2023_002.md
    │       │   │   │   ├── 2023_003.md
    │       │   │   │   ├── 2023_004.md
    │       │   │   │   ├── 2023_005.md
    │       │   │   │   ├── 2023_006.md
    │       │   │   │   ├── 2024_001.md
    │       │   │   │   ├── 2024_002.md
    │       │   │   │   └── 2024_003.md
    │       │   │   └── _index.md
    │       │   ├── tpu/
    │       │   │   ├── WARN/
    │       │   │   │   └── 2022_001.md
    │       │   │   └── _index.md
    │       │   ├── vertex/
    │       │   │   ├── WARN/
    │       │   │   │   └── 2023_001.md
    │       │   │   └── _index.md
    │       │   └── vpc/
    │       │       ├── BP/
    │       │       │   ├── 2022_001.md
    │       │       │   └── 2023_001.md
    │       │       ├── SEC/
    │       │       │   └── 2023_001.md
    │       │       ├── WARN/
    │       │       │   ├── 2022_001.md
    │       │       │   ├── 2023_001.md
    │       │       │   ├── 2023_002.md
    │       │       │   └── 2024_001.md
    │       │       └── _index.md
    │       ├── runbook/
    │       │   ├── _index.md
    │       │   ├── diagnostic-trees/
    │       │   │   ├── _index.md
    │       │   │   ├── bigquery/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── failed-query.md
    │       │   │   ├── cloudrun/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── service-deployment.md
    │       │   │   ├── dataflow/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── failed-streaming-pipeline.md
    │       │   │   │   └── job-permissions.md
    │       │   │   ├── dataproc/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── cluster-creation.md
    │       │   │   │   └── spark-job-failures.md
    │       │   │   ├── gce/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── guestos-bootup.md
    │       │   │   │   ├── ops-agent.md
    │       │   │   │   ├── serial-log-analyzer.md
    │       │   │   │   ├── ssh.md
    │       │   │   │   ├── vm-creation.md
    │       │   │   │   ├── vm-performance.md
    │       │   │   │   └── vm-termination.md
    │       │   │   ├── gcf/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── failed-deployments.md
    │       │   │   ├── gke/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── cluster-autoscaler.md
    │       │   │   │   ├── gke-ip-masq-standard.md
    │       │   │   │   ├── image-pull.md
    │       │   │   │   ├── ip-exhaustion.md
    │       │   │   │   ├── logs.md
    │       │   │   │   ├── monitoring-configuration.md
    │       │   │   │   ├── node-auto-repair.md
    │       │   │   │   ├── node-bootstrapping.md
    │       │   │   │   ├── node-unavailability.md
    │       │   │   │   └── resource-quotas.md
    │       │   │   ├── interconnect/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── bgp-down-flap.md
    │       │   │   ├── lb/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── latency.md
    │       │   │   │   ├── ssl-certificates.md
    │       │   │   │   └── unhealthy-backends.md
    │       │   │   ├── nat/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── public-nat-ip-allocation-failed.md
    │       │   │   ├── pubsub/
    │       │   │   │   ├── _index.md
    │       │   │   │   ├── bigquery-subscription-delivery.md
    │       │   │   │   ├── gcs-subscription-delivery.md
    │       │   │   │   ├── pull-subscription-delivery.md
    │       │   │   │   └── push-subscription-delivery.md
    │       │   │   ├── vertex/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── workbench-instance-stuck-in-provisioning.md
    │       │   │   ├── vpc/
    │       │   │   │   ├── _index.md
    │       │   │   │   └── vm-external-ip-connectivity.md
    │       │   │   └── vpn/
    │       │   │       ├── _index.md
    │       │   │       └── vpn-tunnel-check.md
    │       │   └── steps/
    │       │       ├── _index.md
    │       │       ├── bigquery/
    │       │       │   ├── _index.md
    │       │       │   ├── big-query-end.md
    │       │       │   ├── big-query-error-identification.md
    │       │       │   ├── big-query-failed-query-start.md
    │       │       │   ├── big-query-job-exists.md
    │       │       │   ├── check-bq-job-has-error.md
    │       │       │   ├── check-bq-job-has-failed.md
    │       │       │   ├── check-permissions.md
    │       │       │   ├── confirm-bq-job-is-done.md
    │       │       │   └── run-permission-checks.md
    │       │       ├── cloudrun/
    │       │       │   ├── _index.md
    │       │       │   ├── container-failed-to-start-step.md
    │       │       │   ├── image-was-not-found-step.md
    │       │       │   ├── no-permission-for-image-step.md
    │       │       │   ├── service-deployment-code-step.md
    │       │       │   └── service-deployment-start.md
    │       │       ├── crm/
    │       │       │   ├── _index.md
    │       │       │   └── org-policy-check.md
    │       │       ├── dataflow/
    │       │       │   ├── _index.md
    │       │       │   ├── dataflow-permissions-end.md
    │       │       │   ├── dataflow-resource-permissions.md
    │       │       │   ├── dataflow-user-account-permissions.md
    │       │       │   ├── dataflow-worker-service-account-permissions.md
    │       │       │   ├── failed-streaming-pipeline-end.md
    │       │       │   ├── failed-streaming-pipeline-start.md
    │       │       │   ├── job-graph-is-constructed.md
    │       │       │   ├── job-is-streaming.md
    │       │       │   ├── job-logs-visible.md
    │       │       │   ├── job-state.md
    │       │       │   └── valid-sdk.md
    │       │       ├── dataproc/
    │       │       │   ├── _index.md
    │       │       │   ├── check-autoscaling-policy.md
    │       │       │   ├── check-bq-connector.md
    │       │       │   ├── check-cluster-network-connectivity.md
    │       │       │   ├── check-cluster-network.md
    │       │       │   ├── check-cluster-quota.md
    │       │       │   ├── check-cluster-stock-out.md
    │       │       │   ├── check-cluster-version.md
    │       │       │   ├── check-gc-pause.md
    │       │       │   ├── check-gcs-connector.md
    │       │       │   ├── check-if-job-failed.md
    │       │       │   ├── check-init-script-failure.md
    │       │       │   ├── check-job-throttling.md
    │       │       │   ├── check-killing-orphaned-application.md
    │       │       │   ├── check-logs-exist.md
    │       │       │   ├── check-master-oom.md
    │       │       │   ├── check-permissions.md
    │       │       │   ├── check-port-exhaustion.md
    │       │       │   ├── check-preemptible.md
    │       │       │   ├── check-private-google-access.md
    │       │       │   ├── check-python-import-failure.md
    │       │       │   ├── check-shared-vpc-roles.md
    │       │       │   ├── check-shuffle-failures.md
    │       │       │   ├── check-shuffle-service-kill.md
    │       │       │   ├── check-stackdriver-setting.md
    │       │       │   ├── check-sw-preemption.md
    │       │       │   ├── check-task-not-found.md
    │       │       │   ├── check-worker-disk-usage-issue.md
    │       │       │   ├── check-worker-oom.md
    │       │       │   ├── check-yarn-runtime-exception.md
    │       │       │   ├── cluster-creation-end.md
    │       │       │   ├── cluster-creation-quota.md
    │       │       │   ├── cluster-creation-start.md
    │       │       │   ├── cluster-creation-stockout.md
    │       │       │   ├── cluster-details-dependency-gateway.md
    │       │       │   ├── cluster-details.md
    │       │       │   ├── cluster-exists.md
    │       │       │   ├── cluster-in-error.md
    │       │       │   ├── data-proc-cluster-exists.md
    │       │       │   ├── internal-ip-gateway.md
    │       │       │   ├── job-details-dependency-gateway.md
    │       │       │   ├── job-exists.md
    │       │       │   ├── job-start.md
    │       │       │   ├── service-account-exists.md
    │       │       │   └── spark-job-end.md
    │       │       ├── gce/
    │       │       │   ├── _index.md
    │       │       │   ├── analysing-serial-logs-end.md
    │       │       │   ├── check-live-migrations.md
    │       │       │   ├── check-serial-port-logging.md
    │       │       │   ├── cloud-init-checks.md
    │       │       │   ├── compute-cluster-manager-termination.md
    │       │       │   ├── cpu-overcommitment-check.md
    │       │       │   ├── disk-avg-io-latency-check.md
    │       │       │   ├── disk-health-check.md
    │       │       │   ├── disk-iops-throughput-utilisation-checks.md
    │       │       │   ├── gce-firewall-allows-ssh.md
    │       │       │   ├── gce-iam-policy-check.md
    │       │       │   ├── gce-log-check.md
    │       │       │   ├── gce-vpc-connectivity-check.md
    │       │       │   ├── gcp-ssh-permissions.md
    │       │       │   ├── guest-os-issued-shutdown.md
    │       │       │   ├── guestos-bootup-start.md
    │       │       │   ├── high-vm-cpu-utilization.md
    │       │       │   ├── high-vm-disk-utilization.md
    │       │       │   ├── high-vm-memory-utilization.md
    │       │       │   ├── host-error.md
    │       │       │   ├── instance-property-check.md
    │       │       │   ├── investigate-guest-os-issued-shutdown.md
    │       │       │   ├── investigate-logging-monitoring.md
    │       │       │   ├── investigate-vm-creation-log-failure.md
    │       │       │   ├── linux-guest-os-checks.md
    │       │       │   ├── managed-instance-group-recreation.md
    │       │       │   ├── mig-autoscaling-policy-check.md
    │       │       │   ├── multiple-termination-check.md
    │       │       │   ├── number-of-terminations.md
    │       │       │   ├── ops-agent-end.md
    │       │       │   ├── ops-agent-start.md
    │       │       │   ├── os-login-status-check.md
    │       │       │   ├── posix-user-has-valid-ssh-key-check.md
    │       │       │   ├── preemptible-instance.md
    │       │       │   ├── scheduled-stop-policy.md
    │       │       │   ├── serial-log-analyzer-start.md
    │       │       │   ├── shielded-vm-integrity-failure.md
    │       │       │   ├── single-termination-check.md
    │       │       │   ├── ssh-end.md
    │       │       │   ├── ssh-in-browser-check.md
    │       │       │   ├── ssh-start.md
    │       │       │   ├── stop-operation-gateway.md
    │       │       │   ├── terminate-on-host-maintenance.md
    │       │       │   ├── termination-operation-type.md
    │       │       │   ├── user-or-service-account-initiated-stop.md
    │       │       │   ├── vm-duplicate-ssh-keys-check.md
    │       │       │   ├── vm-guest-os-type.md
    │       │       │   ├── vm-has-a-service-account.md
    │       │       │   ├── vm-has-ops-agent.md
    │       │       │   ├── vm-lifecycle-state.md
    │       │       │   ├── vm-metadata-check.md
    │       │       │   ├── vm-performance-checks.md
    │       │       │   ├── vm-performance-end.md
    │       │       │   ├── vm-performance-start.md
    │       │       │   ├── vm-scope.md
    │       │       │   ├── vm-serial-logs-check.md
    │       │       │   ├── vm-termination-end.md
    │       │       │   ├── vm-termination-start.md
    │       │       │   ├── vm-termination-type.md
    │       │       │   └── windows-guest-os-checks.md
    │       │       ├── gcf/
    │       │       │   ├── _index.md
    │       │       │   ├── default-service-account-check.md
    │       │       │   ├── failed-deployment-end-step.md
    │       │       │   ├── failed-deployments-start.md
    │       │       │   ├── function-global-scope-check.md
    │       │       │   ├── location-constraint-check.md
    │       │       │   └── user-service-account-check.md
    │       │       ├── gcp/
    │       │       │   ├── _index.md
    │       │       │   ├── human-task.md
    │       │       │   ├── resource-attribute-check.md
    │       │       │   └── service-api-status-check.md
    │       │       ├── gcpdiag/
    │       │       │   ├── _index.md
    │       │       │   ├── end-step.md
    │       │       │   └── start-step.md
    │       │       ├── gke/
    │       │       │   ├── _index.md
    │       │       │   ├── api-enabled.md
    │       │       │   ├── ca-disabled-annotation.md
    │       │       │   ├── ca-failed-to-evict-pods.md
    │       │       │   ├── ca-instance-timeout.md
    │       │       │   ├── ca-ip-space-exhausted.md
    │       │       │   ├── ca-min-resource-limit-exceeded.md
    │       │       │   ├── ca-min-size-reached.md
    │       │       │   ├── ca-no-place-to-move-pods.md
    │       │       │   ├── ca-not-safe-to-evict-annotation.md
    │       │       │   ├── ca-out-of-resources.md
    │       │       │   ├── ca-pod-controller-not-found.md
    │       │       │   ├── ca-pod-kube-system-unmovable.md
    │       │       │   ├── ca-pod-not-enough-pdb.md
    │       │       │   ├── ca-pod-unexpected-error.md
    │       │       │   ├── ca-pods-not-backed-by-controller.md
    │       │       │   ├── ca-quota-exceeded.md
    │       │       │   ├── ca-service-account-deleted.md
    │       │       │   ├── check-config-map.md
    │       │       │   ├── check-daemon-set.md
    │       │       │   ├── check-destination-ip.md
    │       │       │   ├── check-node-ip.md
    │       │       │   ├── check-pod-ip.md
    │       │       │   ├── cluster-autoscaler-end.md
    │       │       │   ├── cluster-autoscaler-start.md
    │       │       │   ├── cluster-level-logging-enabled.md
    │       │       │   ├── cluster-level-monitoring-configuration-enabled.md
    │       │       │   ├── cluster-version.md
    │       │       │   ├── gke-ip-masq-standard-end.md
    │       │       │   ├── gke-ip-masq-standard-start.md
    │       │       │   ├── image-connection-timeout-restricted-private.md
    │       │       │   ├── image-connection-timeout.md
    │       │       │   ├── image-dns-issue.md
    │       │       │   ├── image-forbidden.md
    │       │       │   ├── image-not-found-insufficient-scope.md
    │       │       │   ├── image-not-found.md
    │       │       │   ├── image-pull-end.md
    │       │       │   ├── image-pull-start.md
    │       │       │   ├── ip-exhaustion-end.md
    │       │       │   ├── ip-exhaustion-start.md
    │       │       │   ├── live-migration.md
    │       │       │   ├── logging-api-enabled.md
    │       │       │   ├── logging-write-api-quota-exceeded.md
    │       │       │   ├── logs-end.md
    │       │       │   ├── logs-start.md
    │       │       │   ├── monitoring-api-configuration-enabled.md
    │       │       │   ├── monitoring-configuration-end.md
    │       │       │   ├── monitoring-configuration-start.md
    │       │       │   ├── node-auto-repair-end.md
    │       │       │   ├── node-auto-repair-start.md
    │       │       │   ├── node-bootstrapping-end.md
    │       │       │   ├── node-bootstrapping-start.md
    │       │       │   ├── node-disk-full.md
    │       │       │   ├── node-insert-check.md
    │       │       │   ├── node-ip-range-exhaustion.md
    │       │       │   ├── node-not-ready.md
    │       │       │   ├── node-pool-cloud-logging-access-scope.md
    │       │       │   ├── node-pool-cloud-monitoring-access-scope-configuration.md
    │       │       │   ├── node-pool-scope.md
    │       │       │   ├── node-pool-upgrade.md
    │       │       │   ├── node-registration-success.md
    │       │       │   ├── node-removed-by-autoscaler.md
    │       │       │   ├── node-unavailability-end.md
    │       │       │   ├── node-unavailability-start.md
    │       │       │   ├── nodeproblem.md
    │       │       │   ├── pod-ip-range-exhaustion.md
    │       │       │   ├── preemption-condition.md
    │       │       │   ├── resource-quota-exceeded.md
    │       │       │   ├── resource-quotas-end.md
    │       │       │   ├── resource-quotas-start.md
    │       │       │   ├── service-account-logging-permission.md
    │       │       │   ├── service-account-monitoring-permission-configuration.md
    │       │       │   ├── service-account-permission.md
    │       │       │   ├── unallocatable-gpu.md
    │       │       │   └── unallocatable-tpu.md
    │       │       ├── iam/
    │       │       │   ├── _index.md
    │       │       │   ├── iam-policy-check.md
    │       │       │   └── vm-has-an-active-service-account.md
    │       │       ├── interconnect/
    │       │       │   ├── _index.md
    │       │       │   ├── bgp-down-flap-end.md
    │       │       │   ├── bgp-down-flap-start.md
    │       │       │   ├── check-bgp-down.md
    │       │       │   ├── check-bgp-flap.md
    │       │       │   ├── check-cloud-router-maintenance.md
    │       │       │   └── check-interconnect-maintenance.md
    │       │       ├── lb/
    │       │       │   ├── _index.md
    │       │       │   ├── analyze-certificate-status.md
    │       │       │   ├── analyze-domain-statuses.md
    │       │       │   ├── analyze-failed-caa-check.md
    │       │       │   ├── analyze-failed-not-visible-domains.md
    │       │       │   ├── analyze-latest-health-check-log.md
    │       │       │   ├── analyze-provisioning-domains.md
    │       │       │   ├── analyze-rate-limited-domains.md
    │       │       │   ├── analyze-timeout-health-check-log.md
    │       │       │   ├── analyze-unhealthy-health-check-log.md
    │       │       │   ├── analyze-unknown-health-check-log.md
    │       │       │   ├── check-certificate-attachment.md
    │       │       │   ├── check-past-health-check-success.md
    │       │       │   ├── check-provisioning-time.md
    │       │       │   ├── check-vm-performance.md
    │       │       │   ├── latency-end.md
    │       │       │   ├── lb-backend-latency-check.md
    │       │       │   ├── lb-error-rate-check.md
    │       │       │   ├── lb-latency-start.md
    │       │       │   ├── lb-request-count-check.md
    │       │       │   ├── ssl-certificates-end.md
    │       │       │   ├── ssl-certificates-start.md
    │       │       │   ├── unhealthy-backends-end.md
    │       │       │   ├── unhealthy-backends-start.md
    │       │       │   ├── validate-backend-service-port-configuration.md
    │       │       │   ├── validate-backend-service-protocol-configuration.md
    │       │       │   ├── verify-dns-records.md
    │       │       │   ├── verify-firewall-rules.md
    │       │       │   ├── verify-forwarding-rules-port.md
    │       │       │   ├── verify-health-check-logging-enabled.md
    │       │       │   └── verify-no-certificate-map-conflict.md
    │       │       ├── logs/
    │       │       │   ├── _index.md
    │       │       │   ├── check-issue-log-entry.md
    │       │       │   └── logs-check.md
    │       │       ├── monitoring/
    │       │       │   ├── _index.md
    │       │       │   └── time-series-check.md
    │       │       ├── nat/
    │       │       │   ├── _index.md
    │       │       │   ├── nat-allocation-failed-check.md
    │       │       │   ├── nat-dropped-received-packet-check.md
    │       │       │   ├── nat-ip-allocation-auto-only.md
    │       │       │   ├── nat-ip-allocation-failed-end.md
    │       │       │   ├── nat-ip-allocation-failed-start.md
    │       │       │   ├── nat-ip-allocation-manual-only.md
    │       │       │   ├── nat-ip-allocation-method-check.md
    │       │       │   ├── nat-ip-exhaustion-check.md
    │       │       │   └── nat-resource-exhaustion-check.md
    │       │       ├── pubsub/
    │       │       │   ├── _index.md
    │       │       │   ├── active-subscription.md
    │       │       │   ├── big-query-table-existence-check.md
    │       │       │   ├── big-query-writer-permission-check.md
    │       │       │   ├── check-gcs-bucket.md
    │       │       │   ├── check-service-account-permissions.md
    │       │       │   ├── dead-letter-topic-permissions.md
    │       │       │   ├── dead-letter-topic.md
    │       │       │   ├── end-step.md
    │       │       │   ├── gcs-subscription-delivery-end.md
    │       │       │   ├── gcs-subscription-delivery-start.md
    │       │       │   ├── gcs-subscription-existence-check.md
    │       │       │   ├── investigate-bq-push-errors.md
    │       │       │   ├── pubsub-quotas.md
    │       │       │   ├── pull-rate.md
    │       │       │   ├── pull-subscription-delivery-end.md
    │       │       │   ├── pull-subscription-delivery-start.md
    │       │       │   ├── push-subscription-delivery-end.md
    │       │       │   ├── push-subscription-delivery-start.md
    │       │       │   ├── push_subscription_delivery-end.md
    │       │       │   ├── response-code-step.md
    │       │       │   ├── start-step.md
    │       │       │   ├── subscription-existence-check.md
    │       │       │   ├── subscription-status-check.md
    │       │       │   ├── throughput-qualification.md
    │       │       │   └── vpc-sc-step.md
    │       │       ├── vertex/
    │       │       │   ├── _index.md
    │       │       │   ├── check-workbench-instance-compute-engine-ssh.md
    │       │       │   ├── check-workbench-instance-custom-scripts.md
    │       │       │   ├── check-workbench-instance-external-ip-disabled.md
    │       │       │   ├── check-workbench-instance-is-using-latest-env-version.md
    │       │       │   ├── check-workbench-instance-jupyter-space.md
    │       │       │   ├── check-workbench-instance-performance.md
    │       │       │   ├── check-workbench-instance-syslogs-jupyter-running-on-port-8080.md
    │       │       │   ├── check-workbench-instance-using-custom-container.md
    │       │       │   ├── check-workbench-instance-using-official-image.md
    │       │       │   ├── decision-check-workbench-instance-system-logging.md
    │       │       │   ├── workbench-instance-stuck-in-provisioning-end.md
    │       │       │   └── workbench-instance-stuck-in-provisioning-start.md
    │       │       ├── vpc/
    │       │       │   ├── _index.md
    │       │       │   ├── external-interface-check.md
    │       │       │   ├── internal-interface-check.md
    │       │       │   ├── vm-external-ip-connectivity-end.md
    │       │       │   ├── vm-external-ip-connectivity-start.md
    │       │       │   ├── vm-external-ip-connectivity-test.md
    │       │       │   ├── vm-has-external-ip.md
    │       │       │   ├── vpc-firewall-check.md
    │       │       │   └── vpc-route-check.md
    │       │       └── vpn/
    │       │           ├── _index.md
    │       │           ├── tunnel-down-status-reason.md
    │       │           ├── tunnel-packets-drop-check.md
    │       │           ├── tunnel-packets-utilization-check.md
    │       │           ├── vpn-tunnel-check-end.md
    │       │           └── vpn-tunnel-status.md
    │       └── search.md
    ├── go.mod
    ├── go.sum
    ├── hugo.sh
    ├── i18n/
    │   └── en.toml
    └── layouts/
        ├── 404.html
        ├── docs/
        │   └── baseof.html
        ├── partials/
        │   ├── navbar.html
        │   └── page-meta-links.html
        └── shortcodes/
            └── blocks/
                ├── cover.html
                ├── feature.html
                └── section.html
Download .txt
Showing preview only (501K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5649 symbols across 665 files)

FILE: bin/changelog_generator.py
  function lint_name_generator (line 25) | def lint_name_generator(file_path):
  function find_queries (line 38) | def find_queries(file, commit):
  function generate_release_notes (line 70) | def generate_release_notes(old_commit, new_commit, current_version):

FILE: bin/generate_steps.py
  function fetch_and_list_steps (line 23) | def fetch_and_list_steps(output_file_path: str, base_url_path: str):
  function main (line 95) | def main(argv: Sequence[str]) -> None:

FILE: cookiecutter-gcpdiag-rule/{{cookiecutter.__name}}/gcpdiag/lint/{{cookiecutter.product}}/{{cookiecutter.severity.lower()}}_{{cookiecutter.year}}_{{cookiecutter.number}}_{{cookiecutter.__name}}.py
  function prepare_rule (line 22) | def prepare_rule(context: models.Context):
  function prefetch_rule (line 47) | def prefetch_rule(context: models.Context):
  function run_rule (line 79) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/async_queries/api/api.py
  class Creds (line 9) | class Creds(Protocol):
    method update_headers (line 11) | def update_headers(self, headers: Dict[str, str]) -> None:
  class Sleeper (line 15) | class Sleeper(Protocol):
    method sleep (line 17) | async def sleep(self, seconds: float) -> None:
  class RetryStrategy (line 21) | class RetryStrategy(Protocol):
    method get_sleep_intervals (line 23) | def get_sleep_intervals(self) -> Iterable[float]:
  class API (line 27) | class API:
    method __init__ (line 30) | def __init__(self, creds: Creds, retry_strategy: RetryStrategy,
    method call (line 36) | async def call(self,
    method _get_headers (line 53) | def _get_headers(self) -> Dict[str, str]:

FILE: gcpdiag/async_queries/api/api_slowtest.py
  class FakeCreds (line 14) | class FakeCreds:
    method __init__ (line 17) | def __init__(self, token: str) -> None:
    method update_headers (line 20) | def update_headers(self, headers: Dict[str, str]) -> None:
  class FakeSleeper (line 24) | class FakeSleeper:
    method __init__ (line 27) | def __init__(self) -> None:
    method sleep (line 30) | async def sleep(self, seconds: float) -> None:
  class TestAPI (line 35) | class TestAPI(unittest.IsolatedAsyncioTestCase):
    method asyncSetUp (line 38) | async def asyncSetUp(self) -> None:
    method asyncTearDown (line 51) | async def asyncTearDown(self) -> None:
    method test_get_response (line 54) | async def test_get_response(self) -> None:
    method test_enough_retries (line 60) | async def test_enough_retries(self) -> None:
    method test_not_enough_retries (line 71) | async def test_not_enough_retries(self) -> None:
    method test_http_429_retried (line 83) | async def test_http_429_retried(self) -> None:
    method test_other_4xx_http_not_retried (line 94) | async def test_other_4xx_http_not_retried(self) -> None:

FILE: gcpdiag/async_queries/api/constant_time_retry_strategy.py
  class ConstantTimeoutRetryStrategy (line 5) | class ConstantTimeoutRetryStrategy:
    method __init__ (line 11) | def __init__(self, retries: int, timeout: int) -> None:
    method get_sleep_intervals (line 15) | def get_sleep_intervals(self) -> Iterator[float]:

FILE: gcpdiag/async_queries/api/default_random.py
  class Random (line 5) | class Random:
    method generate (line 8) | def generate(self) -> float:

FILE: gcpdiag/async_queries/api/exponential_random_retry_strategy.py
  class Random (line 10) | class Random(Protocol):
    method generate (line 12) | def generate(self) -> float:
  class ExponentialRandomTimeoutRetryStrategy (line 16) | class ExponentialRandomTimeoutRetryStrategy:
    method __init__ (line 27) | def __init__(self, retries: int, random_pct: float, multiplier: float,
    method get_sleep_intervals (line 34) | def get_sleep_intervals(self) -> Iterator[float]:

FILE: gcpdiag/async_queries/api/exponential_random_retry_strategy_test.py
  class FakeRandom (line 10) | class FakeRandom:
    method __init__ (line 14) | def __init__(self, numbers: List[float]) -> None:
    method generate (line 17) | def generate(self) -> float:
  function test_retries (line 21) | def test_retries() -> None:

FILE: gcpdiag/async_queries/api/gcpdiag_creds.py
  function refresh_google_auth_creds (line 13) | def refresh_google_auth_creds(creds: Any) -> None:
  class GcpdiagCreds (line 18) | class GcpdiagCreds:
    method update_headers (line 24) | def update_headers(self, headers: Dict[str, str]) -> None:

FILE: gcpdiag/async_queries/api/get_api.py
  function pick_creds_implementation (line 8) | def pick_creds_implementation() -> api.Creds:
  function get_api (line 20) | def get_api() -> api.API:

FILE: gcpdiag/async_queries/api/sleeper.py
  class Sleeper (line 8) | class Sleeper:
    method sleep (line 10) | async def sleep(self, seconds: float) -> None:

FILE: gcpdiag/async_queries/api/test_webserver.py
  class Response (line 7) | class Response(Protocol):
    method get_response (line 9) | def get_response(self) -> Any:
  class Success (line 13) | class Success:
    method __init__ (line 16) | def __init__(self, data: Any) -> None:
    method get_response (line 19) | def get_response(self) -> Any:
  class Failure (line 30) | class Failure:
    method __init__ (line 34) | def __init__(self, status: int = 500) -> None:
    method get_response (line 37) | def get_response(self) -> Any:
  class WebServer (line 46) | class WebServer:
    method __init__ (line 51) | def __init__(self, port: int, expected_auth_token: str) -> None:
    method start (line 56) | async def start(self) -> None:
    method stop (line 75) | async def stop(self) -> None:

FILE: gcpdiag/async_queries/dataproc/dataproc.py
  class Region (line 10) | class Region:
    method __init__ (line 17) | def __init__(self, api: protocols.API, project_id: str, region: str):
    method load (line 23) | async def load(self) -> None:
    method clusters (line 32) | def clusters(self) -> List[dataproc.Cluster]:
    method _clusters_descriptions (line 36) | def _clusters_descriptions(self) -> List[Any]:
    method _mk_cluster (line 42) | def _mk_cluster(self, desc: Any) -> dataproc.Cluster:
  class ProjectRegions (line 51) | class ProjectRegions(Protocol):
    method get_all (line 53) | async def get_all(self) -> Iterable[str]:
  class Dataproc (line 57) | class Dataproc:
    method __init__ (line 65) | def __init__(self, api: protocols.API, project_id: str,
    method list_clusters (line 73) | async def list_clusters(self) -> List[str]:
    method get_cluster_by_name (line 77) | async def get_cluster_by_name(self, cluster_name: str) -> dataproc.Clu...
    method _load (line 81) | async def _load(self) -> None:
    method _mk_region (line 89) | def _mk_region(self, region: str) -> Region:

FILE: gcpdiag/async_queries/dataproc/dataproc_test.py
  class FakeProjectRegions (line 12) | class FakeProjectRegions:
    method __init__ (line 14) | def __init__(self, regions: List[str]) -> None:
    method get_all (line 17) | async def get_all(self) -> List[str]:
  class TestProjectRegions (line 21) | class TestProjectRegions(unittest.IsolatedAsyncioTestCase):
    method setUp (line 24) | def setUp(self) -> None:
    method test_list_clusters (line 57) | async def test_list_clusters(self) -> None:
    method test_cluster_status (line 61) | async def test_cluster_status(self) -> None:
    method test_deduplication (line 70) | async def test_deduplication(self) -> None:

FILE: gcpdiag/async_queries/project/get_project.py
  function get_project (line 8) | def get_project(project_id: str) -> project.Project:

FILE: gcpdiag/async_queries/project/project.py
  class Project (line 9) | class Project:
    method __init__ (line 14) | def __init__(self, api: protocols.API, project_id: str) -> None:
    method dataproc (line 19) | def dataproc(self) -> dataproc.Dataproc:
    method _project_regions (line 25) | def _project_regions(self) -> project_regions.ProjectRegions:

FILE: gcpdiag/async_queries/project_regions.py
  class ProjectRegions (line 7) | class ProjectRegions:
    method __init__ (line 14) | def __init__(self, api: protocols.API, project_id: str) -> None:
    method get_all (line 20) | async def get_all(self) -> List[str]:
    method load (line 25) | async def load(self) -> None:
    method call_api (line 29) | async def call_api(self) -> Any:
    method parse_resp (line 36) | def parse_resp(self, resp: Any) -> List[str]:

FILE: gcpdiag/async_queries/project_regions_test.py
  class TestProjectRegions (line 10) | class TestProjectRegions(IsolatedAsyncioTestCase):
    method setUp (line 13) | def setUp(self) -> None:
    method test_happy_path (line 28) | async def test_happy_path(self) -> None:
    method test_deduplication (line 32) | async def test_deduplication(self) -> None:

FILE: gcpdiag/async_queries/utils/fake_api.py
  class APICall (line 6) | class APICall:
    method __init__ (line 12) | def __init__(self, method: str, url: str, json: Any = None) -> None:
    method __eq__ (line 17) | def __eq__(self, other: Any) -> bool:
    method __repr__ (line 21) | def __repr__(self) -> str:
  class FakeAPI (line 25) | class FakeAPI:
    method __init__ (line 30) | def __init__(self, responses: List[Tuple[APICall, Any]]) -> None:
    method call (line 34) | async def call(self,
    method get_response (line 43) | def get_response(self, call: APICall) -> Any:
    method count_calls (line 49) | def count_calls(self, call: APICall) -> int:

FILE: gcpdiag/async_queries/utils/loader.py
  class Loader (line 9) | class Loader:
    method __init__ (line 40) | def __init__(self, load_coroutine: Callable[[], Coroutine]) -> None:
    method ensure_loaded (line 44) | async def ensure_loaded(self) -> None:

FILE: gcpdiag/async_queries/utils/protocols.py
  class API (line 6) | class API(Protocol):
    method call (line 8) | async def call(self,
  class ProjectRegions (line 15) | class ProjectRegions(Protocol):
    method get_all (line 17) | async def get_all(self) -> Iterable[str]:

FILE: gcpdiag/caching.py
  function _set_bypass_cache (line 40) | def _set_bypass_cache(value: bool):
  function _get_bypass_cache (line 49) | def _get_bypass_cache():
  function configure_global_cache (line 57) | def configure_global_cache(enabled: bool):
  function bypass_cache (line 64) | def bypass_cache():
  function _clean_cache (line 77) | def _clean_cache():
  function _close_cache (line 90) | def _close_cache():
  function get_disk_cache (line 96) | def get_disk_cache() -> diskcache.Cache:
  function _clean_tmp_deque (line 112) | def _clean_tmp_deque():
  function get_tmp_deque (line 118) | def get_tmp_deque(prefix='tmp-deque-') -> diskcache.Deque:
  function _make_key (line 135) | def _make_key(func, args, kwargs):
  function _acquire_timeout (line 146) | def _acquire_timeout(lock, timeout, name):
  function cached_api_call (line 162) | def cached_api_call(expire=None, in_memory=False):

FILE: gcpdiag/caching_test.py
  function simple_function (line 27) | def simple_function(mixer_arg):
  class CacheBypassTests (line 38) | class CacheBypassTests(unittest.TestCase):
    method test_cache_bypass_in_memory (line 41) | def test_cache_bypass_in_memory(self):
    method test_cache_bypass_disk_cache (line 59) | def test_cache_bypass_disk_cache(self):
    method test_thread_safe_caching (line 75) | def test_thread_safe_caching(self):
  class UseCacheTests (line 95) | class UseCacheTests(unittest.TestCase):
    method test_enable_use_cache (line 98) | def test_enable_use_cache(self):
    method test_disable_use_cache (line 110) | def test_disable_use_cache(self):
    method test_exception_raised_when_cache_disabled (line 120) | def test_exception_raised_when_cache_disabled(self):

FILE: gcpdiag/config.py
  function set_cache_dir (line 72) | def set_cache_dir(path: str):
  function get_cache_dir (line 79) | def get_cache_dir():
  function _get_default_report_dir (line 98) | def _get_default_report_dir():
  function init (line 143) | def init(args, is_cloud_shell=False):
  function set_project_id (line 177) | def set_project_id(project_id):
  function get_project_id (line 183) | def get_project_id():
  function get (line 188) | def get(key):

FILE: gcpdiag/config_test.py
  class Test (line 64) | class Test:
    method clear_globals (line 68) | def clear_globals(self):
    method test_static_properties (line 76) | def test_static_properties(self):
    method test_default_dynamic_properties (line 81) | def test_default_dynamic_properties(self):
    method test_overwrite_dynamic_properties (line 91) | def test_overwrite_dynamic_properties(self):
    method test_include (line 103) | def test_include(self):
    method test_exclude (line 111) | def test_exclude(self):
    method test_empty_config (line 119) | def test_empty_config(self):
    method test_sample_config (line 132) | def test_sample_config(self):
    method test_logging_config (line 148) | def test_logging_config(self):
    method test_per_project_config (line 163) | def test_per_project_config(self):

FILE: gcpdiag/context.py
  class ContextProvider (line 19) | class ContextProvider(abc.ABC):
    method setup_thread_context (line 23) | def setup_thread_context(self) -> None:
    method teardown_thread_context (line 28) | def teardown_thread_context(self) -> None:

FILE: gcpdiag/executor.py
  function _get_real_executor (line 24) | def _get_real_executor() -> concurrent.futures.ThreadPoolExecutor:
  function _context_wrapper (line 32) | def _context_wrapper(fn, context: models.Context):
  class ContextAwareExecutor (line 47) | class ContextAwareExecutor:
    method __init__ (line 54) | def __init__(self, context: models.Context):
    method submit (line 58) | def submit(self, fn: Callable[..., Any], *args: Any,
    method map (line 63) | def map(
    method shutdown (line 76) | def shutdown(self, wait: bool = True):
    method __enter__ (line 80) | def __enter__(self):
    method __exit__ (line 83) | def __exit__(self, exc_type, exc_val, exc_tb):
  function get_executor (line 87) | def get_executor(context: models.Context) -> ContextAwareExecutor:

FILE: gcpdiag/executor_test.py
  class ContextAwareExecutorTest (line 24) | class ContextAwareExecutorTest(unittest.TestCase):
    method test_context_propagation_with_submit (line 26) | def test_context_propagation_with_submit(self):
    method test_context_propagation_with_map (line 39) | def test_context_propagation_with_map(self):

FILE: gcpdiag/hooks.py
  function set_lint_args_hook (line 22) | def set_lint_args_hook(args):
  function set_runbook_args_hook (line 34) | def set_runbook_args_hook(args):
  function verify_access_hook (line 46) | def verify_access_hook(project_id: str):
  function request_builder_hook (line 58) | def request_builder_hook(*args, **kwargs):
  function post_lint_hook (line 71) | def post_lint_hook(report):
  function post_runbook_hook (line 83) | def post_runbook_hook(report):

FILE: gcpdiag/lint/__init__.py
  class LintRuleClass (line 45) | class LintRuleClass(enum.Enum):
    method __str__ (line 57) | def __str__(self):
  class LintRule (line 62) | class LintRule:
    method __hash__ (line 76) | def __hash__(self):
    method __str__ (line 79) | def __str__(self):
    method doc_url (line 83) | def doc_url(self) -> str:
  class LintRuleResult (line 88) | class LintRuleResult:
  class LintReportRuleInterface (line 95) | class LintReportRuleInterface:
    method __init__ (line 101) | def __init__(self, rule: LintRule, lint_result: 'LintResults') -> None:
    method overall_status (line 107) | def overall_status(self) -> str:
    method _any_result_with_status (line 115) | def _any_result_with_status(self, status: str) -> bool:
    method add_skipped (line 118) | def add_skipped(self,
    method add_ok (line 128) | def add_ok(self, resource: models.Resource, short_info: str = '') -> N...
    method add_failed (line 135) | def add_failed(self,
    method finish (line 145) | def finish(self) -> None:
  class LintResultsHandler (line 149) | class LintResultsHandler(Protocol):
    method process_rule_report (line 159) | def process_rule_report(self, rule_report: LintReportRuleInterface) ->...
  class LintResults (line 163) | class LintResults:
    method __init__ (line 168) | def __init__(self) -> None:
    method get_rule_reports (line 172) | def get_rule_reports(self) -> List[LintReportRuleInterface]:
    method add_result_handler (line 175) | def add_result_handler(self, handler: LintResultsHandler) -> None:
    method create_rule_report (line 185) | def create_rule_report(self, rule: LintRule) -> LintReportRuleInterface:
    method register_finished_rule_report (line 188) | def register_finished_rule_report(
    method _notify_result_handlers (line 193) | def _notify_result_handlers(self,
    method get_totals_by_status (line 198) | def get_totals_by_status(self) -> Dict[str, int]:
    method get_rule_statuses (line 206) | def get_rule_statuses(self) -> Dict[str, str]:
    method any_failed (line 210) | def any_failed(self) -> bool:
  class LintRulesPattern (line 214) | class LintRulesPattern:
    method __init__ (line 234) | def __init__(self, pattern_str: str):
    method __str__ (line 264) | def __str__(self):
    method match_rule (line 269) | def match_rule(self, rule: LintRule) -> bool:
  class NotLintRule (line 282) | class NotLintRule(Exception):
  function is_function_named (line 287) | def is_function_named(name: str) -> Callable[[Any], bool]:
  function get_module_function_or_none (line 291) | def get_module_function_or_none(module: types.ModuleType,
  class ExecutionStrategy (line 298) | class ExecutionStrategy(Protocol):
    method run_rules (line 300) | def run_rules(self, context: models.Context, result: LintResults,
    method filter_runnable_rules (line 304) | def filter_runnable_rules(self,
  class SequentialExecutionStrategy (line 309) | class SequentialExecutionStrategy:
    method __init__ (line 316) | def __init__(self, strategies: List[ExecutionStrategy]) -> None:
    method filter_runnable_rules (line 319) | def filter_runnable_rules(self, rules: Iterable[LintRule]) -> List[Lin...
    method run_rules (line 327) | def run_rules(self, context: models.Context, result: LintResults,
  class RuleModule (line 333) | class RuleModule:
    method __init__ (line 337) | def __init__(self, python_module: types.ModuleType) -> None:
    method __repr__ (line 340) | def __repr__(self) -> str:
    method get_method (line 343) | def get_method(self, method_name: str) -> Optional[Callable]:
    method get_attr (line 346) | def get_attr(self, attribute_name: str) -> Optional[Any]:
    method get_module_doc (line 349) | def get_module_doc(self) -> Optional[str]:
  class DefaultPythonModulesGateway (line 353) | class DefaultPythonModulesGateway:
    method list_pkg_modules (line 356) | def list_pkg_modules(self, pkg: Any) -> List[str]:
    method get_module (line 360) | def get_module(self, name: str) -> RuleModule:
  class PythonModulesGateway (line 365) | class PythonModulesGateway(Protocol):
    method list_pkg_modules (line 367) | def list_pkg_modules(self, pkg: Any) -> Iterable[str]:
    method get_module (line 370) | def get_module(self, name: str) -> RuleModule:
  function pick_default_execution_strategy (line 374) | def pick_default_execution_strategy(run_async: bool) -> ExecutionStrategy:
  class LintRuleRepository (line 383) | class LintRuleRepository:
    method __init__ (line 390) | def __init__(self,
    method rules_to_run (line 407) | def rules_to_run(self) -> Iterable[LintRule]:
    method _rules_filtered (line 411) | def _rules_filtered(self) -> Iterator[LintRule]:
    method get_rule_by_module_name (line 423) | def get_rule_by_module_name(self, name: str) -> LintRule:
    method load_rules (line 494) | def load_rules(self, pkg: types.ModuleType) -> None:
    method _register_rule (line 505) | def _register_rule(self, rule: LintRule):
    method run_rules (line 508) | def run_rules(self, context: models.Context) -> None:
  class AsyncRunner (line 515) | class AsyncRunner:
    method __init__ (line 518) | def __init__(self, context: models.Context, result: LintResults,
    method run (line 524) | def run(self) -> None:
    method _run_all (line 527) | async def _run_all(self) -> None:
    method _run_async_rule (line 531) | async def _run_async_rule(self, rule: LintRule) -> None:
  class AsyncExecutionStrategy (line 538) | class AsyncExecutionStrategy:
    method run_rules (line 541) | def run_rules(self, context: models.Context, result: LintResults,
    method filter_runnable_rules (line 546) | def filter_runnable_rules(self, rules: Iterable[LintRule]) -> List[Lin...
  function wrap_prefetch_rule_f (line 550) | def wrap_prefetch_rule_f(rule_name, prefetch_rule_f, context):
  class SyncExecutionStrategy (line 557) | class SyncExecutionStrategy:
    method filter_runnable_rules (line 560) | def filter_runnable_rules(self, rules: Iterable[LintRule]) -> List[Lin...
    method run_rules (line 563) | def run_rules(self, context: models.Context, result: LintResults,

FILE: gcpdiag/lint/apigee/apigee_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/apigee/err_2022_001_p4sa_perm.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/err_2022_002_p4sa_kms_key_perm.py
  function _run_rule_kms_key (line 31) | def _run_rule_kms_key(context: models.Context,
  function run_rule (line 52) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  function _is_valid_kms_key (line 79) | def _is_valid_kms_key(kms_key):
  function _apigee_sa_has_role_permissions (line 83) | def _apigee_sa_has_role_permissions(context: models.Context, kms_key_name,

FILE: gcpdiag/lint/apigee/err_2023_001_vpc_peering_created.py
  function run_rule (line 27) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/err_2023_002_routing_with_mig.py
  function prefetch_rule (line 28) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/err_2023_003_pga_on_mig_subnet.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/err_2023_004_p4nsa_perm.py
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/err_2023_005_fw_rule_xlb_to_mig.py
  function prefetch_rule (line 29) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/err_2023_006_multiple_migs_for_multiple_regions.py
  function prefetch_rule (line 26) | def prefetch_rule(context: models.Context):
  function run_rule (line 32) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/warn_2021_001_empty_env.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/warn_2022_001_env_groups_created.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/apigee/warn_2022_002_env_not_attached.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/asm/asm_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/asm/err_2023_001_traffic_4xx.py
  function prepare_rule (line 26) | def prepare_rule(context: models.Context):
  function run_rule (line 37) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/asm/err_2023_002_traffic_5xx.py
  function prepare_rule (line 26) | def prepare_rule(context: models.Context):
  function run_rule (line 37) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/asm/err_2024_001_secret_not_found.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/asm/err_2024_002_istiod_resource_issues.py
  function prepare_rule (line 34) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/asm/warn_2023_001_grpc_reset.py
  function prepare_rule (line 28) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/asm/warn_2024_001_webhook.py
  function prepare_rule (line 32) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/asm/warn_2025_001_delayedconnect111.py
  function prepare_rule (line 33) | def prepare_rule(context: models.Context):
  function run_rule (line 45) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/asm/warn_2025_002_protocolerror.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 39) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/bigquery_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/bigquery/err_2022_001_concurrent_dml_updates.py
  function prepare_rule (line 35) | def prepare_rule(context: models.Context):
  function run_rule (line 43) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2022_002_response_too_large.py
  function prepare_rule (line 35) | def prepare_rule(context: models.Context):
  function run_rule (line 43) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2022_003_permission_denied_drive_credentials.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2022_004_exceeded_limit_shuffle.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2023_001_job_not_found_error.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2023_002_dataset_not_found.py
  function prepare_rule (line 42) | def prepare_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2023_003_resource_exceeded.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2023_004_concurrent_dml.py
  function prepare_rule (line 40) | def prepare_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2023_005_outdated_credentials_for_scheduled_queries.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2023_006_bigquery_policy_do_not_belong_to_user.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2023_007_data_transfer_service_agent_does_not_exist.py
  function run_rule (line 26) | def run_rule(context: models.Context,

FILE: gcpdiag/lint/bigquery/err_2023_008_user_not_authorized_to_perform_this_action.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 45) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2023_009_not_consistent_with_destination_dataset.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/err_2024_001_query_too_complex.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2022_001_exceeded_rate_limits.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2022_002_column_level_security.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2022_003_copy_job_quota.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2022_004_cross_region_copy_job_quota.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2023_001_query_job_timed_out.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2023_002_wildcard_tables_query.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2023_003_too_many_output_column.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2023_004_bigquery_kms_errors.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2024_001_imports_or_query_appends_per_table.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2024_002_invalid_external_connection.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2024_003_too_many_concurrent_api_requests.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2024_004_too_many_concurrent_queries.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2024_005_exceeded_partition_modifications.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/bigquery/warn_2024_006_tabledata_list_bytes_exceeded.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/billing/billing_rules_snapshot_test.py
  class Test (line 23) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/billing/warn_2022_001_project_billing_enabled.py
  function prepare_rule (line 28) | def prepare_rule(context: models.Context):
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/billing/warn_2022_002_stray_billing_accounts.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/billing/warn_2022_003_cost_anomalies.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 38) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudrun/cloud_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/cloudrun/err_2022_001_missing_cloudrun_serviceagent_role.py
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/bp_2023_001_public_ip.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/bp_2023_002_automated_backup.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/bp_2023_003_log_output_flag.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/bp_ext_2023_001_maint_window.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/bp_ext_2023_002_del_protection.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/bp_ext_2023_003_auto_storage_increases.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function run_rule (line 36) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/bp_ext_2023_004_sla.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/cloudsql_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/cloudsql/err_2023_001_instance_in_suspended.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/sec_2023_001_public_acess.py
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/warn_2022_001_docker_bridge_network.py
  function run_rule (line 32) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  function _is_docker_bridge_ip (line 51) | def _is_docker_bridge_ip(ip: ipaddress.IPv4Address) -> bool:

FILE: gcpdiag/lint/cloudsql/warn_2023_002_high_cpu_usage.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/cloudsql/warn_2023_003_high_mem_usage.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function run_rule (line 55) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/command.py
  class ParseMappingArg (line 34) | class ParseMappingArg(argparse.Action):
    method __call__ (line 37) | def __call__(self, parser, namespace, values, option_string):
  function _flatten_multi_arg (line 55) | def _flatten_multi_arg(arg_list):
  function init_args_parser (line 63) | def init_args_parser():
  function _parse_rule_pattern (line 241) | def _parse_rule_pattern(
  function _load_repository_rules (line 255) | def _load_repository_rules(repo: lint.LintRuleRepository):
  function _get_output_constructor (line 269) | def _get_output_constructor(output_parameter_value, interface):
  function _initialize_output (line 280) | def _initialize_output(output_order):
  function create_and_load_repos (line 296) | def create_and_load_repos(
  function run_rules_for_context (line 315) | def run_rules_for_context(context: models.Context,
  function run (line 321) | def run(argv) -> int:

FILE: gcpdiag/lint/command_test.py
  class TestCommand (line 32) | class TestCommand(TestCase):
    method test_run (line 35) | def test_run(self, mock_email, mock_api):
  class Test (line 49) | class Test(TestCase):
    method test_flatten_multi_arg (line 53) | def test_flatten_multi_arg(self):
    method test_init_args_parser (line 63) | def test_init_args_parser(self):
    method test_provided_init_args_parser (line 87) | def test_provided_init_args_parser(self):
    method test_load_repository_rules (line 100) | def test_load_repository_rules(self):
    method test_create_and_load_repos (line 106) | def test_create_and_load_repos(self):
    method test_parse_label (line 119) | def test_parse_label(self):

FILE: gcpdiag/lint/composer/bp_2023_001_debug_logging_level.py
  function _check_info_logging_level (line 30) | def _check_info_logging_level(config) -> bool:
  function prefetch_rule (line 36) | def prefetch_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/bp_2023_002_parallelism.py
  function prefetch_rule (line 28) | def prefetch_rule(context: models.Context):
  function run_rule (line 32) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/bp_2023_003_statsd.py
  function prefetch_rule (line 29) | def prefetch_rule(context: models.Context):
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/bp_ext_2023_001_number_of_schedulers.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/bp_ext_2023_002_xss_vulnerable_versions.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/composer_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/composer/err_2022_001_composer_p4sa_permissions.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/err_2022_002_composer_sa_permissions.py
  function prefetch_rule (line 37) | def prefetch_rule(context: models.Context):
  function run_rule (line 55) | def run_rule(context: models.Context,

FILE: gcpdiag/lint/composer/err_2023_001_composer_not_in_error_state.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/err_2023_002_verify_ip_range.py
  function prepare_rule (line 43) | def prepare_rule(context: models.Context):
  function run_rule (line 52) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/err_2023_003_dag_timeout_killing.py
  function prefetch_rule (line 33) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/err_2023_004_zombie_detection.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 35) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/err_2023_005_environment_delete_fail_nat_config.py
  function prepare_rule (line 44) | def prepare_rule(context: models.Context):
  function run_rule (line 54) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/err_2024_001_no_error_surfaced.py
  function prefetch_rule (line 35) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2022_001_composer2_p4sa_permissions.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2022_002_fluentd_pod_crashloop.py
  function prefetch_rule (line 43) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 47) | def prepare_rule(context: models.Context):
  function run_rule (line 55) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2022_003_total_dag_parse_time.py
  function prefetch_rule (line 33) | def prefetch_rule(context: models.Context):
  function run_rule (line 54) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_001_kerberos_support.py
  function _check_kerberos_overrides (line 25) | def _check_kerberos_overrides(config) -> bool:
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_002_task_sigkill.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_003_task_fail_resource_pressure.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 35) | def prepare_rule(context: models.Context):
  function run_rule (line 43) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_004_high_database_cpu_usage.py
  function prefetch_rule (line 33) | def prefetch_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_005_environment_is_consistently_healthy.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_006_schedulers_are_healthy.py
  function prefetch_rule (line 34) | def prefetch_rule(context: models.Context):
  function run_rule (line 54) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_007_high_scheduler_cpu_usage.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_008_composer_airflow_db_is_healthy.py
  function prefetch_rule (line 28) | def prefetch_rule(context: models.Context):
  function run_rule (line 43) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2023_009_composer_intermittent_task_failure_issue.py
  function find_env (line 41) | def find_env(arr_of_composer_envs: list, search_str: str):
  function get_dag_task (line 58) | def get_dag_task(error_message: str):
  function prefetch_rule (line 80) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 84) | def prepare_rule(context: models.Context):
  function run_rule (line 93) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2024_001_low_scheduler_cpu_usuage.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2024_002_worker_pod_eviction.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/composer/warn_2024_003_composer_api_disabled.py
  function prefetch_rule (line 39) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 43) | def prepare_rule(context: models.Context):
  function run_rule (line 52) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/bp_2023_001_dataflow_supported_sdk_version_check.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 32) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/dataflow_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/dataflow/err_2023_001_dataflow_sa_perm_check.py
  function prefetch_rule (line 25) | def prefetch_rule(context: models.Context):
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_002_dataflow_ip_space_exhausted.py
  function prepare_rule (line 34) | def prepare_rule(context: models.Context):
  function run_rule (line 42) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_003_dataflow_subnet_format_check.py
  function prepare_rule (line 34) | def prepare_rule(context: models.Context):
  function run_rule (line 42) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_004_dataflow_org_policy_violated.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 45) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_005_dataflow_credential_perm_issue.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_006_dataflow_private_google_access_check.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 45) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_007_dataflow_missing_firewall_issue.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_008_dataflow_sa_worker_perm_check.py
  function prefetch_rule (line 43) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 48) | def prepare_rule(context: models.Context):
  function run_rule (line 57) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_009_splunk_err_invalid_cert.py
  function prepare_rule (line 43) | def prepare_rule(context: models.Context):
  function run_rule (line 54) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_010_bq_streaming_insert_missing_field.py
  function prepare_rule (line 40) | def prepare_rule(context: models.Context):
  function run_rule (line 51) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_011_bq_streaming_insert_mismatch_column.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_012_dataflow_spanner_oom.py
  function prepare_rule (line 45) | def prepare_rule(context: models.Context):
  function run_rule (line 56) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2023_013_dataflow_spanner_deadline_exceeded.py
  function prepare_rule (line 44) | def prepare_rule(context: models.Context):
  function run_rule (line 55) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2024_001_dataflow_gce_quotas.py
  function prepare_rule (line 49) | def prepare_rule(context: models.Context):
  function run_rule (line 60) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2024_002_dataflow_key_commit.py
  function prepare_rule (line 43) | def prepare_rule(context: models.Context):
  function run_rule (line 55) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2024_003_dataflow_write_truncate_unbounded.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2024_004_missing_gcs_permission_temp_bucket.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/err_2024_005_dataflow_not_creating_pubsub_subscription.py
  function prepare_rule (line 40) | def prepare_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/warn_2023_001_dataflow_hot_key.py
  function prepare_rule (line 43) | def prepare_rule(context: models.Context):
  function run_rule (line 53) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/warn_2023_003_dataflow_worker_logs_throttled.py
  function prepare_rule (line 30) | def prepare_rule(context: models.Context):
  function run_rule (line 45) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/warn_2023_004_dataflow_stuck_at_draining.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/warn_2023_006_dataflow_stuck_at_cancelling.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/warn_2024_001_dataflow_operation_ongoing.py
  function prepare_rule (line 45) | def prepare_rule(context: models.Context):
  function run_rule (line 57) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataflow/warn_2024_002_dataflow_streaming_appliance_commit_failed.py
  function prepare_rule (line 43) | def prepare_rule(context: models.Context):
  function run_rule (line 54) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/datafusion_rules_snapshot_test.py
  class Test (line 26) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/datafusion/err_2022_001_connectivity_dataproc_vms.py
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_002_shared_vpc_ip_range.py
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_003_private_peering.py
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_004_cloud_datafusion_sa_permissions.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_005_host_vpc_permissions.py
  function validate_iam_roles (line 33) | def validate_iam_roles(context: models.Context, service_account: str,
  function run_rule (line 81) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_006_private_google_access.py
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_007_cloud_datafusion_sa_permissions.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_008_cloud_datafusion_sa_permissions.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_009_cloud_dataproc_sa_permissions.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_010_cloud_datafusion_sa_permissions.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2022_011_cloud_datafusion_sa_permissions.py
  function prefetch_rule (line 33) | def prefetch_rule(context: models.Context):
  function run_rule (line 37) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/err_2024_001_delete_operation_failing.py
  function find_instance (line 42) | def find_instance(arr_of_datafusion_envs: dict, search_str: str):
  function prefetch_rule (line 48) | def prefetch_rule(context: models.Context):
  function prepare_rule (line 53) | def prepare_rule(context: models.Context):
  function run_rule (line 62) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/warn_2024_001_data_fusion_version.py
  function prefetch_rule (line 33) | def prefetch_rule(context: models.Context):
  function run_rule (line 37) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/warn_2024_002_instance_state_running.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/warn_2024_003_cluster_scaling_down_disabled.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/warn_2024_004_datafusion_dataproc_compatabillity.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function run_rule (line 36) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/datafusion/warn_2024_005_datafusion_dataproc_compatability_preference.py
  function prefetch_rule (line 36) | def prefetch_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  function check_dataproc_version_valid (line 162) | def check_dataproc_version_valid(preference_image_version: str):
  function check_datafusion_dataproc_version_compatibility (line 170) | def check_datafusion_dataproc_version_compatibility(

FILE: gcpdiag/lint/dataproc/bp_2021_001_logging_enabled.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 31) | def run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/bp_2022_001_monitoring_enabled.py
  function run_rule (line 13) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/bp_2022_098_another_dummy_async_rule.py
  class FakeResource (line 11) | class FakeResource(models.Resource):
    method __init__ (line 13) | def __init__(self, text):
    method full_path (line 18) | def full_path(self):
  function async_run_rule (line 23) | async def async_run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/bp_2022_099_dummy_async_rule.py
  class FakeResource (line 11) | class FakeResource(models.Resource):
    method __init__ (line 13) | def __init__(self, text):
    method full_path (line 18) | def full_path(self):
  function async_run_rule (line 23) | async def async_run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/dataproc_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/dataproc/err_2022_002_image_versions.py
  class VersionParser (line 27) | class VersionParser:
    method __init__ (line 32) | def __init__(self, s):
    method parse (line 41) | def parse(self):
    method match_re (line 47) | def match_re(self):
    method fill_properties_from_match (line 52) | def fill_properties_from_match(self):
  class ImageVersion (line 63) | class ImageVersion:
    method __init__ (line 66) | def __init__(self, version_str):
    method is_deprecated (line 70) | def is_deprecated(self):
  function prefetch_rule (line 85) | def prefetch_rule(context: models.Context):
  function run_rule (line 89) | def run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/err_2022_002_image_versions_test.py
  class TestDataprocImageVersions (line 19) | class TestDataprocImageVersions:
    method dotest (line 22) | def dotest(self, versions, expected):
    method test_not_deprecated (line 26) | def test_not_deprecated(self):
    method test_deprecated (line 29) | def test_deprecated(self):
    method test_something_completely_wrong (line 32) | def test_something_completely_wrong(self):
    method test_something_close_but_wrong_parts (line 35) | def test_something_close_but_wrong_parts(self):
    method test_missing_parts (line 38) | def test_missing_parts(self):

FILE: gcpdiag/lint/dataproc/err_2022_003_dataproc_sa_permissions.py
  function run_rule (line 27) | def run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/err_2022_004_dpgce_connectivity.py
  function prefetch_rule (line 28) | def prefetch_rule(context: models.Context):
  function run_rule (line 96) | def run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/err_2023_001_initialization_action_timeout.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/err_2023_002_orphaned_yarn_application.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/err_2023_003_dataproc_permission.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/err_2023_004_dataproc_firewall_issue.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/err_2023_005_dataproc_quota.py
  function prepare_rule (line 42) | def prepare_rule(context: models.Context):
  function format_cluster (line 51) | def format_cluster(cluster_name, uuid):
  function run_rule (line 55) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/err_2023_006_shared_vpc_permission.py
  function validate_iam_roles (line 35) | def validate_iam_roles(
  function shared_vpc_check (line 74) | def shared_vpc_check(host_project, service_project):
  function run_rule (line 78) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/err_2023_007_cluster_creation_stockout.py
  function prepare_rule (line 42) | def prepare_rule(context: models.Context):
  function run_rule (line 51) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/err_2023_008_bad_dirs.py
  function prepare_rule (line 46) | def prepare_rule(context: models.Context):
  function prefetch_rule (line 54) | def prefetch_rule(context: models.Context):
  function is_relevant (line 58) | def is_relevant(entry, context):
  function get_clusters_having_relevant_log_entries (line 70) | def get_clusters_having_relevant_log_entries(context):
  function run_rule (line 78) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/warn_2021_001_cluster_status_running.py
  function prefetch_rule (line 25) | def prefetch_rule(context: models.Context):
  function run_rule (line 29) | def run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/warn_2022_001_cluster_local_ssd_failed_stop.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/warn_2022_002_job_throttling_rate_limit.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function prefetch_rule (line 47) | def prefetch_rule(context: models.Context):
  function is_relevant (line 51) | def is_relevant(entry, context):
  function get_clusters_having_relevant_log_entries (line 63) | def get_clusters_having_relevant_log_entries(context):
  function run_rule (line 71) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/warn_2022_003_sa_permissions.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/warn_2022_004_cluster_status_running_async.py
  function async_run_rule (line 10) | async def async_run_rule(context: models.Context,

FILE: gcpdiag/lint/dataproc/warn_2023_001_job_throttling_too_many.py
  function prepare_rule (line 36) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/warn_2023_002_high_system_memory_usage.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 45) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/warn_2024_001_safemode.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function prefetch_rule (line 49) | def prefetch_rule(context: models.Context):
  function is_relevant (line 53) | def is_relevant(entry, context):
  function get_clusters_having_relevant_log_entries (line 65) | def get_clusters_having_relevant_log_entries(context):
  function run_rule (line 73) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/dataproc/warn_2024_002_hdfs_write_issue.py
  function prepare_rule (line 42) | def prepare_rule(context: models.Context):
  function prefetch_rule (line 51) | def prefetch_rule(context: models.Context):
  function is_relevant (line 55) | def is_relevant(entry, context):
  function get_clusters_having_relevant_log_entries (line 66) | def get_clusters_having_relevant_log_entries(context):
  function run_rule (line 74) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gae/err_2023_001_appengine_vpc_connector_policy.py
  function prepare_rule (line 40) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gae/err_2023_002_appengine_vpc_connector_subnet_overlap.py
  function prepare_rule (line 44) | def prepare_rule(context: models.Context):
  function run_rule (line 52) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gae/err_2025_001_gae_default_service_account_is_deleted.py
  function prepare_rule (line 28) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gae/gae_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/gae/warn_2022_001_appengine_standard_deprecated_runtimes.py
  function run_rule (line 27) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gae/warn_2022_002_appengine_flexible_deprecated_runtimes.py
  function run_rule (line 27) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcb/err_2022_001_missing_cloudbuild_editor_role.py
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcb/err_2022_002_build_failed_whithout_artifact_registry_permission.py
  function run_rule (line 38) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  class FailedBuildStatus (line 61) | class FailedBuildStatus:
  class Repository (line 67) | class Repository(abc.ABC):
    method can_read_registry (line 70) | def can_read_registry(self, context: models.Context,
    method format_message (line 75) | def format_message(self) -> str:
  class GcrRepository (line 79) | class GcrRepository(Repository):
    method __init__ (line 82) | def __init__(self, project_id: str, repository: str):
    method can_read_registry (line 86) | def can_read_registry(self, context: models.Context,
    method format_message (line 96) | def format_message(self) -> str:
  class ArtifactRepository (line 100) | class ArtifactRepository(Repository):
    method __init__ (line 103) | def __init__(self, project_id: str, location: str, repository: str):
    method can_read_registry (line 108) | def can_read_registry(self, context: models.Context,
    method format_message (line 118) | def format_message(self) -> str:
  function find_builds_without_image_upload_permission (line 123) | def find_builds_without_image_upload_permission(
  function get_used_registries (line 137) | def get_used_registries(images: Iterable[str]) -> Iterable[Repository]:

FILE: gcpdiag/lint/gcb/err_2022_003_build_failed_with_logs_bucket_retention_policy.py
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  class FailedBuildStatus (line 47) | class FailedBuildStatus:
  function find_builds_failing_to_upload_logs (line 52) | def find_builds_failing_to_upload_logs(

FILE: gcpdiag/lint/gcb/err_2022_004_missing_cloudbuild_service_agent_role.py
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcb/gcb_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/gce/bp_2021_001_serial_logging_enabled.py
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_2022_003_unused_boot_disks.py
  function run_rule (line 24) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_2023_001_ntp_config.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 45) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_2024_001_legacy_monitoring_agent.py
  function prefetch_rule (line 45) | def prefetch_rule(context: models.Context):
  function run_rule (line 60) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_2024_002_legacy_logging_agent.py
  function prefetch_rule (line 44) | def prefetch_rule(context: models.Context):
  function run_rule (line 60) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_ext_2021_003_secure_boot_enabled.py
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_ext_2022_001_vm_manager_enabled.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_ext_2023_001_gce_scopes.py
  function run_rule (line 32) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_ext_2024_001_no_public_ip.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/bp_ext_2024_002_calculate_vm_iops_throughput.py
  function prepare_rule (line 33) | def prepare_rule(context: models.Context):
  function run_rule (line 41) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  function limit_calculator (line 605) | def limit_calculator(limits_data, mach_fam_json_data, disktype: str,

FILE: gcpdiag/lint/gce/err_2021_001_mig_scaleup_failed.py
  function prepare_rule (line 32) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2021_002_osconfig_perm.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 37) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2021_003_api_service_agent.py
  function prefetch_rule (line 33) | def prefetch_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2021_004_secure_boot_failed.py
  function prepare_rule (line 42) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2021_005_mount_errors.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2022_001_quota_exceeded.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2022_002_premium_guestos_activation_failed.py
  function prepare_rule (line 43) | def prepare_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2024_001_snapshot_rate_limit.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2024_002_performance.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function run_rule (line 82) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2024_003_vm_secure_boot_failures.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/err_2024_004_ops_agent.py
  class Instance (line 77) | class Instance:
    method __init__ (line 93) | def __init__(self, project_id, gce_instance):
    method project_id (line 105) | def project_id(self) -> str:
    method gce_instance (line 109) | def gce_instance(self) -> gce.Instance:
    method is_gke_node (line 113) | def is_gke_node(self) -> bool:
    method id (line 117) | def id(self) -> str:
    method zone (line 121) | def zone(self) -> str:
    method name (line 125) | def name(self) -> str:
    method has_os_inventory (line 129) | def has_os_inventory(self) -> bool:
    method has_os_inventory (line 133) | def has_os_inventory(self, new_value: bool):
    method ops_agent_installed (line 137) | def ops_agent_installed(self) -> bool:
    method ops_agent_installed (line 141) | def ops_agent_installed(self, new_value: bool):
    method has_recent_log_pings (line 145) | def has_recent_log_pings(self) -> bool:
    method has_recent_log_pings (line 149) | def has_recent_log_pings(self, new_value: bool):
    method has_recent_log_entries (line 153) | def has_recent_log_entries(self) -> bool:
    method has_recent_log_entries (line 157) | def has_recent_log_entries(self, new_value: bool):
    method has_logging_uptime_metrics (line 161) | def has_logging_uptime_metrics(self) -> bool:
    method has_logging_uptime_metrics (line 165) | def has_logging_uptime_metrics(self, new_value: bool):
    method has_monitoring_uptime_metrics (line 169) | def has_monitoring_uptime_metrics(self) -> bool:
    method has_monitoring_uptime_metrics (line 173) | def has_monitoring_uptime_metrics(self, new_value: bool):
  function prepare_rule (line 177) | def prepare_rule(context: models.Context):
  function run_rule (line 224) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  function confirm_agent_installation_via_os_config (line 252) | def confirm_agent_installation_via_os_config(
  function format_metric_entries (line 287) | def format_metric_entries(
  function confirm_agent_installation_via_uptime_metrics (line 307) | def confirm_agent_installation_via_uptime_metrics(
  function populate_sub_agents_uptime_metrics_status (line 362) | def populate_sub_agents_uptime_metrics_status(
  function populate_log_type_status (line 381) | def populate_log_type_status(instances: List[Instance],
  function format_log_entries (line 396) | def format_log_entries(
  function confirm_agent_telemetry_transmission (line 439) | def confirm_agent_telemetry_transmission(

FILE: gcpdiag/lint/gce/gce_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/gce/utils.py
  class SerialOutputSearch (line 27) | class SerialOutputSearch:
    method __init__ (line 36) | def __init__(self,
    method _mk_filter (line 52) | def _mk_filter(self) -> str:
    method get_last_match (line 56) | def get_last_match(self, instance_id: str) -> Optional[logs.LogEntrySh...
    method get_all_instance_with_match (line 61) | def get_all_instance_with_match(self):
  class QueryCloudLogs (line 86) | class QueryCloudLogs:
    method __init__ (line 92) | def __init__(self,
    method _mk_filter (line 106) | def _mk_filter(self, logid) -> str:
    method get_entries (line 110) | def get_entries(self, instance_id: str) -> dict:
  function is_cloudsql_peer_network (line 121) | def is_cloudsql_peer_network(url: str) -> bool:
  function is_serial_port_one_logs_available (line 129) | def is_serial_port_one_logs_available(context: models.Context):

FILE: gcpdiag/lint/gce/utils_test.py
  class TestUtils (line 27) | class TestUtils:
    method test_query_order_with_buffer_enabled (line 60) | def test_query_order_with_buffer_enabled(self, mock_logs_query_entries,
    method test_query_order_buffer_disabled (line 90) | def test_query_order_buffer_disabled(self, mock_logs_query_entries,
  function test_is_serial_logs_available (line 115) | def test_is_serial_logs_available():

FILE: gcpdiag/lint/gce/warn_2021_001_logging_perm.py
  function prefetch_rule (line 57) | def prefetch_rule(context: models.Context):
  function run_rule (line 65) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2021_002_disk_latency.py
  function prefetch_rule (line 39) | def prefetch_rule(context: models.Context):
  function run_rule (line 67) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2021_003_monitoring_permissions.py
  function prefetch_rule (line 53) | def prefetch_rule(context: models.Context):
  function run_rule (line 61) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2021_004_disk_full_serial_messages.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 43) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2021_005_out_of_memory.py
  function prepare_rule (line 40) | def prepare_rule(context: models.Context):
  function run_rule (line 45) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2021_006_kernel_panic.py
  function prepare_rule (line 35) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2021_007_bsod.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 42) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_001_iap_tcp_forwarding.py
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_002_duplicated_named_ports.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_003_vm_instances_quota.py
  function prefetch_rule (line 38) | def prefetch_rule(context: models.Context):
  function run_rule (line 56) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_004_docker_bridge_network.py
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  function _is_docker_bridge_ip (line 66) | def _is_docker_bridge_ip(ip: ipaddress.IPv4Address) -> bool:

FILE: gcpdiag/lint/gce/warn_2022_005_cpu_quota.py
  function prefetch_rule (line 48) | def prefetch_rule(context: models.Context):
  function run_rule (line 67) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_006_gpu_quota.py
  function prefetch_rule (line 44) | def prefetch_rule(context: models.Context):
  function run_rule (line 63) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_007_cloudsql_admin_scope.py
  function run_rule (line 36) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_008_ip_address_quota.py
  function prefetch_rule (line 45) | def prefetch_rule(context: models.Context):
  function run_rule (line 64) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_009_disk_quota.py
  function prefetch_rule (line 43) | def prefetch_rule(context: models.Context):
  function run_rule (line 62) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_010_resource_availability.py
  function prepare_rule (line 44) | def prepare_rule(context: models.Context):
  function run_rule (line 52) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_011_valid_sa.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2022_012_windows_kms.py
  function kms_route_access (line 33) | def kms_route_access(instance) -> bool:
  function run_rule (line 43) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2023_001_snapshot_policies_on_unused_disks.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gce/warn_2023_002_airflowtask_oom.py
  function prepare_rule (line 35) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcf/err_2022_001_missing_cloudfunctions_serviceagent_role.py
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcf/err_2022_002_cloudfunctions_org_policy_violation.py
  function prepare_rule (line 42) | def prepare_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcf/err_2022_003_cloudfunctions_memory_limit_exceeded.py
  function prepare_rule (line 32) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcf/gcf_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/gcf/warn_2021_001_cloudfunctions_deprecated_runtimes.py
  function run_rule (line 13) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcf/warn_2021_002_cloudfunctions_request_aborted.py
  function prepare_rule (line 32) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcs/bp_2022_001_bucket_access_uniform.py
  function _is_google_managed (line 31) | def _is_google_managed(bucket):
  function run_rule (line 38) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gcs/gcs_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/gke/bp_2021_001_cloudops_enabled.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2022_001_regional_cluster.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2022_002_unique_subnets.py
  function run_rule (line 28) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2022_003_cluster_eol.py
  function _estimate_oss_release_date (line 43) | def _estimate_oss_release_date(version: Version) -> date:
  function _estimate_gke_eol_date (line 65) | def _estimate_gke_eol_date(version: Version, eol_schedule: Dict):
  function _notification_required (line 96) | def _notification_required(version: Version, eol_schedule: Dict) -> bool:
  function _get_notification_msg (line 121) | def _get_notification_msg(version: Version, eol_schedule: Dict) -> str:
  function run_rule (line 129) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2022_004_http_load_balancing_disabled.py
  function run_rule (line 13) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2023_001_network_policy_minimum_requirements.py
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2023_002_stateful_workloads_not_on_preemptible_node.py
  function run_rule (line 15) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2023_004_vpc_native_cluster.py
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2023_005_gateway_crd.py
  function prepare_rule (line 30) | def prepare_rule(context: models.Context):
  function run_rule (line 41) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_2025_001_gke_nodelocal_dnscache_enabled.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_ext_2022_001_groups_enabled.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_ext_2023_001_maintenance_window.py
  function prepare_rule (line 28) | def prepare_rule(context: models.Context):
  function run_rule (line 32) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/bp_ext_2023_002_private_cluster.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_001_logging_perm.py
  function prefetch_rule (line 26) | def prefetch_rule(context: models.Context):
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_002_monitoring_perm.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_003_kms_key_enabled.py
  function run_rule (line 24) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_004_node_connection_apiserver.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 39) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_005_node_connection_storage.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 39) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_006_scaleup_failed.py
  function prepare_rule (line 33) | def prepare_rule(context: models.Context):
  function is_mig_instance (line 55) | def is_mig_instance(mig_name: str, instance_name: str):
  function run_rule (line 64) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_007_gke_sa.py
  function run_rule (line 27) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_008_api_service_agent.py
  function prefetch_rule (line 35) | def prefetch_rule(context: models.Context):
  function run_rule (line 42) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_009_nodepool_version_skew.py
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_010_internal_forwarding_rule_limits.py
  function prepare_rule (line 28) | def prepare_rule(context: models.Context):
  function run_rule (line 38) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_011_ip_masq_not_reporting_errors.py
  function prepare_rule (line 32) | def prepare_rule(context: models.Context):
  function run_rule (line 41) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_012_np_sa_enabled.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_013_connectivity_cluster_rules.py
  function _run_rule_cluster (line 30) | def _run_rule_cluster(report: lint.LintReportRuleInterface, c: gke.Clust...
  function run_rule (line 52) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_014_connectivity_master.py
  function _run_rule_cluster (line 23) | def _run_rule_cluster(report: lint.LintReportRuleInterface, c: gke.Clust...
  function run_rule (line 55) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2021_015_connectivity_vms.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function _run_rule_cluster (line 38) | def _run_rule_cluster(report: lint.LintReportRuleInterface, c: gke.Clust...
  function run_rule (line 66) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2022_001_connectivity_pod_to_pod.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function _run_rule_cluster (line 38) | def _run_rule_cluster(report: lint.LintReportRuleInterface, c: gke.Clust...
  function run_rule (line 67) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2022_002_private_google_access.py
  function run_rule (line 23) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2022_003_ingress_healthcheck.py
  function _get_rule_allowed_ports (line 28) | def _get_rule_allowed_ports(rule: VpcFirewallRule):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_001_containerfilesystem_quota.py
  function prepare_rule (line 30) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_002_private_routes_based.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_003_containerd_bad_config_file.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 41) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_004_ingress_config.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 38) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_005_gke_cni_issue.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 42) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_006_gw_controller_annotation_error.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_007_gw_controller_http_route_misconfig.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_008_crashloopbackoff.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 41) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_009_missing_cpu_req.py
  function prepare_rule (line 32) | def prepare_rule(context: models.Context):
  function _filter_f (line 43) | def _filter_f(log_entry):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_010_nodelocal_timeout.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_011_wi_pod_ip_not_found.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2023_012_missing_mem_request.py
  function prepare_rule (line 32) | def prepare_rule(context: models.Context):
  function _filter_f (line 43) | def _filter_f(log_entry):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2024_001_psa_violoations.py
  function prepare_rule (line 35) | def prepare_rule(context: models.Context):
  function _filter_f (line 46) | def _filter_f(log_entry):
  function run_rule (line 53) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2024_002_webhook_failure_no_endpoint.py
  function prepare_rule (line 35) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2024_003_default_node_serviceaccount_perm.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/err_2025_001_serial_port_logging.py
  function get_non_compliant_pools (line 29) | def get_non_compliant_pools(cluster: gke.Cluster) -> List[str]:
  function run_rule (line 57) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/gke_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/gke/sec_2021_001_np_uses_default_sa.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/sec_2023_001_worload_id.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/util.py
  class _CantMapLogEntry (line 26) | class _CantMapLogEntry(BaseException):
  function _initialize_clusters_by_name (line 39) | def _initialize_clusters_by_name(context: models.Context):
  function _initialize_clusters_by_instance_id (line 47) | def _initialize_clusters_by_instance_id(context: models.Context):
  function _gke_node_of_log_entry (line 68) | def _gke_node_of_log_entry(context, log_entry):
  function _gke_pod_of_log_entry (line 98) | def _gke_pod_of_log_entry(context, log_entry):
  function _gke_cluster_of_log_entry (line 129) | def _gke_cluster_of_log_entry(context, log_entry):
  function gke_logs_find_bad_nodes (line 146) | def gke_logs_find_bad_nodes(context: models.Context,
  function gke_logs_find_bad_clusters (line 174) | def gke_logs_find_bad_clusters(context: models.Context,
  function get_cluster_object (line 205) | def get_cluster_object(cluster_dict, partial_path):
  function gke_logs_find_bad_pods (line 224) | def gke_logs_find_bad_pods(

FILE: gcpdiag/lint/gke/warn_2021_001_cluster_version.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2021_002_nodes_version.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2021_003_pod_cidr_cluster_size.py
  function nodepool_calc (line 35) | def nodepool_calc(cluster) -> Tuple[dict, dict]:
  function run_rule (line 70) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2021_004_system_workloads_stable.py
  function prefetch_rule (line 47) | def prefetch_rule(context: models.Context):
  function run_rule (line 75) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2021_005_disk_latency.py
  function prefetch_rule (line 39) | def prefetch_rule(context: models.Context):
  function run_rule (line 65) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2021_006_node_conntrack_full.py
  function prepare_rule (line 28) | def prepare_rule(context: models.Context):
  function run_rule (line 38) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2021_007_disk_full.py
  function prefetch_rule (line 33) | def prefetch_rule(context: models.Context):
  function run_rule (line 56) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2021_008_gke_istio_incompatible_versions.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 50) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2021_009_node_deprecated_image_types.py
  function run_rule (line 24) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2022_001_wi_with_regional_cluster.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2022_002_md_concealment.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2022_003_firewall_rules_permission.py
  function run_rule (line 35) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2022_004_logging_api_disabled.py
  function run_rule (line 24) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2022_005_nvdia_gpu.py
  function prefetch_rule (line 29) | def prefetch_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2022_006_nap_node_image_types.py
  function run_rule (line 24) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2022_007_storage_scope.py
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2022_008_dns_lookup_timeout_intra_node_visibility.py
  function run_rule (line 28) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  function _guard_for_unaffected_versions (line 43) | def _guard_for_unaffected_versions(
  function _check_for_affected_version (line 58) | def _check_for_affected_version(cluster: gke.Cluster,

FILE: gcpdiag/lint/gke/warn_2023_001_containerfilesystem_scope.py
  function prepare_rule (line 29) | def prepare_rule(context: models.Context):
  function run_rule (line 39) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2023_002_metadata_server_timeout.py
  function prepare_rule (line 37) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2023_003_monitoring_api_disabled.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2023_004_too_few_pods_per_node.py
  function run_rule (line 28) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2024_001_cluster_nap_limits_prevent_autoscaling.py
  function prepare_rule (line 46) | def prepare_rule(context: models.Context):
  function _filter_f (line 57) | def _filter_f(log_entry: logs.LogEntryShort) -> bool:
  function _extract_sample_affected_pod (line 76) | def _extract_sample_affected_pod(
  function run_rule (line 96) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2024_002_ksa_exceed.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 48) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2024_003_ingress_svc_notfound.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 42) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2024_004_ingress_backendcrd.py
  function prepare_rule (line 33) | def prepare_rule(context: models.Context):
  function run_rule (line 44) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2024_005_ingress_servicetype.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 42) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2024_007_loadbalancer_ipv6_no_internal_range.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 43) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/gke/warn_2025_001_loadbalancer_ipv6_no_external_range.py
  function prepare_rule (line 46) | def prepare_rule(context: models.Context):
  function run_rule (line 59) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/iam/bp_2023_001_auto_grant_editor_role_default_sa.py
  function prefetch_rule (line 26) | def prefetch_rule(context: models.Context):
  function run_rule (line 33) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/iam/iam_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/iam/sec_2021_001_sa_permissions.py
  function prefetch_rule (line 26) | def prefetch_rule(context: models.Context):
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/iam/sec_2024_001_unused_sa.py
  function prefetch_rule (line 31) | def prefetch_rule(context: models.Context):
  function run_rule (line 43) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/interconnect/bp_2023_001_high_availability.py
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/interconnect/interconnect_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/interconnect/warn_2023_001_legacy_dataplane.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/interconnect/warn_2023_002_defunct_attachment.py
  function run_rule (line 24) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/interconnect/warn_2023_003_link_maintenance.py
  function run_rule (line 24) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/interconnect/warn_2025_001_check_interconnect_mtu.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/bp_2022_001_lbpolicy_for_sessionaffinity.py
  function run_rule (line 23) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/bp_2023_001_cloudcdn_for_lb_backend_services.py
  function run_rule (line 27) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/bp_2023_002_healthcheck_logging_for_backend_services.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 38) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/bp_2024_001_sessionaffinity_for_lb_backendservices.py
  function run_rule (line 25) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/bp_2024_002_global_access_for_regional_ilb.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function run_rule (line 37) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/bp_2025_001_protocol_for_lb_backendservices.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/bp_2025_002_timeout_sec_for_lb_backendservices.py
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/bp_2025_003_connection_draining_backend_services.py
  function run_rule (line 23) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/lb/lb_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/lint_rule_repository_test.py
  class FakePyPkg (line 23) | class FakePyPkg:
    method __init__ (line 25) | def __init__(self, name, path):
  class FakeModulesGateway (line 30) | class FakeModulesGateway:
    method __init__ (line 33) | def __init__(self, modules_by_name):
    method list_pkg_modules (line 36) | def list_pkg_modules(self, pkg):
    method get_module (line 41) | def get_module(self, name):
  class FakeModule (line 45) | class FakeModule:
    method __init__ (line 48) | def __init__(self, methods, doc):
    method get_method (line 52) | def get_method(self, name):
    method get_module_doc (line 55) | def get_module_doc(self):
    method get_attr (line 58) | def get_attr(self, attribute):
  class FakeExecutionStrategy (line 62) | class FakeExecutionStrategy:
    method __init__ (line 65) | def __init__(self):
    method filter_runnable_rules (line 68) | def filter_runnable_rules(self, rules):
    method run_rules (line 71) | def run_rules(self, context, result, rules):
  class Setup (line 76) | class Setup:
    method __init__ (line 79) | def __init__(self,
    method repo (line 90) | def repo(self):
    method modules_gw (line 98) | def modules_gw(self):
    method execution_strategy (line 102) | def execution_strategy(self):
  function mk_simple_rule_module (line 106) | def mk_simple_rule_module(methods=None, doc=None):
  function mk_simple_async_rule_module (line 112) | def mk_simple_async_rule_module(methods=None, doc=None):
  function test_sync_happy_path (line 118) | def test_sync_happy_path():
  function test_async_happy_path (line 139) | def test_async_happy_path():
  function test_no_entrypoint_raises (line 160) | def test_no_entrypoint_raises():
  function test_wrong_rule_class_raises (line 171) | def test_wrong_rule_class_raises():
  function test_wrong_module_names_ignored (line 182) | def test_wrong_module_names_ignored():
  function test_tests_ignored (line 195) | def test_tests_ignored():
  function test_empty_doc_raises (line 208) | def test_empty_doc_raises():
  function test_singleline_doc_happy_path (line 220) | def test_singleline_doc_happy_path():
  function test_multiline_doc_happy_path (line 236) | def test_multiline_doc_happy_path():
  function test_non_empty_second_doc_line_raises (line 254) | def test_non_empty_second_doc_line_raises():
  function test_ext_ignored (line 267) | def test_ext_ignored():
  function test_ext_loaded (line 280) | def test_ext_loaded():
  function test_include_id (line 295) | def test_include_id():
  function test_include_class (line 316) | def test_include_class():
  function test_include_product (line 337) | def test_include_product():
  function test_exclude_id (line 362) | def test_exclude_id():
  function test_exclude_class (line 383) | def test_exclude_class():
  function test_exclude_product (line 404) | def test_exclude_product():

FILE: gcpdiag/lint/looker/bp_2025_001_get_all_instances.py
  function run_rule (line 22) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/looker/bp_2025_002_lsp_high_intensity_queries_bq.py
  function prepare_rule (line 33) | def prepare_rule(context: models.Context):
  function run_rule (line 42) | def run_rule(

FILE: gcpdiag/lint/looker/bp_2025_003_get_all_lags_operations.py
  function format_operation_message (line 12) | def format_operation_message(operation):
  function run_rule (line 28) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/looker/looker_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/notebooks/bp_2023_001_enable_report_system_health.py
  function prefetch_rule (line 32) | def prefetch_rule(context: models.Context):
  function run_rule (line 36) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/bp_2023_002_instances_upgrade_available.py
  function prefetch_rule (line 26) | def prefetch_rule(context: models.Context):
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/bp_2023_003_runtimes_upgrade_available.py
  function prefetch_rule (line 26) | def prefetch_rule(context: models.Context):
  function run_rule (line 30) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/bp_2023_004_runtime_idle_shutdown.py
  function prefetch_rule (line 25) | def prefetch_rule(context: models.Context):
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/err_2023_001_instances_health_state.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/err_2023_002_create_notebook_compute_subnetworks_permissions_missing.py
  function prepare_rule (line 49) | def prepare_rule(context: models.Context):
  function find_logs_with_permission_errors (line 67) | def find_logs_with_permission_errors(context: models.Context,
  function run_rule (line 86) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/err_2023_003_create_notebook_permissions_missing.py
  function prepare_rule (line 50) | def prepare_rule(context: models.Context):
  function find_logs_with_permission_errors (line 68) | def find_logs_with_permission_errors(context: models.Context,
  function run_rule (line 80) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/err_2023_004_runtimes_health_state.py
  function prefetch_rule (line 27) | def prefetch_rule(context: models.Context):
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/err_2024_001_executor_explicit_project_permissions.py
  function prepare_rule (line 54) | def prepare_rule(context: models.Context):
  function find_logs_with_permission_errors (line 67) | def find_logs_with_permission_errors(context: models.Context):
  function run_rule (line 79) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/notebooks_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/notebooks/warn_2023_001_notebooks_oom.py
  function prepare_rule (line 31) | def prepare_rule(context: models.Context):
  function run_rule (line 36) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/warn_2023_002_data_disk_utilization.py
  function prefetch_rule (line 25) | def prefetch_rule(context: models.Context):
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/notebooks/warn_2023_003_boot_disk_utilization.py
  function prefetch_rule (line 25) | def prefetch_rule(context: models.Context):
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/output/api_output.py
  class APIOutput (line 22) | class APIOutput(base_output.BaseOutput):
    method result_handler (line 26) | def result_handler(self) -> 'lint.LintResultsHandler':
    method process_rule_report (line 29) | def process_rule_report(self,
    method get_logging_handler (line 33) | def get_logging_handler(self) -> logging.Handler:

FILE: gcpdiag/lint/output/base_output.py
  class BaseOutput (line 11) | class BaseOutput:
    method __init__ (line 19) | def __init__(self,
    method display_banner (line 30) | def display_banner(self) -> None:
    method display_header (line 33) | def display_header(self, context: models.Context) -> None:
    method display_footer (line 36) | def display_footer(self, result: 'lint.LintResults') -> None:
    method get_logging_handler (line 44) | def get_logging_handler(self) -> logging.Handler:
    method print_line (line 47) | def print_line(self, text: str = '') -> None:
    method _should_result_be_skipped (line 51) | def _should_result_be_skipped(self, result: 'lint.LintRuleResult') -> ...
    method _should_rule_be_skipped (line 56) | def _should_rule_be_skipped(
  class _LoggingHandler (line 63) | class _LoggingHandler(logging.Handler):
    method __init__ (line 67) | def __init__(self, output: BaseOutput):
    method format (line 71) | def format(self, record: logging.LogRecord) -> str:
    method emit (line 74) | def emit(self, record: logging.LogRecord) -> None:

FILE: gcpdiag/lint/output/csv_output.py
  class CSVOutput (line 24) | class CSVOutput(base_output.BaseOutput):
    method __init__ (line 29) | def __init__(self,
    method result_handler (line 38) | def result_handler(self) -> 'lint.LintResultsHandler':
    method process_rule_report (line 41) | def process_rule_report(self,
    method _print_rule_report (line 46) | def _print_rule_report(self,
    method _add_result (line 56) | def _add_result(self,
    method display_header (line 78) | def display_header(self, context):
    method display_footer (line 82) | def display_footer(self, result) -> None:

FILE: gcpdiag/lint/output/json_output.py
  class JSONOutput (line 23) | class JSONOutput(base_output.BaseOutput):
    method display_header (line 28) | def display_header(self, context: models.Context) -> None:
    method display_footer (line 33) | def display_footer(self, result: lint.LintResults) -> None:
    method result_handler (line 41) | def result_handler(self) -> 'lint.LintResultsHandler':
    method process_rule_report (line 44) | def process_rule_report(self,
    method _print_rule_report (line 49) | def _print_rule_report(self,
    method _add_result (line 59) | def _add_result(self,

FILE: gcpdiag/lint/output/terminal_output.py
  function is_cloud_shell (line 34) | def is_cloud_shell():
  function emoji_wrap (line 38) | def emoji_wrap(char):
  class OutputOrderer (line 46) | class OutputOrderer:
    method __init__ (line 54) | def __init__(self, result_handler: 'lint.LintResultsHandler',
    method process_rule_report (line 61) | def process_rule_report(self, rule_report: Any) -> None:
    method _output_ready (line 66) | def _output_ready(self) -> None:
    method _has_more_work (line 73) | def _has_more_work(self) -> bool:
    method _is_next_rule_ready (line 77) | def _is_next_rule_ready(self) -> bool:
    method _next_rule_id (line 81) | def _next_rule_id(self) -> str:
  class TerminalOutput (line 85) | class TerminalOutput(base_output.BaseOutput):
    method __init__ (line 91) | def __init__(self,
    method result_handler (line 103) | def result_handler(self) -> 'lint.LintResultsHandler':
    method process_rule_report (line 111) | def process_rule_report(self,
    method _print_rule_report (line 117) | def _print_rule_report(self,
    method _handle_rule_report_result (line 126) | def _handle_rule_report_result(self,
    method _wrap_indent (line 142) | def _wrap_indent(self, text: str, prefix: str) -> str:
    method _italic (line 147) | def _italic(self, text: str) -> str:
    method terminal_update_line (line 154) | def terminal_update_line(self, text: str) -> None:
    method terminal_erase_line (line 167) | def terminal_erase_line(self) -> None:
    method terminal_print_line (line 176) | def terminal_print_line(self, text: str = '') -> None:
    method display_banner (line 187) | def display_banner(self) -> None:
    method _print_rule_header (line 193) | def _print_rule_header(self, rule: 'lint.LintRule') -> None:
    method _print_long_desc (line 204) | def _print_long_desc(self, rule: 'lint.LintRule') -> None:
    method _print_skipped (line 211) | def _print_skipped(self, resource: Optional[models.Resource],
    method _print_ok (line 230) | def _print_ok(self, resource: Optional[models.Resource],
    method _print_failed (line 243) | def _print_failed(self, resource: Optional[models.Resource],
    method get_logging_handler (line 256) | def get_logging_handler(self) -> logging.Handler:
  class _LoggingHandler (line 260) | class _LoggingHandler(logging.Handler):
    method __init__ (line 264) | def __init__(self, output: TerminalOutput) -> None:
    method format (line 268) | def format(self, record: logging.LogRecord) -> str:
    method emit (line 271) | def emit(self, record: logging.LogRecord) -> None:

FILE: gcpdiag/lint/pubsub/bp_2024_001_ouma_less_one_day.py
  function prefetch_rule (line 36) | def prefetch_rule(context: models.Context):
  function run_rule (line 57) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/err_2024_001_bq_subscription_table_not_found.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/err_2024_002_vpc_sc_new_subs_create_policy_violated.py
  function prepare_rule (line 39) | def prepare_rule(context: models.Context):
  function run_rule (line 47) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/err_2024_003_snapshot_creation_fails.py
  function prepare_rule (line 38) | def prepare_rule(context: models.Context):
  function run_rule (line 46) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/err_2025_001_push_service_agent_permission.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/pubsub_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/pubsub/warn_2023_001_detached_subscription_exists.py
  function run_rule (line 27) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/warn_2023_002_bq_subscription_has_dlq_topic.py
  function run_rule (line 26) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/warn_2023_003_topic_atleastone_sub.py
  function run_rule (line 28) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/warn_2023_004_orphaned_subscription_exists.py
  function run_rule (line 29) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/warn_2023_005_bq_subscription_permisions.py
  function prefetch_rule (line 30) | def prefetch_rule(context: models.Context):
  function run_rule (line 34) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/warn_2023_006_push_requests_failing.py
  function prefetch_rule (line 35) | def prefetch_rule(context: models.Context):
  function run_rule (line 58) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/warn_2024_001_dead_letter_queues_permissions.py
  function prefetch_rule (line 35) | def prefetch_rule(context: models.Context):
  function run_rule (line 40) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/pubsub/warn_2024_002_gcs_subscription_permissions.py
  function prefetch_rule (line 34) | def prefetch_rule(context: models.Context):
  function run_rule (line 51) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...
  function check_policy_project (line 85) | def check_policy_project(context, member) -> bool:
  function check_policy_buckets (line 93) | def check_policy_buckets(member) -> bool:

FILE: gcpdiag/lint/pubsub/warn_2024_003_cmek_topic_permissions.py
  function prefetch_rule (line 34) | def prefetch_rule(context: models.Context):
  function run_rule (line 39) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/snapshot_test_base.py
  class RulesSnapshotTestBase (line 37) | class RulesSnapshotTestBase:
    method test_all_rules (line 40) | def test_all_rules(self, snapshot):
    method _list_rules (line 55) | def _list_rules(self):
    method _mk_context (line 58) | def _mk_context(self):
    method _mk_output (line 61) | def _mk_output(self, output_stream):
    method _mk_repo (line 64) | def _mk_repo(self, rule=None):

FILE: gcpdiag/lint/tpu/tpu_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/tpu/warn_2022_001_stockout.py
  function prepare_rule (line 41) | def prepare_rule(context: models.Context):
  function run_rule (line 49) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/vertex/vertex_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/vertex/warn_2023_001_featurestores_state.py
  function prefetch_rule (line 26) | def prefetch_rule(context: models.Context):
  function run_rule (line 31) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/vpc/bp_2022_001_pga_next_hop.py
  function run_rule (line 16) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/vpc/bp_2023_001_public_zone_logging.py
  function run_rule (line 10) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/vpc/sec_2023_001_public_zone_dnssec.py
  function run_rule (line 23) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/vpc/vpc_rules_snapshot_test.py
  class Test (line 19) | class Test(snapshot_test_base.RulesSnapshotTestBase):

FILE: gcpdiag/lint/vpc/warn_2022_001_project_level_quota.py
  function prefetch_rule (line 139) | def prefetch_rule(context: models.Context):
  function run_rule (line 152) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/vpc/warn_2023_001_psa_no_export_custom_routes.py
  function run_rule (line 28) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/vpc/warn_2023_002_private_zone_attachment.py
  function run_rule (line 23) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/lint/vpc/warn_2024_001_unused_reserved_ip_addresses.py
  function run_rule (line 27) | def run_rule(context: models.Context, report: lint.LintReportRuleInterfa...

FILE: gcpdiag/models.py
  function _mapping_str (line 28) | def _mapping_str(mapping: Mapping[str, str]) -> str:
  class Messages (line 32) | class Messages(dict):
    method get_msg (line 34) | def get_msg(self, template: str, **kwargs):
  class Parameter (line 44) | class Parameter(dict[T, V], Generic[T, V]):
    method __init__ (line 47) | def __init__(self, *args, **kwargs):
    method _parse_value (line 55) | def _parse_value(self, value: str) -> Any:
    method __setitem__ (line 61) | def __setitem__(self, key: T, value: V) -> None:
    method update (line 64) | def update(self, *args, **kwargs) -> None:
    method setdefault (line 68) | def setdefault(self, key: T, default: V = None) -> V:
    method __str__ (line 75) | def __str__(self):
  class Context (line 80) | class Context:
    method copy_with (line 98) | def copy_with(self, **changes) -> 'Context':
    method __init__ (line 109) | def __init__(
    method __str__ (line 178) | def __str__(self):
    method __hash__ (line 190) | def __hash__(self):
    method match_project_resource (line 196) | def match_project_resource(
  class Resource (line 243) | class Resource(abc.ABC):
    method __init__ (line 247) | def __init__(self, project_id):
    method __str__ (line 250) | def __str__(self):
    method __hash__ (line 253) | def __hash__(self):
    method __lt__ (line 256) | def __lt__(self, other):
    method __eq__ (line 259) | def __eq__(self, other):
    method project_id (line 266) | def project_id(self) -> str:
    method full_path (line 272) | def full_path(self) -> str:
    method short_path (line 280) | def short_path(self) -> str:

FILE: gcpdiag/models_test.py
  function test_context_region_exception (line 23) | def test_context_region_exception():
  function test_context_to_string (line 29) | def test_context_to_string():
  function test_match_project_resource (line 63) | def test_match_project_resource():
  function test_generic_declaration (line 126) | def test_generic_declaration():
  function test_string_strip (line 131) | def test_string_strip():
  function test_update_method (line 137) | def test_update_method():
  function test_setdefault_existing_key (line 144) | def test_setdefault_existing_key():
  function test_setdefault_non_existing_key (line 150) | def test_setdefault_non_existing_key():

FILE: gcpdiag/product_list.py
  function get_product_list (line 7) | def get_product_list() -> Dict:

FILE: gcpdiag/queries/apigee.py
  class ApigeeEnvironment (line 32) | class ApigeeEnvironment(models.Resource):
    method __init__ (line 37) | def __init__(self, apigee_org, env_name: str):
    method full_path (line 43) | def full_path(self) -> str:
  class ApigeeOrganization (line 47) | class ApigeeOrganization(models.Resource):
    method __init__ (line 56) | def __init__(self,
    method full_path (line 65) | def full_path(self) -> str:
    method environments (line 69) | def environments(self) -> Iterable[ApigeeEnvironment]:
    method runtime_type (line 79) | def runtime_type(self) -> str:
    method runtime_database_encryption_key_name (line 85) | def runtime_database_encryption_key_name(self) -> str:
    method authorized_network (line 92) | def authorized_network(self) -> str:
    method network (line 99) | def network(self) -> network.Network:
  class EnvironmentGroup (line 119) | class EnvironmentGroup(models.Resource):
    method __init__ (line 125) | def __init__(self, apigee_org: ApigeeOrganization, resource_data):
    method name (line 131) | def name(self) -> str:
    method full_path (line 135) | def full_path(self) -> str:
    method host_names (line 139) | def host_names(self) -> List[str]:
  class ApigeeInstance (line 143) | class ApigeeInstance(models.Resource):
    method __init__ (line 149) | def __init__(self, apigee_org: ApigeeOrganization, resource_data):
    method name (line 155) | def name(self) -> str:
    method full_path (line 159) | def full_path(self) -> str:
    method disk_encryption_key_name (line 163) | def disk_encryption_key_name(self) -> str:
    method host (line 167) | def host(self) -> str:
    method location (line 171) | def location(self) -> str:
  function get_org (line 176) | def get_org(context: models.Context) -> Optional[ApigeeOrganization]:
  function get_envgroups (line 203) | def get_envgroups(
  function get_envgroups_attachments (line 221) | def get_envgroups_attachments(envgroup_name: str) -> List[str]:
  function get_instances (line 238) | def get_instances(
  function get_instances_attachments (line 259) | def get_instances_attachments(instance_name: str) -> List[str]:
  function get_network_bridge_instance_groups (line 277) | def get_network_bridge_instance_groups(

FILE: gcpdiag/queries/apigee_stub.py
  class ApigeeApiStub (line 30) | class ApigeeApiStub:
    method __init__ (line 33) | def __init__(self, project_id=DUMMY_PROJECT_ID):
    method organizations (line 36) | def organizations(self):
  class ApigeeOraganizationsApiStub (line 40) | class ApigeeOraganizationsApiStub(ApigeeApiStub):
    method list (line 43) | def list(self, parent):
    method get (line 46) | def get(self, name):
    method envgroups (line 49) | def envgroups(self):
    method instances (line 52) | def instances(self):
  class ApigeeEnvgroupsApiStub (line 56) | class ApigeeEnvgroupsApiStub(ApigeeApiStub):
    method list (line 59) | def list(self, parent):
    method attachments (line 65) | def attachments(self):
    method list_next (line 68) | def list_next(self, previous_request, previous_response):
  class ApigeeInstancesApiStub (line 72) | class ApigeeInstancesApiStub(ApigeeApiStub):
    method list (line 75) | def list(self, parent):
    method attachments (line 81) | def attachments(self):
    method list_next (line 84) | def list_next(self, previous_request, previous_response):
  class ApigeeEnvGroupsAttachmentsApiStub (line 88) | class ApigeeEnvGroupsAttachmentsApiStub(ApigeeApiStub):
    method list (line 91) | def list(self, parent):
    method list_next (line 100) | def list_next(self, previous_request, previous_response):
  class ApigeeInstancesAttachmentsApiStub (line 104) | class ApigeeInstancesAttachmentsApiStub(ApigeeApiStub):
    method list (line 107) | def list(self, parent):
    method list_next (line 116) | def list_next(self, previous_request, previous_response):

FILE: gcpdiag/queries/apigee_test.py
  class TestOrganization (line 43) | class TestOrganization:
    method test_get_org (line 46) | def test_get_org(self):
    method test_get_envgroups (line 60) | def test_get_envgroups(self):
    method test_get_envgroups_attachments (line 71) | def test_get_envgroups_attachments(self):
    method test_get_instances (line 76) | def test_get_instances(self):
    method test_get_instances_attachments (line 87) | def test_get_instances_attachments(self):
    method test_get_network_bridge_instance_groups (line 92) | def test_get_network_bridge_instance_groups(self):

FILE: gcpdiag/queries/apis.py
  function _auth_method (line 43) | def _auth_method():
  function _get_credentials_adc (line 59) | def _get_credentials_adc():
  function _get_credentials_key (line 71) | def _get_credentials_key():
  function set_credentials (line 82) | def set_credentials(cred_json):
  function get_credentials (line 91) | def get_credentials():
  function _get_project_or_billing_id (line 103) | def _get_project_or_billing_id(project_id: str) -> str:
  function login (line 110) | def login():
  function get_user_email (line 115) | def get_user_email() -> str:
  function get_api (line 130) | def get_api(service_name: str,
  function _list_enabled_apis (line 184) | def _list_enabled_apis(project_id: str) -> Set[str]:
  function is_enabled (line 212) | def is_enabled(project_id: str, service_name: str) -> bool:
  function is_all_enabled (line 217) | def is_all_enabled(project_id: str, services: list) -> Dict[str, str]:
  function list_services_with_state (line 228) | def list_services_with_state(project_id: str) -> Dict[str, str]:
  function verify_access (line 244) | def verify_access(project_id: str):

FILE: gcpdiag/queries/apis_stub.py
  function get_json_dir (line 209) | def get_json_dir(project_id: str):
  class ApiStub (line 213) | class ApiStub:
    method fail_next (line 221) | def fail_next(self, fail_count: int, fail_status: int = 429):
    method _maybe_raise_api_exception (line 225) | def _maybe_raise_api_exception(self):
  class RestCallStub (line 238) | class RestCallStub(ApiStub):
    method __init__ (line 241) | def __init__(self,
    method execute (line 257) | def execute(self, num_retries: int = 0) -> dict:
  class ServiceUsageApiStub (line 276) | class ServiceUsageApiStub(ApiStub):
    method __init__ (line 279) | def __init__(self, mock_state=None, project_id=None, service=None):
    method services (line 284) | def services(self):
    method list (line 288) | def list(self, parent, filter):
    method list_next (line 295) | def list_next(self, request, response):
    method get (line 298) | def get(self, name):
    method execute (line 306) | def execute(self, num_retries=0):
  function _batch_request_default_callback (line 319) | def _batch_request_default_callback(req_id, response, exception):
  class BatchRequestStub (line 324) | class BatchRequestStub(ApiStub):
    method __init__ (line 327) | def __init__(self, callback=_batch_request_default_callback):
    method add (line 331) | def add(self, request, callback=None, request_id=None):
    method execute (line 339) | def execute(self):
  function get_api_stub (line 350) | def get_api_stub(service_name: str,

FILE: gcpdiag/queries/apis_test.py
  class TestCredential (line 24) | class TestCredential:
    method test_set_credential_null (line 27) | def test_set_credential_null(self):
    method test_set_credential (line 35) | def test_set_credential(self, mock_cred):
  class Test (line 44) | class Test:
    method test_is_enabled (line 47) | def test_is_enabled(self):
    method test_is_all_enabled (line 51) | def test_is_all_enabled(self):
  class TestTPC (line 60) | class TestTPC(TestCase):
    method test_tpc_endpoint (line 65) | def test_tpc_endpoint(self, mock_build, mock_cred):
    method test_not_tpc_endpoint (line 74) | def test_not_tpc_endpoint(self, mock_build, mock_cred):
    method test_universe_mismatch (line 83) | def test_universe_mismatch(self, mock_build, mock_cred):

FILE: gcpdiag/queries/apis_utils.py
  function execute_concurrently (line 29) | def execute_concurrently(
  function _execute_with_pagination_in_api_context (line 59) | def _execute_with_pagination_in_api_context(
  function execute_concurrently_with_pagination (line 96) | def execute_concurrently_with_pagination(
  function list_all (line 116) | def list_all(request,
  function multi_list_all (line 139) | def multi_list_all(
  function batch_list_all (line 147) | def batch_list_all(api,
  function _original_batch (line 164) | def _original_batch(api,
  function should_retry (line 200) | def should_retry(resp_status):
  function get_nth_exponential_random_retry (line 208) | def get_nth_exponential_random_retry(n, random_pct, multiplier, random_f...
  function batch_execute_all (line 213) | def batch_execute_all(api, requests: list):
  function execute_single_request (line 290) | def execute_single_request(

FILE: gcpdiag/queries/apis_utils_test.py
  class RequestMock (line 27) | class RequestMock(apis_stub.ApiStub):
    method __init__ (line 30) | def __init__(self,
    method execute (line 40) | def execute(self, num_retries: int = 0):
  function next_function_mock (line 51) | def next_function_mock(previous_request, previous_response):
  function mock_sleep (line 62) | def mock_sleep(sleep_time: float):
  class Test (line 68) | class Test(unittest.TestCase):
    method test_list_all (line 70) | def test_list_all(self):
    method test_multi_list_all (line 74) | def test_multi_list_all(self):
    method test_batch_list_all (line 81) | def test_batch_list_all(self):
    method test_batch_execute_all (line 93) | def test_batch_execute_all(self):
    method test_batch_execute_all_unretriable_exception (line 103) | def test_batch_execute_all_unretriable_exception(self):
    method test_batch_execute_all_too_many_failures (line 113) | def test_batch_execute_all_too_many_failures(self):
    method test_batch_execute_all_retriable_exception (line 122) | def test_batch_execute_all_retriable_exception(self):
    method test_batch_execute_batchapi_tempfail (line 140) | def test_batch_execute_batchapi_tempfail(self):
    method test_execute_concurrently_api_server (line 157) | def test_execute_concurrently_api_server(self, mock_get_executor,
    method test_execute_concurrently_cli (line 197) | def test_execute_concurrently_cli(self, mock_batch_execute_all):
  class ExecuteConcurrentlyWithPaginationTest (line 216) | class ExecuteConcurrentlyWithPaginationTest(unittest.TestCase):
    method setUp (line 219) | def setUp(self):
    method test_cli_context_uses_batch_list_all (line 228) | def test_cli_context_uses_batch_list_all(self, mock_batch_list_all):
    method test_api_context_single_page (line 249) | def test_api_context_single_page(self, mock_execute_concurrently):
    method test_api_context_multi_page (line 273) | def test_api_context_multi_page(self, mock_execute_concurrently):
    method test_api_context_skips_404 (line 308) | def test_api_context_skips_404(self, mock_execute_concurrently):
    method test_api_context_raises_other_error (line 332) | def test_api_context_raises_other_error(self, mock_execute_concurrently):

FILE: gcpdiag/queries/artifact_registry.py
  class ArtifactRegistryIAMPolicy (line 25) | class ArtifactRegistryIAMPolicy(iam.BaseIAMPolicy):
    method _is_resource_permission (line 27) | def _is_resource_permission(self, permission):
  class ProjectSettings (line 32) | class ProjectSettings:
  function get_registry_iam_policy (line 37) | def get_registry_iam_policy(context: models.Context, location: str,
  function get_project_settings (line 50) | def get_project_settings(project_id: str) -> ProjectSettings:

FILE: gcpdiag/queries/artifact_registry_stub.py
  class ArtifactRegistryApiStub (line 31) | class ArtifactRegistryApiStub:
    method projects (line 34) | def projects(self):
    method locations (line 37) | def locations(self):
    method repositories (line 40) | def repositories(self):
    method getIamPolicy (line 43) | def getIamPolicy(self, resource: str) -> apis_stub.RestCallStub:
    method getProjectSettings (line 52) | def getProjectSettings(self, name: str) -> apis_stub.RestCallStub:

FILE: gcpdiag/queries/artifact_registry_test.py
  class TestArtifactRegistry (line 30) | class TestArtifactRegistry:
    method test_get_bucket_iam_policy (line 33) | def test_get_bucket_iam_policy(self):
    method test_get_project_settings (line 40) | def test_get_project_settings(self):

FILE: gcpdiag/queries/bigquery.py
  function get_project_policy (line 65) | def get_project_policy(context: models.Context):
  function get_organization_policy (line 80) | def get_organization_policy(context: models.Context, organization_id: str):
  function check_permissions_for_principal (line 103) | def check_permissions_for_principal(
  function get_missing_permissions (line 117) | def get_missing_permissions(required_permissions: Set[str],
  class BigQueryTable (line 128) | class BigQueryTable:
    method __init__ (line 135) | def __init__(self, project_id: str, dataset_id: str, table_id: str):
    method table_identifier (line 141) | def table_identifier(self) -> str:
  class BigQueryRoutine (line 145) | class BigQueryRoutine:
    method __init__ (line 152) | def __init__(self, project_id: str, dataset_id: str, routine_id: str):
    method routine_identifier (line 158) | def routine_identifier(self) -> str:
  class BigQueryJob (line 162) | class BigQueryJob(models.Resource):
    method __init__ (line 169) | def __init__(
    method full_path (line 181) | def full_path(self) -> str:
    method id (line 187) | def id(self) -> str:
    method short_path (line 192) | def short_path(self) -> str:
    method user_email (line 197) | def user_email(self) -> str:
    method _job_configuration (line 201) | def _job_configuration(self) -> dict[str, Any]:
    method _query (line 205) | def _query(self) -> dict[str, Any]:
    method _stats (line 209) | def _stats(self) -> dict[str, Any]:
    method _query_stats (line 214) | def _query_stats(self) -> dict[str, Any]:
    method _query_info (line 219) | def _query_info(self) -> dict[str, Any]:
    method _status (line 223) | def _status(self) -> dict[str, Any]:
    method job_type (line 227) | def job_type(self) -> str:
    method query_sql (line 231) | def query_sql(self) -> str:
    method use_legacy_sql (line 235) | def use_legacy_sql(self) -> bool:
    method priority (line 239) | def priority(self) -> str:
    method edition (line 243) | def edition(self) -> str:
    method creation_time (line 248) | def creation_time(self) -> Optional[int]:
    method start_time (line 254) | def start_time(self) -> Optional[int]:
    method end_time (line 260) | def end_time(self) -> Optional[int]:
    method total_bytes_processed (line 266) | def total_bytes_processed(self) -> int:
    method total_bytes_billed (line 272) | def total_bytes_billed(self) -> int:
    method total_slot_ms (line 278) | def total_slot_ms(self) -> int:
    method cache_hit (line 283) | def cache_hit(self) -> bool:
    method quota_deferments (line 287) | def quota_deferments(self) -> list[str]:
    method query_plan (line 297) | def query_plan(self) -> list[dict[str, Any]]:
    method total_partitions_processed (line 302) | def total_partitions_processed(self) -> int:
    method referenced_tables (line 308) | def referenced_tables(self) -> list[BigQueryTable]:
    method referenced_routines (line 325) | def referenced_routines(self) -> list[BigQueryRoutine]:
    method num_affected_dml_rows (line 342) | def num_affected_dml_rows(self) -> int:
    method dml_stats (line 348) | def dml_stats(self) -> dict[str, int]:
    method statement_type (line 366) | def statement_type(self) -> str:
    method bi_engine_statistics (line 371) | def bi_engine_statistics(self) -> dict[str, Any]:
    method vector_search_statistics (line 391) | def vector_search_statistics(self) -> dict[str, Any]:
    method performance_insights (line 422) | def performance_insights(self) -> dict[str, Any]:
    method optimization_details (line 453) | def optimization_details(self) -> Any:
    method export_data_statistics (line 457) | def export_data_statistics(self) -> dict[str, int]:
    method load_query_statistics (line 471) | def load_query_statistics(self) -> dict[str, int]:
    method spark_statistics (line 499) | def spark_statistics(self) -> dict[str, Any]:
    method transferred_bytes (line 518) | def transferred_bytes(self) -> int:
    method reservation_id (line 524) | def reservation_id(self) -> str:
    method reservation_admin_project_id (line 529) | def reservation_admin_project_id(self) -> Optional[str]:
    method num_child_jobs (line 550) | def num_child_jobs(self) -> int:
    method parent_job_id (line 555) | def parent_job_id(self) -> str:
    method row_level_security_applied (line 560) | def row_level_security_applied(self) -> bool:
    method data_masking_applied (line 566) | def data_masking_applied(self) -> bool:
    method session_id (line 572) | def session_id(self) -> str:
    method final_execution_duration_ms (line 579) | def final_execution_duration_ms(self) -> int:
    method job_state (line 585) | def job_state(self) -> str:
    method job_error_result (line 590) | def job_error_result(self) -> dict[str, Optional[str]]:
    method job_errors (line 602) | def job_errors(self) -> list[dict[str, Optional[str]]]:
    method materialized_view_statistics (line 617) | def materialized_view_statistics(self) -> dict[str, Any]:
    method metadata_cache_statistics (line 648) | def metadata_cache_statistics(self) -> dict[str, Any]:
    method information_schema_user_email (line 673) | def information_schema_user_email(self) -> str | None:
    method information_schema_start_time_str (line 679) | def information_schema_start_time_str(self) -> str | None:
    method information_schema_end_time_str (line 685) | def information_schema_end_time_str(self) -> str | None:
    method information_schema_query (line 691) | def information_schema_query(self) -> str | None:
    method information_schema_total_modified_partitions (line 697) | def information_schema_total_modified_partitions(self) -> Union[int, s...
    method information_schema_resource_warning (line 712) | def information_schema_resource_warning(self) -> str:
    method information_schema_normalized_literals (line 727) | def information_schema_normalized_literals(self) -> str:
  function get_bigquery_job_api_resource_data (line 738) | def get_bigquery_job_api_resource_data(
  function get_information_schema_job_metadata (line 757) | def get_information_schema_job_metadata(
  function get_bigquery_job (line 850) | def get_bigquery_job(
  function _parse_value (line 908) | def _parse_value(field_schema: dict, value_data: Any) -> Any:
  function _parse_row (line 933) | def _parse_row(schema_fields: List[dict],
  function get_query_results (line 945) | def get_query_results(
  function get_bigquery_project (line 1113) | def get_bigquery_project(project_id: str) -> crm.Project:
  function get_table (line 1158) | def get_table(project_id: str, dataset_id: str,

FILE: gcpdiag/queries/bigquery_stub.py
  class GetJobRequest (line 18) | class GetJobRequest(apis_stub.ApiStub):
    method __init__ (line 21) | def __init__(self, project_id: str, location: str, job_id: str):
    method execute (line 32) | def execute(self, num_retries=0):
  class GetQueryResultsRequest (line 56) | class GetQueryResultsRequest(apis_stub.ApiStub):
    method __init__ (line 59) | def __init__(self, project_id: str, location: str, job_id: str):
    method execute (line 69) | def execute(self, num_retries=0):
  class BigQueryJobsStub (line 108) | class BigQueryJobsStub(apis_stub.ApiStub):
    method insert (line 114) | def insert(self, projectId: str, body: dict[str, Any]):
    method get (line 178) | def get(self, projectId: str, jobId: str, location: Optional[str] = No...
    method getQueryResults (line 217) | def getQueryResults(self,
    method query (line 230) | def query(self, projectId: str, body: dict[str, Any]):
  class BigQueryApiStub (line 287) | class BigQueryApiStub(apis_stub.ApiStub):
    method __init__ (line 290) | def __init__(self):
    method jobs (line 295) | def jobs(self):
    method new_batch_http_request (line 299) | def new_batch_http_request(self, callback=None):

FILE: gcpdiag/queries/bigquery_test.py
  class TestBigQueryQueries (line 30) | class TestBigQueryQueries:
    method test_get_bigquery_job1_success_and_properties (line 38) | def test_get_bigquery_job1_success_and_properties(self, mock_api_is_en...
    method test_get_query_results_success (line 73) | def test_get_query_results_success(self, mock_api_is_enabled, mock_uuid,
    method test_get_query_results_api_disabled (line 99) | def test_get_query_results_api_disabled(self, mock_api_is_enabled,
    method test_get_bigquery_job2_success (line 114) | def test_get_bigquery_job2_success(self, mock_api_is_enabled,
    method test_get_bigquery_job_returns_none_on_api_fail (line 132) | def test_get_bigquery_job_returns_none_on_api_fail(self):
    method test_get_info_schema_not_found_returns_none (line 143) | def test_get_info_schema_not_found_returns_none(self, mock_get_user_em...
    method test_get_info_schema_api_disabled (line 156) | def test_get_info_schema_api_disabled(self, mock_api_is_enabled,
    method test_get_bigquery_job_info_schema_fails (line 171) | def test_get_bigquery_job_info_schema_fails(self, mock_api_is_enabled,
    method test_get_job_api_data_not_found_raises_error (line 193) | def test_get_job_api_data_not_found_raises_error(self, mock_api_is_ena...
    method test_get_bigquery_job_info_schema_extended_fields_fail (line 209) | def test_get_bigquery_job_info_schema_extended_fields_fail(

FILE: gcpdiag/queries/billing.py
  class BillingAccount (line 31) | class BillingAccount(models.Resource):
    method full_path (line 39) | def full_path(self) -> str:
    method name (line 43) | def name(self) -> str:
    method display_name (line 47) | def display_name(self) -> str:
    method is_open (line 50) | def is_open(self) -> bool:
    method is_master (line 53) | def is_master(self) -> bool:
    method list_projects (line 56) | def list_projects(self, context) -> list:
    method __init__ (line 59) | def __init__(self, project_id, resource_data):
  class ProjectBillingInfo (line 64) | class ProjectBillingInfo(models.Resource):
    method full_path (line 72) | def full_path(self) -> str:
    method name (line 76) | def name(self) -> str:
    method project_id (line 80) | def project_id(self) -> str:
    method billing_account_name (line 84) | def billing_account_name(self) -> str:
    method is_billing_enabled (line 87) | def is_billing_enabled(self) -> bool:
    method __init__ (line 90) | def __init__(self, project_id, resource_data):
  class CostInsights (line 95) | class CostInsights(models.Resource):
    method full_path (line 99) | def full_path(self) -> str:
    method description (line 103) | def description(self) -> str:
    method anomaly_details (line 107) | def anomaly_details(self) -> dict:
    method forecasted_units (line 111) | def forecasted_units(self) -> str:
    method forecasted_currency (line 115) | def forecasted_currency(self) -> str:
    method actual_units (line 119) | def actual_units(self) -> str:
    method actual_currency (line 123) | def actual_currency(self) -> str:
    method start_time (line 127) | def start_time(self) -> str:
    method end_time (line 131) | def end_time(self) -> str:
    method anomaly_type (line 135) | def anomaly_type(self) -> str:
    method is_anomaly (line 139) | def is_anomaly(self) -> bool:
    method build_anomaly_description (line 144) | def build_anomaly_description(self):
    method __init__ (line 151) | def __init__(self, project_id, resource_data):
  function get_billing_info (line 157) | def get_billing_info(project_id) -> ProjectBillingInfo:
  function get_billing_account (line 171) | def get_billing_account(project_id: str) -> Optional[BillingAccount]:
  function get_all_billing_accounts (line 197) | def get_all_billing_accounts(project_id: str) -> Optional[List[BillingAc...
  function get_all_projects_in_billing_account (line 221) | def get_all_projects_in_billing_account(
  function get_cost_insights_for_a_project (line 257) | def get_cost_insights_for_a_project(project_id: str):

FILE: gcpdiag/queries/billing_stub.py
  class BillingApiStub (line 29) | class BillingApiStub:
    method __init__ (line 32) | def __init__(self, project_id=DUMMY_PROJECT_ID):
    method projects (line 35) | def projects(self):
    method billingAccounts (line 38) | def billingAccounts(self):
  class ProjectBillingInfo (line 42) | class ProjectBillingInfo(BillingApiStub):
    method getBillingInfo (line 45) | def getBillingInfo(self, name):
  class BillingAccountStub (line 49) | class BillingAccountStub(BillingApiStub):
    method get (line 52) | def get(self, name):
    method list (line 55) | def list(self):
    method list_next (line 58) | def list_next(self, previous_request, previous_response):
    method projects (line 61) | def projects(self):
  class BillingAccountProjectsStub (line 65) | class BillingAccountProjectsStub(BillingApiStub):
    method list (line 68) | def list(self, name):
    method list_next (line 72) | def list_next(self, previous_request, previous_response):
  class RecommenderBillingApiStub (line 76) | class RecommenderBillingApiStub:
    method __init__ (line 79) | def __init__(self, project_id=DUMMY_PROJECT_ID):
    method locations (line 82) | def locations(self):
    method insightTypes (line 85) | def insightTypes(self):
    method insights (line 88) | def insights(self):
    method get (line 91) | def get(self, name):
    method list (line 94) | def list(self, parent):
    method list_next (line 97) | def list_next(self, previous_request, previous_response):

FILE: gcpdiag/queries/billing_test.py
  class TestBilling (line 42) | class TestBilling:
    method test_get_billing_account (line 45) | def test_get_billing_account(self):
    method test_get_all_billing_accounts (line 55) | def test_get_all_billing_accounts(self):
    method test_get_all_projects_in_billing_account (line 62) | def test_get_all_projects_in_billing_account(self):
    method test_get_billing_info (line 71) | def test_get_billing_info(self):
    method test_get_cost_insights_for_a_project (line 80) | def test_get_cost_insights_for_a_project(self):

FILE: gcpdiag/queries/cloudasset.py
  class AssetResource (line 28) | class AssetResource(models.Resource):
    method __init__ (line 32) | def __init__(self, project_id, resource_data):
    method name (line 37) | def name(self) -> str:
    method full_path (line 45) | def full_path(self) -> str:
    method asset_type (line 49) | def asset_type(self) -> str:
  function search_all_resources (line 54) | def search_all_resources(

FILE: gcpdiag/queries/cloudasset_stub.py
  class CloudAssetApiStub (line 25) | class CloudAssetApiStub(apis_stub.ApiStub):
    method v1 (line 28) | def v1(self):
    method searchAllResources (line 32) | def searchAllResources(self, scope, assetTypes=None, query=None):

FILE: gcpdiag/queries/cloudasset_test.py
  class TestCloudAsset (line 28) | class TestCloudAsset:
    method test_search_all_resources (line 31) | def test_search_all_resources(self):

FILE: gcpdiag/queries/cloudrun.py
  class Service (line 28) | class Service(models.Resource):
    method __init__ (line 32) | def __init__(self, project_id, resource_data):
    method name (line 37) | def name(self) -> str:
    method id (line 45) | def id(self) -> str:
    method full_path (line 49) | def full_path(self) -> str:
    method conditions (line 53) | def conditions(self) -> Dict[str, 'ServiceCondition']:
    method short_path (line 60) | def short_path(self) -> str:
  class ServiceCondition (line 65) | class ServiceCondition:
    method __init__ (line 69) | def __init__(self, resource_data):
    method message (line 73) | def message(self) -> str:
  function get_all_locations (line 77) | def get_all_locations(project_id: str) -> Iterable[str]:
  function get_services (line 107) | def get_services(context: models.Context) -> Mapping[str, Service]:
  function get_service (line 154) | def get_service(project_id: str, region: str, service_name: str) -> Serv...

FILE: gcpdiag/queries/cloudrun_stub.py
  class CloudRunApiStub (line 31) | class CloudRunApiStub:
    method projects (line 34) | def projects(self):
    method locations (line 37) | def locations(self):
    method services (line 40) | def services(self):
    method list (line 43) | def list(self, **args):
    method get (line 52) | def get(self, name):
  class GetServiceRequest (line 56) | class GetServiceRequest:
    method __init__ (line 59) | def __init__(self, name: str):
    method execute (line 62) | def execute(self, num_retries=0):

FILE: gcpdiag/queries/cloudrun_test.py
  class TestCloudRun (line 27) | class TestCloudRun:
    method test_get_services (line 30) | def test_get_services(self):
    method test_get_service (line 36) | def test_get_service(self):

FILE: gcpdiag/queries/cloudsql.py
  class Instance (line 25) | class Instance(models.Resource):
    method __init__ (line 29) | def __init__(self, project_id: str, resource_data: dict):
    method name (line 34) | def name(self) -> str:
    method state (line 38) | def state(self) -> str:
    method version (line 42) | def version(self) -> str:
    method is_regional (line 46) | def is_regional(self) -> bool:
    method ip_addresses (line 51) | def ip_addresses(self) -> Iterable[network.IPv4AddrOrIPv6Addr]:
    method has_public_ip (line 58) | def has_public_ip(self) -> bool:
    method has_maint_window (line 63) | def has_maint_window(self) -> int:
    method is_storage_auto_resize_enabled (line 71) | def is_storage_auto_resize_enabled(self) -> bool:
    method has_del_protection (line 75) | def has_del_protection(self) -> bool:
    method authorizednetworks (line 80) | def authorizednetworks(self) -> List[str]:
    method is_publically_accessible (line 89) | def is_publically_accessible(self) -> List[str]:
    method is_automated_backup_enabled (line 93) | def is_automated_backup_enabled(self) -> bool:
    method is_suspended_state (line 98) | def is_suspended_state(self) -> bool:
    method is_shared_core (line 102) | def is_shared_core(self) -> bool:
    method is_high_available (line 108) | def is_high_available(self) -> bool:
    method flags (line 113) | def flags(self) -> dict:
    method is_log_output_configured_as_table (line 118) | def is_log_output_configured_as_table(self) -> bool:
    method self_link (line 122) | def self_link(self) -> str:
    method full_path (line 126) | def full_path(self) -> str:
    method __str__ (line 129) | def __str__(self) -> str:
  function get_instances (line 134) | def get_instances(context: models.Context) -> Iterable[Instance]:

FILE: gcpdiag/queries/cloudsql_stub.py
  class CloudSQLApiStub (line 24) | class CloudSQLApiStub:
    method instances (line 27) | def instances(self):
    method list (line 31) | def list(self, project):

FILE: gcpdiag/queries/cloudsql_test.py
  class TestCloudSQL (line 27) | class TestCloudSQL:
    method test_get_instances (line 30) | def test_get_instances(self):
    method test_docker_bridge_ip_addresses (line 35) | def test_docker_bridge_ip_addresses(self):

FILE: gcpdiag/queries/composer.py
  class Environment (line 28) | class Environment(models.Resource):
    method __init__ (line 32) | def __init__(self, project_id: str, resource_data: dict):
    method num_schedulers (line 39) | def num_schedulers(self) -> int:
    method worker_cpu (line 45) | def worker_cpu(self) -> float:
    method worker_memory_gb (line 50) | def worker_memory_gb(self) -> float:
    method worker_max_count (line 55) | def worker_max_count(self) -> int:
    method worker_concurrency (line 60) | def worker_concurrency(self) -> float:
    method parallelism (line 75) | def parallelism(self) -> float:
    method composer_version (line 79) | def composer_version(self) -> str:
    method airflow_version (line 85) | def airflow_version(self) -> str:
    method is_composer2 (line 91) | def is_composer2(self) -> bool:
    method full_path (line 95) | def full_path(self) -> str:
    method state (line 99) | def state(self) -> str:
    method image_version (line 103) | def image_version(self) -> str:
    method short_path (line 107) | def short_path(self) -> str:
    method airflow_config_overrides (line 111) | def airflow_config_overrides(self) -> dict:
    method service_account (line 116) | def service_account(self) -> str:
    method parse_full_path (line 125) | def parse_full_path(self) -> Tuple[str, str]:
    method __str__ (line 132) | def __str__(self) -> str:
    method is_private_ip (line 135) | def is_private_ip(self) -> bool:
    method gke_cluster (line 140) | def gke_cluster(self) -> str:
  function _query_region_envs (line 153) | def _query_region_envs(region, api, project_id):
  function _query_regions_envs (line 162) | def _query_regions_envs(regions, api, project_id, context: models.Context):
  function get_environments (line 172) | def get_environments(context: models.Context) -> Iterable[Environment]:

FILE: gcpdiag/queries/composer_stub.py
  class ComposerApiStub (line 26) | class ComposerApiStub:
    method projects (line 29) | def projects(self):
    method locations (line 32) | def locations(self):
    method environments (line 35) | def environments(self):
    method list (line 39) | def list(self, parent):

FILE: gcpdiag/queries/composer_test.py
  class TestComposer (line 27) | class TestComposer:
    method test_get_environments (line 30) | def test_get_environments(self):
    method test_service_account (line 35) | def test_service_account(self):
    method test_is_private_ip (line 45) | def test_is_private_ip(self):

FILE: gcpdiag/queries/crm.py
  class Project (line 28) | class Project(models.Resource):
    method __init__ (line 38) | def __init__(self, resource_data):
    method number (line 48) | def number(self) -> int:
    method id (line 52) | def id(self) -> str:
    method name (line 57) | def name(self) -> str:
    method full_path (line 61) | def full_path(self) -> str:
    method short_path (line 65) | def short_path(self) -> str:
    method default_compute_service_account (line 69) | def default_compute_service_account(self) -> str:
    method parent (line 73) | def parent(self) -> str:
  function get_project (line 78) | def get_project(project_id: str) -> Project:
  function get_all_projects_in_parent (line 131) | def get_all_projects_in_parent(project_id: str) -> List[ProjectBillingIn...
  class Organization (line 169) | class Organization(models.Resource):
    method __init__ (line 177) | def __init__(self, project_id, resource_data):
    method id (line 182) | def id(self) -> str:
    method name (line 188) | def name(self) -> str:
    method full_path (line 193) | def full_path(self) -> str:
    method short_path (line 197) | def short_path(self) -> str:
  function get_organization (line 202) | def get_organization(project_id: str,

FILE: gcpdiag/queries/crm_stub.py
  class CrmApiStub (line 30) | class CrmApiStub:
    method new_batch_http_request (line 36) | def new_batch_http_request(self):
    method projects (line 39) | def projects(self):
    method organizations (line 42) | def organizations(self):
    method list (line 46) | def list(self, parent=None, page_token=None, filter=None):
    method list_next (line 50) | def list_next(self, previous_request, previous_response):
    method search (line 53) | def search(self, query=None):
    method search_next (line 56) | def search_next(self, previous_request, previous_response):
    method get (line 60) | def get(self, project_id=None, name=None):
    method getAncestry (line 67) | def getAncestry(self, projectId='gcpdiag-bigquery1-aaaa', project_id=N...
    method getIamPolicy (line 75) | def getIamPolicy(self, resource):
    method getEffectiveOrgPolicy (line 81) | def getEffectiveOrgPolicy(self, resource, body):
    method listOrgPolicies (line 95) | def listOrgPolicies(self, resource):
    method listOrgPolicies_next (line 102) | def listOrgPolicies_next(self, previous_request, previous_response):

FILE: gcpdiag/queries/crm_test.py
  function get_cache_stub (line 28) | def get_cache_stub():
  class Test (line 35) | class Test:
    method test_get_project (line 38) | def test_get_project(self):

FILE: gcpdiag/queries/dataflow.py
  class Job (line 22) | class Job(models.Resource):
    method __init__ (line 39) | def __init__(self, project_id: str, resource_data: dict):
    method full_path (line 44) | def full_path(self) -> str:
    method id (line 48) | def id(self) -> str:
    method state (line 52) | def state(self) -> str:
    method job_type (line 56) | def job_type(self) -> str:
    method location (line 60) | def location(self) -> str:
    method sdk_support_status (line 64) | def sdk_support_status(self) -> str:
    method sdk_language (line 68) | def sdk_language(self) -> str:
    method minutes_in_current_state (line 73) | def minutes_in_current_state(self) -> int:
  function get_region_dataflow_jobs (line 80) | def get_region_dataflow_jobs(api, context: models.Context,
  function get_all_dataflow_jobs (line 107) | def get_all_dataflow_jobs(context: models.Context) -> List[Job]:
  function get_job (line 129) | def get_job(project_id: str, job: str, region: str) -> Union[Job, None]:
  function get_all_dataflow_jobs_for_project (line 147) | def get_all_dataflow_jobs_for_project(
  function logs_excluded (line 173) | def logs_excluded(project_id: str) -> Union[bool, None]:

FILE: gcpdiag/queries/dataflow_stub.py
  class DataflowApiStub (line 6) | class DataflowApiStub(apis_stub.ApiStub):
    method projects (line 9) | def projects(self):
    method locations (line 12) | def locations(self):
    method jobs (line 15) | def jobs(self):
  class DataflowJobsStub (line 19) | class DataflowJobsStub:
    method list (line 23) | def list(self, projectId, location):
    method list_next (line 28) | def list_next(self, previous_request, previous_response):
    method get (line 32) | def get(self, projectId, location, jobId):
    method aggregated (line 36) | def aggregated(
    method aggregated_next (line 42) | def aggregated_next(self, previous_request, previous_response):

FILE: gcpdiag/queries/dataflow_test.py
  class TestDataFlow (line 13) | class TestDataFlow(unittest.TestCase):
    method test_get_jobs (line 16) | def test_get_jobs(self):
    method test_get_jobs_with_id (line 22) | def test_get_jobs_with_id(self):
    method test_get_jobs_for_project (line 34) | def test_get_jobs_for_project(self):

FILE: gcpdiag/queries/datafusion.py
  class Instance (line 37) | class Instance(models.Resource):
    method __init__ (line 45) | def __init__(self, project_id, resource_data):
    method full_path (line 50) | def full_path(self) -> str:
    method short_path (line 59) | def short_path(self) -> str:
    method name (line 67) | def name(self) -> str:
    method location (line 72) | def location(self) -> str:
    method zone (line 77) | def zone(self) -> str:
    method type (line 81) | def type(self) -> str:
    method is_basic_type (line 85) | def is_basic_type(self) -> bool:
    method is_enterprise_type (line 89) | def is_enterprise_type(self) -> bool:
    method is_developer_type (line 93) | def is_developer_type(self) -> bool:
    method is_private (line 97) | def is_private(self) -> bool:
    method status (line 103) | def status(self) -> str:
    method status_details (line 107) | def status_details(self) -> Optional[str]:
    method is_running (line 113) | def is_running(self) -> bool:
    method is_deleting (line 117) | def is_deleting(self) -> bool:
    method version (line 121) | def version(self) -> Version:
    method api_service_agent (line 125) | def api_service_agent(self) -> str:
    method dataproc_service_account (line 129) | def dataproc_service_account(self) -> str:
    method tenant_project_id (line 136) | def tenant_project_id(self) -> str:
    method uses_shared_vpc (line 140) | def uses_shared_vpc(self) -> bool:
    method network (line 155) | def network(self) -> network.Network:
    method tp_ipv4_cidr (line 180) | def tp_ipv4_cidr(self) -> Optional[IPv4NetOrIPv6Net]:
    method api_endpoint (line 187) | def api_endpoint(self) -> str:
  function get_instances (line 192) | def get_instances(context: models.Context) -> Mapping[str, Instance]:
  function extract_support_datafusion_version (line 235) | def extract_support_datafusion_version() -> Dict[str, str]:
  class Profile (line 289) | class Profile(models.Resource):
    method __init__ (line 294) | def __init__(self, project_id, instance_name, resource_data):
    method full_path (line 300) | def full_path(self) -> str:
    method short_path (line 309) | def short_path(self) -> str:
    method name (line 318) | def name(self) -> str:
    method region (line 322) | def region(self) -> str:
    method status (line 329) | def status(self) -> str:
    method scope (line 333) | def scope(self) -> str:
    method is_dataproc_provisioner (line 337) | def is_dataproc_provisioner(self) -> bool:
    method is_existing_dataproc_provisioner (line 341) | def is_existing_dataproc_provisioner(self) -> bool:
    method autoscaling_enabled (line 345) | def autoscaling_enabled(self) -> bool:
    method image_version (line 353) | def image_version(self) -> str:
    method auto_scaling_policy (line 360) | def auto_scaling_policy(self) -> str:
  function get_instance_system_compute_profile (line 368) | def get_instance_system_compute_profile(
  function get_instance_user_compute_profile (line 386) | def get_instance_user_compute_profile(context: models.Context,
  function extract_datafusion_dataproc_version (line 409) | def extract_datafusion_dataproc_version() -> Dict[str, list[str]]:
  class Preference (line 458) | class Preference(models.Resource):
    method __init__ (line 463) | def __init__(self, project_id, instance, resource_data):
    method full_path (line 469) | def full_path(self) -> str:
    method image_version (line 477) | def image_version(self):
  function get_system_preferences (line 482) | def get_system_preferences(context: models.Context,
  function get_namespace_preferences (line 492) | def get_namespace_preferences(context: models.Context,
  function get_application_preferences (line 512) | def get_application_preferences(context: models.Context,

FILE: gcpdiag/queries/datafusion_stub.py
  class DataFusionApiStub (line 28) | class DataFusionApiStub(apis_stub.ApiStub):
    method __init__ (line 31) | def __init__(self, mock_state='init', region=None):
    method projects (line 35) | def projects(self):
    method locations (line 38) | def locations(self):
    method instances (line 41) | def instances(self):
    method list (line 44) | def list(self, parent):

FILE: gcpdiag/queries/datafusion_test.py
  class TestDataFusion (line 55) | class TestDataFusion:
    method test_get_instances (line 58) | def test_get_instances(self):
    method test_running (line 63) | def test_running(self):
    method test_is_private_ip (line 69) | def test_is_private_ip(self):
  class TestExtractVersionPolicyDict (line 77) | class TestExtractVersionPolicyDict:
    method test_extract_support_datafusion_version (line 80) | def test_extract_support_datafusion_version(self):
    method test_extract_datafusion_dataproc_version (line 84) | def test_extract_datafusion_dataproc_version(self):
  class TestComputeProfile (line 92) | class TestComputeProfile:
    method test_get_instance_system_compute_profile (line 95) | def test_get_instance_system_compute_profile(self):
    method test_get_instance_user_compute_profile (line 102) | def test_get_instance_user_compute_profile(self):
  class TestPreferences (line 113) | class TestPreferences:
    method test_get_system_preferences (line 116) | def test_get_system_preferences(self):
    method test_get_application_preferences (line 123) | def test_get_application_preferences(self):
    method test_get_namespace_preferences (line 130) | def test_get_namespace_preferences(self):

FILE: gcpdiag/queries/dataproc.py
  class Cluster (line 28) | class Cluster(models.Resource):
    method __init__ (line 34) | def __init__(self, name: str, project_id: str, resource_data: Mapping):
    method is_running (line 39) | def is_running(self) -> bool:
    method get_software_property (line 42) | def get_software_property(self, property_name) -> str:
    method is_stackdriver_logging_enabled (line 46) | def is_stackdriver_logging_enabled(self) -> bool:
    method is_stackdriver_monitoring_enabled (line 53) | def is_stackdriver_monitoring_enabled(self) -> bool:
    method region (line 58) | def region(self) -> str:
    method zone (line 67) | def zone(self) -> Optional[str]:
    method full_path (line 77) | def full_path(self) -> str:
    method short_path (line 83) | def short_path(self) -> str:
    method status (line 87) | def status(self) -> str:
    method __str__ (line 90) | def __str__(self) -> str:
    method cluster_uuid (line 94) | def cluster_uuid(self) -> str:
    method image_version (line 98) | def image_version(self):
    method vm_service_account_email (line 102) | def vm_service_account_email(self):
    method is_custom_gcs_connector (line 109) | def is_custom_gcs_connector(self) -> bool:
    method cluster_provided_bq_connector (line 115) | def cluster_provided_bq_connector(self):
    method is_gce_cluster (line 138) | def is_gce_cluster(self) -> bool:
    method gce_network_uri (line 142) | def gce_network_uri(self) -> Optional[str]:
    method gce_subnetwork_uri (line 157) | def gce_subnetwork_uri(self) -> Optional[str]:
    method is_single_node_cluster (line 172) | def is_single_node_cluster(self) -> bool:
    method is_ha_cluster (line 179) | def is_ha_cluster(self) -> bool:
    method is_internal_ip_only (line 186) | def is_internal_ip_only(self) -> bool:
    method has_autoscaling_policy (line 195) | def has_autoscaling_policy(self) -> bool:
    method autoscaling_policy_id (line 200) | def autoscaling_policy_id(self) -> str:
    method number_of_primary_workers (line 210) | def number_of_primary_workers(self) -> float:
    method number_of_secondary_workers (line 216) | def number_of_secondary_workers(self) -> float:
    method is_preemptible_primary_workers (line 222) | def is_preemptible_primary_workers(self) -> bool:
    method is_preemptible_secondary_workers (line 228) | def is_preemptible_secondary_workers(self) -> bool:
    method initialization_actions (line 234) | def initialization_actions(self) -> List[str]:
  class Region (line 238) | class Region:
    method __init__ (line 244) | def __init__(self, project_id: str, region: str):
    method get_clusters (line 248) | def get_clusters(self, context: models.Context) -> Iterable[Cluster]:
    method query_api (line 262) | def query_api(self) -> Iterable[dict]:
  class Dataproc (line 278) | class Dataproc:
    method __init__ (line 283) | def __init__(self, project_id: str):
    method get_regions (line 286) | def get_regions(self) -> Iterable[Region]:
    method is_api_enabled (line 292) | def is_api_enabled(self) -> bool:
  function get_clusters (line 297) | def get_clusters(context: models.Context) -> Iterable[Cluster]:
  function get_cluster (line 310) | def get_cluster(cluster_name, region, project) -> Optional[Cluster]:
  class AutoScalingPolicy (line 324) | class AutoScalingPolicy(models.Resource):
    method __init__ (line 329) | def __init__(self, project_id, resource_data, region):
    method policy_id (line 335) | def policy_id(self) -> str:
    method full_path (line 339) | def full_path(self) -> str:
    method short_path (line 343) | def short_path(self) -> str:
    method name (line 347) | def name(self) -> str:
    method scale_down_factor (line 351) | def scale_down_factor(self) -> float:
    method has_graceful_decommission_timeout (line 356) | def has_graceful_decommission_timeout(self) -> bool:
    method graceful_decommission_timeout (line 365) | def graceful_decommission_timeout(self) -> float:
  function get_auto_scaling_policy (line 373) | def get_auto_scaling_policy(project_id: str, region: str,
  function list_auto_scaling_policies (line 388) | def list_auto_scaling_policies(project_id: str,
  class Job (line 405) | class Job(models.Resource):
    method __init__ (line 410) | def __init__(self, project_id, job_id, region, resource_data):
    method full_path (line 417) | def full_path(self) -> str:
    method short_path (line 422) | def short_path(self) -> str:
    method cluster_name (line 426) | def cluster_name(self) -> str:
    method cluster_uuid (line 430) | def cluster_uuid(self) -> str:
    method state (line 434) | def state(self):
    method details (line 438) | def details(self):
    method status_history (line 444) | def status_history(self):
    method yarn_applications (line 454) | def yarn_applications(self):
    method driver_output_resource_uri (line 458) | def driver_output_resource_uri(self):
    method job_uuid (line 462) | def job_uuid(self):
    method job_provided_bq_connector (line 466) | def job_provided_bq_connector(self):
  function get_job_by_jobid (line 483) | def get_job_by_jobid(project_id: str, region: str, job_id: str):
  function extract_dataproc_supported_version (line 496) | def extract_dataproc_supported_version() -> list[str]:
  function extract_dataproc_bigquery_version (line 532) | def extract_dataproc_bigquery_version(image_version) -> list[str]:

FILE: gcpdiag/queries/dataproc_stub.py
  class DataprocApiStub (line 28) | class DataprocApiStub(apis_stub.ApiStub):
    method __init__ (line 31) | def __init__(self, json_basename=None, project_id=None, mock_state='in...
    method projects (line 36) | def projects(self):
    method regions (line 39) | def regions(self):
    method clusters (line 42) | def clusters(self):
    method jobs (line 45) | def jobs(self):
    method autoscalingPolicies (line 48) | def autoscalingPolicies(self):
    method get (line 51) | def get(self, name='', clusterName='', region='', projectId='', jobId=...
    method list (line 76) | def list(self, projectId, region):
    method execute (line 83) | def execute(self, num_retries=0):

FILE: gcpdiag/queries/dataproc_test.py
  class TestDataproc (line 30) | class TestDataproc:
    method test_get_clusters (line 33) | def test_get_clusters(self):
    method test_get_cluster (line 38) | def test_get_cluster(self):
    method test_is_running (line 42) | def test_is_running(self):
    method test_stackdriver_logging_enabled (line 47) | def test_stackdriver_logging_enabled(self):
    method test_monitoring_enabled (line 61) | def test_monitoring_enabled(self):
    method test_zone (line 71) | def test_zone(self):
    method test_is_gce_cluster (line 78) | def test_is_gce_cluster(self):
    method test_gce_network_uri (line 85) | def test_gce_network_uri(self):
    method test_auto_scaling_policy (line 93) | def test_auto_scaling_policy(self):
    method test_get_job_by_jobid_ (line 101) | def test_get_job_by_jobid_(self):

FILE: gcpdiag/queries/dns.py
  function find_dns_records (line 24) | def find_dns_records(domain: str) -> Set:

FILE: gcpdiag/queries/dns_stub.py
  function find_dns_records (line 14) | def find_dns_records(domain: str) -> Set:

FILE: gcpdiag/queries/gae.py
  class Service (line 28) | class Service(models.Resource):
    method __init__ (line 32) | def __init__(self, project_id, resource_data):
    method name (line 37) | def name(self) -> str:
    method id (line 45) | def id(self) -> str:
    method full_path (line 49) | def full_path(self) -> str:
    method short_path (line 53) | def short_path(self) -> str:
  class Version (line 58) | class Version(models.Resource):
    method __init__ (line 63) | def __init__(self, project_id, resource_data):
    method id (line 68) | def id(self) -> str:
    method full_path (line 72) | def full_path(self) -> str:
    method short_path (line 76) | def short_path(self) -> str:
    method runtime (line 81) | def runtime(self) -> str:
    method env (line 85) | def env(self) -> str:
  function get_services (line 90) | def get_services(context: models.Context) -> Mapping[str, Service]:
  function get_versions (line 125) | def get_versions(context: models.Context) -> Mapping[str, Version]:

FILE: gcpdiag/queries/gae_stub.py
  class AppEngineApiStub (line 27) | class AppEngineApiStub(apis_stub.ApiStub):
    method __init__ (line 30) | def __init__(self, mock_state='init'):
    method apps (line 33) | def apps(self):
    method services (line 36) | def services(self):
    method versions (line 39) | def versions(self):
    method list (line 42) | def list(self, appsId='appsId', servicesId='servicesId'):

FILE: gcpdiag/queries/gae_test.py
  class TestAppEngine (line 27) | class TestAppEngine:
    method test_get_services (line 30) | def test_get_services(self):
    method test_get_versions (line 35) | def test_get_versions(self):

FILE: gcpdiag/queries/gcb.py
  class BuildOptions (line 62) | class BuildOptions:
    method is_bucket_streaming_enabled (line 67) | def is_bucket_streaming_enabled(self) -> bool:
  class BuildOptionsBuilder (line 72) | class BuildOptionsBuilder:
    method __init__ (line 75) | def __init__(self, options: dict):
    method build (line 78) | def build(self) -> BuildOptions:
    method _get_logging (line 84) | def _get_logging(self) -> str:
    method _get_log_streaming_option (line 87) | def _get_log_streaming_option(self) -> str:
  class FailureInfo (line 92) | class FailureInfo:
  class FailureInfoBuilder (line 97) | class FailureInfoBuilder:
    method __init__ (line 100) | def __init__(self, failure_info: dict):
    method build (line 103) | def build(self) -> FailureInfo:
    method _get_failure_type (line 106) | def _get_failure_type(self) -> str:
  class Build (line 110) | class Build(models.Resource):
    method __init__ (line 114) | def __init__(self, project_id, location, resource_data):
    method id (line 120) | def id(self) -> str:
    method full_path (line 124) | def full_path(self) -> str:
    method short_path (line 128) | def short_path(self) -> str:
    method status (line 133) | def status(self) -> str:
    method service_account (line 137) | def service_account(self) -> Optional[str]:
    method images (line 141) | def images(self) -> List[str]:
    method logs_bucket (line 145) | def logs_bucket(self) -> str:
    method options (line 149) | def options(self) -> BuildOptions:
    method failure_info (line 153) | def failure_info(self) -> FailureInfo:
  class Trigger (line 158) | class Trigger(models.Resource):
    method __init__ (line 162) | def __init__(self, project_id, resource_data):
    method name (line 167) | def name(self) -> str:
    method id (line 173) | def id(self) -> str:
    method full_path (line 177) | def full_path(self) -> str:
    method short_path (line 181) | def short_path(self) -> str:
  function get_builds (line 187) | def get_builds(context: models.Context) -> Mapping[str, Build]:
  function get_triggers (line 240) | def get_triggers(context: models.Context) -> Mapping[str, Trigger]:

FILE: gcpdiag/queries/gcb_stub.py
  class CloudBuildApiStub (line 28) | class CloudBuildApiStub:
    method new_batch_http_request (line 31) | def new_batch_http_request(self):
    method projects (line 34) | def projects(self):
    method locations (line 37) | def locations(self):
    method builds (line 40) | def builds(self):
    method triggers (line 43) | def triggers(self):
  class CloudBuildBuildsApiStub (line 47) | class CloudBuildBuildsApiStub:
    method list (line 51) | def list(self, parent, filter):
  class CloudBuildTriggersApiStub (line 67) | class CloudBuildTriggersApiStub:
    method list (line 70) | def list(self, parent):

FILE: gcpdiag/queries/gcb_test.py
  class TestCloudBuild (line 35) | class TestCloudBuild:
    method test_get_builds (line 38) | def test_get_builds(self):
    method test_build_service_account (line 48) | def test_build_service_account(self):
    method test_build_images (line 55) | def test_build_images(self):
    method test_build_failure_info (line 61) | def test_build_failure_info(self):
    method test_build_options (line 70) | def test_build_options(self):

FILE: gcpdiag/queries/gce.py
  class InstanceTemplate (line 39) | class InstanceTemplate(models.Resource):
    method __init__ (line 44) | def __init__(self, project_id, resource_data):
    method self_link (line 49) | def self_link(self) -> str:
    method full_path (line 53) | def full_path(self) -> str:
    method short_path (line 62) | def short_path(self) -> str:
    method name (line 67) | def name(self) -> str:
    method tags (line 71) | def tags(self) -> List[str]:
    method service_account (line 75) | def service_account(self) -> Optional[str]:
    method network (line 86) | def network(self) -> network_q.Network:
    method subnetwork (line 91) | def subnetwork(self) -> network_q.Subnetwork:
    method get_metadata (line 96) | def get_metadata(self, key: str) -> str:
  class InstanceGroup (line 103) | class InstanceGroup(models.Resource):
    method __init__ (line 108) | def __init__(self, project_id, resource_data):
    method full_path (line 113) | def full_path(self) -> str:
    method short_path (line 124) | def short_path(self) -> str:
    method self_link (line 129) | def self_link(self) -> str:
    method name (line 133) | def name(self) -> str:
    method named_ports (line 137) | def named_ports(self) -> List[dict]:
    method has_named_ports (line 142) | def has_named_ports(self) -> bool:
  class ManagedInstanceGroup (line 148) | class ManagedInstanceGroup(models.Resource):
    method __init__ (line 154) | def __init__(self, project_id, resource_data):
    method full_path (line 160) | def full_path(self) -> str:
    method short_path (line 171) | def short_path(self) -> str:
    method is_gke (line 175) | def is_gke(self) -> bool:
    method self_link (line 189) | def self_link(self) -> str:
    method name (line 193) | def name(self) -> str:
    method region (line 197) | def region(self) -> str:
    method zone (line 219) | def zone(self) -> Optional[str]:
    method count_no_action_instances (line 228) | def count_no_action_instances(self) -> int:
    method is_instance_member (line 232) | def is_instance_member(self, project_id: str, region: str,
    method template (line 239) | def template(self) -> InstanceTemplate:
    method version_target_reached (line 260) | def version_target_reached(self) -> bool:
    method get (line 264) | def get(self, path: str, default: Any = None) -> Any:
  class Autoscaler (line 271) | class Autoscaler(models.Resource):
    method __init__ (line 276) | def __init__(self, project_id, resource_data):
    method self_link (line 281) | def self_link(self) -> str:
    method full_path (line 285) | def full_path(self) -> str:
    method name (line 294) | def name(self) -> str:
    method get (line 297) | def get(self, path: str, default: Any = None) -> Any:
  class SerialPortOutput (line 304) | class SerialPortOutput:
    method __init__ (line 314) | def __init__(self, project_id, instance_id, contents):
    method contents (line 320) | def contents(self) -> List[str]:
    method instance_id (line 324) | def instance_id(self) -> str:
  class Instance (line 328) | class Instance(models.Resource):
    method __init__ (line 334) | def __init__(self, project_id, resource_data):
    method id (line 341) | def id(self) -> str:
    method name (line 345) | def name(self) -> str:
    method full_path (line 349) | def full_path(self) -> str:
    method short_path (line 360) | def short_path(self) -> str:
    method creation_timestamp (line 367) | def creation_timestamp(self) -> datetime:
    method region (line 374) | def region(self) -> str:
    method zone (line 389) | def zone(self) -> str:
    method disks (line 398) | def disks(self) -> List[dict]:
    method boot_disk_licenses (line 404) | def boot_disk_licenses(self) -> List[str]:
    method guest_os_features (line 415) | def guest_os_features(self) -> List[str]:
    method startrestricted (line 423) | def startrestricted(self) -> bool:
    method laststarttimestamp (line 426) | def laststarttimestamp(self) -> str:
    method laststoptimestamp (line 429) | def laststoptimestamp(self) -> str:
    method is_serial_port_logging_enabled (line 434) | def is_serial_port_logging_enabled(self) -> bool:
    method is_oslogin_enabled (line 438) | def is_oslogin_enabled(self) -> bool:
    method is_metadata_enabled (line 442) | def is_metadata_enabled(self, metadata_name) -> bool:
    method has_label (line 447) | def has_label(self, label) -> bool:
    method is_dataproc_instance (line 450) | def is_dataproc_instance(self) -> bool:
    method is_gke_node (line 453) | def is_gke_node(self) -> bool:
    method is_preemptible_vm (line 457) | def is_preemptible_vm(self) -> bool:
    method min_cpu_platform (line 462) | def min_cpu_platform(self) -> str:
    method created_by_mig (line 468) | def created_by_mig(self) -> bool:
    method is_windows_machine (line 486) | def is_windows_machine(self) -> bool:
    method is_public_machine (line 494) | def is_public_machine(self) -> bool:
    method machine_type (line 499) | def machine_type(self):
    method check_license (line 511) | def check_license(self, licenses: List[str]) -> bool:
    method get_boot_disk_image (line 522) | def get_boot_disk_image(self) -> str:
    method is_sole_tenant_vm (line 539) | def is_sole_tenant_vm(self) -> bool:
    method network (line 543) | def network(self) -> network_q.Network:
    method network_ips (line 555) | def network_ips(self) -> List[network_q.IPv4AddrOrIPv6Addr]:
    method get_network_interfaces (line 562) | def get_network_interfaces(self):
    method subnetworks (line 566) | def subnetworks(self) -> List[network_q.Subnetwork]:
    method routes (line 573) | def routes(self) -> List[network_q.Route]:
    method get_network_ip_for_instance_interface (line 587) | def get_network_ip_for_instance_interface(
    method secure_boot_enabled (line 595) | def secure_boot_enabled(self) -> bool:
    method access_scopes (line 601) | def access_scopes(self) -> List[str]:
    method service_account (line 609) | def service_account(self) -> Optional[str]:
    method tags (line 617) | def tags(self) -> List[str]:
    method get_metadata (line 623) | def get_metadata(self, key: str) -> str:
    method status (line 635) | def status(self) -> str:
    method is_running (line 640) | def is_running(self) -> bool:
    method network_interface_count (line 645) | def network_interface_count(self) -> int:
    method mig (line 651) | def mig(self) -> ManagedInstanceGroup:
    method labels (line 690) | def labels(self) -> dict:
  class Disk (line 694) | class Disk(models.Resource):
    method __init__ (line 699) | def __init__(self, project_id, resource_data):
    method id (line 704) | def id(self) -> str:
    method name (line 708) | def name(self) -> str:
    method type (line 712) | def type(self) -> str:
    method users (line 720) | def users(self) -> list:
    method zone (line 731) | def zone(self) -> str:
    method source_image (line 739) | def source_image(self) -> str:
    method full_path (line 743) | def full_path(self) -> str:
    method short_path (line 754) | def short_path(self) -> str:
    method bootable (line 758) | def bootable(self) -> bool:
    method in_use (line 762) | def in_use(self) -> bool:
    method size (line 766) | def size(self) -> int:
    method provisionediops (line 770) | def provisionediops(self) -> Optional[int]:
    method has_snapshot_schedule (line 774) | def has_snapshot_schedule(self) -> bool:
  function get_gce_zones (line 779) | def get_gce_zones(project_id: str) -> Set[str]:
  function get_gce_public_licences (line 792) | def get_gce_public_licences(project_id: str) -> List[str]:
  function get_instance (line 808) | def get_instance(project_id: str, zone: str, instance_name: str) -> Inst...
  function get_instance_by_id (line 820) | def get_instance_by_id(project_id: str, instance_id: str) -> Optional[In...
  function get_global_operations (line 853) | def get_global_operations(
  function get_disk (line 886) | def get_disk(project_id: str, zone: str, disk_name: str) -> Disk:
  function get_instance_group_manager (line 894) | def get_instance_group_manager(
  function get_region_instance_group_manager (line 922) | def get_region_instance_group_manager(
  function get_autoscaler (line 951) | def get_autoscaler(project_id: str, zone: str,
  function get_region_autoscaler (line 965) | def get_region_autoscaler(project_id: str, region: str,
  function get_instances (line 980) | def get_instances(context: models.Context) -> Mapping[str, Instance]:
  function get_instance_groups (line 1025) | def get_instance_groups(context: models.Context) -> Mapping[str, Instanc...
  function get_managed_instance_groups (line 1066) | def get_managed_instance_groups(
  function get_region_managed_instance_groups (line 1110) | def get_region_managed_instance_groups(
  function get_instance_templates (line 1156) | def get_instance_templates(project_id: str) -> Mapping[str, InstanceTemp...
  function get_project_metadata (line 1176) | def get_project_metadata(project_id) -> Mapping[str, str]:
  function get_instances_serial_port_output (line 1194) | def get_instances_serial_port_output(context: models.Context):
  function get_instance_serial_port_output (line 1265) | def get_instance_serial_port_output(
  class Region (line 1309) | class Region(models.Resource):
    method __init__ (line 1314) | def __init__(self, project_id, resource_data):
    method self_link (line 1319) | def self_link(self) -> str:
    method full_path (line 1323) | def full_path(self) -> str:
    method name (line 1332) | def name(self) -> str:
  function get_all_regions (line 1337) | def get_all_regions(project_id: str) -> Iterable[Region]:
  function get_regions_with_instances (line 1363) | def get_regions_with_instances(context: models.Context) -> Iterable[Regi...
  function get_all_disks (line 1383) | def get_all_disks(context: models.Context) -> Iterable[Disk]:
  function get_all_disks_of_instance (line 1417) | def get_all_disks_of_instance(context: models.Context, zone: str,
  class InstanceEffectiveFirewalls (line 1459) | class InstanceEffectiveFirewalls(network_q.EffectiveFirewalls):
    method __init__ (line 1468) | def __init__(self, instance, nic, resource_data):
  function get_instance_interface_effective_firewalls (line 1475) | def get_instance_interface_effective_firewalls(
  function is_project_serial_port_logging_enabled (line 1489) | def is_project_serial_port_logging_enabled(project_id: str) -> bool:
  function is_serial_port_buffer_enabled (line 1498) | def is_serial_port_buffer_enabled():
  class _SerialOutputJob (line 1503) | class _SerialOutputJob:
    method __init__ (line 1509) | def __init__(self,
  class SerialOutputQuery (line 1516) | class SerialOutputQuery:
    method __init__ (line 1521) | def __init__(self, job):
    method entries (line 1525) | def entries(self) -> Sequence:
  function execute_fetch_serial_port_outputs (line 1540) | def execute_fetch_serial_port_outputs(
  function fetch_serial_port_outputs (line 1555) | def fetch_serial_port_outputs(context: models.Context) -> SerialOutputQu...
  class HealthCheck (line 1562) | class HealthCheck(models.Resource):
    method __init__ (line 1568) | def __init__(self, project_id, resource_data):
    method name (line 1573) | def name(self) -> str:
    method full_path (line 1577) | def full_path(self) -> str:
    method short_path (line 1586) | def short_path(self) -> str:
    method self_link (line 1591) | def self_link(self) -> str:
    method is_log_enabled (line 1595) | def is_log_enabled(self) -> bool:
    method region (line 1605) | def region(self):
    method type (line 1614) | def type(self) -> str:
    method request_path (line 1618) | def request_path(self) -> str:
    method request (line 1622) | def request(self) -> str:
    method response (line 1626) | def response(self) -> str:
    method port (line 1630) | def port(self) -> int:
    method port_specification (line 1634) | def port_specification(self) -> str:
    method timeout_sec (line 1638) | def timeout_sec(self) -> int:
    method check_interval_sec (line 1642) | def check_interval_sec(self) -> int:
    method unhealthy_threshold (line 1646) | def unhealthy_threshold(self) -> int:
    method healthy_threshold (line 1650) | def healthy_threshold(self) -> int:
    method get_health_check_property (line 1653) | def get_health_check_property(self, property_name: str, default_value=...
  function get_health_check (line 1670) | def get_health_check(project_id: str,
  class NetworkEndpointGroup (line 1685) | class NetworkEndpointGroup(models.Resource):
    method __init__ (line 1691) | def __init__(self, project_id, resource_data):
    method name (line 1696) | def name(self) -> str:
    method id (line 1700) | def id(self) -> str:
    method full_path (line 1704) | def full_path(self) -> str:
    method short_path (line 1713) | def short_path(self) -> str:
    method self_link (line 1718) | def self_link(self) -> str:
  function get_zonal_network_endpoint_groups (line 1723) | def get_zonal_network_endpoint_groups(

FILE: gcpdiag/queries/gce_stub.py
  class ComputeEngineApiStub (line 29) | class ComputeEngineApiStub(apis_stub.ApiStub):
    method __init__ (line 44) | def __init__(self, mock_state='init', project_id=None, zone=None, page...
    method regions (line 50) | def regions(self):
    method zones (line 53) | def zones(self):
    method disks (line 56) | def disks(self):
    method list (line 59) | def list(self, project, zone=None, returnPartialSuccess=None, fields=N...
    method aggregatedList (line 74) | def aggregatedList(
    method aggregatedList_next (line 91) | def aggregatedList_next(self, previous_request, previous_response):
    method list_next (line 102) | def list_next(self, previous_request, previous_response):
    method instances (line 113) | def instances(self):
    method globalOperations (line 116) | def globalOpera
Copy disabled (too large) Download .json
Condensed preview — 2970 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (22,573K chars).
[
  {
    "path": ".bumpversion.cfg",
    "chars": 407,
    "preview": "[bumpversion]\ncurrent_version = 0.81-test\nparse = (?P<major>\\d+)\\.(?P<minor>\\d+)(-(?P<release>.*))?\nmessage = Bump versi"
  },
  {
    "path": ".coveragerc",
    "chars": 41,
    "preview": "[run]\nomit =\n    *_test.py\n    *_stub.py\n"
  },
  {
    "path": ".devcontainer/README.md",
    "chars": 4112,
    "preview": "# Remote Container\n\n[Remote Container](https://code.visualstudio.com/docs/remote/containers) (aka Development Container)"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "chars": 1688,
    "preview": "{\n\t\"name\": \"gcpdiag\",\n\t\"image\": \"us-docker.pkg.dev/gcpdiag-dist/common/gcpdiag-pipenv-python-3.12:0.87\", // Using our cu"
  },
  {
    "path": ".gitallowed",
    "chars": 78,
    "preview": "gcpdiag/queries/client_secrets.json\nwebsite/content/en/docs/authentication.md\n"
  },
  {
    "path": ".github/workflows/code-analysis.yml",
    "chars": 1584,
    "preview": "name: Code analysis\non:\n  pull_request:\n  push:\n\n# Declare default permissions as Read only.\npermissions: read-all\n\nenv:"
  },
  {
    "path": ".github/workflows/scorecard.yml",
    "chars": 2448,
    "preview": "# This workflow uses actions that are not certified by GitHub. They are provided\n# by a third-party and are governed by "
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1642,
    "preview": "name: Test\non:\n  pull_request:\n  push:\n\n# Declare default permissions as read only.\npermissions: read-all\n\nenv:\n  PIPENV"
  },
  {
    "path": ".gitignore",
    "chars": 323,
    "preview": ".coverage\ndist\n.pipenv-dockerized\n*.pyc\n__pycache__\n.terraform\nterraform.tfstate\nterraform.tfstate.backup\nterraform.tfst"
  },
  {
    "path": ".isort.cfg",
    "chars": 20,
    "preview": "[settings]\nprofile=\n"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 3175,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": ".pylint-dictionary.txt",
    "chars": 3404,
    "preview": "ack\naiohttp\naiplatform\nallowedPolicyMemberDomains\napi\napigee\nApigee\nApigee's\nApigeeX\napis\nAPIs\napiserver\nAPIState\nargs\nA"
  },
  {
    "path": ".pylintrc",
    "chars": 14453,
    "preview": "# This Pylint rcfile contains a best-effort configuration to uphold the\n# best-practices and style described in the Goog"
  },
  {
    "path": ".safety-policy.yml",
    "chars": 112,
    "preview": "security:\n  ignore-vulnerabilities:\n    # Waiting for upstream fix for CVE-2025-69872 in diskcache\n    \"86338\":\n"
  },
  {
    "path": ".style.yapf",
    "chars": 49,
    "preview": "[style]\nbased_on_style = google\nindent_width = 2\n"
  },
  {
    "path": ".vscode/extensions.json",
    "chars": 108,
    "preview": "{\n  \"recommendations\": [\n    \"ms-python.pylint\",\n    \"ms-python.mypy-type-checker\",\n    \"eeyore.yapf\"\n  ]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 812,
    "preview": "{\n    \"editor.formatOnSave\": true,\n    \"editor.insertSpaces\": true,\n    \"editor.tabSize\": 2,\n    \"files.insertFinalNewli"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 48517,
    "preview": "\n# Changelog\n\n## 0.79 (2025-05-27)\n\n### New Lints\n\n- lb/bp/2025\\_003: new rule: lint rule for best practices for load ba"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 4483,
    "preview": "# Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1103,
    "preview": "# How to Contribute\n\nWe'd love to accept your patches and contributions to this project. There are\njust a few small guid"
  },
  {
    "path": "LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "Makefile",
    "chars": 4528,
    "preview": "VERSION=$(shell sed -n 's/^current_version\\s*=\\s*//p' <.bumpversion.cfg)\nDIST_NAME=gcpdiag-$(VERSION)\nSHELL=/bin/bash\n\n."
  },
  {
    "path": "PRIVACY.md",
    "chars": 33,
    "preview": "See: https://gcpdiag.dev/privacy\n"
  },
  {
    "path": "Pipfile",
    "chars": 1001,
    "preview": "[[source]]\nurl = \"https://pypi.python.org/simple\"\nverify_ssl = true\nname = \"pypi\"\n\n[requires]\npython_version = \"3.12\"\n\n["
  },
  {
    "path": "README.md",
    "chars": 11077,
    "preview": "# gcpdiag - Diagnostics for Google Cloud Platform\n\n[![code analysis badge](https://github.com/GoogleCloudPlatform/gcpdia"
  },
  {
    "path": "bin/changelog_generator.py",
    "chars": 7197,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2024 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
  },
  {
    "path": "bin/curl-wrap.sh",
    "chars": 815,
    "preview": "#!/bin/sh\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not "
  },
  {
    "path": "bin/gcpdiag",
    "chars": 3105,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
  },
  {
    "path": "bin/gcpdiag-dockerized",
    "chars": 8303,
    "preview": "#!/bin/bash\nset -e\nTHIS_WRAPPER_VERSION=0.11\nSUPPORTED_RUNTIME=\"docker podman\"\nDEFAULT_OUTPUT_DIR=\"$HOME/tmp\"\n\n# Initial"
  },
  {
    "path": "bin/gcpdiag-mocked",
    "chars": 2593,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
  },
  {
    "path": "bin/generate_steps.py",
    "chars": 3512,
    "preview": "#!/usr/bin/env python3\n\"\"\"Generate a markdown table with all gcpdiag runbook steps.\"\"\"\n\nimport importlib\nimport inspect\n"
  },
  {
    "path": "bin/json-cleaner",
    "chars": 3696,
    "preview": "#!/usr/bin/env python3\n\"\"\"Development script to strip out any sensitive data from GCP API responses.\"\"\"\n\n# pylint: disab"
  },
  {
    "path": "bin/pipenv-dockerized",
    "chars": 988,
    "preview": "#!/bin/bash\n\nif [ \"$#\" == \"0\" ]; then\n  echo \"usage: $0 PYTHON_VERSION COMMAND ARG1 ARG2 ARG3\" >&2\n  exit 1\nfi\nPYTHON_VE"
  },
  {
    "path": "bin/precommit-gke-eol-file.sh",
    "chars": 490,
    "preview": "#!/bin/sh\n\n# WARNING: This script is deprecated and may be removed in a future release.\n# Please use 'gcpdiag/queries/gk"
  },
  {
    "path": "bin/precommit-required-files",
    "chars": 13920,
    "preview": "#!/usr/bin/env python3\n\"\"\"Verify that the lint rules are documented in the website.\"\"\"\n\n# pylint: disable=invalid-name\n\n"
  },
  {
    "path": "bin/precommit-required-files-wrapper",
    "chars": 385,
    "preview": "#!/bin/sh\n\n# wrapper to call precommit-required-files with correct environment set\n# (this is particularly problematic i"
  },
  {
    "path": "bin/precommit-todo-annotations",
    "chars": 668,
    "preview": "#!/bin/sh\n\n# An hook script to verify changes to be committed do not contain\n# any 'TODO:' comments.\n\n# To bypass this h"
  },
  {
    "path": "bin/runbook-starter-code-generator",
    "chars": 12122,
    "preview": "#!/usr/bin/env python3\n\"\"\"Generate runbook starter code\"\"\"\n\nimport os\nimport re\nimport subprocess\nimport sys\nimport text"
  },
  {
    "path": "bin/steps_table.md",
    "chars": 61666,
    "preview": "\n|Runbook name| **Runbook Step** | stepType | `StepId` |\n|:------------|:----------- |:----------- |:----------- |\n|[bgp"
  },
  {
    "path": "bin/templates/diagnostic-tree.jinja",
    "chars": 1389,
    "preview": "{#- Prepare the tree traversal part -#}\n{% macro traverse_dt(step, ROOT_DIR) %}\n  {% set dt_path = '/steps/' ~ step.prod"
  },
  {
    "path": "bin/templates/python-file.py.tpl",
    "chars": 601,
    "preview": "# Copyright [YEAR] Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this"
  },
  {
    "path": "bin/templates/runbook-starter-code.py.tpl",
    "chars": 6299,
    "preview": "# Copyright [YEAR] Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this"
  },
  {
    "path": "bin/templates/runbook-test.py.tpl",
    "chars": 941,
    "preview": "# Copyright [YEAR] Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this"
  },
  {
    "path": "bin/templates/steps.jinja",
    "chars": 2485,
    "preview": "---\ntitle: \"{{ step.product }}/{{ step.label }}\"\nlinkTitle: \"{{ step.label }}\"\nweight: 3\ntype: docs\ndescription: >\n  {{ "
  },
  {
    "path": "bin/terraform",
    "chars": 406,
    "preview": "#!/bin/sh\n\n# terraform wrapper using docker\n\nUSE_TTY=\"\"\nCWD=$(pwd)\n[ -t 0 ] && USE_TTY=\"-it\"\n\nexec docker run $USE_TTY \\"
  },
  {
    "path": "cookiecutter-gcpdiag-rule/cookiecutter.json",
    "chars": 777,
    "preview": "{\n  \"rule_name\": \"\",\n  \"__name\": \"{{ cookiecutter.rule_name.lower().replace(' ', '_').replace('-', '_') }}\",\n  \"year\": \""
  },
  {
    "path": "cookiecutter-gcpdiag-rule/cookiecutter_runner.py",
    "chars": 3239,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "cookiecutter-gcpdiag-rule/hooks/post_gen_project.py",
    "chars": 1413,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "cookiecutter-gcpdiag-rule/{{cookiecutter.__name}}/gcpdiag/lint/{{cookiecutter.product}}/{{cookiecutter.severity.lower()}}_{{cookiecutter.year}}_{{cookiecutter.number}}_{{cookiecutter.__name}}.py",
    "chars": 3229,
    "preview": "# Copyright {{cookiecutter.year}} Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you m"
  },
  {
    "path": "cookiecutter-gcpdiag-rule/{{cookiecutter.__name}}/website/content/en/rules/{{cookiecutter.product}}/{{cookiecutter.severity}}/{{cookiecutter.year}}_{{cookiecutter.number}}.md",
    "chars": 2228,
    "preview": "---\ntitle: \"{{cookiecutter.product}}/{{cookiecutter.severity}}/{{cookiecutter.year}}_{{cookiecutter.number}}\"\nlinkTitle:"
  },
  {
    "path": "docker/gcpdiag/Dockerfile",
    "chars": 3011,
    "preview": "# Copyright 2024 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "docker/gcpdiag/Makefile",
    "chars": 1306,
    "preview": "BIN_DIR=../../bin\nVERSION=$(shell sed -n 's/^current_version\\s*=\\s*//p' <../../.bumpversion.cfg)\nifneq (,$(findstring te"
  },
  {
    "path": "docker/gcpdiag/entrypoint.sh",
    "chars": 1030,
    "preview": "#!/bin/bash\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
  },
  {
    "path": "docker/hugo/Dockerfile",
    "chars": 782,
    "preview": "# Use the official extended Hugo image. The versioned tag provides the extended build.\nFROM ghcr.io/gohugoio/hugo:v0.148"
  },
  {
    "path": "docker/hugo/Makefile",
    "chars": 174,
    "preview": "VERSION=0.3\nIMAGE=us-docker.pkg.dev/gcpdiag-dist/common/gcpdiag-hugo\n\nbuild:\n\tdocker build --pull --no-cache -t $(IMAGE)"
  },
  {
    "path": "docker/hugo/README.md",
    "chars": 107,
    "preview": "This image is used to build the gcpdiag.dev website on gcpdiag.dev and includes\nHugo + the Docsy template.\n"
  },
  {
    "path": "docker/pipenv-python-3.12/Dockerfile",
    "chars": 2000,
    "preview": "# Copyright 2024 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "docker/pipenv-python-3.12/Makefile",
    "chars": 189,
    "preview": "VERSION=0.87\nIMAGE=us-docker.pkg.dev/gcpdiag-dist/common/gcpdiag-pipenv-python-3.12\n\nbuild:\n\tdocker build --pull --no-ca"
  },
  {
    "path": "docker/pipenv-python-3.12/entrypoint.sh",
    "chars": 930,
    "preview": "#!/bin/bash\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
  },
  {
    "path": "docker/pipenv-python-3.7/Dockerfile",
    "chars": 1706,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "docker/pipenv-python-3.7/Makefile",
    "chars": 187,
    "preview": "VERSION=0.8\nIMAGE=us-docker.pkg.dev/gcpdiag-dist/common/gcpdiag-pipenv-python-3.7\n\nbuild:\n\tdocker build --pull --no-cach"
  },
  {
    "path": "docker/pipenv-python-3.7/entrypoint.sh",
    "chars": 930,
    "preview": "#!/bin/bash\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
  },
  {
    "path": "docker/pipenv-python-3.9/Dockerfile",
    "chars": 2010,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "docker/pipenv-python-3.9/Makefile",
    "chars": 187,
    "preview": "VERSION=0.8\nIMAGE=us-docker.pkg.dev/gcpdiag-dist/common/gcpdiag-pipenv-python-3.9\n\nbuild:\n\tdocker build --pull --no-cach"
  },
  {
    "path": "docker/pipenv-python-3.9/entrypoint.sh",
    "chars": 930,
    "preview": "#!/bin/bash\n# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
  },
  {
    "path": "gcpdiag/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/async_queries/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/async_queries/api/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/async_queries/api/api.py",
    "chars": 1537,
    "preview": "\"\"\" Make REST API requests \"\"\"\nfrom typing import Any, Dict, Iterable, Optional, Protocol\n\nimport aiohttp\n\nfrom gcpdiag."
  },
  {
    "path": "gcpdiag/async_queries/api/api_slowtest.py",
    "chars": 3482,
    "preview": "\"\"\"\n  Tests for API\n  python -m unittest gcpdiag.async_queries.api_test\n\"\"\"\nimport asyncio\nimport os\nimport unittest\nfro"
  },
  {
    "path": "gcpdiag/async_queries/api/constant_time_retry_strategy.py",
    "chars": 462,
    "preview": "\"\"\" Retry strategy: n retries with fixed timeout between them \"\"\"\nfrom typing import Iterator\n\n\nclass ConstantTimeoutRet"
  },
  {
    "path": "gcpdiag/async_queries/api/default_random.py",
    "chars": 187,
    "preview": "\"\"\" Generate random numbers between 0 and 1 \"\"\"\nimport random\n\n\nclass Random:\n  \"\"\" Generate random numbers between 0 an"
  },
  {
    "path": "gcpdiag/async_queries/api/exponential_random_retry_strategy.py",
    "chars": 980,
    "preview": "\"\"\"\n  Retry strategy:\n    n retries with exponential timeout plus some random deviations\n\"\"\"\nfrom typing import Iterator"
  },
  {
    "path": "gcpdiag/async_queries/api/exponential_random_retry_strategy_test.py",
    "chars": 805,
    "preview": "\"\"\" Tests for ExponentialRandomTimeoutRetryStrategy \"\"\"\n\nfrom typing import List\n\nimport pytest\n\nfrom gcpdiag.async_quer"
  },
  {
    "path": "gcpdiag/async_queries/api/gcpdiag_creds.py",
    "chars": 715,
    "preview": "\"\"\"\n  Adapter between gcpdiag.async_queries.api.Creds protocol and\n  gcpdiag.queries.apis.get_credentials\n\"\"\"\n\nfrom typi"
  },
  {
    "path": "gcpdiag/async_queries/api/get_api.py",
    "chars": 1226,
    "preview": "\"\"\" Helper method to initialize API object \"\"\"\nfrom gcpdiag import config\nfrom gcpdiag.async_queries.api import (api, de"
  },
  {
    "path": "gcpdiag/async_queries/api/sleeper.py",
    "chars": 230,
    "preview": "\"\"\"\n  Simple wrapper for asyncio.sleep\n  (mostly needed to replace it with testing double during unit testing)\n\"\"\"\nimpor"
  },
  {
    "path": "gcpdiag/async_queries/api/test_webserver.py",
    "chars": 1892,
    "preview": "\"\"\" Simple web server used for testing \"\"\"\nfrom typing import Any, List, Protocol\n\nfrom aiohttp import web\n\n\nclass Respo"
  },
  {
    "path": "gcpdiag/async_queries/dataproc/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/async_queries/dataproc/dataproc.py",
    "chars": 2886,
    "preview": "\"\"\" Gateway for Dataproc service \"\"\"\nimport asyncio\nimport functools\nfrom typing import Any, Dict, Iterable, List, Mappi"
  },
  {
    "path": "gcpdiag/async_queries/dataproc/dataproc_test.py",
    "chars": 2577,
    "preview": "'Tests for gcpdiag.async_queries.dataproc.Dataproc'\nimport asyncio\nimport unittest\nfrom typing import List\n\nimport yaml "
  },
  {
    "path": "gcpdiag/async_queries/project/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/async_queries/project/get_project.py",
    "chars": 286,
    "preview": "\"\"\" Helper method to initialize Project object \"\"\"\nfrom gcpdiag.async_queries.api import get_api\nfrom gcpdiag.async_quer"
  },
  {
    "path": "gcpdiag/async_queries/project/project.py",
    "chars": 971,
    "preview": "\"\"\" Class representing different services available within a GCP project \"\"\"\nimport functools\n\nfrom gcpdiag.async_querie"
  },
  {
    "path": "gcpdiag/async_queries/project_regions.py",
    "chars": 1220,
    "preview": "\"\"\" Gateway for extracting available GCP regions \"\"\"\nfrom typing import Any, Iterable, List, Mapping, Optional\n\nfrom gcp"
  },
  {
    "path": "gcpdiag/async_queries/project_regions_test.py",
    "chars": 1153,
    "preview": "'Tests for gcpdiag.async_queries.ProjectRegions'\nfrom asyncio import gather\nfrom unittest import IsolatedAsyncioTestCase"
  },
  {
    "path": "gcpdiag/async_queries/py.typed",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/async_queries/utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/async_queries/utils/fake_api.py",
    "chars": 1448,
    "preview": "'Testing double for gcpdiag.async_queries.api.API'\nfrom asyncio import sleep\nfrom typing import Any, List, Optional, Tup"
  },
  {
    "path": "gcpdiag/async_queries/utils/loader.py",
    "chars": 1400,
    "preview": "\"\"\"\n  Helper class to optimize gateway objects loading\n  so that data only loaded once\n\"\"\"\nimport asyncio\nfrom typing im"
  },
  {
    "path": "gcpdiag/async_queries/utils/protocols.py",
    "chars": 355,
    "preview": "\"\"\" Common protocols used by async queries \"\"\"\n\nfrom typing import Any, Iterable, Optional, Protocol\n\n\nclass API(Protoco"
  },
  {
    "path": "gcpdiag/caching.py",
    "chars": 7607,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/caching_test.py",
    "chars": 4416,
    "preview": "# Copyright 2024 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/config.py",
    "chars": 5726,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/config_test.py",
    "chars": 5404,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/context.py",
    "chars": 1003,
    "preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/executor.py",
    "chars": 2748,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/executor_test.py",
    "chars": 1871,
    "preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/hooks.py",
    "chars": 3266,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/__init__.py",
    "chars": 20996,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/lint/apigee/apigee_rules_snapshot_test.py",
    "chars": 783,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/err_2022_001_p4sa_perm.py",
    "chars": 1652,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/err_2022_002_p4sa_kms_key_perm.py",
    "chars": 3504,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/err_2023_001_vpc_peering_created.py",
    "chars": 2254,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/err_2023_002_routing_with_mig.py",
    "chars": 2562,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/err_2023_003_pga_on_mig_subnet.py",
    "chars": 2233,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/err_2023_004_p4nsa_perm.py",
    "chars": 2045,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/err_2023_005_fw_rule_xlb_to_mig.py",
    "chars": 2368,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/err_2023_006_multiple_migs_for_multiple_regions.py",
    "chars": 2109,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/ERR_2022_001.txt",
    "chars": 424,
    "preview": "*  apigee/ERR/2022_001: Apigee Service Agent permissions\n   - projects/gcpdiag-apigee1-aaaa                             "
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/ERR_2022_002.txt",
    "chars": 316,
    "preview": "*  apigee/ERR/2022_002: Cloud KMS key is enabled and could be accessed by Apigee Service Agent\n   - projects/gcpdiag-api"
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/ERR_2023_001.txt",
    "chars": 155,
    "preview": "*  apigee/ERR/2023_001: Customer's network is peered to Apigee's network\n   - organizations/gcpdiag-apigee1-aaaa        "
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/ERR_2023_002.txt",
    "chars": 169,
    "preview": "*  apigee/ERR/2023_002: Network bridge managed instance group is correctly configured.\n   - organizations/gcpdiag-apigee"
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/ERR_2023_003.txt",
    "chars": 217,
    "preview": "*  apigee/ERR/2023_003: Private Google Access (PGA) for subnet of Managed Instance Group is enabled.\n   - projects/gcpdi"
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/ERR_2023_004.txt",
    "chars": 177,
    "preview": "*  apigee/ERR/2023_004: Service Networking API is enabled and SA account has the required role\n   - projects/gcpdiag-api"
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/ERR_2023_005.txt",
    "chars": 554,
    "preview": "*  apigee/ERR/2023_005: External Load Balancer (XLB) is able to connect to the Managed Instance Group(MIG).\n   - project"
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/ERR_2023_006.txt",
    "chars": 171,
    "preview": "*  apigee/ERR/2023_006: A multi-region setup requires a separate MIG for each region.\n   - organizations/gcpdiag-apigee1"
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/WARN_2021_001.txt",
    "chars": 792,
    "preview": "*  apigee/WARN/2021_001: Every environment group contains at least one environment.\n   - organizations/gcpdiag-apigee1-a"
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/WARN_2022_001.txt",
    "chars": 167,
    "preview": "*  apigee/WARN/2022_001: Environment groups are created in the Apigee runtime plane.\n   (logging api is disabled)       "
  },
  {
    "path": "gcpdiag/lint/apigee/snapshots/WARN_2022_002.txt",
    "chars": 497,
    "preview": "*  apigee/WARN/2022_002: Environments are attached to Apigee X instances\n   - organizations/gcpdiag-apigee1-aaaa/environ"
  },
  {
    "path": "gcpdiag/lint/apigee/warn_2021_001_empty_env.py",
    "chars": 1754,
    "preview": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/warn_2022_001_env_groups_created.py",
    "chars": 3895,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/apigee/warn_2022_002_env_not_attached.py",
    "chars": 1960,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/asm/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/lint/asm/asm_rules_snapshot_test.py",
    "chars": 774,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/asm/err_2023_001_traffic_4xx.py",
    "chars": 2147,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/asm/err_2023_002_traffic_5xx.py",
    "chars": 2141,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/asm/err_2024_001_secret_not_found.py",
    "chars": 2393,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/asm/err_2024_002_istiod_resource_issues.py",
    "chars": 2532,
    "preview": "# Copyright 2024 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/asm/snapshots/ERR_2023_001.txt",
    "chars": 154,
    "preview": "*  asm/ERR/2023_001: ASM traffic indicates Client side requests failure\n   (logging api is disabled)                    "
  },
  {
    "path": "gcpdiag/lint/asm/snapshots/ERR_2023_002.txt",
    "chars": 154,
    "preview": "*  asm/ERR/2023_002: ASM traffic indicates Client side requests failure\n   (logging api is disabled)                    "
  },
  {
    "path": "gcpdiag/lint/asm/snapshots/ERR_2024_001.txt",
    "chars": 168,
    "preview": "*  asm/ERR/2024_001: Getting timed out error for secret not found for ingress gateway\n   (logging api is disabled)      "
  },
  {
    "path": "gcpdiag/lint/asm/snapshots/ERR_2024_002.txt",
    "chars": 173,
    "preview": "*  asm/ERR/2024_002: Sufficient resources (CPU and memory) then Istiod pods are scheduled.\n   (logging api is disabled) "
  },
  {
    "path": "gcpdiag/lint/asm/snapshots/WARN_2023_001.txt",
    "chars": 161,
    "preview": "*  asm/WARN/2023_001: gRCP Config stream reset event detected in istio proxies\n   (logging api is disabled)             "
  },
  {
    "path": "gcpdiag/lint/asm/snapshots/WARN_2024_001.txt",
    "chars": 145,
    "preview": "*  asm/WARN/2024_001: No webhook creation failures were found.\n   (logging api is disabled)                             "
  },
  {
    "path": "gcpdiag/lint/asm/snapshots/WARN_2025_001.txt",
    "chars": 149,
    "preview": "*  asm/WARN/2025_001: ASM: Envoy doesn't report connection failure\n   (logging api is disabled)                         "
  },
  {
    "path": "gcpdiag/lint/asm/snapshots/WARN_2025_002.txt",
    "chars": 173,
    "preview": "*  asm/WARN/2025_002: Upstream connection established successfully with no protocol errors\n   (logging api is disabled) "
  },
  {
    "path": "gcpdiag/lint/asm/warn_2023_001_grpc_reset.py",
    "chars": 2238,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/asm/warn_2024_001_webhook.py",
    "chars": 2540,
    "preview": "#Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this fi"
  },
  {
    "path": "gcpdiag/lint/asm/warn_2025_001_delayedconnect111.py",
    "chars": 2558,
    "preview": "# Copyright 2024 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/asm/warn_2025_002_protocolerror.py",
    "chars": 2221,
    "preview": "# Copyright 2025 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "gcpdiag/lint/bigquery/bigquery_rules_snapshot_test.py",
    "chars": 789,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2022_001_concurrent_dml_updates.py",
    "chars": 2721,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2022_002_response_too_large.py",
    "chars": 2615,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2022_003_permission_denied_drive_credentials.py",
    "chars": 2723,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2022_004_exceeded_limit_shuffle.py",
    "chars": 2680,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_001_job_not_found_error.py",
    "chars": 3427,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_002_dataset_not_found.py",
    "chars": 3494,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_003_resource_exceeded.py",
    "chars": 2744,
    "preview": "#\n# Copyright 2021 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_004_concurrent_dml.py",
    "chars": 2911,
    "preview": "#\n# Copyright 2021 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_005_outdated_credentials_for_scheduled_queries.py",
    "chars": 2700,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_006_bigquery_policy_do_not_belong_to_user.py",
    "chars": 2922,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_007_data_transfer_service_agent_does_not_exist.py",
    "chars": 1845,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_008_user_not_authorized_to_perform_this_action.py",
    "chars": 3319,
    "preview": "# Copyright 2022 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2023_009_not_consistent_with_destination_dataset.py",
    "chars": 2776,
    "preview": "# Copyright 2023 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/err_2024_001_query_too_complex.py",
    "chars": 2918,
    "preview": "#\n# Copyright 2024 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2022_001.txt",
    "chars": 211,
    "preview": "*  bigquery/ERR/2022_001: BigQuery jobs not failing due to concurrent DML updates on the same table\n   - projects/gcpdia"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2022_002.txt",
    "chars": 226,
    "preview": "*  bigquery/ERR/2022_002: BigQuery jobs are not failing due to results being larger than the maximum response size\n   - "
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2022_003.txt",
    "chars": 219,
    "preview": "*  bigquery/ERR/2022_003: BigQuery jobs not failing while accessing data in Drive due to a permission issue\n   - project"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2022_004.txt",
    "chars": 211,
    "preview": "*  bigquery/ERR/2022_004: BigQuery jobs are not failing due to shuffle operation resources exceeded\n   - projects/gcpdia"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_001.txt",
    "chars": 175,
    "preview": "*  bigquery/ERR/2023_001: Jobs called via the API are all found\n   - projects/gcpdiag-cloudsql1-aaaa                    "
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_002.txt",
    "chars": 223,
    "preview": "*  bigquery/ERR/2023_002: BigQuery hasn't reported any unknown datasets while performing copy tables operations\n   - pro"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_003.txt",
    "chars": 197,
    "preview": "*  bigquery/ERR/2023_003: BigQuery query job do not encounter resource exceeded error\n   - projects/gcpdiag-cloudsql1-aa"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_004.txt",
    "chars": 223,
    "preview": "*  bigquery/ERR/2023_004: BigQuery query job do not encounter dml concurrency issue when mutating concurrently.\n   - pro"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_005.txt",
    "chars": 194,
    "preview": "*  bigquery/ERR/2023_005: Scheduled query not failing due to outdated credentials.\n   - projects/gcpdiag-cloudsql1-aaaa "
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_006.txt",
    "chars": 202,
    "preview": "*  bigquery/ERR/2023_006: An organization's policy doesn't block the BigQuery user domain.\n   - projects/gcpdiag-cloudsq"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_007.txt",
    "chars": 215,
    "preview": "*  bigquery/ERR/2023_007: Data Transfer Service Agent exists and has the required roles.\n   - projects/gcpdiag-cloudsql1"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_008.txt",
    "chars": 204,
    "preview": "*  bigquery/ERR/2023_008: User has the required roles to create or modify scheduled queries.\n   - projects/gcpdiag-cloud"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2023_009.txt",
    "chars": 202,
    "preview": "*  bigquery/ERR/2023_009: BigQuery job not failed due to Scheduled query with multiple DML\n   - projects/gcpdiag-cloudsq"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/ERR_2024_001.txt",
    "chars": 218,
    "preview": "*  bigquery/ERR/2024_001: BigQuery jobs are not failing due to too many subqueries or query is too complex\n   - projects"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2022_001.txt",
    "chars": 175,
    "preview": "*  bigquery/WARN/2022_001: BigQuery does not exceed rate limits\n   - projects/gcpdiag-cloudsql1-aaaa                    "
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2022_002.txt",
    "chars": 186,
    "preview": "*  bigquery/WARN/2022_002: BigQuery does not violate column level security\n   - projects/gcpdiag-cloudsql1-aaaa         "
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2022_003.txt",
    "chars": 193,
    "preview": "*  bigquery/WARN/2022_003: BigQuery copy job does not exceed the daily copy quota\n   - projects/gcpdiag-cloudsql1-aaaa  "
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2022_004.txt",
    "chars": 206,
    "preview": "*  bigquery/WARN/2022_004: BigQuery copy job does not exceed the cross-region daily copy quota\n   - projects/gcpdiag-clo"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2023_001.txt",
    "chars": 192,
    "preview": "*  bigquery/WARN/2023_001: BigQuery query job does not time out during execution\n   - projects/gcpdiag-cloudsql1-aaaa   "
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2023_002.txt",
    "chars": 173,
    "preview": "*  bigquery/WARN/2023_002: No errors querying wildcard tables\n   - projects/gcpdiag-cloudsql1-aaaa                      "
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2023_003.txt",
    "chars": 206,
    "preview": "*  bigquery/WARN/2023_003: BigQuery query job does not fail with too many output columns error\n   - projects/gcpdiag-clo"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2023_004.txt",
    "chars": 210,
    "preview": "*  bigquery/WARN/2023_004: BigQuery CMEK-related operations do not fail due to missing permissions\n   - projects/gcpdiag"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2024_001.txt",
    "chars": 203,
    "preview": "*  bigquery/WARN/2024_001: BigQuery table does not exceed import or query appends per table\n   - projects/gcpdiag-clouds"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2024_002.txt",
    "chars": 196,
    "preview": "*  bigquery/WARN/2024_002: BigQuery external connection with Cloud SQL does not fail\n   - projects/gcpdiag-cloudsql1-aaa"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2024_003.txt",
    "chars": 223,
    "preview": "*  bigquery/WARN/2024_003: BigQuery job does not fail due to Maximum API requests per user per method exceeded.\n   - pro"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2024_004.txt",
    "chars": 216,
    "preview": "*  bigquery/WARN/2024_004: BigQuery job not exceeding the concurrent queries limit for remote functions.\n   - projects/g"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2024_005.txt",
    "chars": 233,
    "preview": "*  bigquery/WARN/2024_005: BigQuery table does not exceed number of partition modifications to a column partitioned tabl"
  },
  {
    "path": "gcpdiag/lint/bigquery/snapshots/WARN_2024_006.txt",
    "chars": 211,
    "preview": "*  bigquery/WARN/2024_006: BigQuery job does not exceed tabledata.list bytes per second per project\n   - projects/gcpdia"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2022_001_exceeded_rate_limits.py",
    "chars": 2553,
    "preview": "#\n# Copyright 2021 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2022_002_column_level_security.py",
    "chars": 2565,
    "preview": "#\n# Copyright 2021 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2022_003_copy_job_quota.py",
    "chars": 2678,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2022_004_cross_region_copy_job_quota.py",
    "chars": 2990,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2023_001_query_job_timed_out.py",
    "chars": 2700,
    "preview": "#\n# Copyright 2021 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2023_002_wildcard_tables_query.py",
    "chars": 3148,
    "preview": "#\n# Copyright 2022 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2023_003_too_many_output_column.py",
    "chars": 2753,
    "preview": "#\n# Copyright 2021 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2023_004_bigquery_kms_errors.py",
    "chars": 2870,
    "preview": "#\n# Copyright 2021 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2024_001_imports_or_query_appends_per_table.py",
    "chars": 2848,
    "preview": "#\n# Copyright 2024 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2024_002_invalid_external_connection.py",
    "chars": 2877,
    "preview": "#\n# Copyright 2024 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2024_003_too_many_concurrent_api_requests.py",
    "chars": 2635,
    "preview": "#\n# Copyright 2024 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2024_004_too_many_concurrent_queries.py",
    "chars": 2770,
    "preview": "#\n# Copyright 2024 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2024_005_exceeded_partition_modifications.py",
    "chars": 3090,
    "preview": "#\n# Copyright 2024 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  },
  {
    "path": "gcpdiag/lint/bigquery/warn_2024_006_tabledata_list_bytes_exceeded.py",
    "chars": 2933,
    "preview": "#\n# Copyright 2024 Google LLC\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this f"
  }
]

// ... and 2770 more files (download for full content)

About this extraction

This page contains the full source code of the GoogleCloudPlatform/gcpdiag GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2970 files (19.9 MB), approximately 5.4M tokens, and a symbol index with 5649 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!