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.
Files changed (348) hide show
  1. k8s_itests/__init__.py +0 -0
  2. k8s_itests/test_autoscaling.py +23 -0
  3. k8s_itests/utils.py +38 -0
  4. paasta_tools/__init__.py +20 -0
  5. paasta_tools/adhoc_tools.py +142 -0
  6. paasta_tools/api/__init__.py +13 -0
  7. paasta_tools/api/api.py +330 -0
  8. paasta_tools/api/api_docs/swagger.json +2323 -0
  9. paasta_tools/api/client.py +106 -0
  10. paasta_tools/api/settings.py +33 -0
  11. paasta_tools/api/tweens/__init__.py +6 -0
  12. paasta_tools/api/tweens/auth.py +125 -0
  13. paasta_tools/api/tweens/profiling.py +108 -0
  14. paasta_tools/api/tweens/request_logger.py +124 -0
  15. paasta_tools/api/views/__init__.py +13 -0
  16. paasta_tools/api/views/autoscaler.py +100 -0
  17. paasta_tools/api/views/exception.py +45 -0
  18. paasta_tools/api/views/flink.py +73 -0
  19. paasta_tools/api/views/instance.py +395 -0
  20. paasta_tools/api/views/pause_autoscaler.py +71 -0
  21. paasta_tools/api/views/remote_run.py +113 -0
  22. paasta_tools/api/views/resources.py +76 -0
  23. paasta_tools/api/views/service.py +35 -0
  24. paasta_tools/api/views/version.py +25 -0
  25. paasta_tools/apply_external_resources.py +79 -0
  26. paasta_tools/async_utils.py +109 -0
  27. paasta_tools/autoscaling/__init__.py +0 -0
  28. paasta_tools/autoscaling/autoscaling_service_lib.py +57 -0
  29. paasta_tools/autoscaling/forecasting.py +106 -0
  30. paasta_tools/autoscaling/max_all_k8s_services.py +41 -0
  31. paasta_tools/autoscaling/pause_service_autoscaler.py +77 -0
  32. paasta_tools/autoscaling/utils.py +52 -0
  33. paasta_tools/bounce_lib.py +184 -0
  34. paasta_tools/broadcast_log_to_services.py +62 -0
  35. paasta_tools/cassandracluster_tools.py +210 -0
  36. paasta_tools/check_autoscaler_max_instances.py +212 -0
  37. paasta_tools/check_cassandracluster_services_replication.py +35 -0
  38. paasta_tools/check_flink_services_health.py +203 -0
  39. paasta_tools/check_kubernetes_api.py +57 -0
  40. paasta_tools/check_kubernetes_services_replication.py +141 -0
  41. paasta_tools/check_oom_events.py +244 -0
  42. paasta_tools/check_services_replication_tools.py +324 -0
  43. paasta_tools/check_spark_jobs.py +234 -0
  44. paasta_tools/cleanup_kubernetes_cr.py +138 -0
  45. paasta_tools/cleanup_kubernetes_crd.py +145 -0
  46. paasta_tools/cleanup_kubernetes_jobs.py +344 -0
  47. paasta_tools/cleanup_tron_namespaces.py +96 -0
  48. paasta_tools/cli/__init__.py +13 -0
  49. paasta_tools/cli/authentication.py +85 -0
  50. paasta_tools/cli/cli.py +260 -0
  51. paasta_tools/cli/cmds/__init__.py +13 -0
  52. paasta_tools/cli/cmds/autoscale.py +143 -0
  53. paasta_tools/cli/cmds/check.py +334 -0
  54. paasta_tools/cli/cmds/cook_image.py +147 -0
  55. paasta_tools/cli/cmds/get_docker_image.py +76 -0
  56. paasta_tools/cli/cmds/get_image_version.py +172 -0
  57. paasta_tools/cli/cmds/get_latest_deployment.py +93 -0
  58. paasta_tools/cli/cmds/info.py +155 -0
  59. paasta_tools/cli/cmds/itest.py +117 -0
  60. paasta_tools/cli/cmds/list.py +66 -0
  61. paasta_tools/cli/cmds/list_clusters.py +42 -0
  62. paasta_tools/cli/cmds/list_deploy_queue.py +171 -0
  63. paasta_tools/cli/cmds/list_namespaces.py +84 -0
  64. paasta_tools/cli/cmds/local_run.py +1396 -0
  65. paasta_tools/cli/cmds/logs.py +1601 -0
  66. paasta_tools/cli/cmds/mark_for_deployment.py +1988 -0
  67. paasta_tools/cli/cmds/mesh_status.py +174 -0
  68. paasta_tools/cli/cmds/pause_service_autoscaler.py +107 -0
  69. paasta_tools/cli/cmds/push_to_registry.py +275 -0
  70. paasta_tools/cli/cmds/remote_run.py +252 -0
  71. paasta_tools/cli/cmds/rollback.py +347 -0
  72. paasta_tools/cli/cmds/secret.py +549 -0
  73. paasta_tools/cli/cmds/security_check.py +59 -0
  74. paasta_tools/cli/cmds/spark_run.py +1400 -0
  75. paasta_tools/cli/cmds/start_stop_restart.py +401 -0
  76. paasta_tools/cli/cmds/status.py +2302 -0
  77. paasta_tools/cli/cmds/validate.py +1012 -0
  78. paasta_tools/cli/cmds/wait_for_deployment.py +275 -0
  79. paasta_tools/cli/fsm/__init__.py +13 -0
  80. paasta_tools/cli/fsm/autosuggest.py +82 -0
  81. paasta_tools/cli/fsm/template/README.md +8 -0
  82. paasta_tools/cli/fsm/template/cookiecutter.json +7 -0
  83. paasta_tools/cli/fsm/template/{{cookiecutter.service}}/kubernetes-PROD.yaml +91 -0
  84. paasta_tools/cli/fsm/template/{{cookiecutter.service}}/monitoring.yaml +20 -0
  85. paasta_tools/cli/fsm/template/{{cookiecutter.service}}/service.yaml +8 -0
  86. paasta_tools/cli/fsm/template/{{cookiecutter.service}}/smartstack.yaml +6 -0
  87. paasta_tools/cli/fsm_cmd.py +121 -0
  88. paasta_tools/cli/paasta_tabcomplete.sh +23 -0
  89. paasta_tools/cli/schemas/adhoc_schema.json +199 -0
  90. paasta_tools/cli/schemas/autoscaling_schema.json +91 -0
  91. paasta_tools/cli/schemas/autotuned_defaults/cassandracluster_schema.json +37 -0
  92. paasta_tools/cli/schemas/autotuned_defaults/kubernetes_schema.json +89 -0
  93. paasta_tools/cli/schemas/deploy_schema.json +173 -0
  94. paasta_tools/cli/schemas/eks_schema.json +970 -0
  95. paasta_tools/cli/schemas/kubernetes_schema.json +970 -0
  96. paasta_tools/cli/schemas/rollback_schema.json +160 -0
  97. paasta_tools/cli/schemas/service_schema.json +25 -0
  98. paasta_tools/cli/schemas/smartstack_schema.json +322 -0
  99. paasta_tools/cli/schemas/tron_schema.json +699 -0
  100. paasta_tools/cli/utils.py +1118 -0
  101. paasta_tools/clusterman.py +21 -0
  102. paasta_tools/config_utils.py +385 -0
  103. paasta_tools/contrib/__init__.py +0 -0
  104. paasta_tools/contrib/bounce_log_latency_parser.py +68 -0
  105. paasta_tools/contrib/check_manual_oapi_changes.sh +24 -0
  106. paasta_tools/contrib/check_orphans.py +306 -0
  107. paasta_tools/contrib/create_dynamodb_table.py +35 -0
  108. paasta_tools/contrib/create_paasta_playground.py +105 -0
  109. paasta_tools/contrib/emit_allocated_cpu_metrics.py +50 -0
  110. paasta_tools/contrib/get_running_task_allocation.py +346 -0
  111. paasta_tools/contrib/habitat_fixer.py +86 -0
  112. paasta_tools/contrib/ide_helper.py +316 -0
  113. paasta_tools/contrib/is_pod_healthy_in_proxy.py +139 -0
  114. paasta_tools/contrib/is_pod_healthy_in_smartstack.py +50 -0
  115. paasta_tools/contrib/kill_bad_containers.py +109 -0
  116. paasta_tools/contrib/mass-deploy-tag.sh +44 -0
  117. paasta_tools/contrib/mock_patch_checker.py +86 -0
  118. paasta_tools/contrib/paasta_update_soa_memcpu.py +520 -0
  119. paasta_tools/contrib/render_template.py +129 -0
  120. paasta_tools/contrib/rightsizer_soaconfigs_update.py +348 -0
  121. paasta_tools/contrib/service_shard_remove.py +157 -0
  122. paasta_tools/contrib/service_shard_update.py +373 -0
  123. paasta_tools/contrib/shared_ip_check.py +77 -0
  124. paasta_tools/contrib/timeouts_metrics_prom.py +64 -0
  125. paasta_tools/delete_kubernetes_deployments.py +89 -0
  126. paasta_tools/deployment_utils.py +44 -0
  127. paasta_tools/docker_wrapper.py +234 -0
  128. paasta_tools/docker_wrapper_imports.py +13 -0
  129. paasta_tools/drain_lib.py +351 -0
  130. paasta_tools/dump_locally_running_services.py +71 -0
  131. paasta_tools/eks_tools.py +119 -0
  132. paasta_tools/envoy_tools.py +373 -0
  133. paasta_tools/firewall.py +504 -0
  134. paasta_tools/firewall_logging.py +154 -0
  135. paasta_tools/firewall_update.py +172 -0
  136. paasta_tools/flink_tools.py +345 -0
  137. paasta_tools/flinkeks_tools.py +90 -0
  138. paasta_tools/frameworks/__init__.py +0 -0
  139. paasta_tools/frameworks/adhoc_scheduler.py +71 -0
  140. paasta_tools/frameworks/constraints.py +87 -0
  141. paasta_tools/frameworks/native_scheduler.py +652 -0
  142. paasta_tools/frameworks/native_service_config.py +301 -0
  143. paasta_tools/frameworks/task_store.py +245 -0
  144. paasta_tools/generate_all_deployments +9 -0
  145. paasta_tools/generate_authenticating_services.py +94 -0
  146. paasta_tools/generate_deployments_for_service.py +255 -0
  147. paasta_tools/generate_services_file.py +114 -0
  148. paasta_tools/generate_services_yaml.py +30 -0
  149. paasta_tools/hacheck.py +76 -0
  150. paasta_tools/instance/__init__.py +0 -0
  151. paasta_tools/instance/hpa_metrics_parser.py +122 -0
  152. paasta_tools/instance/kubernetes.py +1362 -0
  153. paasta_tools/iptables.py +240 -0
  154. paasta_tools/kafkacluster_tools.py +143 -0
  155. paasta_tools/kubernetes/__init__.py +0 -0
  156. paasta_tools/kubernetes/application/__init__.py +0 -0
  157. paasta_tools/kubernetes/application/controller_wrappers.py +476 -0
  158. paasta_tools/kubernetes/application/tools.py +90 -0
  159. paasta_tools/kubernetes/bin/__init__.py +0 -0
  160. paasta_tools/kubernetes/bin/kubernetes_remove_evicted_pods.py +164 -0
  161. paasta_tools/kubernetes/bin/paasta_cleanup_remote_run_resources.py +135 -0
  162. paasta_tools/kubernetes/bin/paasta_cleanup_stale_nodes.py +181 -0
  163. paasta_tools/kubernetes/bin/paasta_secrets_sync.py +758 -0
  164. paasta_tools/kubernetes/remote_run.py +558 -0
  165. paasta_tools/kubernetes_tools.py +4679 -0
  166. paasta_tools/list_kubernetes_service_instances.py +128 -0
  167. paasta_tools/list_tron_namespaces.py +60 -0
  168. paasta_tools/long_running_service_tools.py +678 -0
  169. paasta_tools/mac_address.py +44 -0
  170. paasta_tools/marathon_dashboard.py +0 -0
  171. paasta_tools/mesos/__init__.py +0 -0
  172. paasta_tools/mesos/cfg.py +46 -0
  173. paasta_tools/mesos/cluster.py +60 -0
  174. paasta_tools/mesos/exceptions.py +59 -0
  175. paasta_tools/mesos/framework.py +77 -0
  176. paasta_tools/mesos/log.py +48 -0
  177. paasta_tools/mesos/master.py +306 -0
  178. paasta_tools/mesos/mesos_file.py +169 -0
  179. paasta_tools/mesos/parallel.py +52 -0
  180. paasta_tools/mesos/slave.py +115 -0
  181. paasta_tools/mesos/task.py +94 -0
  182. paasta_tools/mesos/util.py +69 -0
  183. paasta_tools/mesos/zookeeper.py +37 -0
  184. paasta_tools/mesos_maintenance.py +848 -0
  185. paasta_tools/mesos_tools.py +1051 -0
  186. paasta_tools/metrics/__init__.py +0 -0
  187. paasta_tools/metrics/metastatus_lib.py +1110 -0
  188. paasta_tools/metrics/metrics_lib.py +217 -0
  189. paasta_tools/monitoring/__init__.py +13 -0
  190. paasta_tools/monitoring/check_k8s_api_performance.py +110 -0
  191. paasta_tools/monitoring_tools.py +652 -0
  192. paasta_tools/monkrelaycluster_tools.py +146 -0
  193. paasta_tools/nrtsearchservice_tools.py +143 -0
  194. paasta_tools/nrtsearchserviceeks_tools.py +68 -0
  195. paasta_tools/oom_logger.py +321 -0
  196. paasta_tools/paasta_deploy_tron_jobs +3 -0
  197. paasta_tools/paasta_execute_docker_command.py +123 -0
  198. paasta_tools/paasta_native_serviceinit.py +21 -0
  199. paasta_tools/paasta_service_config_loader.py +201 -0
  200. paasta_tools/paastaapi/__init__.py +29 -0
  201. paasta_tools/paastaapi/api/__init__.py +3 -0
  202. paasta_tools/paastaapi/api/autoscaler_api.py +302 -0
  203. paasta_tools/paastaapi/api/default_api.py +569 -0
  204. paasta_tools/paastaapi/api/remote_run_api.py +604 -0
  205. paasta_tools/paastaapi/api/resources_api.py +157 -0
  206. paasta_tools/paastaapi/api/service_api.py +1736 -0
  207. paasta_tools/paastaapi/api_client.py +818 -0
  208. paasta_tools/paastaapi/apis/__init__.py +22 -0
  209. paasta_tools/paastaapi/configuration.py +455 -0
  210. paasta_tools/paastaapi/exceptions.py +137 -0
  211. paasta_tools/paastaapi/model/__init__.py +5 -0
  212. paasta_tools/paastaapi/model/adhoc_launch_history.py +176 -0
  213. paasta_tools/paastaapi/model/autoscaler_count_msg.py +176 -0
  214. paasta_tools/paastaapi/model/deploy_queue.py +178 -0
  215. paasta_tools/paastaapi/model/deploy_queue_service_instance.py +194 -0
  216. paasta_tools/paastaapi/model/envoy_backend.py +185 -0
  217. paasta_tools/paastaapi/model/envoy_location.py +184 -0
  218. paasta_tools/paastaapi/model/envoy_status.py +181 -0
  219. paasta_tools/paastaapi/model/flink_cluster_overview.py +188 -0
  220. paasta_tools/paastaapi/model/flink_config.py +173 -0
  221. paasta_tools/paastaapi/model/flink_job.py +186 -0
  222. paasta_tools/paastaapi/model/flink_job_details.py +192 -0
  223. paasta_tools/paastaapi/model/flink_jobs.py +175 -0
  224. paasta_tools/paastaapi/model/float_and_error.py +173 -0
  225. paasta_tools/paastaapi/model/hpa_metric.py +176 -0
  226. paasta_tools/paastaapi/model/inline_object.py +170 -0
  227. paasta_tools/paastaapi/model/inline_response200.py +170 -0
  228. paasta_tools/paastaapi/model/inline_response2001.py +170 -0
  229. paasta_tools/paastaapi/model/instance_bounce_status.py +200 -0
  230. paasta_tools/paastaapi/model/instance_mesh_status.py +186 -0
  231. paasta_tools/paastaapi/model/instance_status.py +220 -0
  232. paasta_tools/paastaapi/model/instance_status_adhoc.py +187 -0
  233. paasta_tools/paastaapi/model/instance_status_cassandracluster.py +173 -0
  234. paasta_tools/paastaapi/model/instance_status_flink.py +173 -0
  235. paasta_tools/paastaapi/model/instance_status_kafkacluster.py +173 -0
  236. paasta_tools/paastaapi/model/instance_status_kubernetes.py +263 -0
  237. paasta_tools/paastaapi/model/instance_status_kubernetes_autoscaling_status.py +187 -0
  238. paasta_tools/paastaapi/model/instance_status_kubernetes_v2.py +197 -0
  239. paasta_tools/paastaapi/model/instance_status_tron.py +204 -0
  240. paasta_tools/paastaapi/model/instance_tasks.py +182 -0
  241. paasta_tools/paastaapi/model/integer_and_error.py +173 -0
  242. paasta_tools/paastaapi/model/kubernetes_container.py +178 -0
  243. paasta_tools/paastaapi/model/kubernetes_container_v2.py +219 -0
  244. paasta_tools/paastaapi/model/kubernetes_healthcheck.py +176 -0
  245. paasta_tools/paastaapi/model/kubernetes_pod.py +201 -0
  246. paasta_tools/paastaapi/model/kubernetes_pod_event.py +176 -0
  247. paasta_tools/paastaapi/model/kubernetes_pod_v2.py +213 -0
  248. paasta_tools/paastaapi/model/kubernetes_replica_set.py +185 -0
  249. paasta_tools/paastaapi/model/kubernetes_version.py +202 -0
  250. paasta_tools/paastaapi/model/remote_run_outcome.py +189 -0
  251. paasta_tools/paastaapi/model/remote_run_start.py +185 -0
  252. paasta_tools/paastaapi/model/remote_run_stop.py +176 -0
  253. paasta_tools/paastaapi/model/remote_run_token.py +173 -0
  254. paasta_tools/paastaapi/model/resource.py +187 -0
  255. paasta_tools/paastaapi/model/resource_item.py +187 -0
  256. paasta_tools/paastaapi/model/resource_value.py +176 -0
  257. paasta_tools/paastaapi/model/smartstack_backend.py +191 -0
  258. paasta_tools/paastaapi/model/smartstack_location.py +181 -0
  259. paasta_tools/paastaapi/model/smartstack_status.py +181 -0
  260. paasta_tools/paastaapi/model/task_tail_lines.py +176 -0
  261. paasta_tools/paastaapi/model_utils.py +1879 -0
  262. paasta_tools/paastaapi/models/__init__.py +62 -0
  263. paasta_tools/paastaapi/rest.py +287 -0
  264. paasta_tools/prune_completed_pods.py +220 -0
  265. paasta_tools/puppet_service_tools.py +59 -0
  266. paasta_tools/py.typed +1 -0
  267. paasta_tools/remote_git.py +127 -0
  268. paasta_tools/run-paasta-api-in-dev-mode.py +57 -0
  269. paasta_tools/run-paasta-api-playground.py +51 -0
  270. paasta_tools/secret_providers/__init__.py +66 -0
  271. paasta_tools/secret_providers/vault.py +214 -0
  272. paasta_tools/secret_tools.py +277 -0
  273. paasta_tools/setup_istio_mesh.py +353 -0
  274. paasta_tools/setup_kubernetes_cr.py +412 -0
  275. paasta_tools/setup_kubernetes_crd.py +138 -0
  276. paasta_tools/setup_kubernetes_internal_crd.py +154 -0
  277. paasta_tools/setup_kubernetes_job.py +353 -0
  278. paasta_tools/setup_prometheus_adapter_config.py +1028 -0
  279. paasta_tools/setup_tron_namespace.py +248 -0
  280. paasta_tools/slack.py +75 -0
  281. paasta_tools/smartstack_tools.py +676 -0
  282. paasta_tools/spark_tools.py +283 -0
  283. paasta_tools/synapse_srv_namespaces_fact.py +42 -0
  284. paasta_tools/tron/__init__.py +0 -0
  285. paasta_tools/tron/client.py +158 -0
  286. paasta_tools/tron/tron_command_context.py +194 -0
  287. paasta_tools/tron/tron_timeutils.py +101 -0
  288. paasta_tools/tron_tools.py +1448 -0
  289. paasta_tools/utils.py +4307 -0
  290. paasta_tools/yaml_tools.py +44 -0
  291. paasta_tools-1.21.3.data/scripts/apply_external_resources.py +79 -0
  292. paasta_tools-1.21.3.data/scripts/bounce_log_latency_parser.py +68 -0
  293. paasta_tools-1.21.3.data/scripts/check_autoscaler_max_instances.py +212 -0
  294. paasta_tools-1.21.3.data/scripts/check_cassandracluster_services_replication.py +35 -0
  295. paasta_tools-1.21.3.data/scripts/check_flink_services_health.py +203 -0
  296. paasta_tools-1.21.3.data/scripts/check_kubernetes_api.py +57 -0
  297. paasta_tools-1.21.3.data/scripts/check_kubernetes_services_replication.py +141 -0
  298. paasta_tools-1.21.3.data/scripts/check_manual_oapi_changes.sh +24 -0
  299. paasta_tools-1.21.3.data/scripts/check_oom_events.py +244 -0
  300. paasta_tools-1.21.3.data/scripts/check_orphans.py +306 -0
  301. paasta_tools-1.21.3.data/scripts/check_spark_jobs.py +234 -0
  302. paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_cr.py +138 -0
  303. paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_crd.py +145 -0
  304. paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_jobs.py +344 -0
  305. paasta_tools-1.21.3.data/scripts/create_dynamodb_table.py +35 -0
  306. paasta_tools-1.21.3.data/scripts/create_paasta_playground.py +105 -0
  307. paasta_tools-1.21.3.data/scripts/delete_kubernetes_deployments.py +89 -0
  308. paasta_tools-1.21.3.data/scripts/emit_allocated_cpu_metrics.py +50 -0
  309. paasta_tools-1.21.3.data/scripts/generate_all_deployments +9 -0
  310. paasta_tools-1.21.3.data/scripts/generate_authenticating_services.py +94 -0
  311. paasta_tools-1.21.3.data/scripts/generate_deployments_for_service.py +255 -0
  312. paasta_tools-1.21.3.data/scripts/generate_services_file.py +114 -0
  313. paasta_tools-1.21.3.data/scripts/generate_services_yaml.py +30 -0
  314. paasta_tools-1.21.3.data/scripts/get_running_task_allocation.py +346 -0
  315. paasta_tools-1.21.3.data/scripts/habitat_fixer.py +86 -0
  316. paasta_tools-1.21.3.data/scripts/ide_helper.py +316 -0
  317. paasta_tools-1.21.3.data/scripts/is_pod_healthy_in_proxy.py +139 -0
  318. paasta_tools-1.21.3.data/scripts/is_pod_healthy_in_smartstack.py +50 -0
  319. paasta_tools-1.21.3.data/scripts/kill_bad_containers.py +109 -0
  320. paasta_tools-1.21.3.data/scripts/kubernetes_remove_evicted_pods.py +164 -0
  321. paasta_tools-1.21.3.data/scripts/mass-deploy-tag.sh +44 -0
  322. paasta_tools-1.21.3.data/scripts/mock_patch_checker.py +86 -0
  323. paasta_tools-1.21.3.data/scripts/paasta_cleanup_remote_run_resources.py +135 -0
  324. paasta_tools-1.21.3.data/scripts/paasta_cleanup_stale_nodes.py +181 -0
  325. paasta_tools-1.21.3.data/scripts/paasta_deploy_tron_jobs +3 -0
  326. paasta_tools-1.21.3.data/scripts/paasta_execute_docker_command.py +123 -0
  327. paasta_tools-1.21.3.data/scripts/paasta_secrets_sync.py +758 -0
  328. paasta_tools-1.21.3.data/scripts/paasta_tabcomplete.sh +23 -0
  329. paasta_tools-1.21.3.data/scripts/paasta_update_soa_memcpu.py +520 -0
  330. paasta_tools-1.21.3.data/scripts/render_template.py +129 -0
  331. paasta_tools-1.21.3.data/scripts/rightsizer_soaconfigs_update.py +348 -0
  332. paasta_tools-1.21.3.data/scripts/service_shard_remove.py +157 -0
  333. paasta_tools-1.21.3.data/scripts/service_shard_update.py +373 -0
  334. paasta_tools-1.21.3.data/scripts/setup_istio_mesh.py +353 -0
  335. paasta_tools-1.21.3.data/scripts/setup_kubernetes_cr.py +412 -0
  336. paasta_tools-1.21.3.data/scripts/setup_kubernetes_crd.py +138 -0
  337. paasta_tools-1.21.3.data/scripts/setup_kubernetes_internal_crd.py +154 -0
  338. paasta_tools-1.21.3.data/scripts/setup_kubernetes_job.py +353 -0
  339. paasta_tools-1.21.3.data/scripts/setup_prometheus_adapter_config.py +1028 -0
  340. paasta_tools-1.21.3.data/scripts/shared_ip_check.py +77 -0
  341. paasta_tools-1.21.3.data/scripts/synapse_srv_namespaces_fact.py +42 -0
  342. paasta_tools-1.21.3.data/scripts/timeouts_metrics_prom.py +64 -0
  343. paasta_tools-1.21.3.dist-info/LICENSE +201 -0
  344. paasta_tools-1.21.3.dist-info/METADATA +74 -0
  345. paasta_tools-1.21.3.dist-info/RECORD +348 -0
  346. paasta_tools-1.21.3.dist-info/WHEEL +5 -0
  347. paasta_tools-1.21.3.dist-info/entry_points.txt +20 -0
  348. paasta_tools-1.21.3.dist-info/top_level.txt +2 -0
@@ -0,0 +1,678 @@
1
+ import copy
2
+ import logging
3
+ import os
4
+ import socket
5
+ from typing import Dict
6
+ from typing import List
7
+ from typing import Mapping
8
+ from typing import Optional
9
+ from typing import Sequence
10
+ from typing import Tuple
11
+ from typing import Type
12
+
13
+ import service_configuration_lib
14
+
15
+ from paasta_tools.autoscaling.utils import AutoscalingParamsDict
16
+ from paasta_tools.autoscaling.utils import MetricsProviderDict
17
+ from paasta_tools.paasta_service_config_loader import PaastaServiceConfigLoader
18
+ from paasta_tools.utils import BranchDictV2
19
+ from paasta_tools.utils import compose_job_id
20
+ from paasta_tools.utils import decompose_job_id
21
+ from paasta_tools.utils import deep_merge_dictionaries
22
+ from paasta_tools.utils import DEFAULT_SOA_DIR
23
+ from paasta_tools.utils import DeployBlacklist
24
+ from paasta_tools.utils import DeployWhitelist
25
+ from paasta_tools.utils import InstanceConfig
26
+ from paasta_tools.utils import InstanceConfigDict
27
+ from paasta_tools.utils import InvalidInstanceConfig
28
+ from paasta_tools.utils import InvalidJobNameError
29
+ from paasta_tools.utils import load_system_paasta_config
30
+ from paasta_tools.utils import SystemPaastaConfig
31
+
32
+ log = logging.getLogger(__name__)
33
+ logging.getLogger("long_running_service_tools").setLevel(logging.WARNING)
34
+
35
+ ZK_PAUSE_AUTOSCALE_PATH = "/autoscaling/paused"
36
+ DEFAULT_CONTAINER_PORT = 8888
37
+
38
+ DEFAULT_AUTOSCALING_SETPOINT = 0.8
39
+ DEFAULT_DESIRED_ACTIVE_REQUESTS_PER_REPLICA = 1
40
+ DEFAULT_ACTIVE_REQUESTS_AUTOSCALING_MOVING_AVERAGE_WINDOW = 1800
41
+ DEFAULT_UWSGI_AUTOSCALING_MOVING_AVERAGE_WINDOW = 1800
42
+ DEFAULT_PISCINA_AUTOSCALING_MOVING_AVERAGE_WINDOW = 1800
43
+ DEFAULT_GUNICORN_AUTOSCALING_MOVING_AVERAGE_WINDOW = 1800
44
+
45
+ METRICS_PROVIDER_CPU = "cpu"
46
+ METRICS_PROVIDER_UWSGI = "uwsgi"
47
+ METRICS_PROVIDER_UWSGI_V2 = "uwsgi-v2"
48
+ METRICS_PROVIDER_GUNICORN = "gunicorn"
49
+ METRICS_PROVIDER_PISCINA = "piscina"
50
+ METRICS_PROVIDER_ACTIVE_REQUESTS = "active-requests"
51
+ METRICS_PROVIDER_PROMQL = "arbitrary_promql"
52
+
53
+ ALL_METRICS_PROVIDERS = [
54
+ METRICS_PROVIDER_CPU,
55
+ METRICS_PROVIDER_UWSGI,
56
+ METRICS_PROVIDER_UWSGI_V2,
57
+ METRICS_PROVIDER_GUNICORN,
58
+ METRICS_PROVIDER_PISCINA,
59
+ METRICS_PROVIDER_ACTIVE_REQUESTS,
60
+ METRICS_PROVIDER_PROMQL,
61
+ ]
62
+
63
+
64
+ class LongRunningServiceConfigDict(InstanceConfigDict, total=False):
65
+ autoscaling: AutoscalingParamsDict
66
+ drain_method: str
67
+ fs_group: int
68
+ container_port: int
69
+ drain_method_params: Dict
70
+ healthcheck_cmd: str
71
+ healthcheck_grace_period_seconds: float
72
+ healthcheck_interval_seconds: float
73
+ healthcheck_max_consecutive_failures: int
74
+ healthcheck_mode: str
75
+ healthcheck_timeout_seconds: float
76
+ healthcheck_uri: str
77
+ instances: int
78
+ max_instances: int
79
+ min_instances: int
80
+ nerve_ns: str
81
+ network_mode: str
82
+ registrations: List[str]
83
+ replication_threshold: int
84
+ bounce_start_deadline: float
85
+ bounce_margin_factor: float
86
+ should_ping_for_unhealthy_pods: bool
87
+ weight: int
88
+
89
+
90
+ class ServiceNamespaceConfig(dict):
91
+ def get_healthcheck_mode(self) -> str:
92
+ """Get the healthcheck mode for the service. In most cases, this will match the mode
93
+ of the service, but we do provide the opportunity for users to specify both. Default to the mode
94
+ if no healthcheck_mode is specified.
95
+ """
96
+ healthcheck_mode = self.get("healthcheck_mode", None)
97
+ if not healthcheck_mode:
98
+ return self.get_mode()
99
+ else:
100
+ return healthcheck_mode
101
+
102
+ def get_mode(self) -> str:
103
+ """Get the mode that the service runs in and check that we support it.
104
+ If the mode is not specified, we check whether the service uses smartstack
105
+ in order to determine the appropriate default value. If proxy_port is specified
106
+ in the config, the service uses smartstack, and we can thus safely assume its mode is http.
107
+ If the mode is not defined and the service does not use smartstack, we set the mode to None.
108
+ """
109
+ mode = self.get("mode", None)
110
+ if mode is None:
111
+ if not self.is_in_smartstack():
112
+ return None
113
+ else:
114
+ return "http"
115
+ elif mode in ["http", "tcp", "https"]:
116
+ return mode
117
+ else:
118
+ raise InvalidSmartstackMode("Unknown mode: %s" % mode)
119
+
120
+ def get_healthcheck_uri(self) -> str:
121
+ return self.get("healthcheck_uri", "/status")
122
+
123
+ def get_discover(self) -> str:
124
+ return self.get("discover", "region")
125
+
126
+ def is_in_smartstack(self) -> bool:
127
+ return "proxy_port" in self
128
+
129
+ def get_timeout_server_ms(self) -> int:
130
+ return self.get("timeout_server_ms", 1000)
131
+
132
+ def get_longest_timeout_ms(self) -> int:
133
+ """Calculate the longest amount of time a connection to this service might stay open."""
134
+ return max(
135
+ [self.get_timeout_server_ms()]
136
+ + list(self.get("endpoint_timeouts", {}).values())
137
+ )
138
+
139
+
140
+ class LongRunningServiceConfig(InstanceConfig):
141
+ config_dict: LongRunningServiceConfigDict
142
+
143
+ def __init__(
144
+ self,
145
+ service: str,
146
+ cluster: str,
147
+ instance: str,
148
+ config_dict: LongRunningServiceConfigDict,
149
+ branch_dict: Optional[BranchDictV2],
150
+ soa_dir: str = DEFAULT_SOA_DIR,
151
+ ) -> None:
152
+ super().__init__(
153
+ cluster=cluster,
154
+ instance=instance,
155
+ service=service,
156
+ config_dict=config_dict,
157
+ branch_dict=branch_dict,
158
+ soa_dir=soa_dir,
159
+ )
160
+
161
+ def get_bounce_method(self) -> str:
162
+ raise NotImplementedError
163
+
164
+ def get_kubernetes_namespace(self) -> str:
165
+ """
166
+ Only needed on kubernetes LongRunningServiceConfig
167
+ """
168
+ raise NotImplementedError
169
+
170
+ def get_sanitised_deployment_name(self) -> str:
171
+ """
172
+ Only needed on kubernetes LongRunningServiceConfig
173
+ """
174
+ raise NotImplementedError
175
+
176
+ def get_service_name_smartstack(self) -> str:
177
+ """
178
+ This is just the service name here
179
+ For cassandra we have to override this to support apollo
180
+ """
181
+ return self.get_service()
182
+
183
+ def get_env(
184
+ self, system_paasta_config: Optional[SystemPaastaConfig] = None
185
+ ) -> Dict[str, str]:
186
+ env = super().get_env(system_paasta_config=system_paasta_config)
187
+ env["PAASTA_PORT"] = str(self.get_container_port())
188
+ return env
189
+
190
+ def get_container_port(self) -> int:
191
+ return self.config_dict.get("container_port", DEFAULT_CONTAINER_PORT)
192
+
193
+ def get_drain_method(self, service_namespace_config: ServiceNamespaceConfig) -> str:
194
+ """Get the drain method specified in the service's configuration.
195
+
196
+ :param service_config: The service instance's configuration dictionary
197
+ :returns: The drain method specified in the config, or 'noop' if not specified"""
198
+ default = "noop"
199
+ # Default to hacheck draining if the service is in smartstack
200
+ if service_namespace_config.is_in_smartstack():
201
+ default = "hacheck"
202
+ return self.config_dict.get("drain_method", default)
203
+
204
+ def get_drain_method_params(
205
+ self, service_namespace_config: ServiceNamespaceConfig
206
+ ) -> Dict:
207
+ """Get the drain method parameters specified in the service's configuration.
208
+
209
+ :param service_config: The service instance's configuration dictionary
210
+ :returns: The drain_method_params dictionary specified in the config, or {} if not specified"""
211
+ default: Dict = {}
212
+ if service_namespace_config.is_in_smartstack():
213
+ default = {"delay": 60}
214
+ return self.config_dict.get("drain_method_params", default)
215
+
216
+ # FIXME(jlynch|2016-08-02, PAASTA-4964): DEPRECATE nerve_ns and remove it
217
+ def get_nerve_namespace(self) -> str:
218
+ return decompose_job_id(self.get_registrations()[0])[1]
219
+
220
+ def get_registrations(self) -> List[str]:
221
+ for registration in self.get_invalid_registrations():
222
+ log.error(
223
+ "Provided registration {} for service "
224
+ "{} is invalid".format(registration, self.service)
225
+ )
226
+
227
+ registrations = self.config_dict.get("registrations", [])
228
+
229
+ # Backwards compatibility with nerve_ns
230
+ # FIXME(jlynch|2016-08-02, PAASTA-4964): DEPRECATE nerve_ns and remove it
231
+ if not registrations and "nerve_ns" in self.config_dict:
232
+ registrations.append(
233
+ compose_job_id(self.service, self.config_dict["nerve_ns"])
234
+ )
235
+
236
+ return registrations or [compose_job_id(self.service, self.instance)]
237
+
238
+ def get_invalid_registrations(self) -> List[str]:
239
+ registrations = self.config_dict.get("registrations", [])
240
+ invalid_registrations: List[str] = []
241
+ for registration in registrations:
242
+ try:
243
+ decompose_job_id(registration)
244
+ except InvalidJobNameError:
245
+ invalid_registrations.append(registration)
246
+ return invalid_registrations
247
+
248
+ def get_replication_crit_percentage(self) -> int:
249
+ return self.config_dict.get("replication_threshold", 50)
250
+
251
+ def get_fs_group(self) -> Optional[int]:
252
+ return self.config_dict.get("fs_group")
253
+
254
+ def get_healthcheck_uri(
255
+ self, service_namespace_config: ServiceNamespaceConfig
256
+ ) -> str:
257
+ return self.config_dict.get(
258
+ "healthcheck_uri", service_namespace_config.get_healthcheck_uri()
259
+ )
260
+
261
+ def get_healthcheck_cmd(self) -> str:
262
+ cmd = self.config_dict.get("healthcheck_cmd", None)
263
+ if cmd is None:
264
+ raise InvalidInstanceConfig(
265
+ "healthcheck mode 'cmd' requires a healthcheck_cmd to run"
266
+ )
267
+ else:
268
+ return cmd
269
+
270
+ def get_healthcheck_grace_period_seconds(self) -> float:
271
+ """
272
+ How long before kubernetes will start sending healthcheck and liveness probes.
273
+ """
274
+ return self.config_dict.get("healthcheck_grace_period_seconds", 60)
275
+
276
+ def get_healthcheck_interval_seconds(self) -> float:
277
+ return self.config_dict.get("healthcheck_interval_seconds", 10)
278
+
279
+ def get_healthcheck_timeout_seconds(self) -> float:
280
+ return self.config_dict.get("healthcheck_timeout_seconds", 10)
281
+
282
+ def get_healthcheck_max_consecutive_failures(self) -> int:
283
+ return self.config_dict.get("healthcheck_max_consecutive_failures", 30)
284
+
285
+ def get_healthcheck_mode(
286
+ self, service_namespace_config: ServiceNamespaceConfig
287
+ ) -> str:
288
+ mode = self.config_dict.get("healthcheck_mode", None)
289
+ if mode is None:
290
+ mode = service_namespace_config.get_healthcheck_mode()
291
+ elif mode not in ["http", "https", "tcp", "cmd", None]:
292
+ raise InvalidHealthcheckMode("Unknown mode: %s" % mode)
293
+ return mode
294
+
295
+ def get_bounce_start_deadline(self) -> float:
296
+ return self.config_dict.get("bounce_start_deadline", 0)
297
+
298
+ def get_autoscaled_instances(self) -> int:
299
+ raise NotImplementedError()
300
+
301
+ def get_instances(self, with_limit: bool = True) -> int:
302
+ """Gets the number of instances for a service, ignoring whether the user has requested
303
+ the service to be started or stopped"""
304
+ if self.is_autoscaling_enabled():
305
+ autoscaled_instances = self.get_autoscaled_instances()
306
+ if autoscaled_instances is None:
307
+ return self.get_max_instances()
308
+ else:
309
+ limited_instances = (
310
+ self.limit_instance_count(autoscaled_instances)
311
+ if with_limit
312
+ else autoscaled_instances
313
+ )
314
+ return limited_instances
315
+ else:
316
+ instances = self.config_dict.get("instances", 1)
317
+ log.debug("Autoscaling not enabled, returning %d instances" % instances)
318
+ return instances
319
+
320
+ def get_min_instances(self) -> int:
321
+ return self.config_dict.get("min_instances", 1)
322
+
323
+ def is_autoscaling_enabled(self) -> bool:
324
+ return self.get_max_instances() is not None
325
+
326
+ def get_max_instances(self) -> Optional[int]:
327
+ return self.config_dict.get("max_instances", None)
328
+
329
+ def get_desired_instances(self) -> int:
330
+ """Get the number of instances specified in zookeeper or the service's configuration.
331
+ If the number of instances in zookeeper is less than min_instances, returns min_instances.
332
+ If the number of instances in zookeeper is greater than max_instances, returns max_instances.
333
+
334
+ Defaults to 0 if not specified in the config.
335
+
336
+ :returns: The number of instances specified in the config, 0 if not
337
+ specified or if desired_state is not 'start'.
338
+ """
339
+ if self.get_desired_state() == "start":
340
+ return self.get_instances()
341
+ else:
342
+ log.debug("Instance is set to stop. Returning '0' instances")
343
+ return 0
344
+
345
+ def limit_instance_count(self, instances: int) -> int:
346
+ """
347
+ Returns param instances if it is between min_instances and max_instances.
348
+ Returns max_instances if instances > max_instances
349
+ Returns min_instances if instances < min_instances
350
+ """
351
+ return max(self.get_min_instances(), min(self.get_max_instances(), instances))
352
+
353
+ def get_autoscaling_params(self) -> AutoscalingParamsDict:
354
+ default_provider_params: MetricsProviderDict = {
355
+ "type": METRICS_PROVIDER_CPU,
356
+ "decision_policy": "proportional",
357
+ "setpoint": DEFAULT_AUTOSCALING_SETPOINT,
358
+ }
359
+
360
+ params = copy.deepcopy(
361
+ self.config_dict.get("autoscaling", AutoscalingParamsDict({}))
362
+ )
363
+ if "metrics_providers" not in params or len(params["metrics_providers"]) == 0:
364
+ params["metrics_providers"] = [default_provider_params]
365
+ else:
366
+ params["metrics_providers"] = [
367
+ deep_merge_dictionaries(
368
+ overrides=provider,
369
+ defaults=default_provider_params,
370
+ )
371
+ for provider in params["metrics_providers"]
372
+ ]
373
+ return params
374
+
375
+ def get_autoscaling_metrics_provider(
376
+ self, provider_type: str
377
+ ) -> Optional[MetricsProviderDict]:
378
+ autoscaling_params = self.get_autoscaling_params()
379
+ # We only allow one metric provider of each type, so we can bail early if we find a match
380
+ for provider in autoscaling_params["metrics_providers"]:
381
+ if provider["type"] == provider_type:
382
+ return provider
383
+ return None
384
+
385
+ def should_use_metrics_provider(self, provider_type: str) -> bool:
386
+ return (
387
+ self.is_autoscaling_enabled()
388
+ and self.get_autoscaling_metrics_provider(provider_type) is not None
389
+ )
390
+
391
+ def validate(
392
+ self,
393
+ params: Optional[List[str]] = None,
394
+ ) -> List[str]:
395
+ error_messages = super().validate(params=params)
396
+ invalid_registrations = self.get_invalid_registrations()
397
+ if invalid_registrations:
398
+ service_instance = compose_job_id(self.service, self.instance)
399
+ registrations_str = ", ".join(invalid_registrations)
400
+ error_messages.append(
401
+ f"Service registrations must be of the form service.registration. "
402
+ f"The following registrations for {service_instance} are "
403
+ f"invalid: {registrations_str}"
404
+ )
405
+ return error_messages
406
+
407
+ def get_bounce_margin_factor(self) -> float:
408
+ return self.config_dict.get("bounce_margin_factor", 0.95)
409
+
410
+ def get_should_ping_for_unhealthy_pods(self, default: bool) -> bool:
411
+ return self.config_dict.get("should_ping_for_unhealthy_pods", default)
412
+
413
+ def get_weight(self) -> int:
414
+ return self.config_dict.get("weight", 10)
415
+
416
+
417
+ class InvalidHealthcheckMode(Exception):
418
+ pass
419
+
420
+
421
+ def get_healthcheck_for_instance(
422
+ service: str,
423
+ instance: str,
424
+ service_manifest: LongRunningServiceConfig,
425
+ random_port: int,
426
+ soa_dir: str = DEFAULT_SOA_DIR,
427
+ ) -> Tuple[Optional[str], Optional[str]]:
428
+ """
429
+ Returns healthcheck for a given service instance in the form of a tuple (mode, healthcheck_command)
430
+ or (None, None) if no healthcheck
431
+ """
432
+ namespace = service_manifest.get_nerve_namespace()
433
+ smartstack_config = load_service_namespace_config(
434
+ service=service, namespace=namespace, soa_dir=soa_dir
435
+ )
436
+ mode = service_manifest.get_healthcheck_mode(smartstack_config)
437
+ hostname = socket.getfqdn()
438
+
439
+ if mode == "http" or mode == "https":
440
+ path = service_manifest.get_healthcheck_uri(smartstack_config)
441
+ healthcheck_command = "%s://%s:%d%s" % (mode, hostname, random_port, path)
442
+ elif mode == "tcp":
443
+ healthcheck_command = "%s://%s:%d" % (mode, hostname, random_port)
444
+ elif mode == "cmd":
445
+ healthcheck_command = service_manifest.get_healthcheck_cmd()
446
+ else:
447
+ mode = None
448
+ healthcheck_command = None
449
+ return (mode, healthcheck_command)
450
+
451
+
452
+ def load_service_namespace_config(
453
+ service: str, namespace: str, soa_dir: str = DEFAULT_SOA_DIR
454
+ ) -> ServiceNamespaceConfig:
455
+ """Attempt to read the configuration for a service's namespace in a more strict fashion.
456
+
457
+ Retrieves the following keys:
458
+
459
+ - proxy_port: the proxy port defined for the given namespace
460
+ - healthcheck_mode: the mode for the healthcheck (http or tcp)
461
+ - healthcheck_port: An alternate port to use for health checking
462
+ - healthcheck_uri: URI target for healthchecking
463
+ - healthcheck_timeout_s: healthcheck timeout in seconds
464
+ - healthcheck_body_expect: an expected string in healthcheck response body
465
+ - updown_timeout_s: updown_service timeout in seconds
466
+ - timeout_connect_ms: proxy frontend timeout in milliseconds
467
+ - timeout_server_ms: proxy server backend timeout in milliseconds
468
+ - retries: the number of retries on a proxy backend
469
+ - mode: the mode the service is run in (http or tcp)
470
+ - routes: a list of tuples of (source, destination)
471
+ - discover: the scope at which to discover services e.g. 'habitat'
472
+ - advertise: a list of scopes to advertise services at e.g. ['habitat', 'region']
473
+ - extra_advertise: a list of tuples of (source, destination)
474
+ e.g. [('region:dc6-prod', 'region:useast1-prod')]
475
+ - extra_healthcheck_headers: a dict of HTTP headers that must
476
+ be supplied when health checking. E.g. { 'Host': 'example.com' }
477
+ - lb_policy: Envoy load balancer policies. E.g. "ROUND_ROBIN"
478
+
479
+ :param service: The service name
480
+ :param namespace: The namespace to read
481
+ :param soa_dir: The SOA config directory to read from
482
+ :returns: A dict of the above keys, if they were defined
483
+ """
484
+
485
+ smartstack_config = service_configuration_lib.read_extra_service_information(
486
+ service_name=service,
487
+ extra_info="smartstack",
488
+ soa_dir=soa_dir,
489
+ deepcopy=False,
490
+ )
491
+
492
+ namespace_config_from_file = smartstack_config.get(namespace, {})
493
+
494
+ service_namespace_config = ServiceNamespaceConfig()
495
+ # We can't really use .get, as we don't want the key to be in the returned
496
+ # dict at all if it doesn't exist in the config file.
497
+ # We also can't just copy the whole dict, as we only care about some keys
498
+ # and there's other things that appear in the smartstack section in
499
+ # several cases.
500
+ key_whitelist = {
501
+ "healthcheck_mode",
502
+ "healthcheck_uri",
503
+ "healthcheck_port",
504
+ "healthcheck_timeout_s",
505
+ "healthcheck_body_expect",
506
+ "updown_timeout_s",
507
+ "proxy_port",
508
+ "timeout_connect_ms",
509
+ "timeout_server_ms",
510
+ "retries",
511
+ "mode",
512
+ "discover",
513
+ "advertise",
514
+ "extra_healthcheck_headers",
515
+ "lb_policy",
516
+ "endpoint_timeouts",
517
+ }
518
+
519
+ for key, value in namespace_config_from_file.items():
520
+ if key in key_whitelist:
521
+ service_namespace_config[key] = value
522
+
523
+ # Other code in paasta_tools checks 'mode' after the config file
524
+ # is loaded, so this ensures that it is set to the appropriate default
525
+ # if not otherwise specified, even if appropriate default is None.
526
+ service_namespace_config["mode"] = service_namespace_config.get_mode()
527
+
528
+ if "routes" in namespace_config_from_file:
529
+ service_namespace_config["routes"] = [
530
+ (route["source"], dest)
531
+ for route in namespace_config_from_file["routes"]
532
+ for dest in route["destinations"]
533
+ ]
534
+
535
+ if "extra_advertise" in namespace_config_from_file:
536
+ service_namespace_config["extra_advertise"] = [
537
+ (src, dst)
538
+ for src in namespace_config_from_file["extra_advertise"]
539
+ for dst in namespace_config_from_file["extra_advertise"][src]
540
+ ]
541
+
542
+ return service_namespace_config
543
+
544
+
545
+ class InvalidSmartstackMode(Exception):
546
+ pass
547
+
548
+
549
+ def get_proxy_port_for_instance(
550
+ service_config: LongRunningServiceConfig,
551
+ ) -> Optional[int]:
552
+ """Get the proxy_port defined in the first namespace configuration for a
553
+ service instance.
554
+
555
+ This means that the namespace first has to be loaded from the service instance's
556
+ configuration, and then the proxy_port has to loaded from the smartstack configuration
557
+ for that namespace.
558
+
559
+ :param service_config: The instance of the services LongRunningServiceConfig
560
+ :returns: The proxy_port for the service instance, or None if not defined"""
561
+ registration = service_config.get_registrations()[0]
562
+ service, namespace, _, __ = decompose_job_id(registration)
563
+ nerve_dict = load_service_namespace_config(
564
+ service=service, namespace=namespace, soa_dir=service_config.soa_dir
565
+ )
566
+ return nerve_dict.get("proxy_port")
567
+
568
+
569
+ def host_passes_blacklist(
570
+ host_attributes: Mapping[str, str], blacklist: DeployBlacklist
571
+ ) -> bool:
572
+ """
573
+ :param host: A single host attributes dict
574
+ :param blacklist: A list of lists like [["location_type", "location"], ["foo", "bar"]]
575
+ :returns: boolean, True if the host gets passed the blacklist
576
+ """
577
+ try:
578
+ for location_type, location in blacklist:
579
+ if host_attributes.get(location_type) == location:
580
+ return False
581
+ except ValueError as e:
582
+ log.error(f"Errors processing the following blacklist: {blacklist}")
583
+ log.error("I will assume the host does not pass\nError was: %s" % e)
584
+ return False
585
+ return True
586
+
587
+
588
+ def host_passes_whitelist(
589
+ host_attributes: Mapping[str, str], whitelist: DeployWhitelist
590
+ ) -> bool:
591
+ """
592
+ :param host: A single host attributes dict.
593
+ :param whitelist: A 2 item list like ["location_type", ["location1", 'location2']]
594
+ :returns: boolean, True if the host gets past the whitelist
595
+ """
596
+ # No whitelist, so disable whitelisting behavior.
597
+ if whitelist is None or len(whitelist) == 0:
598
+ return True
599
+ try:
600
+ (location_type, locations) = whitelist
601
+ if host_attributes.get(location_type) in locations:
602
+ return True
603
+ except ValueError as e:
604
+ log.error(f"Errors processing the following whitelist: {whitelist}")
605
+ log.error("I will assume the host does not pass\nError was: %s" % e)
606
+ return False
607
+ return False
608
+
609
+
610
+ def get_all_namespaces(
611
+ soa_dir: str = DEFAULT_SOA_DIR,
612
+ ) -> Sequence[Tuple[str, ServiceNamespaceConfig]]:
613
+ """Get all the smartstack namespaces across all services.
614
+ This is mostly so synapse can get everything it needs in one call.
615
+
616
+ :param soa_dir: The SOA config directory to read from
617
+ :returns: A list of tuples of the form (service.namespace, namespace_config)"""
618
+ rootdir = os.path.abspath(soa_dir)
619
+ namespace_list: List[Tuple[str, ServiceNamespaceConfig]] = []
620
+ for srv_dir in os.listdir(rootdir):
621
+ namespace_list.extend(get_all_namespaces_for_service(srv_dir, soa_dir))
622
+ return namespace_list
623
+
624
+
625
+ def get_all_namespaces_for_service(
626
+ service: str, soa_dir: str = DEFAULT_SOA_DIR, full_name: bool = True
627
+ ) -> Sequence[Tuple[str, ServiceNamespaceConfig]]:
628
+ """Get all the smartstack namespaces listed for a given service name.
629
+
630
+ :param service: The service name
631
+ :param soa_dir: The SOA config directory to read from
632
+ :param full_name: A boolean indicating if the service name should be prepended to the namespace in the
633
+ returned tuples as described below (Default: True)
634
+ :returns: A list of tuples of the form (service<SPACER>namespace, namespace_config) if full_name is true,
635
+ otherwise of the form (namespace, namespace_config)
636
+ """
637
+ service_config = service_configuration_lib.read_service_configuration(
638
+ service, soa_dir
639
+ )
640
+ smartstack = service_config.get("smartstack", {})
641
+ namespace_list = []
642
+ for namespace in smartstack:
643
+ if full_name:
644
+ name = compose_job_id(service, namespace)
645
+ else:
646
+ name = namespace
647
+ namespace_list.append((name, smartstack[namespace]))
648
+ return namespace_list
649
+
650
+
651
+ def get_expected_instance_count_for_namespace(
652
+ service: str,
653
+ namespace: str,
654
+ instance_type_class: Type[LongRunningServiceConfig],
655
+ cluster: str = None,
656
+ soa_dir: str = DEFAULT_SOA_DIR,
657
+ ) -> int:
658
+ """Get the number of expected instances for a namespace, based on the number
659
+ of instances set to run on that namespace as specified in service configuration files.
660
+
661
+ :param service: The service's name
662
+ :param namespace: The namespace for that service to check
663
+ instance_type_class: The type of the instance, options are e.g. KubernetesDeploymentConfig,
664
+ :param soa_dir: The SOA configuration directory to read from
665
+ :returns: An integer value of the # of expected instances for the namespace"""
666
+ total_expected = 0
667
+ if not cluster:
668
+ cluster = load_system_paasta_config().get_cluster()
669
+
670
+ pscl = PaastaServiceConfigLoader(
671
+ service=service, soa_dir=soa_dir, load_deployments=False
672
+ )
673
+ for job_config in pscl.instance_configs(
674
+ cluster=cluster, instance_type_class=instance_type_class
675
+ ):
676
+ if f"{service}.{namespace}" in job_config.get_registrations():
677
+ total_expected += job_config.get_instances()
678
+ return total_expected