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,252 @@
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
+ import argparse
16
+ import shutil
17
+ import time
18
+ from typing import List
19
+
20
+ from paasta_tools.cli.utils import get_paasta_oapi_api_clustername
21
+ from paasta_tools.cli.utils import get_paasta_oapi_client_with_auth
22
+ from paasta_tools.cli.utils import lazy_choices_completer
23
+ from paasta_tools.cli.utils import run_interactive_cli
24
+ from paasta_tools.kubernetes.remote_run import TOOLBOX_MOCK_SERVICE
25
+ from paasta_tools.paastaapi.model.remote_run_start import RemoteRunStart
26
+ from paasta_tools.paastaapi.model.remote_run_stop import RemoteRunStop
27
+ from paasta_tools.utils import get_username
28
+ from paasta_tools.utils import list_all_instances_for_service
29
+ from paasta_tools.utils import list_clusters
30
+ from paasta_tools.utils import list_services
31
+ from paasta_tools.utils import load_system_paasta_config
32
+ from paasta_tools.utils import SystemPaastaConfig
33
+
34
+
35
+ KUBECTL_CMD_TEMPLATE = (
36
+ "{kubectl_wrapper} --token {token} exec -it -n {namespace} {pod} -- /bin/bash"
37
+ )
38
+
39
+
40
+ def _list_services_and_toolboxes() -> List[str]:
41
+ try:
42
+ toolbox_instances = list_all_instances_for_service(
43
+ TOOLBOX_MOCK_SERVICE, instance_type="adhoc"
44
+ )
45
+ except Exception:
46
+ toolbox_instances = set()
47
+ # NOTE: API authorization is enforced by service, and we want different rules
48
+ # for each toolbox, so we combine service and instance in this case to properly
49
+ # allow that to happen.
50
+ return list(list_services()) + sorted(
51
+ f"{TOOLBOX_MOCK_SERVICE}-{instance}" for instance in toolbox_instances
52
+ )
53
+
54
+
55
+ def paasta_remote_run_start(
56
+ args: argparse.Namespace,
57
+ system_paasta_config: SystemPaastaConfig,
58
+ ) -> int:
59
+ client = get_paasta_oapi_client_with_auth(
60
+ cluster=get_paasta_oapi_api_clustername(cluster=args.cluster, is_eks=True),
61
+ system_paasta_config=system_paasta_config,
62
+ )
63
+ if not client:
64
+ print("Cannot get a paasta-api client")
65
+ return 1
66
+
67
+ user = get_username()
68
+ start_response = client.remote_run.remote_run_start(
69
+ args.service,
70
+ args.instance,
71
+ RemoteRunStart(
72
+ user=user,
73
+ interactive=args.interactive,
74
+ recreate=args.recreate,
75
+ max_duration=args.max_duration,
76
+ toolbox=args.toolbox,
77
+ ),
78
+ )
79
+ if start_response.status >= 300:
80
+ print(f"Error from PaaSTA APIs while starting job: {start_response.message}")
81
+ return 1
82
+
83
+ print(
84
+ f"Triggered remote-run job for {args.service}. Waiting for pod to come online..."
85
+ )
86
+ start_time = time.time()
87
+ while time.time() - start_time < args.timeout:
88
+ poll_response = client.remote_run.remote_run_poll(
89
+ service=args.service,
90
+ instance=args.instance,
91
+ job_name=start_response.job_name,
92
+ user=user,
93
+ toolbox=args.toolbox,
94
+ )
95
+ if poll_response.status == 200:
96
+ print("")
97
+ break
98
+ print(f"\rStatus: {poll_response.message}", end="")
99
+ time.sleep(10)
100
+ else:
101
+ print("Timed out while waiting for job to start")
102
+ return 1
103
+
104
+ if not args.interactive and not args.toolbox:
105
+ print("Successfully started remote-run job")
106
+ return 0
107
+
108
+ print("Pod ready, establishing interactive session...")
109
+
110
+ if args.toolbox:
111
+ # NOTE: we only do this for toolbox containers since those images are built with interactive
112
+ # access in mind, and SSH sessions provide better auditability of user actions.
113
+ # I.e., being `nobody` is fine in a normal remote-run, but in toolbox containers
114
+ # we will require knowing the real user (and some tools may need that too).
115
+ exec_command = f"ssh -A {poll_response.pod_address}"
116
+ else:
117
+ token_response = client.remote_run.remote_run_token(
118
+ args.service, args.instance, user
119
+ )
120
+ kubectl_wrapper = f"kubectl-eks-{args.cluster}"
121
+ if not shutil.which(kubectl_wrapper):
122
+ kubectl_wrapper = f"kubectl-{args.cluster}"
123
+ exec_command = KUBECTL_CMD_TEMPLATE.format(
124
+ kubectl_wrapper=kubectl_wrapper,
125
+ namespace=poll_response.namespace,
126
+ pod=poll_response.pod_name,
127
+ token=token_response.token,
128
+ )
129
+
130
+ run_interactive_cli(exec_command)
131
+ return 0
132
+
133
+
134
+ def paasta_remote_run_stop(
135
+ args: argparse.Namespace,
136
+ system_paasta_config: SystemPaastaConfig,
137
+ ) -> int:
138
+ client = get_paasta_oapi_client_with_auth(
139
+ cluster=get_paasta_oapi_api_clustername(cluster=args.cluster, is_eks=True),
140
+ system_paasta_config=system_paasta_config,
141
+ )
142
+ if not client:
143
+ print("Cannot get a paasta-api client")
144
+ return 1
145
+ response = client.remote_run.remote_run_stop(
146
+ args.service,
147
+ args.instance,
148
+ RemoteRunStop(user=get_username(), toolbox=args.toolbox),
149
+ )
150
+ print(response.message)
151
+ return 0 if response.status < 300 else 1
152
+
153
+
154
+ def add_common_args_to_parser(parser: argparse.ArgumentParser):
155
+ service_arg = parser.add_argument(
156
+ "-s",
157
+ "--service",
158
+ help="The name of the service you wish to inspect. Required.",
159
+ required=True,
160
+ )
161
+ service_arg.completer = lazy_choices_completer(_list_services_and_toolboxes) # type: ignore
162
+ instance_or_toolbox = parser.add_mutually_exclusive_group()
163
+ instance_or_toolbox.add_argument(
164
+ "-i",
165
+ "--instance",
166
+ help=(
167
+ "Simulate a docker run for a particular instance of the "
168
+ "service, like 'main' or 'canary'. Required."
169
+ ),
170
+ default="main",
171
+ )
172
+ instance_or_toolbox.add_argument(
173
+ "--toolbox",
174
+ help="The selected service is a 'toolbox' container",
175
+ action="store_true",
176
+ default=False,
177
+ )
178
+ cluster_arg = parser.add_argument(
179
+ "-c",
180
+ "--cluster",
181
+ help="The name of the cluster you wish to run your task on. Required.",
182
+ required=True,
183
+ )
184
+ cluster_arg.completer = lazy_choices_completer(list_clusters) # type: ignore
185
+
186
+
187
+ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
188
+ remote_run_parser = subparsers.add_parser(
189
+ "remote-run",
190
+ help="Run services / jobs remotely",
191
+ description="'paasta remote-run' runs services / jobs remotely",
192
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
193
+ )
194
+ subparsers = remote_run_parser.add_subparsers(dest="remote_run_command")
195
+ start_parser = subparsers.add_parser(
196
+ "start",
197
+ help="Start or connect to a remote-run job",
198
+ description="Starts or connects to a remote-run-job",
199
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
200
+ )
201
+ start_parser.add_argument(
202
+ "-I",
203
+ "--interactive",
204
+ help=(
205
+ "Run container in interactive mode. If interactive is set the "
206
+ 'default command will be "bash" unless otherwise set by the "--cmd" flag'
207
+ ),
208
+ action="store_true",
209
+ default=False,
210
+ )
211
+ start_parser.add_argument(
212
+ "-m",
213
+ "--max-duration",
214
+ help=(
215
+ "Amount of time in seconds after which the job is "
216
+ "automatically stopped (capped by the API backend)"
217
+ ),
218
+ type=int,
219
+ default=1800,
220
+ )
221
+ start_parser.add_argument(
222
+ "-r",
223
+ "--recreate",
224
+ help="Recreate remote-run job if already existing",
225
+ action="store_true",
226
+ default=False,
227
+ )
228
+ start_parser.add_argument(
229
+ "-t",
230
+ "--timeout",
231
+ help="Maximum time to wait for a job to start, in seconds",
232
+ type=int,
233
+ default=600,
234
+ )
235
+ stop_parser = subparsers.add_parser(
236
+ "stop",
237
+ help="Stop your remote-run job if it exists",
238
+ description="Stop your remote-run job if it exists",
239
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
240
+ )
241
+ add_common_args_to_parser(start_parser)
242
+ add_common_args_to_parser(stop_parser)
243
+ remote_run_parser.set_defaults(command=paasta_remote_run)
244
+
245
+
246
+ def paasta_remote_run(args: argparse.Namespace) -> int:
247
+ system_paasta_config = load_system_paasta_config()
248
+ if args.remote_run_command == "start":
249
+ return paasta_remote_run_start(args, system_paasta_config)
250
+ elif args.remote_run_command == "stop":
251
+ return paasta_remote_run_stop(args, system_paasta_config)
252
+ raise ValueError(f"Unsupported subcommand: {args.remote_run_command}")
@@ -0,0 +1,347 @@
1
+ #!/usr/bin/env python
2
+ # Copyright 2015-2016 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
+ import argparse
16
+ from typing import Collection
17
+ from typing import Dict
18
+ from typing import Generator
19
+ from typing import Mapping
20
+ from typing import Tuple
21
+
22
+ from humanize import naturaltime
23
+
24
+ from paasta_tools.cli.cmds.mark_for_deployment import can_user_deploy_service
25
+ from paasta_tools.cli.cmds.mark_for_deployment import get_deploy_info
26
+ from paasta_tools.cli.cmds.mark_for_deployment import mark_for_deployment
27
+ from paasta_tools.cli.utils import extract_tags
28
+ from paasta_tools.cli.utils import figure_out_service_name
29
+ from paasta_tools.cli.utils import lazy_choices_completer
30
+ from paasta_tools.cli.utils import list_deploy_groups
31
+ from paasta_tools.cli.utils import validate_full_git_sha
32
+ from paasta_tools.cli.utils import validate_given_deploy_groups
33
+ from paasta_tools.deployment_utils import get_currently_deployed_version
34
+ from paasta_tools.remote_git import list_remote_refs
35
+ from paasta_tools.utils import _log_audit
36
+ from paasta_tools.utils import datetime_from_utc_to_local
37
+ from paasta_tools.utils import DEFAULT_SOA_DIR
38
+ from paasta_tools.utils import DeploymentVersion
39
+ from paasta_tools.utils import format_table
40
+ from paasta_tools.utils import get_git_url
41
+ from paasta_tools.utils import list_services
42
+ from paasta_tools.utils import PaastaColors
43
+ from paasta_tools.utils import parse_timestamp
44
+ from paasta_tools.utils import RollbackTypes
45
+
46
+
47
+ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
48
+ list_parser = subparsers.add_parser(
49
+ "rollback",
50
+ help="Rollback a docker image to a previous deploy",
51
+ description=(
52
+ "'paasta rollback' is a human-friendly tool for marking a particular "
53
+ "docker image for deployment, which invokes a bounce. While the command "
54
+ "is called 'rollback', it can be used to roll forward or back, as long "
55
+ "as there is a docker image available for the input Git SHA."
56
+ ),
57
+ epilog=(
58
+ "This rollback command uses the Git control plane, which requires network "
59
+ "connectivity as well as authorization to the Git repo.\n\n"
60
+ + PaastaColors.yellow(
61
+ "WARNING: You MUST manually revert changes in Git and go through the normal push process after using this command.\n"
62
+ )
63
+ + PaastaColors.yellow(
64
+ "WARNING: Failing to do so means that Jenkins will redeploy the latest code on the next scheduled build!"
65
+ )
66
+ ),
67
+ # we manually format the epilog to add newlines + give it an attention-grabbing color
68
+ # re: reverting changes in Git post-rollback
69
+ formatter_class=argparse.RawDescriptionHelpFormatter,
70
+ )
71
+ arg_commit = list_parser.add_argument(
72
+ "-k",
73
+ "--commit",
74
+ help="Git SHA to mark for rollback. "
75
+ "A commit to rollback to is required for paasta rollback to run. However if one is not provided, "
76
+ "paasta rollback will instead output a list of valid git shas to rollback to.",
77
+ required=False,
78
+ )
79
+ arg_commit.completer = lazy_choices_completer(list_previously_deployed_shas) # type: ignore
80
+ arg_version = list_parser.add_argument(
81
+ "-i",
82
+ "--image-version",
83
+ help="Extra version metadata to mark for rollback. "
84
+ "If your service has enabled no-commit redeploys, both a commit and the extra metadata is required for paasta rollback to run. However if one is not provided, "
85
+ "paasta rollback will instead output a list of valid versions to rollback to.",
86
+ required=False,
87
+ default=None,
88
+ )
89
+ arg_version.completer = lazy_choices_completer(list_previously_deployed_image_versions) # type: ignore
90
+ arg_deploy_group = list_parser.add_argument(
91
+ "-l",
92
+ "--deploy-groups",
93
+ help="Mark one or more deploy groups to roll back (e.g. "
94
+ '"all.main", "all.main,all.canary"). If no deploy groups specified,'
95
+ "no deploy groups for that service are rolled back. To rollback all deploy groups "
96
+ "use the flag -a or --all-deploy-groups",
97
+ default="",
98
+ required=False,
99
+ )
100
+ arg_deploy_group.completer = lazy_choices_completer(list_deploy_groups) # type: ignore
101
+ list_parser.add_argument(
102
+ "-a",
103
+ "--all-deploy-groups",
104
+ help="Rollback all deploy groups for the service",
105
+ action="store_true",
106
+ required=False,
107
+ )
108
+
109
+ arg_service = list_parser.add_argument(
110
+ "-s", "--service", help='Name of the service to rollback (e.g. "service1")'
111
+ )
112
+ arg_service.completer = lazy_choices_completer(list_services) # type: ignore
113
+ list_parser.add_argument(
114
+ "-y",
115
+ "-d",
116
+ "--soa-dir",
117
+ dest="soa_dir",
118
+ metavar="SOA_DIR",
119
+ default=DEFAULT_SOA_DIR,
120
+ help="define a different soa config directory",
121
+ )
122
+ list_parser.add_argument(
123
+ "-f",
124
+ "--force",
125
+ help=("Do not check if Git SHA was marked for deployment previously."),
126
+ action="store_true",
127
+ )
128
+ list_parser.set_defaults(command=paasta_rollback)
129
+
130
+
131
+ def list_previously_deployed_shas(
132
+ parsed_args: argparse.Namespace, **kwargs: None
133
+ ) -> Generator[str, None, None]:
134
+ service = parsed_args.service
135
+ soa_dir = parsed_args.soa_dir
136
+ deploy_groups = {
137
+ deploy_group
138
+ for deploy_group in parsed_args.deploy_groups.split(",")
139
+ if deploy_group
140
+ }
141
+ return (
142
+ version.sha
143
+ for version in get_versions_for_service(service, deploy_groups, soa_dir)
144
+ )
145
+
146
+
147
+ def list_previously_deployed_image_versions(
148
+ parsed_args: argparse.Namespace, **kwargs: None
149
+ ) -> Generator[str, None, None]:
150
+ service = parsed_args.service
151
+ soa_dir = parsed_args.soa_dir
152
+ deploy_groups = {
153
+ deploy_group
154
+ for deploy_group in parsed_args.deploy_groups.split(",")
155
+ if deploy_group
156
+ }
157
+ return (
158
+ version.image_version
159
+ for version in get_versions_for_service(service, deploy_groups, soa_dir)
160
+ )
161
+
162
+
163
+ def get_versions_for_service(
164
+ service: str, deploy_groups: Collection[str], soa_dir: str
165
+ ) -> Mapping[DeploymentVersion, Tuple[str, str]]:
166
+ """Returns a dictionary of 2-tuples of the form (timestamp, deploy_group) for each version tuple of (deploy sha, image_version)"""
167
+ if service is None:
168
+ return {}
169
+ git_url = get_git_url(service=service, soa_dir=soa_dir)
170
+ all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
171
+ deploy_groups, _ = validate_given_deploy_groups(all_deploy_groups, deploy_groups)
172
+ previously_deployed_versions: Dict[DeploymentVersion, Tuple[str, str]] = {}
173
+ for ref, sha in list_remote_refs(git_url).items():
174
+ regex_match = extract_tags(ref)
175
+ try:
176
+ deploy_group = regex_match["deploy_group"]
177
+ tstamp = regex_match["tstamp"]
178
+ image_version = regex_match["image_version"]
179
+ except KeyError:
180
+ pass
181
+ else:
182
+ # Now we filter and dedup by picking the most recent sha for a deploy group
183
+ # Note that all strings are greater than ''
184
+ if deploy_group in deploy_groups:
185
+ version = DeploymentVersion(sha=sha, image_version=image_version)
186
+ tstamp_so_far = previously_deployed_versions.get(version, ("all", ""))[
187
+ 1
188
+ ]
189
+ if tstamp > tstamp_so_far:
190
+ previously_deployed_versions[version] = (tstamp, deploy_group)
191
+ return previously_deployed_versions
192
+
193
+
194
+ def list_previous_versions(
195
+ service: str,
196
+ deploy_groups: Collection[str],
197
+ any_given_deploy_groups: bool,
198
+ versions: Mapping[DeploymentVersion, Tuple],
199
+ ) -> None:
200
+ def format_timestamp(tstamp: str) -> str:
201
+ return naturaltime(datetime_from_utc_to_local(parse_timestamp(tstamp)))
202
+
203
+ print("Below is a list of recent commits:")
204
+ # Latest 10 versions sorted by deployment time
205
+ list_of_versions = sorted(versions.items(), key=lambda x: x[1], reverse=True)[:10]
206
+ rows = [("Timestamp -- UTC", "Human time", "deploy_group", "Version")]
207
+ for version, (timestamp, deploy_group) in list_of_versions:
208
+ rows.extend(
209
+ [(timestamp, format_timestamp(timestamp), deploy_group, repr(version))]
210
+ )
211
+ for line in format_table(rows):
212
+ print(line)
213
+ if len(list_of_versions) >= 2:
214
+ version, (timestamp, deploy_group) = list_of_versions[1]
215
+ deploy_groups_arg_line = (
216
+ "-l %s " % ",".join(deploy_groups) if any_given_deploy_groups else ""
217
+ )
218
+ version_arg = (
219
+ f" --image-version {version.image_version}" if version.image_version else ""
220
+ )
221
+ print(
222
+ "\nFor example, to use the second to last version from {} used on {}, run:".format(
223
+ format_timestamp(timestamp), PaastaColors.bold(deploy_group)
224
+ )
225
+ )
226
+ print(
227
+ PaastaColors.bold(
228
+ f" paasta rollback -s {service} {deploy_groups_arg_line}-k {version.sha}{version_arg}"
229
+ )
230
+ )
231
+
232
+
233
+ def paasta_rollback(args: argparse.Namespace) -> int:
234
+ """Call mark_for_deployment with rollback parameters
235
+ :param args: contains all the arguments passed onto the script: service,
236
+ deploy groups and sha. These arguments will be verified and passed onto
237
+ mark_for_deployment.
238
+ """
239
+
240
+ soa_dir = args.soa_dir
241
+ service = figure_out_service_name(args, soa_dir)
242
+
243
+ deploy_info = get_deploy_info(service=service, soa_dir=args.soa_dir)
244
+ if not can_user_deploy_service(deploy_info, service):
245
+ return 1
246
+
247
+ git_url = get_git_url(service, soa_dir)
248
+
249
+ if args.all_deploy_groups:
250
+ given_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
251
+ else:
252
+ given_deploy_groups = {
253
+ deploy_group
254
+ for deploy_group in args.deploy_groups.split(",")
255
+ if deploy_group
256
+ }
257
+
258
+ all_deploy_groups = list_deploy_groups(service=service, soa_dir=soa_dir)
259
+ deploy_groups, invalid = validate_given_deploy_groups(
260
+ all_deploy_groups, given_deploy_groups
261
+ )
262
+
263
+ if len(invalid) > 0:
264
+ print(
265
+ PaastaColors.yellow(
266
+ "These deploy groups are not valid and will be skipped: %s.\n"
267
+ % (",").join(invalid)
268
+ )
269
+ )
270
+
271
+ if len(deploy_groups) == 0 and not args.all_deploy_groups:
272
+ print(
273
+ PaastaColors.red(
274
+ "ERROR: No valid deploy groups specified for %s.\n Use the flag -a to rollback all valid deploy groups for this service"
275
+ % (service)
276
+ )
277
+ )
278
+ return 1
279
+
280
+ versions = get_versions_for_service(service, deploy_groups, soa_dir)
281
+ commit = args.commit
282
+ image_version = args.image_version
283
+ new_version = DeploymentVersion(sha=commit, image_version=image_version)
284
+ if not commit:
285
+ print("Please specify a commit to mark for rollback (-k, --commit).")
286
+ list_previous_versions(
287
+ service, deploy_groups, bool(given_deploy_groups), versions
288
+ )
289
+ return 1
290
+ elif new_version not in versions and not args.force:
291
+ print(
292
+ PaastaColors.red(
293
+ f"This version {new_version} has never been deployed before."
294
+ )
295
+ )
296
+ print("Please double check it or use --force to skip this verification.\n")
297
+ list_previous_versions(
298
+ service, deploy_groups, bool(given_deploy_groups), versions
299
+ )
300
+ return 1
301
+
302
+ try:
303
+ validate_full_git_sha(args.commit)
304
+ except argparse.ArgumentTypeError as e:
305
+ print(PaastaColors.red(f"Error: {e}"))
306
+ return 1
307
+
308
+ # TODO: Add similar check for when image_version is empty and no-commit redeploys is enforced for requested deploy_group
309
+
310
+ returncode = 0
311
+
312
+ for deploy_group in deploy_groups:
313
+ rolled_back_from = get_currently_deployed_version(service, deploy_group)
314
+ returncode |= mark_for_deployment(
315
+ git_url=git_url,
316
+ service=service,
317
+ deploy_group=deploy_group,
318
+ commit=commit,
319
+ image_version=image_version,
320
+ )
321
+
322
+ # we could also gate this by the return code from m-f-d, but we probably care more about someone wanting to
323
+ # rollback than we care about if the underlying machinery was successfully able to complete the request
324
+ if rolled_back_from != new_version:
325
+ audit_action_details = {
326
+ "rolled_back_from": str(rolled_back_from),
327
+ "rolled_back_to": str(new_version),
328
+ "rollback_type": RollbackTypes.USER_INITIATED_ROLLBACK.value,
329
+ "deploy_group": deploy_group,
330
+ }
331
+ _log_audit(
332
+ action="rollback", action_details=audit_action_details, service=service
333
+ )
334
+
335
+ if returncode == 0:
336
+ print(
337
+ PaastaColors.yellow(
338
+ f"WARNING: You MUST manually revert changes in Git! Use 'git revert {rolled_back_from.sha}', and go through the normal push process. "
339
+ )
340
+ )
341
+ print(
342
+ PaastaColors.yellow(
343
+ f"WARNING: Failing to do so means that Jenkins will redeploy the latest code on the next scheduled build!"
344
+ )
345
+ )
346
+
347
+ return returncode