paasta-tools 1.21.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- k8s_itests/__init__.py +0 -0
- k8s_itests/test_autoscaling.py +23 -0
- k8s_itests/utils.py +38 -0
- paasta_tools/__init__.py +20 -0
- paasta_tools/adhoc_tools.py +142 -0
- paasta_tools/api/__init__.py +13 -0
- paasta_tools/api/api.py +330 -0
- paasta_tools/api/api_docs/swagger.json +2323 -0
- paasta_tools/api/client.py +106 -0
- paasta_tools/api/settings.py +33 -0
- paasta_tools/api/tweens/__init__.py +6 -0
- paasta_tools/api/tweens/auth.py +125 -0
- paasta_tools/api/tweens/profiling.py +108 -0
- paasta_tools/api/tweens/request_logger.py +124 -0
- paasta_tools/api/views/__init__.py +13 -0
- paasta_tools/api/views/autoscaler.py +100 -0
- paasta_tools/api/views/exception.py +45 -0
- paasta_tools/api/views/flink.py +73 -0
- paasta_tools/api/views/instance.py +395 -0
- paasta_tools/api/views/pause_autoscaler.py +71 -0
- paasta_tools/api/views/remote_run.py +113 -0
- paasta_tools/api/views/resources.py +76 -0
- paasta_tools/api/views/service.py +35 -0
- paasta_tools/api/views/version.py +25 -0
- paasta_tools/apply_external_resources.py +79 -0
- paasta_tools/async_utils.py +109 -0
- paasta_tools/autoscaling/__init__.py +0 -0
- paasta_tools/autoscaling/autoscaling_service_lib.py +57 -0
- paasta_tools/autoscaling/forecasting.py +106 -0
- paasta_tools/autoscaling/max_all_k8s_services.py +41 -0
- paasta_tools/autoscaling/pause_service_autoscaler.py +77 -0
- paasta_tools/autoscaling/utils.py +52 -0
- paasta_tools/bounce_lib.py +184 -0
- paasta_tools/broadcast_log_to_services.py +62 -0
- paasta_tools/cassandracluster_tools.py +210 -0
- paasta_tools/check_autoscaler_max_instances.py +212 -0
- paasta_tools/check_cassandracluster_services_replication.py +35 -0
- paasta_tools/check_flink_services_health.py +203 -0
- paasta_tools/check_kubernetes_api.py +57 -0
- paasta_tools/check_kubernetes_services_replication.py +141 -0
- paasta_tools/check_oom_events.py +244 -0
- paasta_tools/check_services_replication_tools.py +324 -0
- paasta_tools/check_spark_jobs.py +234 -0
- paasta_tools/cleanup_kubernetes_cr.py +138 -0
- paasta_tools/cleanup_kubernetes_crd.py +145 -0
- paasta_tools/cleanup_kubernetes_jobs.py +344 -0
- paasta_tools/cleanup_tron_namespaces.py +96 -0
- paasta_tools/cli/__init__.py +13 -0
- paasta_tools/cli/authentication.py +85 -0
- paasta_tools/cli/cli.py +260 -0
- paasta_tools/cli/cmds/__init__.py +13 -0
- paasta_tools/cli/cmds/autoscale.py +143 -0
- paasta_tools/cli/cmds/check.py +334 -0
- paasta_tools/cli/cmds/cook_image.py +147 -0
- paasta_tools/cli/cmds/get_docker_image.py +76 -0
- paasta_tools/cli/cmds/get_image_version.py +172 -0
- paasta_tools/cli/cmds/get_latest_deployment.py +93 -0
- paasta_tools/cli/cmds/info.py +155 -0
- paasta_tools/cli/cmds/itest.py +117 -0
- paasta_tools/cli/cmds/list.py +66 -0
- paasta_tools/cli/cmds/list_clusters.py +42 -0
- paasta_tools/cli/cmds/list_deploy_queue.py +171 -0
- paasta_tools/cli/cmds/list_namespaces.py +84 -0
- paasta_tools/cli/cmds/local_run.py +1396 -0
- paasta_tools/cli/cmds/logs.py +1601 -0
- paasta_tools/cli/cmds/mark_for_deployment.py +1988 -0
- paasta_tools/cli/cmds/mesh_status.py +174 -0
- paasta_tools/cli/cmds/pause_service_autoscaler.py +107 -0
- paasta_tools/cli/cmds/push_to_registry.py +275 -0
- paasta_tools/cli/cmds/remote_run.py +252 -0
- paasta_tools/cli/cmds/rollback.py +347 -0
- paasta_tools/cli/cmds/secret.py +549 -0
- paasta_tools/cli/cmds/security_check.py +59 -0
- paasta_tools/cli/cmds/spark_run.py +1400 -0
- paasta_tools/cli/cmds/start_stop_restart.py +401 -0
- paasta_tools/cli/cmds/status.py +2302 -0
- paasta_tools/cli/cmds/validate.py +1012 -0
- paasta_tools/cli/cmds/wait_for_deployment.py +275 -0
- paasta_tools/cli/fsm/__init__.py +13 -0
- paasta_tools/cli/fsm/autosuggest.py +82 -0
- paasta_tools/cli/fsm/template/README.md +8 -0
- paasta_tools/cli/fsm/template/cookiecutter.json +7 -0
- paasta_tools/cli/fsm/template/{{cookiecutter.service}}/kubernetes-PROD.yaml +91 -0
- paasta_tools/cli/fsm/template/{{cookiecutter.service}}/monitoring.yaml +20 -0
- paasta_tools/cli/fsm/template/{{cookiecutter.service}}/service.yaml +8 -0
- paasta_tools/cli/fsm/template/{{cookiecutter.service}}/smartstack.yaml +6 -0
- paasta_tools/cli/fsm_cmd.py +121 -0
- paasta_tools/cli/paasta_tabcomplete.sh +23 -0
- paasta_tools/cli/schemas/adhoc_schema.json +199 -0
- paasta_tools/cli/schemas/autoscaling_schema.json +91 -0
- paasta_tools/cli/schemas/autotuned_defaults/cassandracluster_schema.json +37 -0
- paasta_tools/cli/schemas/autotuned_defaults/kubernetes_schema.json +89 -0
- paasta_tools/cli/schemas/deploy_schema.json +173 -0
- paasta_tools/cli/schemas/eks_schema.json +970 -0
- paasta_tools/cli/schemas/kubernetes_schema.json +970 -0
- paasta_tools/cli/schemas/rollback_schema.json +160 -0
- paasta_tools/cli/schemas/service_schema.json +25 -0
- paasta_tools/cli/schemas/smartstack_schema.json +322 -0
- paasta_tools/cli/schemas/tron_schema.json +699 -0
- paasta_tools/cli/utils.py +1118 -0
- paasta_tools/clusterman.py +21 -0
- paasta_tools/config_utils.py +385 -0
- paasta_tools/contrib/__init__.py +0 -0
- paasta_tools/contrib/bounce_log_latency_parser.py +68 -0
- paasta_tools/contrib/check_manual_oapi_changes.sh +24 -0
- paasta_tools/contrib/check_orphans.py +306 -0
- paasta_tools/contrib/create_dynamodb_table.py +35 -0
- paasta_tools/contrib/create_paasta_playground.py +105 -0
- paasta_tools/contrib/emit_allocated_cpu_metrics.py +50 -0
- paasta_tools/contrib/get_running_task_allocation.py +346 -0
- paasta_tools/contrib/habitat_fixer.py +86 -0
- paasta_tools/contrib/ide_helper.py +316 -0
- paasta_tools/contrib/is_pod_healthy_in_proxy.py +139 -0
- paasta_tools/contrib/is_pod_healthy_in_smartstack.py +50 -0
- paasta_tools/contrib/kill_bad_containers.py +109 -0
- paasta_tools/contrib/mass-deploy-tag.sh +44 -0
- paasta_tools/contrib/mock_patch_checker.py +86 -0
- paasta_tools/contrib/paasta_update_soa_memcpu.py +520 -0
- paasta_tools/contrib/render_template.py +129 -0
- paasta_tools/contrib/rightsizer_soaconfigs_update.py +348 -0
- paasta_tools/contrib/service_shard_remove.py +157 -0
- paasta_tools/contrib/service_shard_update.py +373 -0
- paasta_tools/contrib/shared_ip_check.py +77 -0
- paasta_tools/contrib/timeouts_metrics_prom.py +64 -0
- paasta_tools/delete_kubernetes_deployments.py +89 -0
- paasta_tools/deployment_utils.py +44 -0
- paasta_tools/docker_wrapper.py +234 -0
- paasta_tools/docker_wrapper_imports.py +13 -0
- paasta_tools/drain_lib.py +351 -0
- paasta_tools/dump_locally_running_services.py +71 -0
- paasta_tools/eks_tools.py +119 -0
- paasta_tools/envoy_tools.py +373 -0
- paasta_tools/firewall.py +504 -0
- paasta_tools/firewall_logging.py +154 -0
- paasta_tools/firewall_update.py +172 -0
- paasta_tools/flink_tools.py +345 -0
- paasta_tools/flinkeks_tools.py +90 -0
- paasta_tools/frameworks/__init__.py +0 -0
- paasta_tools/frameworks/adhoc_scheduler.py +71 -0
- paasta_tools/frameworks/constraints.py +87 -0
- paasta_tools/frameworks/native_scheduler.py +652 -0
- paasta_tools/frameworks/native_service_config.py +301 -0
- paasta_tools/frameworks/task_store.py +245 -0
- paasta_tools/generate_all_deployments +9 -0
- paasta_tools/generate_authenticating_services.py +94 -0
- paasta_tools/generate_deployments_for_service.py +255 -0
- paasta_tools/generate_services_file.py +114 -0
- paasta_tools/generate_services_yaml.py +30 -0
- paasta_tools/hacheck.py +76 -0
- paasta_tools/instance/__init__.py +0 -0
- paasta_tools/instance/hpa_metrics_parser.py +122 -0
- paasta_tools/instance/kubernetes.py +1362 -0
- paasta_tools/iptables.py +240 -0
- paasta_tools/kafkacluster_tools.py +143 -0
- paasta_tools/kubernetes/__init__.py +0 -0
- paasta_tools/kubernetes/application/__init__.py +0 -0
- paasta_tools/kubernetes/application/controller_wrappers.py +476 -0
- paasta_tools/kubernetes/application/tools.py +90 -0
- paasta_tools/kubernetes/bin/__init__.py +0 -0
- paasta_tools/kubernetes/bin/kubernetes_remove_evicted_pods.py +164 -0
- paasta_tools/kubernetes/bin/paasta_cleanup_remote_run_resources.py +135 -0
- paasta_tools/kubernetes/bin/paasta_cleanup_stale_nodes.py +181 -0
- paasta_tools/kubernetes/bin/paasta_secrets_sync.py +758 -0
- paasta_tools/kubernetes/remote_run.py +558 -0
- paasta_tools/kubernetes_tools.py +4679 -0
- paasta_tools/list_kubernetes_service_instances.py +128 -0
- paasta_tools/list_tron_namespaces.py +60 -0
- paasta_tools/long_running_service_tools.py +678 -0
- paasta_tools/mac_address.py +44 -0
- paasta_tools/marathon_dashboard.py +0 -0
- paasta_tools/mesos/__init__.py +0 -0
- paasta_tools/mesos/cfg.py +46 -0
- paasta_tools/mesos/cluster.py +60 -0
- paasta_tools/mesos/exceptions.py +59 -0
- paasta_tools/mesos/framework.py +77 -0
- paasta_tools/mesos/log.py +48 -0
- paasta_tools/mesos/master.py +306 -0
- paasta_tools/mesos/mesos_file.py +169 -0
- paasta_tools/mesos/parallel.py +52 -0
- paasta_tools/mesos/slave.py +115 -0
- paasta_tools/mesos/task.py +94 -0
- paasta_tools/mesos/util.py +69 -0
- paasta_tools/mesos/zookeeper.py +37 -0
- paasta_tools/mesos_maintenance.py +848 -0
- paasta_tools/mesos_tools.py +1051 -0
- paasta_tools/metrics/__init__.py +0 -0
- paasta_tools/metrics/metastatus_lib.py +1110 -0
- paasta_tools/metrics/metrics_lib.py +217 -0
- paasta_tools/monitoring/__init__.py +13 -0
- paasta_tools/monitoring/check_k8s_api_performance.py +110 -0
- paasta_tools/monitoring_tools.py +652 -0
- paasta_tools/monkrelaycluster_tools.py +146 -0
- paasta_tools/nrtsearchservice_tools.py +143 -0
- paasta_tools/nrtsearchserviceeks_tools.py +68 -0
- paasta_tools/oom_logger.py +321 -0
- paasta_tools/paasta_deploy_tron_jobs +3 -0
- paasta_tools/paasta_execute_docker_command.py +123 -0
- paasta_tools/paasta_native_serviceinit.py +21 -0
- paasta_tools/paasta_service_config_loader.py +201 -0
- paasta_tools/paastaapi/__init__.py +29 -0
- paasta_tools/paastaapi/api/__init__.py +3 -0
- paasta_tools/paastaapi/api/autoscaler_api.py +302 -0
- paasta_tools/paastaapi/api/default_api.py +569 -0
- paasta_tools/paastaapi/api/remote_run_api.py +604 -0
- paasta_tools/paastaapi/api/resources_api.py +157 -0
- paasta_tools/paastaapi/api/service_api.py +1736 -0
- paasta_tools/paastaapi/api_client.py +818 -0
- paasta_tools/paastaapi/apis/__init__.py +22 -0
- paasta_tools/paastaapi/configuration.py +455 -0
- paasta_tools/paastaapi/exceptions.py +137 -0
- paasta_tools/paastaapi/model/__init__.py +5 -0
- paasta_tools/paastaapi/model/adhoc_launch_history.py +176 -0
- paasta_tools/paastaapi/model/autoscaler_count_msg.py +176 -0
- paasta_tools/paastaapi/model/deploy_queue.py +178 -0
- paasta_tools/paastaapi/model/deploy_queue_service_instance.py +194 -0
- paasta_tools/paastaapi/model/envoy_backend.py +185 -0
- paasta_tools/paastaapi/model/envoy_location.py +184 -0
- paasta_tools/paastaapi/model/envoy_status.py +181 -0
- paasta_tools/paastaapi/model/flink_cluster_overview.py +188 -0
- paasta_tools/paastaapi/model/flink_config.py +173 -0
- paasta_tools/paastaapi/model/flink_job.py +186 -0
- paasta_tools/paastaapi/model/flink_job_details.py +192 -0
- paasta_tools/paastaapi/model/flink_jobs.py +175 -0
- paasta_tools/paastaapi/model/float_and_error.py +173 -0
- paasta_tools/paastaapi/model/hpa_metric.py +176 -0
- paasta_tools/paastaapi/model/inline_object.py +170 -0
- paasta_tools/paastaapi/model/inline_response200.py +170 -0
- paasta_tools/paastaapi/model/inline_response2001.py +170 -0
- paasta_tools/paastaapi/model/instance_bounce_status.py +200 -0
- paasta_tools/paastaapi/model/instance_mesh_status.py +186 -0
- paasta_tools/paastaapi/model/instance_status.py +220 -0
- paasta_tools/paastaapi/model/instance_status_adhoc.py +187 -0
- paasta_tools/paastaapi/model/instance_status_cassandracluster.py +173 -0
- paasta_tools/paastaapi/model/instance_status_flink.py +173 -0
- paasta_tools/paastaapi/model/instance_status_kafkacluster.py +173 -0
- paasta_tools/paastaapi/model/instance_status_kubernetes.py +263 -0
- paasta_tools/paastaapi/model/instance_status_kubernetes_autoscaling_status.py +187 -0
- paasta_tools/paastaapi/model/instance_status_kubernetes_v2.py +197 -0
- paasta_tools/paastaapi/model/instance_status_tron.py +204 -0
- paasta_tools/paastaapi/model/instance_tasks.py +182 -0
- paasta_tools/paastaapi/model/integer_and_error.py +173 -0
- paasta_tools/paastaapi/model/kubernetes_container.py +178 -0
- paasta_tools/paastaapi/model/kubernetes_container_v2.py +219 -0
- paasta_tools/paastaapi/model/kubernetes_healthcheck.py +176 -0
- paasta_tools/paastaapi/model/kubernetes_pod.py +201 -0
- paasta_tools/paastaapi/model/kubernetes_pod_event.py +176 -0
- paasta_tools/paastaapi/model/kubernetes_pod_v2.py +213 -0
- paasta_tools/paastaapi/model/kubernetes_replica_set.py +185 -0
- paasta_tools/paastaapi/model/kubernetes_version.py +202 -0
- paasta_tools/paastaapi/model/remote_run_outcome.py +189 -0
- paasta_tools/paastaapi/model/remote_run_start.py +185 -0
- paasta_tools/paastaapi/model/remote_run_stop.py +176 -0
- paasta_tools/paastaapi/model/remote_run_token.py +173 -0
- paasta_tools/paastaapi/model/resource.py +187 -0
- paasta_tools/paastaapi/model/resource_item.py +187 -0
- paasta_tools/paastaapi/model/resource_value.py +176 -0
- paasta_tools/paastaapi/model/smartstack_backend.py +191 -0
- paasta_tools/paastaapi/model/smartstack_location.py +181 -0
- paasta_tools/paastaapi/model/smartstack_status.py +181 -0
- paasta_tools/paastaapi/model/task_tail_lines.py +176 -0
- paasta_tools/paastaapi/model_utils.py +1879 -0
- paasta_tools/paastaapi/models/__init__.py +62 -0
- paasta_tools/paastaapi/rest.py +287 -0
- paasta_tools/prune_completed_pods.py +220 -0
- paasta_tools/puppet_service_tools.py +59 -0
- paasta_tools/py.typed +1 -0
- paasta_tools/remote_git.py +127 -0
- paasta_tools/run-paasta-api-in-dev-mode.py +57 -0
- paasta_tools/run-paasta-api-playground.py +51 -0
- paasta_tools/secret_providers/__init__.py +66 -0
- paasta_tools/secret_providers/vault.py +214 -0
- paasta_tools/secret_tools.py +277 -0
- paasta_tools/setup_istio_mesh.py +353 -0
- paasta_tools/setup_kubernetes_cr.py +412 -0
- paasta_tools/setup_kubernetes_crd.py +138 -0
- paasta_tools/setup_kubernetes_internal_crd.py +154 -0
- paasta_tools/setup_kubernetes_job.py +353 -0
- paasta_tools/setup_prometheus_adapter_config.py +1028 -0
- paasta_tools/setup_tron_namespace.py +248 -0
- paasta_tools/slack.py +75 -0
- paasta_tools/smartstack_tools.py +676 -0
- paasta_tools/spark_tools.py +283 -0
- paasta_tools/synapse_srv_namespaces_fact.py +42 -0
- paasta_tools/tron/__init__.py +0 -0
- paasta_tools/tron/client.py +158 -0
- paasta_tools/tron/tron_command_context.py +194 -0
- paasta_tools/tron/tron_timeutils.py +101 -0
- paasta_tools/tron_tools.py +1448 -0
- paasta_tools/utils.py +4307 -0
- paasta_tools/yaml_tools.py +44 -0
- paasta_tools-1.21.3.data/scripts/apply_external_resources.py +79 -0
- paasta_tools-1.21.3.data/scripts/bounce_log_latency_parser.py +68 -0
- paasta_tools-1.21.3.data/scripts/check_autoscaler_max_instances.py +212 -0
- paasta_tools-1.21.3.data/scripts/check_cassandracluster_services_replication.py +35 -0
- paasta_tools-1.21.3.data/scripts/check_flink_services_health.py +203 -0
- paasta_tools-1.21.3.data/scripts/check_kubernetes_api.py +57 -0
- paasta_tools-1.21.3.data/scripts/check_kubernetes_services_replication.py +141 -0
- paasta_tools-1.21.3.data/scripts/check_manual_oapi_changes.sh +24 -0
- paasta_tools-1.21.3.data/scripts/check_oom_events.py +244 -0
- paasta_tools-1.21.3.data/scripts/check_orphans.py +306 -0
- paasta_tools-1.21.3.data/scripts/check_spark_jobs.py +234 -0
- paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_cr.py +138 -0
- paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_crd.py +145 -0
- paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_jobs.py +344 -0
- paasta_tools-1.21.3.data/scripts/create_dynamodb_table.py +35 -0
- paasta_tools-1.21.3.data/scripts/create_paasta_playground.py +105 -0
- paasta_tools-1.21.3.data/scripts/delete_kubernetes_deployments.py +89 -0
- paasta_tools-1.21.3.data/scripts/emit_allocated_cpu_metrics.py +50 -0
- paasta_tools-1.21.3.data/scripts/generate_all_deployments +9 -0
- paasta_tools-1.21.3.data/scripts/generate_authenticating_services.py +94 -0
- paasta_tools-1.21.3.data/scripts/generate_deployments_for_service.py +255 -0
- paasta_tools-1.21.3.data/scripts/generate_services_file.py +114 -0
- paasta_tools-1.21.3.data/scripts/generate_services_yaml.py +30 -0
- paasta_tools-1.21.3.data/scripts/get_running_task_allocation.py +346 -0
- paasta_tools-1.21.3.data/scripts/habitat_fixer.py +86 -0
- paasta_tools-1.21.3.data/scripts/ide_helper.py +316 -0
- paasta_tools-1.21.3.data/scripts/is_pod_healthy_in_proxy.py +139 -0
- paasta_tools-1.21.3.data/scripts/is_pod_healthy_in_smartstack.py +50 -0
- paasta_tools-1.21.3.data/scripts/kill_bad_containers.py +109 -0
- paasta_tools-1.21.3.data/scripts/kubernetes_remove_evicted_pods.py +164 -0
- paasta_tools-1.21.3.data/scripts/mass-deploy-tag.sh +44 -0
- paasta_tools-1.21.3.data/scripts/mock_patch_checker.py +86 -0
- paasta_tools-1.21.3.data/scripts/paasta_cleanup_remote_run_resources.py +135 -0
- paasta_tools-1.21.3.data/scripts/paasta_cleanup_stale_nodes.py +181 -0
- paasta_tools-1.21.3.data/scripts/paasta_deploy_tron_jobs +3 -0
- paasta_tools-1.21.3.data/scripts/paasta_execute_docker_command.py +123 -0
- paasta_tools-1.21.3.data/scripts/paasta_secrets_sync.py +758 -0
- paasta_tools-1.21.3.data/scripts/paasta_tabcomplete.sh +23 -0
- paasta_tools-1.21.3.data/scripts/paasta_update_soa_memcpu.py +520 -0
- paasta_tools-1.21.3.data/scripts/render_template.py +129 -0
- paasta_tools-1.21.3.data/scripts/rightsizer_soaconfigs_update.py +348 -0
- paasta_tools-1.21.3.data/scripts/service_shard_remove.py +157 -0
- paasta_tools-1.21.3.data/scripts/service_shard_update.py +373 -0
- paasta_tools-1.21.3.data/scripts/setup_istio_mesh.py +353 -0
- paasta_tools-1.21.3.data/scripts/setup_kubernetes_cr.py +412 -0
- paasta_tools-1.21.3.data/scripts/setup_kubernetes_crd.py +138 -0
- paasta_tools-1.21.3.data/scripts/setup_kubernetes_internal_crd.py +154 -0
- paasta_tools-1.21.3.data/scripts/setup_kubernetes_job.py +353 -0
- paasta_tools-1.21.3.data/scripts/setup_prometheus_adapter_config.py +1028 -0
- paasta_tools-1.21.3.data/scripts/shared_ip_check.py +77 -0
- paasta_tools-1.21.3.data/scripts/synapse_srv_namespaces_fact.py +42 -0
- paasta_tools-1.21.3.data/scripts/timeouts_metrics_prom.py +64 -0
- paasta_tools-1.21.3.dist-info/LICENSE +201 -0
- paasta_tools-1.21.3.dist-info/METADATA +74 -0
- paasta_tools-1.21.3.dist-info/RECORD +348 -0
- paasta_tools-1.21.3.dist-info/WHEEL +5 -0
- paasta_tools-1.21.3.dist-info/entry_points.txt +20 -0
- paasta_tools-1.21.3.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import service_configuration_lib
|
|
4
|
+
|
|
5
|
+
from paasta_tools.kubernetes_tools import KubernetesDeploymentConfig
|
|
6
|
+
from paasta_tools.kubernetes_tools import KubernetesDeploymentConfigDict
|
|
7
|
+
from paasta_tools.utils import BranchDictV2
|
|
8
|
+
from paasta_tools.utils import deep_merge_dictionaries
|
|
9
|
+
from paasta_tools.utils import DEFAULT_SOA_DIR
|
|
10
|
+
from paasta_tools.utils import load_service_instance_config
|
|
11
|
+
from paasta_tools.utils import load_v2_deployments_json
|
|
12
|
+
from paasta_tools.utils import time_cache
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class EksDeploymentConfig(KubernetesDeploymentConfig):
|
|
16
|
+
config_dict: KubernetesDeploymentConfigDict
|
|
17
|
+
|
|
18
|
+
config_filename_prefix = "eks"
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
service: str,
|
|
23
|
+
cluster: str,
|
|
24
|
+
instance: str,
|
|
25
|
+
config_dict: KubernetesDeploymentConfigDict,
|
|
26
|
+
branch_dict: Optional[BranchDictV2],
|
|
27
|
+
soa_dir: str = DEFAULT_SOA_DIR,
|
|
28
|
+
) -> None:
|
|
29
|
+
super().__init__(
|
|
30
|
+
cluster=cluster,
|
|
31
|
+
instance=instance,
|
|
32
|
+
service=service,
|
|
33
|
+
config_dict=config_dict,
|
|
34
|
+
branch_dict=branch_dict,
|
|
35
|
+
soa_dir=soa_dir,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def load_eks_service_config_no_cache(
|
|
40
|
+
service: str,
|
|
41
|
+
instance: str,
|
|
42
|
+
cluster: str,
|
|
43
|
+
load_deployments: bool = True,
|
|
44
|
+
soa_dir: str = DEFAULT_SOA_DIR,
|
|
45
|
+
) -> "EksDeploymentConfig":
|
|
46
|
+
"""Read a service instance's configuration for EKS.
|
|
47
|
+
|
|
48
|
+
If a branch isn't specified for a config, the 'branch' key defaults to
|
|
49
|
+
paasta-${cluster}.${instance}.
|
|
50
|
+
|
|
51
|
+
:param name: The service name
|
|
52
|
+
:param instance: The instance of the service to retrieve
|
|
53
|
+
:param cluster: The cluster to read the configuration for
|
|
54
|
+
:param load_deployments: A boolean indicating if the corresponding deployments.json for this service
|
|
55
|
+
should also be loaded
|
|
56
|
+
:param soa_dir: The SOA configuration directory to read from
|
|
57
|
+
:returns: A dictionary of whatever was in the config for the service instance"""
|
|
58
|
+
general_config = service_configuration_lib.read_service_configuration(
|
|
59
|
+
service, soa_dir=soa_dir
|
|
60
|
+
)
|
|
61
|
+
instance_config = load_service_instance_config(
|
|
62
|
+
service, instance, "eks", cluster, soa_dir=soa_dir
|
|
63
|
+
)
|
|
64
|
+
general_config = deep_merge_dictionaries(
|
|
65
|
+
overrides=instance_config, defaults=general_config
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
branch_dict: Optional[BranchDictV2] = None
|
|
69
|
+
if load_deployments:
|
|
70
|
+
deployments_json = load_v2_deployments_json(service, soa_dir=soa_dir)
|
|
71
|
+
temp_instance_config = EksDeploymentConfig(
|
|
72
|
+
service=service,
|
|
73
|
+
cluster=cluster,
|
|
74
|
+
instance=instance,
|
|
75
|
+
config_dict=general_config,
|
|
76
|
+
branch_dict=None,
|
|
77
|
+
soa_dir=soa_dir,
|
|
78
|
+
)
|
|
79
|
+
branch = temp_instance_config.get_branch()
|
|
80
|
+
deploy_group = temp_instance_config.get_deploy_group()
|
|
81
|
+
branch_dict = deployments_json.get_branch_dict(service, branch, deploy_group)
|
|
82
|
+
|
|
83
|
+
return EksDeploymentConfig(
|
|
84
|
+
service=service,
|
|
85
|
+
cluster=cluster,
|
|
86
|
+
instance=instance,
|
|
87
|
+
config_dict=general_config,
|
|
88
|
+
branch_dict=branch_dict,
|
|
89
|
+
soa_dir=soa_dir,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@time_cache(ttl=5)
|
|
94
|
+
def load_eks_service_config(
|
|
95
|
+
service: str,
|
|
96
|
+
instance: str,
|
|
97
|
+
cluster: str,
|
|
98
|
+
load_deployments: bool = True,
|
|
99
|
+
soa_dir: str = DEFAULT_SOA_DIR,
|
|
100
|
+
) -> "EksDeploymentConfig":
|
|
101
|
+
"""Read a service instance's configuration for EKS.
|
|
102
|
+
|
|
103
|
+
If a branch isn't specified for a config, the 'branch' key defaults to
|
|
104
|
+
paasta-${cluster}.${instance}.
|
|
105
|
+
|
|
106
|
+
:param name: The service name
|
|
107
|
+
:param instance: The instance of the service to retrieve
|
|
108
|
+
:param cluster: The cluster to read the configuration for
|
|
109
|
+
:param load_deployments: A boolean indicating if the corresponding deployments.json for this service
|
|
110
|
+
should also be loaded
|
|
111
|
+
:param soa_dir: The SOA configuration directory to read from
|
|
112
|
+
:returns: A dictionary of whatever was in the config for the service instance"""
|
|
113
|
+
return load_eks_service_config_no_cache(
|
|
114
|
+
service=service,
|
|
115
|
+
instance=instance,
|
|
116
|
+
cluster=cluster,
|
|
117
|
+
load_deployments=load_deployments,
|
|
118
|
+
soa_dir=soa_dir,
|
|
119
|
+
)
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# Copyright 2015-2019 Yelp Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
import collections
|
|
15
|
+
import os
|
|
16
|
+
import socket
|
|
17
|
+
from typing import AbstractSet
|
|
18
|
+
from typing import Any
|
|
19
|
+
from typing import Collection
|
|
20
|
+
from typing import DefaultDict
|
|
21
|
+
from typing import Dict
|
|
22
|
+
from typing import FrozenSet
|
|
23
|
+
from typing import Iterable
|
|
24
|
+
from typing import List
|
|
25
|
+
from typing import Mapping
|
|
26
|
+
from typing import MutableMapping
|
|
27
|
+
from typing import Optional
|
|
28
|
+
from typing import Sequence
|
|
29
|
+
from typing import Set
|
|
30
|
+
from typing import Tuple
|
|
31
|
+
|
|
32
|
+
import requests
|
|
33
|
+
from kubernetes.client import V1Pod
|
|
34
|
+
from mypy_extensions import TypedDict
|
|
35
|
+
|
|
36
|
+
from paasta_tools import yaml_tools as yaml
|
|
37
|
+
from paasta_tools.utils import get_user_agent
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class EnvoyBackend(TypedDict, total=False):
|
|
41
|
+
address: str
|
|
42
|
+
port_value: int
|
|
43
|
+
hostname: str
|
|
44
|
+
eds_health_status: str
|
|
45
|
+
weight: int
|
|
46
|
+
has_associated_task: bool
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def are_services_up_in_pod(
|
|
50
|
+
envoy_host: str,
|
|
51
|
+
envoy_admin_port: int,
|
|
52
|
+
envoy_admin_endpoint_format: str,
|
|
53
|
+
registrations: Collection[str],
|
|
54
|
+
pod_ip: str,
|
|
55
|
+
pod_port: int,
|
|
56
|
+
) -> bool:
|
|
57
|
+
"""Returns whether a service in a k8s pod is reachable via envoy
|
|
58
|
+
:param envoy_host: The host that this check should contact for replication information.
|
|
59
|
+
:param envoy_admin_port: The port that Envoy's admin interface is listening on
|
|
60
|
+
:param registrations: The service_name.instance_name of the services
|
|
61
|
+
:param pod_ip: IP of the pod itself
|
|
62
|
+
:param pod_port: The port to reach the service in the pod
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
for registration in registrations:
|
|
66
|
+
backends_per_registration = get_backends(
|
|
67
|
+
registration,
|
|
68
|
+
envoy_host=envoy_host,
|
|
69
|
+
envoy_admin_port=envoy_admin_port,
|
|
70
|
+
envoy_admin_endpoint_format=envoy_admin_endpoint_format,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
healthy_backends = [
|
|
74
|
+
backend
|
|
75
|
+
for backend in backends_per_registration.get(registration, [])
|
|
76
|
+
if backend[0]["address"] == pod_ip
|
|
77
|
+
and backend[0]["port_value"] == pod_port
|
|
78
|
+
and backend[0]["eds_health_status"] == "HEALTHY"
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
if not healthy_backends:
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def are_namespaces_up_in_eds(
|
|
88
|
+
envoy_eds_path: str,
|
|
89
|
+
namespaces: Collection[str],
|
|
90
|
+
pod_ip: str,
|
|
91
|
+
pod_port: int,
|
|
92
|
+
) -> bool:
|
|
93
|
+
"""Returns whether a Pod is registered on Envoy through the EDS
|
|
94
|
+
:param envoy_eds_path: path where EDS yaml files are stored
|
|
95
|
+
:param namespaces: list of namespaces to check
|
|
96
|
+
:param pod_ip: IP of the pod
|
|
97
|
+
:param pod_port: The port to reach the service in the pod
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
for namespace in namespaces:
|
|
101
|
+
backends_from_eds = get_backends_from_eds(namespace, envoy_eds_path)
|
|
102
|
+
if (pod_ip, pod_port) not in backends_from_eds:
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
return True
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def retrieve_envoy_clusters(
|
|
109
|
+
envoy_host: str, envoy_admin_port: int, envoy_admin_endpoint_format: str
|
|
110
|
+
) -> Dict[str, Any]:
|
|
111
|
+
envoy_uri = envoy_admin_endpoint_format.format(
|
|
112
|
+
host=envoy_host, port=envoy_admin_port, endpoint="clusters?format=json"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# timeout after 3 seconds and retry 3 times
|
|
116
|
+
envoy_admin_request = requests.Session()
|
|
117
|
+
envoy_admin_request.headers.update({"User-Agent": get_user_agent()})
|
|
118
|
+
envoy_admin_request.mount("http://", requests.adapters.HTTPAdapter(max_retries=3))
|
|
119
|
+
envoy_admin_request.mount("https://", requests.adapters.HTTPAdapter(max_retries=3))
|
|
120
|
+
envoy_admin_response = envoy_admin_request.get(envoy_uri, timeout=3)
|
|
121
|
+
return envoy_admin_response.json()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def get_casper_endpoints(
|
|
125
|
+
clusters_info: Mapping[str, Any]
|
|
126
|
+
) -> FrozenSet[Tuple[str, int]]:
|
|
127
|
+
"""Filters out and returns casper endpoints from Envoy clusters."""
|
|
128
|
+
casper_endpoints: Set[Tuple[str, int]] = set()
|
|
129
|
+
for cluster_status in clusters_info["cluster_statuses"]:
|
|
130
|
+
if "host_statuses" in cluster_status:
|
|
131
|
+
if cluster_status["name"].startswith("spectre.") and cluster_status[
|
|
132
|
+
"name"
|
|
133
|
+
].endswith(".egress_cluster"):
|
|
134
|
+
for host_status in cluster_status["host_statuses"]:
|
|
135
|
+
casper_endpoints.add(
|
|
136
|
+
(
|
|
137
|
+
host_status["address"]["socket_address"]["address"],
|
|
138
|
+
host_status["address"]["socket_address"]["port_value"],
|
|
139
|
+
)
|
|
140
|
+
)
|
|
141
|
+
return frozenset(casper_endpoints)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def get_backends_from_eds(namespace: str, envoy_eds_path: str) -> List[Tuple[str, int]]:
|
|
145
|
+
"""Returns a list of backends for a given namespace. Casper backends are also returned (if present).
|
|
146
|
+
|
|
147
|
+
:param namespace: return backends for this namespace
|
|
148
|
+
:param envoy_eds_path: path where EDS yaml files are stored
|
|
149
|
+
:returns backends: a list of touples representing the backends for
|
|
150
|
+
the requested service
|
|
151
|
+
"""
|
|
152
|
+
backends = []
|
|
153
|
+
eds_file_for_namespace = f"{envoy_eds_path}/{namespace}/{namespace}.yaml"
|
|
154
|
+
|
|
155
|
+
if os.access(eds_file_for_namespace, os.R_OK):
|
|
156
|
+
with open(eds_file_for_namespace) as f:
|
|
157
|
+
eds_yaml = yaml.safe_load(f)
|
|
158
|
+
for resource in eds_yaml.get("resources", []):
|
|
159
|
+
endpoints = resource.get("endpoints")
|
|
160
|
+
# endpoints could be None if there are no backends listed
|
|
161
|
+
if endpoints:
|
|
162
|
+
for endpoint in endpoints:
|
|
163
|
+
for lb_endpoint in endpoint.get("lb_endpoints", []):
|
|
164
|
+
address = lb_endpoint["endpoint"]["address"][
|
|
165
|
+
"socket_address"
|
|
166
|
+
]["address"]
|
|
167
|
+
port_value = lb_endpoint["endpoint"]["address"][
|
|
168
|
+
"socket_address"
|
|
169
|
+
]["port_value"]
|
|
170
|
+
backends.append((address, port_value))
|
|
171
|
+
return backends
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def get_backends(
|
|
175
|
+
service: str,
|
|
176
|
+
envoy_host: str,
|
|
177
|
+
envoy_admin_port: int,
|
|
178
|
+
envoy_admin_endpoint_format: str,
|
|
179
|
+
) -> Dict[str, List[Tuple[EnvoyBackend, bool]]]:
|
|
180
|
+
"""Fetches JSON from Envoy admin's /clusters endpoint and returns a list of backends.
|
|
181
|
+
|
|
182
|
+
:param service: If None, return backends for all services, otherwise only return backends for this particular
|
|
183
|
+
service.
|
|
184
|
+
:param envoy_host: The host that this check should contact for replication information.
|
|
185
|
+
:param envoy_admin_port: The port that Envoy's admin interface is listening on
|
|
186
|
+
:param envoy_admin_endpoint_format: The format of Envoy's admin endpoint
|
|
187
|
+
:returns backends: A list of dicts representing the backends of all
|
|
188
|
+
services or the requested service
|
|
189
|
+
"""
|
|
190
|
+
if service:
|
|
191
|
+
services = [service]
|
|
192
|
+
else:
|
|
193
|
+
services = None
|
|
194
|
+
return get_multiple_backends(
|
|
195
|
+
services,
|
|
196
|
+
envoy_host=envoy_host,
|
|
197
|
+
envoy_admin_port=envoy_admin_port,
|
|
198
|
+
envoy_admin_endpoint_format=envoy_admin_endpoint_format,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def get_multiple_backends(
|
|
203
|
+
services: Optional[Sequence[str]],
|
|
204
|
+
envoy_host: str,
|
|
205
|
+
envoy_admin_port: int,
|
|
206
|
+
envoy_admin_endpoint_format: str,
|
|
207
|
+
resolve_hostnames: bool = True,
|
|
208
|
+
) -> Dict[str, List[Tuple[EnvoyBackend, bool]]]:
|
|
209
|
+
"""Fetches JSON from Envoy admin's /clusters endpoint and returns a list of backends.
|
|
210
|
+
|
|
211
|
+
:param services: If None, return backends for all services, otherwise only return backends for these particular
|
|
212
|
+
services.
|
|
213
|
+
:param envoy_host: The host that this check should contact for replication information.
|
|
214
|
+
:param envoy_admin_port: The port that Envoy's admin interface is listening on
|
|
215
|
+
:param envoy_admin_endpoint_format: The format of Envoy's admin endpoint
|
|
216
|
+
:returns backends: A list of dicts representing the backends of all
|
|
217
|
+
services or the requested service
|
|
218
|
+
"""
|
|
219
|
+
clusters_info = retrieve_envoy_clusters(
|
|
220
|
+
envoy_host=envoy_host,
|
|
221
|
+
envoy_admin_port=envoy_admin_port,
|
|
222
|
+
envoy_admin_endpoint_format=envoy_admin_endpoint_format,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
casper_endpoints = get_casper_endpoints(clusters_info)
|
|
226
|
+
|
|
227
|
+
backends: DefaultDict[
|
|
228
|
+
str, List[Tuple[EnvoyBackend, bool]]
|
|
229
|
+
] = collections.defaultdict(list)
|
|
230
|
+
for cluster_status in clusters_info["cluster_statuses"]:
|
|
231
|
+
if "host_statuses" in cluster_status:
|
|
232
|
+
if cluster_status["name"].endswith(".egress_cluster"):
|
|
233
|
+
service_name = cluster_status["name"][: -len(".egress_cluster")]
|
|
234
|
+
|
|
235
|
+
if services is None or service_name in services:
|
|
236
|
+
cluster_backends = []
|
|
237
|
+
casper_endpoint_found = False
|
|
238
|
+
for host_status in cluster_status["host_statuses"]:
|
|
239
|
+
address = host_status["address"]["socket_address"]["address"]
|
|
240
|
+
port_value = host_status["address"]["socket_address"][
|
|
241
|
+
"port_value"
|
|
242
|
+
]
|
|
243
|
+
|
|
244
|
+
# Check if this endpoint is actually a casper backend
|
|
245
|
+
# If so, omit from the service's list of backends
|
|
246
|
+
if not service_name.startswith("spectre."):
|
|
247
|
+
if (address, port_value) in casper_endpoints:
|
|
248
|
+
casper_endpoint_found = True
|
|
249
|
+
continue
|
|
250
|
+
|
|
251
|
+
hostname = address
|
|
252
|
+
if resolve_hostnames:
|
|
253
|
+
try:
|
|
254
|
+
hostname = socket.gethostbyaddr(address)[0].split(".")[
|
|
255
|
+
0
|
|
256
|
+
]
|
|
257
|
+
except socket.herror:
|
|
258
|
+
# Default to the raw IP address if we can't lookup the hostname
|
|
259
|
+
pass
|
|
260
|
+
|
|
261
|
+
cluster_backends.append(
|
|
262
|
+
(
|
|
263
|
+
EnvoyBackend(
|
|
264
|
+
address=address,
|
|
265
|
+
port_value=port_value,
|
|
266
|
+
hostname=hostname,
|
|
267
|
+
eds_health_status=host_status["health_status"][
|
|
268
|
+
"eds_health_status"
|
|
269
|
+
],
|
|
270
|
+
weight=host_status["weight"],
|
|
271
|
+
),
|
|
272
|
+
casper_endpoint_found,
|
|
273
|
+
)
|
|
274
|
+
)
|
|
275
|
+
backends[service_name] += cluster_backends
|
|
276
|
+
return backends
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def match_backends_and_pods(
|
|
280
|
+
backends: Iterable[EnvoyBackend],
|
|
281
|
+
pods: Iterable[V1Pod],
|
|
282
|
+
) -> List[Tuple[Optional[EnvoyBackend], Optional[V1Pod]]]:
|
|
283
|
+
"""Returns tuples of matching (backend, pod) pairs, as matched by IP. Each backend will be listed exactly
|
|
284
|
+
once. If a backend does not match with a pod, (backend, None) will be included.
|
|
285
|
+
If a pod's IP does not match with any backends, (None, pod) will be included.
|
|
286
|
+
|
|
287
|
+
:param backends: An iterable of Envoy backend dictionaries, e.g. the list returned by
|
|
288
|
+
envoy_tools.get_multiple_backends.
|
|
289
|
+
:param pods: A list of pods
|
|
290
|
+
"""
|
|
291
|
+
|
|
292
|
+
# { ip : [backend1, backend2], ... }
|
|
293
|
+
backends_by_ip: DefaultDict[str, List[EnvoyBackend]] = collections.defaultdict(list)
|
|
294
|
+
backend_pod_pairs = []
|
|
295
|
+
|
|
296
|
+
for backend in backends:
|
|
297
|
+
ip = backend["address"]
|
|
298
|
+
backends_by_ip[ip].append(backend)
|
|
299
|
+
|
|
300
|
+
for pod in pods:
|
|
301
|
+
ip = pod.status.pod_ip
|
|
302
|
+
for backend in backends_by_ip.pop(ip, [None]):
|
|
303
|
+
backend_pod_pairs.append((backend, pod))
|
|
304
|
+
|
|
305
|
+
# we've been popping in the above loop, so anything left didn't match a k8s pod.
|
|
306
|
+
for backends in backends_by_ip.values():
|
|
307
|
+
for backend in backends:
|
|
308
|
+
backend_pod_pairs.append((backend, None))
|
|
309
|
+
|
|
310
|
+
return backend_pod_pairs
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def build_envoy_location_dict(
|
|
314
|
+
location: str,
|
|
315
|
+
matched_envoy_backends_and_tasks: Sequence[
|
|
316
|
+
Tuple[Optional[EnvoyBackend], Optional[V1Pod]]
|
|
317
|
+
],
|
|
318
|
+
should_return_individual_backends: bool,
|
|
319
|
+
casper_proxied_backends: AbstractSet[Tuple[str, int]],
|
|
320
|
+
) -> MutableMapping[str, Any]:
|
|
321
|
+
running_backends_count = 0
|
|
322
|
+
envoy_backends = []
|
|
323
|
+
is_proxied_through_casper = False
|
|
324
|
+
for backend, task in matched_envoy_backends_and_tasks:
|
|
325
|
+
if backend is None:
|
|
326
|
+
continue
|
|
327
|
+
if backend["eds_health_status"] == "HEALTHY":
|
|
328
|
+
running_backends_count += 1
|
|
329
|
+
if should_return_individual_backends:
|
|
330
|
+
backend["has_associated_task"] = task is not None
|
|
331
|
+
envoy_backends.append(backend)
|
|
332
|
+
if (backend["address"], backend["port_value"]) in casper_proxied_backends:
|
|
333
|
+
is_proxied_through_casper = True
|
|
334
|
+
return {
|
|
335
|
+
"name": location,
|
|
336
|
+
"running_backends_count": running_backends_count,
|
|
337
|
+
"backends": envoy_backends,
|
|
338
|
+
"is_proxied_through_casper": is_proxied_through_casper,
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def get_replication_for_all_services(
|
|
343
|
+
envoy_host: str,
|
|
344
|
+
envoy_admin_port: int,
|
|
345
|
+
envoy_admin_endpoint_format: str,
|
|
346
|
+
) -> Dict[str, int]:
|
|
347
|
+
"""Returns the replication level for all services known to this Envoy
|
|
348
|
+
|
|
349
|
+
:param envoy_host: The host that this check should contact for replication information.
|
|
350
|
+
:param envoy_admin_port: The port number that this check should contact for replication information.
|
|
351
|
+
:param envoy_admin_endpoint_format: The format of Envoy's admin endpoint
|
|
352
|
+
:returns available_instance_counts: A dictionary mapping the service names
|
|
353
|
+
to an integer number of available replicas.
|
|
354
|
+
"""
|
|
355
|
+
backends = get_multiple_backends(
|
|
356
|
+
services=None,
|
|
357
|
+
envoy_host=envoy_host,
|
|
358
|
+
envoy_admin_port=envoy_admin_port,
|
|
359
|
+
envoy_admin_endpoint_format=envoy_admin_endpoint_format,
|
|
360
|
+
resolve_hostnames=False, # we're not really going to use the hostnames, so skip fetching them to save time
|
|
361
|
+
)
|
|
362
|
+
return collections.Counter(
|
|
363
|
+
[
|
|
364
|
+
service_name
|
|
365
|
+
for service_name, service_backends in backends.items()
|
|
366
|
+
for b in service_backends
|
|
367
|
+
if backend_is_up(b[0])
|
|
368
|
+
]
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def backend_is_up(backend: EnvoyBackend) -> bool:
|
|
373
|
+
return backend["eds_health_status"] == "HEALTHY"
|