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,172 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import logging
|
|
3
|
+
import os.path
|
|
4
|
+
import time
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
|
|
7
|
+
from inotify.adapters import Inotify
|
|
8
|
+
from inotify.constants import IN_MODIFY
|
|
9
|
+
from inotify.constants import IN_MOVED_TO
|
|
10
|
+
|
|
11
|
+
from paasta_tools import firewall
|
|
12
|
+
from paasta_tools.cli.utils import get_instance_config
|
|
13
|
+
from paasta_tools.utils import DEFAULT_SOA_DIR
|
|
14
|
+
from paasta_tools.utils import load_system_paasta_config
|
|
15
|
+
from paasta_tools.utils import TimeoutError
|
|
16
|
+
|
|
17
|
+
log = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
DEFAULT_UPDATE_SECS = 5
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def parse_args(argv):
|
|
23
|
+
parser = argparse.ArgumentParser(
|
|
24
|
+
description="Monitor synapse changes and update service firewall rules"
|
|
25
|
+
)
|
|
26
|
+
parser.add_argument(
|
|
27
|
+
"-d",
|
|
28
|
+
"--soa-dir",
|
|
29
|
+
dest="soa_dir",
|
|
30
|
+
metavar="soa_dir",
|
|
31
|
+
default=DEFAULT_SOA_DIR,
|
|
32
|
+
help="define a different soa config directory (default %(default)s)",
|
|
33
|
+
)
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
"--synapse-service-dir",
|
|
36
|
+
dest="synapse_service_dir",
|
|
37
|
+
default=firewall.DEFAULT_SYNAPSE_SERVICE_DIR,
|
|
38
|
+
help="Path to synapse service dir (default %(default)s)",
|
|
39
|
+
)
|
|
40
|
+
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true")
|
|
41
|
+
|
|
42
|
+
subparsers = parser.add_subparsers(
|
|
43
|
+
help="mode to run firewall update in", dest="mode"
|
|
44
|
+
)
|
|
45
|
+
subparsers.required = True
|
|
46
|
+
|
|
47
|
+
daemon_parser = subparsers.add_parser(
|
|
48
|
+
"daemon",
|
|
49
|
+
description=(
|
|
50
|
+
"Run a daemon which watches updates to synapse backends and updates iptables rules."
|
|
51
|
+
),
|
|
52
|
+
)
|
|
53
|
+
daemon_parser.add_argument(
|
|
54
|
+
"-u",
|
|
55
|
+
"--update-secs",
|
|
56
|
+
dest="update_secs",
|
|
57
|
+
default=DEFAULT_UPDATE_SECS,
|
|
58
|
+
type=int,
|
|
59
|
+
help="Poll for new containers every N secs (default %(default)s)",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
subparsers.add_parser(
|
|
63
|
+
"cron",
|
|
64
|
+
description=(
|
|
65
|
+
"Do a one-time update of iptables rules to match the current running services."
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
args = parser.parse_args(argv)
|
|
70
|
+
return args
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def setup_logging(verbose):
|
|
74
|
+
level = logging.DEBUG if verbose else logging.WARNING
|
|
75
|
+
logging.basicConfig(level=level)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def run_daemon(args):
|
|
79
|
+
# Main loop waiting on inotify file events
|
|
80
|
+
inotify = Inotify(block_duration_s=1) # event_gen blocks for 1 second
|
|
81
|
+
inotify.add_watch(args.synapse_service_dir.encode(), IN_MOVED_TO | IN_MODIFY)
|
|
82
|
+
services_by_dependencies_time = 0
|
|
83
|
+
|
|
84
|
+
for event in inotify.event_gen(): # blocks for only up to 1 second at a time
|
|
85
|
+
if services_by_dependencies_time + args.update_secs < time.time():
|
|
86
|
+
services_by_dependencies = (
|
|
87
|
+
smartstack_dependencies_of_running_firewalled_services(
|
|
88
|
+
soa_dir=args.soa_dir
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
services_by_dependencies_time = time.time()
|
|
92
|
+
|
|
93
|
+
if event is None:
|
|
94
|
+
continue
|
|
95
|
+
|
|
96
|
+
process_inotify_event(
|
|
97
|
+
event, services_by_dependencies, args.soa_dir, args.synapse_service_dir
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def run_cron(args):
|
|
102
|
+
with firewall.firewall_flock():
|
|
103
|
+
firewall.general_update(args.soa_dir, args.synapse_service_dir)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def process_inotify_event(
|
|
107
|
+
event, services_by_dependencies, soa_dir, synapse_service_dir
|
|
108
|
+
):
|
|
109
|
+
filename = event[3].decode()
|
|
110
|
+
log.debug(f"process_inotify_event on {filename}")
|
|
111
|
+
|
|
112
|
+
service_instance, suffix = os.path.splitext(filename)
|
|
113
|
+
if suffix != ".json":
|
|
114
|
+
return
|
|
115
|
+
|
|
116
|
+
services_to_update = services_by_dependencies.get(service_instance, ())
|
|
117
|
+
if not services_to_update:
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
# filter active_service_groups() down to just the names in services_to_update
|
|
121
|
+
service_groups = {
|
|
122
|
+
service_group: macs
|
|
123
|
+
for service_group, macs in firewall.active_service_groups().items()
|
|
124
|
+
if service_group in services_to_update
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
with firewall.firewall_flock():
|
|
129
|
+
firewall.ensure_service_chains(service_groups, soa_dir, synapse_service_dir)
|
|
130
|
+
|
|
131
|
+
for service_to_update in services_to_update:
|
|
132
|
+
log.debug(f"Updated {service_to_update}")
|
|
133
|
+
except TimeoutError as e:
|
|
134
|
+
log.error(
|
|
135
|
+
"Unable to update firewalls for {} because time-out obtaining flock: {}".format(
|
|
136
|
+
service_groups.keys(), e
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def smartstack_dependencies_of_running_firewalled_services(soa_dir=DEFAULT_SOA_DIR):
|
|
142
|
+
dependencies_to_services = defaultdict(set)
|
|
143
|
+
for service, instance, _, _ in firewall.services_running_here():
|
|
144
|
+
config = get_instance_config(
|
|
145
|
+
service=service,
|
|
146
|
+
instance=instance,
|
|
147
|
+
cluster=load_system_paasta_config().get_cluster(),
|
|
148
|
+
load_deployments=False,
|
|
149
|
+
soa_dir=soa_dir,
|
|
150
|
+
)
|
|
151
|
+
outbound_firewall = config.get_outbound_firewall()
|
|
152
|
+
if not outbound_firewall:
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
dependencies = config.get_dependencies() or ()
|
|
156
|
+
|
|
157
|
+
smartstack_dependencies = [
|
|
158
|
+
d["smartstack"] for d in dependencies if d.get("smartstack")
|
|
159
|
+
]
|
|
160
|
+
for smartstack_dependency in smartstack_dependencies:
|
|
161
|
+
# TODO: filter down to only services that have no proxy_port
|
|
162
|
+
dependencies_to_services[smartstack_dependency].add(
|
|
163
|
+
firewall.ServiceGroup(service, instance)
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
return dependencies_to_services
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def main(argv=None):
|
|
170
|
+
args = parse_args(argv)
|
|
171
|
+
setup_logging(args.verbose)
|
|
172
|
+
{"daemon": run_daemon, "cron": run_cron}[args.mode](args)
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# Copyright 2015-2019 Yelp Inc.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
import json
|
|
14
|
+
from typing import Any
|
|
15
|
+
from typing import List
|
|
16
|
+
from typing import Mapping
|
|
17
|
+
from typing import Optional
|
|
18
|
+
from urllib.parse import urljoin
|
|
19
|
+
from urllib.parse import urlparse
|
|
20
|
+
|
|
21
|
+
import requests
|
|
22
|
+
import service_configuration_lib
|
|
23
|
+
from mypy_extensions import TypedDict
|
|
24
|
+
|
|
25
|
+
from paasta_tools.api import settings
|
|
26
|
+
from paasta_tools.api.client import PaastaOApiClient
|
|
27
|
+
from paasta_tools.async_utils import async_timeout
|
|
28
|
+
from paasta_tools.kubernetes_tools import get_cr
|
|
29
|
+
from paasta_tools.kubernetes_tools import paasta_prefixed
|
|
30
|
+
from paasta_tools.kubernetes_tools import sanitised_cr_name
|
|
31
|
+
from paasta_tools.long_running_service_tools import LongRunningServiceConfig
|
|
32
|
+
from paasta_tools.long_running_service_tools import LongRunningServiceConfigDict
|
|
33
|
+
from paasta_tools.paastaapi.exceptions import ApiException
|
|
34
|
+
from paasta_tools.paastaapi.model.flink_cluster_overview import FlinkClusterOverview
|
|
35
|
+
from paasta_tools.paastaapi.model.flink_config import FlinkConfig
|
|
36
|
+
from paasta_tools.paastaapi.model.flink_job_details import FlinkJobDetails
|
|
37
|
+
from paasta_tools.paastaapi.model.flink_jobs import FlinkJobs
|
|
38
|
+
from paasta_tools.utils import BranchDictV2
|
|
39
|
+
from paasta_tools.utils import deep_merge_dictionaries
|
|
40
|
+
from paasta_tools.utils import DEFAULT_SOA_DIR
|
|
41
|
+
from paasta_tools.utils import load_service_instance_config
|
|
42
|
+
from paasta_tools.utils import load_v2_deployments_json
|
|
43
|
+
|
|
44
|
+
FLINK_INGRESS_PORT = 31080
|
|
45
|
+
FLINK_DASHBOARD_TIMEOUT_SECONDS = 5
|
|
46
|
+
CONFIG_KEYS = {"flink-version", "flink-revision"}
|
|
47
|
+
OVERVIEW_KEYS = {
|
|
48
|
+
"taskmanagers",
|
|
49
|
+
"slots-total",
|
|
50
|
+
"slots-available",
|
|
51
|
+
"jobs-running",
|
|
52
|
+
"jobs-finished",
|
|
53
|
+
"jobs-cancelled",
|
|
54
|
+
"jobs-failed",
|
|
55
|
+
}
|
|
56
|
+
JOB_DETAILS_KEYS = {"jid", "name", "state", "start-time"}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class TaskManagerConfig(TypedDict, total=False):
|
|
60
|
+
instances: int
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class FlinkDeploymentConfigDict(LongRunningServiceConfigDict, total=False):
|
|
64
|
+
taskmanager: TaskManagerConfig
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class FlinkDeploymentConfig(LongRunningServiceConfig):
|
|
68
|
+
config_dict: FlinkDeploymentConfigDict
|
|
69
|
+
|
|
70
|
+
config_filename_prefix = "flink"
|
|
71
|
+
|
|
72
|
+
def __init__(
|
|
73
|
+
self,
|
|
74
|
+
service: str,
|
|
75
|
+
cluster: str,
|
|
76
|
+
instance: str,
|
|
77
|
+
config_dict: FlinkDeploymentConfigDict,
|
|
78
|
+
branch_dict: Optional[BranchDictV2],
|
|
79
|
+
soa_dir: str = DEFAULT_SOA_DIR,
|
|
80
|
+
) -> None:
|
|
81
|
+
|
|
82
|
+
super().__init__(
|
|
83
|
+
cluster=cluster,
|
|
84
|
+
instance=instance,
|
|
85
|
+
service=service,
|
|
86
|
+
soa_dir=soa_dir,
|
|
87
|
+
config_dict=config_dict,
|
|
88
|
+
branch_dict=branch_dict,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def validate(
|
|
92
|
+
self,
|
|
93
|
+
params: List[str] = [
|
|
94
|
+
"cpus",
|
|
95
|
+
"mem",
|
|
96
|
+
"security",
|
|
97
|
+
"dependencies_reference",
|
|
98
|
+
"deploy_group",
|
|
99
|
+
],
|
|
100
|
+
) -> List[str]:
|
|
101
|
+
# Use InstanceConfig to validate shared config keys like cpus and mem
|
|
102
|
+
error_msgs = super().validate(params=params)
|
|
103
|
+
|
|
104
|
+
if error_msgs:
|
|
105
|
+
name = self.get_instance()
|
|
106
|
+
return [f"{name}: {msg}" for msg in error_msgs]
|
|
107
|
+
else:
|
|
108
|
+
return []
|
|
109
|
+
|
|
110
|
+
# Since Flink services are stateful, losing capacity is not transparent to the users
|
|
111
|
+
def get_replication_crit_percentage(self) -> int:
|
|
112
|
+
return self.config_dict.get("replication_threshold", 100)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def load_flink_instance_config(
|
|
116
|
+
service: str,
|
|
117
|
+
instance: str,
|
|
118
|
+
cluster: str,
|
|
119
|
+
load_deployments: bool = True,
|
|
120
|
+
soa_dir: str = DEFAULT_SOA_DIR,
|
|
121
|
+
) -> FlinkDeploymentConfig:
|
|
122
|
+
"""Read a service instance's configuration for Flink.
|
|
123
|
+
|
|
124
|
+
If a branch isn't specified for a config, the 'branch' key defaults to
|
|
125
|
+
paasta-${cluster}.${instance}.
|
|
126
|
+
|
|
127
|
+
:param service: The service name
|
|
128
|
+
:param instance: The instance of the service to retrieve
|
|
129
|
+
:param cluster: The cluster to read the configuration for
|
|
130
|
+
:param load_deployments: A boolean indicating if the corresponding deployments.json for this service
|
|
131
|
+
should also be loaded
|
|
132
|
+
:param soa_dir: The SOA configuration directory to read from
|
|
133
|
+
:returns: A dictionary of whatever was in the config for the service instance"""
|
|
134
|
+
general_config = service_configuration_lib.read_service_configuration(
|
|
135
|
+
service, soa_dir=soa_dir
|
|
136
|
+
)
|
|
137
|
+
instance_config = load_service_instance_config(
|
|
138
|
+
service, instance, "flink", cluster, soa_dir=soa_dir
|
|
139
|
+
)
|
|
140
|
+
general_config = deep_merge_dictionaries(
|
|
141
|
+
overrides=instance_config, defaults=general_config
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
branch_dict: Optional[BranchDictV2] = None
|
|
145
|
+
if load_deployments:
|
|
146
|
+
deployments_json = load_v2_deployments_json(service, soa_dir=soa_dir)
|
|
147
|
+
temp_instance_config = FlinkDeploymentConfig(
|
|
148
|
+
service=service,
|
|
149
|
+
cluster=cluster,
|
|
150
|
+
instance=instance,
|
|
151
|
+
config_dict=general_config,
|
|
152
|
+
branch_dict=None,
|
|
153
|
+
soa_dir=soa_dir,
|
|
154
|
+
)
|
|
155
|
+
branch = temp_instance_config.get_branch()
|
|
156
|
+
deploy_group = temp_instance_config.get_deploy_group()
|
|
157
|
+
branch_dict = deployments_json.get_branch_dict(service, branch, deploy_group)
|
|
158
|
+
|
|
159
|
+
return FlinkDeploymentConfig(
|
|
160
|
+
service=service,
|
|
161
|
+
cluster=cluster,
|
|
162
|
+
instance=instance,
|
|
163
|
+
config_dict=general_config,
|
|
164
|
+
branch_dict=branch_dict,
|
|
165
|
+
soa_dir=soa_dir,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
# TODO: read this from CRD in service configs
|
|
170
|
+
def cr_id(service: str, instance: str) -> Mapping[str, str]:
|
|
171
|
+
return dict(
|
|
172
|
+
group="yelp.com",
|
|
173
|
+
version="v1alpha1",
|
|
174
|
+
namespace="paasta-flinks",
|
|
175
|
+
plural="flinks",
|
|
176
|
+
name=sanitised_cr_name(service, instance),
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def get_flink_ingress_url_root(cluster: str, is_eks: bool) -> str:
|
|
181
|
+
if is_eks:
|
|
182
|
+
return f"http://flink.eks.{cluster}.paasta:{FLINK_INGRESS_PORT}/"
|
|
183
|
+
else:
|
|
184
|
+
return f"http://flink.k8s.{cluster}.paasta:{FLINK_INGRESS_PORT}/"
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _dashboard_get(cr_name: str, cluster: str, path: str, is_eks: bool) -> str:
|
|
188
|
+
root = get_flink_ingress_url_root(cluster, is_eks)
|
|
189
|
+
url = f"{root}{cr_name}/{path}"
|
|
190
|
+
response = requests.get(url, timeout=FLINK_DASHBOARD_TIMEOUT_SECONDS)
|
|
191
|
+
response.raise_for_status()
|
|
192
|
+
return response.text
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _filter_for_endpoint(json_response: Any, endpoint: str) -> Mapping[str, Any]:
|
|
196
|
+
"""
|
|
197
|
+
Filter json response to include only a subset of fields.
|
|
198
|
+
"""
|
|
199
|
+
if endpoint == "config":
|
|
200
|
+
return {
|
|
201
|
+
key: value for (key, value) in json_response.items() if key in CONFIG_KEYS
|
|
202
|
+
}
|
|
203
|
+
if endpoint == "overview":
|
|
204
|
+
return {
|
|
205
|
+
key: value for (key, value) in json_response.items() if key in OVERVIEW_KEYS
|
|
206
|
+
}
|
|
207
|
+
if endpoint == "jobs":
|
|
208
|
+
return json_response
|
|
209
|
+
if endpoint.startswith("jobs"):
|
|
210
|
+
return {
|
|
211
|
+
key: value
|
|
212
|
+
for (key, value) in json_response.items()
|
|
213
|
+
if key in JOB_DETAILS_KEYS
|
|
214
|
+
}
|
|
215
|
+
return json_response
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _get_jm_rest_api_base_url(cr: Mapping[str, Any]) -> str:
|
|
219
|
+
metadata = cr["metadata"]
|
|
220
|
+
cluster = metadata["labels"][paasta_prefixed("cluster")]
|
|
221
|
+
is_eks = metadata["labels"].get("paasta.yelp.com/eks", "False")
|
|
222
|
+
base_url = get_flink_ingress_url_root(cluster, is_eks == "True")
|
|
223
|
+
|
|
224
|
+
# this will look something like http://flink-jobmanager-host:port/paasta-service-cr-name
|
|
225
|
+
_, _, service_cr_name, *_ = urlparse(
|
|
226
|
+
metadata["annotations"]["flink.yelp.com/dashboard_url"]
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
return urljoin(base_url, service_cr_name)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def curl_flink_endpoint(cr_id: Mapping[str, str], endpoint: str) -> Mapping[str, Any]:
|
|
233
|
+
try:
|
|
234
|
+
cr = get_cr(settings.kubernetes_client, cr_id)
|
|
235
|
+
if cr is None:
|
|
236
|
+
raise ValueError(f"failed to get CR for id: {cr_id}")
|
|
237
|
+
base_url = _get_jm_rest_api_base_url(cr)
|
|
238
|
+
|
|
239
|
+
# Closing 'base_url' with '/' to force urljoin to append 'endpoint' to the path.
|
|
240
|
+
# If not, urljoin replaces the 'base_url' path with 'endpoint'.
|
|
241
|
+
url = urljoin(base_url + "/", endpoint)
|
|
242
|
+
response = requests.get(url, timeout=FLINK_DASHBOARD_TIMEOUT_SECONDS)
|
|
243
|
+
if not response.ok:
|
|
244
|
+
return {
|
|
245
|
+
"status": response.status_code,
|
|
246
|
+
"error": response.reason,
|
|
247
|
+
"text": response.text,
|
|
248
|
+
}
|
|
249
|
+
return _filter_for_endpoint(response.json(), endpoint)
|
|
250
|
+
except requests.RequestException as e:
|
|
251
|
+
url = e.request.url
|
|
252
|
+
err = e.response or str(e)
|
|
253
|
+
raise ValueError(f"failed HTTP request to flink API {url}: {err}")
|
|
254
|
+
except json.JSONDecodeError as e:
|
|
255
|
+
raise ValueError(f"JSON decoding error from flink API: {e}")
|
|
256
|
+
except ConnectionError as e:
|
|
257
|
+
raise ValueError(f"failed HTTP request to flink API: {e}")
|
|
258
|
+
except ApiException as e:
|
|
259
|
+
raise ValueError(f"failed HTTP request to flink API: {e}")
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def get_flink_jobmanager_overview(
|
|
263
|
+
cr_name: str, cluster: str, is_eks: bool
|
|
264
|
+
) -> Mapping[str, Any]:
|
|
265
|
+
try:
|
|
266
|
+
response = _dashboard_get(cr_name, cluster, "overview", is_eks)
|
|
267
|
+
return json.loads(response)
|
|
268
|
+
except requests.RequestException as e:
|
|
269
|
+
url = e.request.url
|
|
270
|
+
err = e.response or str(e)
|
|
271
|
+
raise ValueError(f"failed HTTP request to Jobmanager dashboard {url}: {err}")
|
|
272
|
+
except json.JSONDecodeError as e:
|
|
273
|
+
raise ValueError(f"JSON decoding error from Jobmanager dashboard: {e}")
|
|
274
|
+
except ConnectionError as e:
|
|
275
|
+
raise ValueError(f"failed HTTP request to Jobmanager dashboard: {e}")
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def get_flink_jobs_from_paasta_api_client(
|
|
279
|
+
service: str, instance: str, client: PaastaOApiClient
|
|
280
|
+
) -> FlinkJobs:
|
|
281
|
+
"""Get flink jobs for (service, instance) pair by connecting to the paasta api endpoint.
|
|
282
|
+
|
|
283
|
+
Appends exception to output list if any.
|
|
284
|
+
|
|
285
|
+
:param service: The service name
|
|
286
|
+
:param instance: The instance of the service to retrieve
|
|
287
|
+
:param client: The paasta api client
|
|
288
|
+
:returns: Flink jobs in the flink cluster"""
|
|
289
|
+
return client.service.list_flink_cluster_jobs(
|
|
290
|
+
service=service,
|
|
291
|
+
instance=instance,
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@async_timeout()
|
|
296
|
+
async def get_flink_job_details_from_paasta_api_client(
|
|
297
|
+
service: str, instance: str, job_id: str, client: PaastaOApiClient
|
|
298
|
+
) -> FlinkJobDetails:
|
|
299
|
+
"""Get flink job details for (service, instance) pair by connecting to the paasta api endpoint.
|
|
300
|
+
|
|
301
|
+
Appends exception to output list if any.
|
|
302
|
+
|
|
303
|
+
:param service: The service name
|
|
304
|
+
:param instance: The instance of the service to retrieve
|
|
305
|
+
:param client: The paasta api client
|
|
306
|
+
:returns: Flink jobs in the flink cluster"""
|
|
307
|
+
return client.service.get_flink_cluster_job_details(
|
|
308
|
+
service=service,
|
|
309
|
+
instance=instance,
|
|
310
|
+
job_id=job_id,
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def get_flink_config_from_paasta_api_client(
|
|
315
|
+
service: str, instance: str, client: PaastaOApiClient
|
|
316
|
+
) -> FlinkConfig:
|
|
317
|
+
"""Get flink config for (service, instance) pair by connecting to the paasta api endpoint.
|
|
318
|
+
|
|
319
|
+
Appends exception to output list if any.
|
|
320
|
+
|
|
321
|
+
:param service: The service name
|
|
322
|
+
:param instance: The instance of the service to retrieve
|
|
323
|
+
:param client: The paasta api client
|
|
324
|
+
:returns: Flink cluster configurations"""
|
|
325
|
+
return client.service.get_flink_cluster_config(
|
|
326
|
+
service=service,
|
|
327
|
+
instance=instance,
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def get_flink_overview_from_paasta_api_client(
|
|
332
|
+
service: str, instance: str, client: PaastaOApiClient
|
|
333
|
+
) -> FlinkClusterOverview:
|
|
334
|
+
"""Get flink cluster overview for (service, instance) pair by connecting to the paasta api endpoint.
|
|
335
|
+
|
|
336
|
+
Appends exception to output list if any.
|
|
337
|
+
|
|
338
|
+
:param service: The service name
|
|
339
|
+
:param instance: The instance of the service to retrieve
|
|
340
|
+
:param client: The paasta api client
|
|
341
|
+
:returns: Flink cluster overview"""
|
|
342
|
+
return client.service.get_flink_cluster_overview(
|
|
343
|
+
service=service,
|
|
344
|
+
instance=instance,
|
|
345
|
+
)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import service_configuration_lib
|
|
4
|
+
|
|
5
|
+
from paasta_tools.flink_tools import FlinkDeploymentConfig
|
|
6
|
+
from paasta_tools.flink_tools import FlinkDeploymentConfigDict
|
|
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
|
+
|
|
13
|
+
|
|
14
|
+
class FlinkEksDeploymentConfig(FlinkDeploymentConfig):
|
|
15
|
+
config_dict: FlinkDeploymentConfigDict
|
|
16
|
+
|
|
17
|
+
config_filename_prefix = "flinkeks"
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
service: str,
|
|
22
|
+
cluster: str,
|
|
23
|
+
instance: str,
|
|
24
|
+
config_dict: FlinkDeploymentConfigDict,
|
|
25
|
+
branch_dict: Optional[BranchDictV2],
|
|
26
|
+
soa_dir: str = DEFAULT_SOA_DIR,
|
|
27
|
+
) -> None:
|
|
28
|
+
|
|
29
|
+
super().__init__(
|
|
30
|
+
cluster=cluster,
|
|
31
|
+
instance=instance,
|
|
32
|
+
service=service,
|
|
33
|
+
soa_dir=soa_dir,
|
|
34
|
+
config_dict=config_dict,
|
|
35
|
+
branch_dict=branch_dict,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def load_flinkeks_instance_config(
|
|
40
|
+
service: str,
|
|
41
|
+
instance: str,
|
|
42
|
+
cluster: str,
|
|
43
|
+
load_deployments: bool = True,
|
|
44
|
+
soa_dir: str = DEFAULT_SOA_DIR,
|
|
45
|
+
) -> FlinkEksDeploymentConfig:
|
|
46
|
+
"""Read a service instance's configuration for Flink on EKS.
|
|
47
|
+
|
|
48
|
+
If a branch isn't specified for a config, the 'branch' key defaults to
|
|
49
|
+
paasta-${cluster}.${instance}.
|
|
50
|
+
|
|
51
|
+
:param service: 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, "flinkeks", 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 = FlinkEksDeploymentConfig(
|
|
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 FlinkEksDeploymentConfig(
|
|
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
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# Copyright 2015-2017 Yelp Inc.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
from typing import Dict
|
|
16
|
+
from typing import List
|
|
17
|
+
from typing import Tuple
|
|
18
|
+
|
|
19
|
+
from pymesos import MesosSchedulerDriver
|
|
20
|
+
|
|
21
|
+
from paasta_tools.frameworks.constraints import ConstraintState
|
|
22
|
+
from paasta_tools.frameworks.native_scheduler import LIVE_TASK_STATES
|
|
23
|
+
from paasta_tools.frameworks.native_scheduler import NativeScheduler
|
|
24
|
+
from paasta_tools.frameworks.native_service_config import TaskInfo
|
|
25
|
+
from paasta_tools.frameworks.native_service_config import UnknownNativeServiceError
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AdhocScheduler(NativeScheduler):
|
|
29
|
+
def __init__(self, *args, **kwargs):
|
|
30
|
+
self.dry_run = kwargs.pop("dry_run")
|
|
31
|
+
|
|
32
|
+
if kwargs.get("service_config_overrides") is None:
|
|
33
|
+
kwargs["service_config_overrides"] = {}
|
|
34
|
+
kwargs["service_config_overrides"].setdefault("instances", 1)
|
|
35
|
+
self.finished_countdown = kwargs["service_config_overrides"]["instances"]
|
|
36
|
+
|
|
37
|
+
super().__init__(*args, **kwargs)
|
|
38
|
+
|
|
39
|
+
def need_to_stop(self):
|
|
40
|
+
# Is used to decide whether to stop the driver or try to start more tasks.
|
|
41
|
+
return self.finished_countdown == 0
|
|
42
|
+
|
|
43
|
+
def statusUpdate(self, driver: MesosSchedulerDriver, update: Dict):
|
|
44
|
+
super().statusUpdate(driver, update)
|
|
45
|
+
|
|
46
|
+
if update["state"] not in LIVE_TASK_STATES:
|
|
47
|
+
self.finished_countdown -= 1
|
|
48
|
+
|
|
49
|
+
# Stop if task ran and finished
|
|
50
|
+
if self.need_to_stop():
|
|
51
|
+
driver.stop()
|
|
52
|
+
|
|
53
|
+
def tasks_and_state_for_offer(
|
|
54
|
+
self, driver: MesosSchedulerDriver, offer, state: ConstraintState
|
|
55
|
+
) -> Tuple[List[TaskInfo], ConstraintState]:
|
|
56
|
+
# In dry run satisfy exit-conditions after we got the offer
|
|
57
|
+
if self.dry_run or self.need_to_stop():
|
|
58
|
+
if self.dry_run:
|
|
59
|
+
tasks, _ = super().tasks_and_state_for_offer(driver, offer, state)
|
|
60
|
+
print("Would have launched: ", tasks)
|
|
61
|
+
driver.stop()
|
|
62
|
+
return [], state
|
|
63
|
+
|
|
64
|
+
return super().tasks_and_state_for_offer(driver, offer, state)
|
|
65
|
+
|
|
66
|
+
def kill_tasks_if_necessary(self, *args, **kwargs):
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
def validate_config(self):
|
|
70
|
+
if self.service_config.get_cmd() is None:
|
|
71
|
+
raise UnknownNativeServiceError("missing cmd in service config")
|