paasta-tools 1.22.0__py3-none-any.whl → 1.23.1__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 (65) hide show
  1. paasta_tools/__init__.py +1 -1
  2. paasta_tools/api/api_docs/swagger.json +3 -0
  3. paasta_tools/cli/cmds/remote_run.py +40 -4
  4. paasta_tools/cli/cmds/spark_run.py +15 -0
  5. paasta_tools/contrib/paasta_update_soa_memcpu.py +82 -19
  6. paasta_tools/kubernetes/remote_run.py +2 -0
  7. paasta_tools/kubernetes_tools.py +23 -5
  8. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/paasta_update_soa_memcpu.py +82 -19
  9. {paasta_tools-1.22.0.dist-info → paasta_tools-1.23.1.dist-info}/METADATA +2 -2
  10. {paasta_tools-1.22.0.dist-info → paasta_tools-1.23.1.dist-info}/RECORD +65 -65
  11. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/apply_external_resources.py +0 -0
  12. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/bounce_log_latency_parser.py +0 -0
  13. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_autoscaler_max_instances.py +0 -0
  14. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_cassandracluster_services_replication.py +0 -0
  15. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_flink_services_health.py +0 -0
  16. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_kubernetes_api.py +0 -0
  17. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_kubernetes_services_replication.py +0 -0
  18. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_manual_oapi_changes.sh +0 -0
  19. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_oom_events.py +0 -0
  20. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_orphans.py +0 -0
  21. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/check_spark_jobs.py +0 -0
  22. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/cleanup_kubernetes_cr.py +0 -0
  23. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/cleanup_kubernetes_crd.py +0 -0
  24. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/cleanup_kubernetes_jobs.py +0 -0
  25. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/create_dynamodb_table.py +0 -0
  26. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/create_paasta_playground.py +0 -0
  27. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/delete_kubernetes_deployments.py +0 -0
  28. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/emit_allocated_cpu_metrics.py +0 -0
  29. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/generate_all_deployments +0 -0
  30. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/generate_authenticating_services.py +0 -0
  31. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/generate_deployments_for_service.py +0 -0
  32. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/generate_services_file.py +0 -0
  33. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/generate_services_yaml.py +0 -0
  34. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/get_running_task_allocation.py +0 -0
  35. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/habitat_fixer.py +0 -0
  36. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/ide_helper.py +0 -0
  37. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/is_pod_healthy_in_proxy.py +0 -0
  38. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/is_pod_healthy_in_smartstack.py +0 -0
  39. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/kill_bad_containers.py +0 -0
  40. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/kubernetes_remove_evicted_pods.py +0 -0
  41. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/mass-deploy-tag.sh +0 -0
  42. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/mock_patch_checker.py +0 -0
  43. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/paasta_cleanup_remote_run_resources.py +0 -0
  44. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/paasta_cleanup_stale_nodes.py +0 -0
  45. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/paasta_deploy_tron_jobs +0 -0
  46. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/paasta_execute_docker_command.py +0 -0
  47. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/paasta_secrets_sync.py +0 -0
  48. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/paasta_tabcomplete.sh +0 -0
  49. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/render_template.py +0 -0
  50. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/rightsizer_soaconfigs_update.py +0 -0
  51. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/service_shard_remove.py +0 -0
  52. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/service_shard_update.py +0 -0
  53. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/setup_istio_mesh.py +0 -0
  54. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/setup_kubernetes_cr.py +0 -0
  55. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/setup_kubernetes_crd.py +0 -0
  56. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/setup_kubernetes_internal_crd.py +0 -0
  57. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/setup_kubernetes_job.py +0 -0
  58. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/setup_prometheus_adapter_config.py +0 -0
  59. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/shared_ip_check.py +0 -0
  60. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/synapse_srv_namespaces_fact.py +0 -0
  61. {paasta_tools-1.22.0.data → paasta_tools-1.23.1.data}/scripts/timeouts_metrics_prom.py +0 -0
  62. {paasta_tools-1.22.0.dist-info → paasta_tools-1.23.1.dist-info}/LICENSE +0 -0
  63. {paasta_tools-1.22.0.dist-info → paasta_tools-1.23.1.dist-info}/WHEEL +0 -0
  64. {paasta_tools-1.22.0.dist-info → paasta_tools-1.23.1.dist-info}/entry_points.txt +0 -0
  65. {paasta_tools-1.22.0.dist-info → paasta_tools-1.23.1.dist-info}/top_level.txt +0 -0
paasta_tools/__init__.py CHANGED
@@ -17,4 +17,4 @@
17
17
  # setup phase, the dependencies may not exist on disk yet.
18
18
  #
19
19
  # Don't bump version manually. See `make release` docs in ./Makefile
20
- __version__ = "1.22.0"
20
+ __version__ = "1.23.1"
@@ -1037,6 +1037,9 @@
1037
1037
  "404": {
1038
1038
  "description": "Service instance not found"
1039
1039
  },
1040
+ "409": {
1041
+ "description": "A pod was found but is currently being terminated"
1042
+ },
1040
1043
  "500": {
1041
1044
  "description": "Failure"
1042
1045
  }
@@ -14,6 +14,8 @@
14
14
  # limitations under the License.
15
15
  import argparse
16
16
  import shutil
17
+ import subprocess
18
+ import sys
17
19
  import time
18
20
  from typing import List
19
21
 
@@ -32,9 +34,12 @@ from paasta_tools.utils import load_system_paasta_config
32
34
  from paasta_tools.utils import SystemPaastaConfig
33
35
 
34
36
 
35
- KUBECTL_CMD_TEMPLATE = (
37
+ KUBECTL_EXEC_CMD_TEMPLATE = (
36
38
  "{kubectl_wrapper} --token {token} exec -it -n {namespace} {pod} -- /bin/bash"
37
39
  )
40
+ KUBECTL_CP_CMD_TEMPLATE = (
41
+ "{kubectl_wrapper} --token {token} -n {namespace} cp {filename} {pod}:/tmp/"
42
+ )
38
43
 
39
44
 
40
45
  def _list_services_and_toolboxes() -> List[str]:
@@ -55,7 +60,9 @@ def _list_services_and_toolboxes() -> List[str]:
55
60
  def paasta_remote_run_start(
56
61
  args: argparse.Namespace,
57
62
  system_paasta_config: SystemPaastaConfig,
63
+ recursed: bool = False,
58
64
  ) -> int:
65
+ status_prefix = "\x1b[2K\r" # Clear line, carriage return
59
66
  client = get_paasta_oapi_client_with_auth(
60
67
  cluster=get_paasta_oapi_api_clustername(cluster=args.cluster, is_eks=True),
61
68
  system_paasta_config=system_paasta_config,
@@ -95,10 +102,18 @@ def paasta_remote_run_start(
95
102
  if poll_response.status == 200:
96
103
  print("")
97
104
  break
98
- print(f"\rStatus: {poll_response.message}", end="")
105
+ print(f"{status_prefix}Status: {poll_response.message}", end="")
106
+ if poll_response.status == 404:
107
+ # Probably indicates a pod was terminating. Now that its gone, retry the whole process
108
+ if not recursed:
109
+ print("\nPod finished terminating. Rerunning")
110
+ return paasta_remote_run_start(args, system_paasta_config, True)
111
+ else:
112
+ print("\nSomething went wrong. Pod still not found.")
113
+ return 1
99
114
  time.sleep(10)
100
115
  else:
101
- print("Timed out while waiting for job to start")
116
+ print(f"{status_prefix}Timed out while waiting for job to start")
102
117
  return 1
103
118
 
104
119
  if not args.interactive and not args.toolbox:
@@ -120,13 +135,28 @@ def paasta_remote_run_start(
120
135
  kubectl_wrapper = f"kubectl-eks-{args.cluster}"
121
136
  if not shutil.which(kubectl_wrapper):
122
137
  kubectl_wrapper = f"kubectl-{args.cluster}"
123
- exec_command = KUBECTL_CMD_TEMPLATE.format(
138
+ exec_command = KUBECTL_EXEC_CMD_TEMPLATE.format(
124
139
  kubectl_wrapper=kubectl_wrapper,
125
140
  namespace=poll_response.namespace,
126
141
  pod=poll_response.pod_name,
127
142
  token=token_response.token,
128
143
  )
129
144
 
145
+ if args.copy_file:
146
+ for filename in args.copy_file:
147
+ cp_command = KUBECTL_CP_CMD_TEMPLATE.format(
148
+ kubectl_wrapper=kubectl_wrapper,
149
+ namespace=poll_response.namespace,
150
+ pod=poll_response.pod_name,
151
+ filename=filename,
152
+ token=token_response.token,
153
+ ).split(" ")
154
+ call = subprocess.run(cp_command, capture_output=True)
155
+ if call.returncode != 0:
156
+ print("Error copying file to remote-run pod: ", file=sys.stderr)
157
+ print(call.stderr.decode("utf-8"), file=sys.stderr)
158
+ return 1
159
+
130
160
  run_interactive_cli(exec_command)
131
161
  return 0
132
162
 
@@ -232,6 +262,12 @@ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
232
262
  type=int,
233
263
  default=600,
234
264
  )
265
+ start_parser.add_argument(
266
+ "--copy-file",
267
+ help="Adds a local file to /tmp inside the pod",
268
+ type=str,
269
+ action="append",
270
+ )
235
271
  stop_parser = subparsers.add_parser(
236
272
  "stop",
237
273
  help="Stop your remote-run job if it exists",
@@ -375,6 +375,20 @@ def add_subparser(subparsers):
375
375
  default=False,
376
376
  )
377
377
 
378
+ list_parser.add_argument(
379
+ "--jira-ticket",
380
+ help=(
381
+ "The top level jira ticket used to track the project that this spark-job is related to. "
382
+ "eg: --jira-ticket=PROJ-123. "
383
+ "Must be passed for all adhoc jobs. "
384
+ "See https://yelpwiki.yelpcorp.com/spaces/AML/pages/402885641. "
385
+ ),
386
+ type=str,
387
+ required=False,
388
+ dest="jira_ticket",
389
+ default=None,
390
+ )
391
+
378
392
  aws_group = list_parser.add_argument_group(
379
393
  title="AWS credentials options",
380
394
  description="If --aws-credentials-yaml is specified, it overrides all "
@@ -1383,6 +1397,7 @@ def paasta_spark_run(args: argparse.Namespace) -> int:
1383
1397
  use_eks=True,
1384
1398
  k8s_server_address=k8s_server_address,
1385
1399
  service_account_name=service_account_name,
1400
+ jira_ticket=args.jira_ticket,
1386
1401
  )
1387
1402
 
1388
1403
  return configure_and_run_docker_container(
@@ -135,6 +135,11 @@ def cwd(path):
135
135
  os.chdir(pwd)
136
136
 
137
137
 
138
+ def _force_str_to_int(value: str) -> int:
139
+ """Force convert strings into ints - even if they're technically floats."""
140
+ return int(float(value))
141
+
142
+
138
143
  def get_report_from_splunk(creds, app, filename, criteria_filter):
139
144
  """Expect a table containing at least the following fields:
140
145
  criteria (<service> kubernetes-<cluster_name> <instance>)
@@ -165,29 +170,87 @@ def get_report_from_splunk(creds, app, filename, criteria_filter):
165
170
  resp_text = [x for x in resp_text if x]
166
171
  resp_text = [json.loads(x) for x in resp_text]
167
172
  services_to_update = {}
173
+
168
174
  for d in resp_text:
169
175
  if "result" not in d:
170
176
  raise ValueError(f"Splunk request didn't return any results: {resp_text}")
171
177
  criteria = d["result"]["criteria"]
172
- serv = {}
173
- serv["service"] = criteria.split(" ")[0]
174
- serv["cluster"] = criteria.split(" ")[1]
175
- serv["instance"] = criteria.split(" ")[2]
176
- serv["owner"] = d["result"].get("service_owner", "Unavailable")
177
- serv["date"] = d["result"]["_time"].split(" ")[0]
178
- serv["money"] = d["result"].get("estimated_monthly_savings", 0)
179
- serv["project"] = d["result"].get("project", "Unavailable")
180
- serv["cpus"] = d["result"].get("suggested_cpus")
181
- serv["old_cpus"] = d["result"].get("current_cpus")
182
- serv["mem"] = d["result"].get("suggested_mem")
183
- serv["old_mem"] = d["result"].get("current_mem")
184
- serv["disk"] = d["result"].get("suggested_disk")
185
- serv["old_disk"] = d["result"].get("current_disk")
186
- serv["min_instances"] = d["result"].get("suggested_min_instances")
187
- serv["max_instances"] = d["result"].get("suggested_max_instances")
188
- serv["hacheck_cpus"] = d["result"].get("suggested_hacheck_cpus")
189
- serv["cpu_burst_add"] = d["result"].get("suggested_cpu_burst_add")
190
- services_to_update[criteria] = serv
178
+
179
+ serv = {
180
+ "cluster": criteria.split(" ")[1],
181
+ "date": d["result"]["_time"].split(" ")[0],
182
+ "instance": criteria.split(" ")[2],
183
+ "money": d["result"].get("estimated_monthly_savings", 0),
184
+ "owner": d["result"].get("service_owner", "Unavailable"),
185
+ "project": d["result"].get("project", "Unavailable"),
186
+ "service": criteria.split(" ")[0],
187
+ # only mergeable fields below
188
+ "cpu_burst_add": d["result"].get("suggested_cpu_burst_add"),
189
+ "cpus": d["result"].get("suggested_cpus"),
190
+ "disk": d["result"].get("suggested_disk"),
191
+ "hacheck_cpus": d["result"].get("suggested_hacheck_cpus"),
192
+ "max_instances": d["result"].get("suggested_max_instances"),
193
+ "mem": d["result"].get("suggested_mem"),
194
+ "min_instances": d["result"].get("suggested_min_instances"),
195
+ "old_cpus": d["result"].get("current_cpus"),
196
+ "old_disk": d["result"].get("current_disk"),
197
+ "old_mem": d["result"].get("current_mem"),
198
+ }
199
+
200
+ # the report we get is all strings, so we need to convert them to the right types
201
+ field_conversions = {
202
+ "current_cpus": float,
203
+ "suggested_cpu_burst_add": float,
204
+ "suggested_cpus": float,
205
+ "suggested_disk": int,
206
+ "suggested_hacheck_cpus": float,
207
+ "suggested_max_instances": int,
208
+ "suggested_mem": int,
209
+ "suggested_min_instances": int,
210
+ # not quite sure why these are floats...they're ints in soaconfigs
211
+ "current_disk": _force_str_to_int,
212
+ "current_mem": _force_str_to_int,
213
+ }
214
+
215
+ # merge results if we've already seen rows for this service
216
+ # NOTE: this is necessary since the Splunk search can return multiple rows
217
+ # for the same (service, cluster, instance) tuple as the autotune query
218
+ # treats certain cpu allocation changes as if the tuple was entirely different.
219
+ # this is ostensibly due to a theory that if you update resource allocation, existing
220
+ # autotune data is potentially invalidated - but in practice this ends up hampering
221
+ # autotune for services with highly variable resource allocation - e.g., we have some services
222
+ # that have their cpu allocation tweaked by +/-.1 cpu pretty frequently, but then min/max autotune
223
+ # is never updated.
224
+ if criteria in services_to_update:
225
+ for key in serv:
226
+ # we probably don't want to merge any other fields since they're going to be strings :p
227
+ if key not in field_conversions:
228
+ continue
229
+
230
+ last_proposed_suggestion = services_to_update[criteria][key]
231
+ proposed_suggestion = serv[key]
232
+
233
+ # if both are non-null, take the max of the two
234
+ if (
235
+ last_proposed_suggestion is not None
236
+ and proposed_suggestion is not None
237
+ ):
238
+ services_to_update[criteria][key] = max(
239
+ last_proposed_suggestion,
240
+ proposed_suggestion,
241
+ key=field_conversions[key],
242
+ )
243
+ # otherwise, if only one of these is non-null, use that one
244
+ elif last_proposed_suggestion is not None:
245
+ services_to_update[criteria][key] = last_proposed_suggestion
246
+ elif proposed_suggestion is not None:
247
+ services_to_update[criteria][key] = proposed_suggestion
248
+ # otherwise, if we didn't enter any of the above branches, we're essentially leaving in place the
249
+ # existing None
250
+
251
+ # otherwise, simply add the service to the final report
252
+ else:
253
+ services_to_update[criteria] = serv
191
254
 
192
255
  return {
193
256
  "search": search,
@@ -189,6 +189,8 @@ def remote_run_ready(
189
189
  if not pod:
190
190
  return {"status": 404, "message": "No pod found"}
191
191
  if pod.status.phase == "Running":
192
+ if pod.metadata.deletion_timestamp:
193
+ return {"status": 409, "message": "Pod is terminating"}
192
194
  result: RemoteRunOutcome = {
193
195
  "status": 200,
194
196
  "message": "Pod ready",
@@ -4334,21 +4334,39 @@ def ensure_service_account(
4334
4334
  kube_client: KubeClient,
4335
4335
  k8s_role: Optional[str] = None,
4336
4336
  ) -> None:
4337
+ role_annotation = "eks.amazonaws.com/role-arn"
4337
4338
  sa_name = get_service_account_name(iam_role, k8s_role)
4338
4339
 
4339
- if not any(
4340
- sa.metadata and sa.metadata.name == sa_name
4341
- for sa in get_all_service_accounts(kube_client, namespace)
4342
- ):
4340
+ existing_sa = None
4341
+ for sa in get_all_service_accounts(kube_client, namespace):
4342
+ if sa.metadata and sa.metadata.name == sa_name:
4343
+ existing_sa = sa
4344
+ break
4345
+ else:
4343
4346
  sa = V1ServiceAccount(
4344
4347
  kind="ServiceAccount",
4345
4348
  metadata=V1ObjectMeta(
4346
4349
  name=sa_name,
4347
4350
  namespace=namespace,
4348
- annotations={"eks.amazonaws.com/role-arn": iam_role},
4351
+ annotations={role_annotation: iam_role},
4349
4352
  ),
4350
4353
  )
4351
4354
  kube_client.core.create_namespaced_service_account(namespace=namespace, body=sa)
4355
+ if existing_sa:
4356
+ if (
4357
+ not sa.metadata.annotations
4358
+ or sa.metadata.annotations.get(role_annotation, None) != iam_role
4359
+ ):
4360
+ # NOTE: we don't annotate SAs apart with anything other
4361
+ # than the pod identity role ARN, so this will remove
4362
+ # any annotations that folks may have manually added
4363
+ sa.metadata.annotations = {role_annotation: iam_role}
4364
+ kube_client.core.patch_namespaced_service_account(
4365
+ namespace=namespace, body=sa, name=sa.metadata.name
4366
+ )
4367
+ log.info(
4368
+ f"Updated ServiceAccount {sa.metadata.name} iam_role to {iam_role}"
4369
+ )
4352
4370
 
4353
4371
  # we're expecting that any Role dynamically associated with a Service Account already exists.
4354
4372
  # at Yelp, this means that we have a version-controlled resource for the Role in Puppet.
@@ -135,6 +135,11 @@ def cwd(path):
135
135
  os.chdir(pwd)
136
136
 
137
137
 
138
+ def _force_str_to_int(value: str) -> int:
139
+ """Force convert strings into ints - even if they're technically floats."""
140
+ return int(float(value))
141
+
142
+
138
143
  def get_report_from_splunk(creds, app, filename, criteria_filter):
139
144
  """Expect a table containing at least the following fields:
140
145
  criteria (<service> kubernetes-<cluster_name> <instance>)
@@ -165,29 +170,87 @@ def get_report_from_splunk(creds, app, filename, criteria_filter):
165
170
  resp_text = [x for x in resp_text if x]
166
171
  resp_text = [json.loads(x) for x in resp_text]
167
172
  services_to_update = {}
173
+
168
174
  for d in resp_text:
169
175
  if "result" not in d:
170
176
  raise ValueError(f"Splunk request didn't return any results: {resp_text}")
171
177
  criteria = d["result"]["criteria"]
172
- serv = {}
173
- serv["service"] = criteria.split(" ")[0]
174
- serv["cluster"] = criteria.split(" ")[1]
175
- serv["instance"] = criteria.split(" ")[2]
176
- serv["owner"] = d["result"].get("service_owner", "Unavailable")
177
- serv["date"] = d["result"]["_time"].split(" ")[0]
178
- serv["money"] = d["result"].get("estimated_monthly_savings", 0)
179
- serv["project"] = d["result"].get("project", "Unavailable")
180
- serv["cpus"] = d["result"].get("suggested_cpus")
181
- serv["old_cpus"] = d["result"].get("current_cpus")
182
- serv["mem"] = d["result"].get("suggested_mem")
183
- serv["old_mem"] = d["result"].get("current_mem")
184
- serv["disk"] = d["result"].get("suggested_disk")
185
- serv["old_disk"] = d["result"].get("current_disk")
186
- serv["min_instances"] = d["result"].get("suggested_min_instances")
187
- serv["max_instances"] = d["result"].get("suggested_max_instances")
188
- serv["hacheck_cpus"] = d["result"].get("suggested_hacheck_cpus")
189
- serv["cpu_burst_add"] = d["result"].get("suggested_cpu_burst_add")
190
- services_to_update[criteria] = serv
178
+
179
+ serv = {
180
+ "cluster": criteria.split(" ")[1],
181
+ "date": d["result"]["_time"].split(" ")[0],
182
+ "instance": criteria.split(" ")[2],
183
+ "money": d["result"].get("estimated_monthly_savings", 0),
184
+ "owner": d["result"].get("service_owner", "Unavailable"),
185
+ "project": d["result"].get("project", "Unavailable"),
186
+ "service": criteria.split(" ")[0],
187
+ # only mergeable fields below
188
+ "cpu_burst_add": d["result"].get("suggested_cpu_burst_add"),
189
+ "cpus": d["result"].get("suggested_cpus"),
190
+ "disk": d["result"].get("suggested_disk"),
191
+ "hacheck_cpus": d["result"].get("suggested_hacheck_cpus"),
192
+ "max_instances": d["result"].get("suggested_max_instances"),
193
+ "mem": d["result"].get("suggested_mem"),
194
+ "min_instances": d["result"].get("suggested_min_instances"),
195
+ "old_cpus": d["result"].get("current_cpus"),
196
+ "old_disk": d["result"].get("current_disk"),
197
+ "old_mem": d["result"].get("current_mem"),
198
+ }
199
+
200
+ # the report we get is all strings, so we need to convert them to the right types
201
+ field_conversions = {
202
+ "current_cpus": float,
203
+ "suggested_cpu_burst_add": float,
204
+ "suggested_cpus": float,
205
+ "suggested_disk": int,
206
+ "suggested_hacheck_cpus": float,
207
+ "suggested_max_instances": int,
208
+ "suggested_mem": int,
209
+ "suggested_min_instances": int,
210
+ # not quite sure why these are floats...they're ints in soaconfigs
211
+ "current_disk": _force_str_to_int,
212
+ "current_mem": _force_str_to_int,
213
+ }
214
+
215
+ # merge results if we've already seen rows for this service
216
+ # NOTE: this is necessary since the Splunk search can return multiple rows
217
+ # for the same (service, cluster, instance) tuple as the autotune query
218
+ # treats certain cpu allocation changes as if the tuple was entirely different.
219
+ # this is ostensibly due to a theory that if you update resource allocation, existing
220
+ # autotune data is potentially invalidated - but in practice this ends up hampering
221
+ # autotune for services with highly variable resource allocation - e.g., we have some services
222
+ # that have their cpu allocation tweaked by +/-.1 cpu pretty frequently, but then min/max autotune
223
+ # is never updated.
224
+ if criteria in services_to_update:
225
+ for key in serv:
226
+ # we probably don't want to merge any other fields since they're going to be strings :p
227
+ if key not in field_conversions:
228
+ continue
229
+
230
+ last_proposed_suggestion = services_to_update[criteria][key]
231
+ proposed_suggestion = serv[key]
232
+
233
+ # if both are non-null, take the max of the two
234
+ if (
235
+ last_proposed_suggestion is not None
236
+ and proposed_suggestion is not None
237
+ ):
238
+ services_to_update[criteria][key] = max(
239
+ last_proposed_suggestion,
240
+ proposed_suggestion,
241
+ key=field_conversions[key],
242
+ )
243
+ # otherwise, if only one of these is non-null, use that one
244
+ elif last_proposed_suggestion is not None:
245
+ services_to_update[criteria][key] = last_proposed_suggestion
246
+ elif proposed_suggestion is not None:
247
+ services_to_update[criteria][key] = proposed_suggestion
248
+ # otherwise, if we didn't enter any of the above branches, we're essentially leaving in place the
249
+ # existing None
250
+
251
+ # otherwise, simply add the service to the final report
252
+ else:
253
+ services_to_update[criteria] = serv
191
254
 
192
255
  return {
193
256
  "search": search,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: paasta-tools
3
- Version: 1.22.0
3
+ Version: 1.23.1
4
4
  Summary: Tools for Yelps SOA infrastructure
5
5
  Author: Compute Infrastructure @ Yelp
6
6
  Author-email: compute-infra@yelp.com
@@ -58,7 +58,7 @@ Requires-Dist: requests-cache >=0.4.10
58
58
  Requires-Dist: retry
59
59
  Requires-Dist: ruamel.yaml
60
60
  Requires-Dist: sensu-plugin
61
- Requires-Dist: service-configuration-lib >=3.3.2
61
+ Requires-Dist: service-configuration-lib >=3.3.3
62
62
  Requires-Dist: signalfx
63
63
  Requires-Dist: slackclient >=1.2.1
64
64
  Requires-Dist: sticht >=1.1.0
@@ -1,7 +1,7 @@
1
1
  k8s_itests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  k8s_itests/test_autoscaling.py,sha256=gX30L1wG1sDBaM0wE2aYR4OqHPSLvQBZ6LV0mLTrXZA,536
3
3
  k8s_itests/utils.py,sha256=PNibpYR0-g8Jcts9CjpkNb3oVzmdk9tZQrrNRuATCCM,966
4
- paasta_tools/__init__.py,sha256=t8XiLjvZXh6dTrPIbHbG5uSNFHdxp-tUFJtAsZSn0Ok,865
4
+ paasta_tools/__init__.py,sha256=n0D4kQV7j4p__FY8f7_Hd88wZ3obadBB9UXlYdqsmTk,865
5
5
  paasta_tools/adhoc_tools.py,sha256=OfhyZwilB93kNX8r4Nq_KyZCvsZ4rNX-FBcQAi41KCM,4751
6
6
  paasta_tools/apply_external_resources.py,sha256=DHZJ8zkGQKTBR6Ku2lNxnrdHo8rD7PD0rZEN2yloOn8,3375
7
7
  paasta_tools/async_utils.py,sha256=ELB2qHP-F2IlMes-kxgy5q9PRUSUTZ-AKw5hQ2K0l_E,3514
@@ -43,7 +43,7 @@ paasta_tools/generate_services_yaml.py,sha256=BM760XGEOmLeJcEm0ez5nBZ2NmFJWsNXbZ
43
43
  paasta_tools/hacheck.py,sha256=GtQd32G4JoB2bOWqzH9h9NPrkg8a50i-iXAblfYz2p4,2748
44
44
  paasta_tools/iptables.py,sha256=SQ7hutHarfCd13oAknKv_h9rUuln4rf11W6C2HHUy9g,7518
45
45
  paasta_tools/kafkacluster_tools.py,sha256=NMfowdpYhFpXW55MKx_eX6rrQj5Fn-5M_9ryZKd749A,4992
46
- paasta_tools/kubernetes_tools.py,sha256=nHc1CdVMrGg3DJTdu49viog6cXdhQrgvFbqrZ-QZquA,180306
46
+ paasta_tools/kubernetes_tools.py,sha256=zR29IQMhBUei1B8W5Oo-XskN91kfbReMzW6JxL4I_0U,181094
47
47
  paasta_tools/list_kubernetes_service_instances.py,sha256=UEPiTqNxUAqUgSyPzJlNcrI2W4HBwpngzDM1QD6AAVQ,3910
48
48
  paasta_tools/list_tron_namespaces.py,sha256=wfSkPY9_C-RkORmnon3DWL2lVZ4GNSSDG9VkFrDfY1E,1679
49
49
  paasta_tools/long_running_service_tools.py,sha256=PE4K9opcx16tEc3XxWgQBKCpV4cJYS2JfN-dyTFhmB4,26137
@@ -85,7 +85,7 @@ paasta_tools/api/__init__.py,sha256=H0VmJeHyCSXD9GbiEjjQwcB_sKOcoBiyK-IEJMmtCyQ,
85
85
  paasta_tools/api/api.py,sha256=SwlBbwH9e8ihnBSSkLU65CHrnzyQeDHPfRg_ik5LWZU,9859
86
86
  paasta_tools/api/client.py,sha256=RwEeM0fiwdcEpJQQEocuhdEZVnMdh8QwRHTwbx3wFP8,3614
87
87
  paasta_tools/api/settings.py,sha256=UbRnHL2GKeRfzfQ4qdlDy2KapGR-GoGpXK0SzNXUeM4,1303
88
- paasta_tools/api/api_docs/swagger.json,sha256=SgRjrGL8hQpITv00g_bTlxdBADed6Br-0vE3ULkaFto,89395
88
+ paasta_tools/api/api_docs/swagger.json,sha256=iNQm2m0vtbZulS3JozcodUC7gvU9Mfqy16YLZ5P_s_g,89538
89
89
  paasta_tools/api/tweens/__init__.py,sha256=nN1myeu8LuQKCDxz4XF9f55IDi13DSQgQ5e7OLP7DK8,144
90
90
  paasta_tools/api/tweens/auth.py,sha256=dran1Duk0tInhN_dutg-QgRcPfc5DADk5h7D2WVBPek,4197
91
91
  paasta_tools/api/tweens/profiling.py,sha256=prvrusCyDzP2j-64UCI-XGYxqDyyx8CDLKXl64oi-6M,3756
@@ -131,11 +131,11 @@ paasta_tools/cli/cmds/mark_for_deployment.py,sha256=mlb2BJECJnvbzAY7nTVly_kA5pNh
131
131
  paasta_tools/cli/cmds/mesh_status.py,sha256=PRhUVeDqURVm1RtiCH5Hcj7OUOqvkOTfa_JsCyCmyDg,6125
132
132
  paasta_tools/cli/cmds/pause_service_autoscaler.py,sha256=3Ie0wTkpRkl-Uja33WzWkPmBa5EJcPxMNAcZ8_P1LSo,3494
133
133
  paasta_tools/cli/cmds/push_to_registry.py,sha256=F7hWPY7MFtqznUfmJoQ0QPc5zAF5BS30_FWdQOrIqME,9736
134
- paasta_tools/cli/cmds/remote_run.py,sha256=kpNuh1UgZG6lYQyp2guIv9I11QTAQkCKUFp0Ehq_qqA,8988
134
+ paasta_tools/cli/cmds/remote_run.py,sha256=ObyUzWtv3uipiU7344-7QASzsWov7r5qSfugkz-ePLo,10490
135
135
  paasta_tools/cli/cmds/rollback.py,sha256=_42IwJaCXzo8e_GRbjImeG-7_o4ZGUMqX6meLRXD10Y,13841
136
136
  paasta_tools/cli/cmds/secret.py,sha256=onVUKyh4uuxBHLcBQcMYH_1uBbRjJrnPa5nMwHGzDSk,19709
137
137
  paasta_tools/cli/cmds/security_check.py,sha256=IEtcM0Hv2BWcavCjWcnPbyfrLcCRYC8jHLiHDj020z4,2377
138
- paasta_tools/cli/cmds/spark_run.py,sha256=jV_SNlLQ_m8OssRMGIjvoU5jOfavFRZXu0h71jEQNnc,50868
138
+ paasta_tools/cli/cmds/spark_run.py,sha256=3-kGdVAE3lukxIOhnrb022Ni031KtPirD5mWzsBswsU,51358
139
139
  paasta_tools/cli/cmds/start_stop_restart.py,sha256=MIMShmHer_uPEsLCb3qDaBOYyHSgqDHrLHEVFCcxaE0,14600
140
140
  paasta_tools/cli/cmds/status.py,sha256=dFTqEAJykVK7tLrxsxHXxS3SSBqzILTmXwaHP13cZQg,82409
141
141
  paasta_tools/cli/cmds/validate.py,sha256=7U1UDG5UHlfCZlK0S4EYYsA7s8YwOudS1zsRiYTPbWs,40059
@@ -174,7 +174,7 @@ paasta_tools/contrib/is_pod_healthy_in_smartstack.py,sha256=CWNIiwm-1FpXT5hpmZFA
174
174
  paasta_tools/contrib/kill_bad_containers.py,sha256=DVpemHWcH_gxlXK_9KS5pGOLbgbpwqN04lx1qyC0_Yk,3861
175
175
  paasta_tools/contrib/mass-deploy-tag.sh,sha256=cfPgDDvAOhy3ijTUocklogzoIY8hfoE6T5QI-0aqcfM,1578
176
176
  paasta_tools/contrib/mock_patch_checker.py,sha256=Y_kpCYrfxhkdMTf8KTvObtwD9hk1Cre9xhYMS5JxxEg,2575
177
- paasta_tools/contrib/paasta_update_soa_memcpu.py,sha256=nCVY7q6oiplRwxHXHXGo2qPbp0y2jKHdH9mK-bEefj0,17885
177
+ paasta_tools/contrib/paasta_update_soa_memcpu.py,sha256=RTFlg1VNJqj0etKLcQPuhlNfuZjbQuXiF2slKOvCXFw,20827
178
178
  paasta_tools/contrib/render_template.py,sha256=NWMFcWJ4ddV6rQsTVsINYhyVUh9kheR2Rtam-LJ5IsY,3991
179
179
  paasta_tools/contrib/rightsizer_soaconfigs_update.py,sha256=0UPVtDyX6wXXurv7l5fiKuzXH8VEszKx_V7UqDm6Ck0,10493
180
180
  paasta_tools/contrib/service_shard_remove.py,sha256=WCvCxu3GTYEa3cYnWybTOiuHN14axj0x5_-snVd-mqE,4927
@@ -191,7 +191,7 @@ paasta_tools/instance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
191
191
  paasta_tools/instance/hpa_metrics_parser.py,sha256=IsAYHSITL0z7LZUPC7gFj8oeASBx_Ad4bj5507irLx8,4371
192
192
  paasta_tools/instance/kubernetes.py,sha256=abgU_f-YAh2kOVruh_nAXGX4TOvOix-iwfM3QN7oVFE,46989
193
193
  paasta_tools/kubernetes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
194
- paasta_tools/kubernetes/remote_run.py,sha256=vGWwL-ZqAfBV1CVTuRS1ggAxdTCxt7fxMFaWN5GfrRY,17685
194
+ paasta_tools/kubernetes/remote_run.py,sha256=XGhpqRGYpaH3FHVZ2319kcI2dbC-UDOKmpbflrb1f1I,17797
195
195
  paasta_tools/kubernetes/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
196
196
  paasta_tools/kubernetes/application/controller_wrappers.py,sha256=nyUW-qtgNha5YzqTmwFfwVAcepKGqd9kl8ERpeNpt-k,19150
197
197
  paasta_tools/kubernetes/application/tools.py,sha256=-qbkn4ynM_LFa-NfiDMFZ3G4jty93DWKbx3_Go3OIIo,3618
@@ -290,61 +290,61 @@ paasta_tools/tron/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
290
290
  paasta_tools/tron/client.py,sha256=ypWjM4bZCzQWLn-qe1driqAxvF0ux8dROuFUv63dryA,5562
291
291
  paasta_tools/tron/tron_command_context.py,sha256=c6mph_DAt7pjcE3Uo271haJ0DfxJzfvcRhR2o-UmOeY,5379
292
292
  paasta_tools/tron/tron_timeutils.py,sha256=vDn04K7A3Xbs3lM04EgLuViC8AavOc5qyo8J5MC5nLk,3054
293
- paasta_tools-1.22.0.data/scripts/apply_external_resources.py,sha256=BOIdCQ5Md9RI3enzqbIWQge3clkXhPybAmLE3hqfDwQ,3347
294
- paasta_tools-1.22.0.data/scripts/bounce_log_latency_parser.py,sha256=dC06a0a5LdtPJ8xo88QWe5DMH_vwVB1BNbkFH7kJ3j0,2225
295
- paasta_tools-1.22.0.data/scripts/check_autoscaler_max_instances.py,sha256=2z6ifSU26-ULOK-FXp75b45mCdjSJnuvU8TxvapB8Wk,9423
296
- paasta_tools-1.22.0.data/scripts/check_cassandracluster_services_replication.py,sha256=mKlCK9pRNzxnOt41wA6CtDQIHhcky438i044kA6pbEc,1127
297
- paasta_tools-1.22.0.data/scripts/check_flink_services_health.py,sha256=ElYa1hr6KUcXuu0B8Nf-dt2Vfyo5FrwF5gVV4QBX7Lg,7162
298
- paasta_tools-1.22.0.data/scripts/check_kubernetes_api.py,sha256=BhOqJkkKNJPfonfIPonW5dlIubd1ji-3ppjXHomNwzM,1522
299
- paasta_tools-1.22.0.data/scripts/check_kubernetes_services_replication.py,sha256=LCLlumReRdy9Cw_sPpqanjPcBlbcrJDiECaYYru5Cwk,5751
300
- paasta_tools-1.22.0.data/scripts/check_manual_oapi_changes.sh,sha256=1IdphwXP7xnMNS7huZ3FeEHy67-nY4n3ydHmbojQvJg,879
301
- paasta_tools-1.22.0.data/scripts/check_oom_events.py,sha256=tUr14T2LYEgqwpAq4vkZ_Z0VTPOfQg7yrSSkwGQ86Hg,7801
302
- paasta_tools-1.22.0.data/scripts/check_orphans.py,sha256=zVC5ShFY7LUnPDUytRNsMgvqXkECHvyZlc3qZMpxLko,9985
303
- paasta_tools-1.22.0.data/scripts/check_spark_jobs.py,sha256=pVUdWmZSBuh4CbpW7cZ1Loq8FX0QFS0LQk2b24TGRyE,7317
304
- paasta_tools-1.22.0.data/scripts/cleanup_kubernetes_cr.py,sha256=m-w_wuTuVG9FlwQQkxXYgri5DTGac9Nc2pbK4k1FNDE,4659
305
- paasta_tools-1.22.0.data/scripts/cleanup_kubernetes_crd.py,sha256=p9eLk-0-pU-hcVg-GAM92h1ZdQqlvmYhBzUFCiMPYR8,4478
306
- paasta_tools-1.22.0.data/scripts/cleanup_kubernetes_jobs.py,sha256=7LHB4tsz1kt-zygssIfQbBY6c3LSqXYDUILvHkSfBog,12433
307
- paasta_tools-1.22.0.data/scripts/create_dynamodb_table.py,sha256=9wJftWGgNtvLnpXeUqpoMXBIIep1hNySf0YiQmzpl5c,1167
308
- paasta_tools-1.22.0.data/scripts/create_paasta_playground.py,sha256=jzoE5e1pxWeVXwCEkD9O0jefOhEnIlSa3QMP9PC2f0M,3239
309
- paasta_tools-1.22.0.data/scripts/delete_kubernetes_deployments.py,sha256=de4C-5yqEuCeJXp6zhbc0v-c0LOElr4qabLnOTRcX4o,3124
310
- paasta_tools-1.22.0.data/scripts/emit_allocated_cpu_metrics.py,sha256=Cjd3xoOJoYSP3ciSAlZ7fh6_z678KpYt43Xh-WVCY1M,1859
311
- paasta_tools-1.22.0.data/scripts/generate_all_deployments,sha256=Qr5B0zogTOr8Lcn_7dpORixpGIJcXZ_pWz_ZlWnmsik,248
312
- paasta_tools-1.22.0.data/scripts/generate_authenticating_services.py,sha256=r5AQyquVm8_rbAhBETUU2ZHZvolpqZZTakW3lKFiOqw,2982
313
- paasta_tools-1.22.0.data/scripts/generate_deployments_for_service.py,sha256=FAFzIAtKY7GsA13s-ssCMH7T-_p9B1pBtyyYFzsCZ6k,9822
314
- paasta_tools-1.22.0.data/scripts/generate_services_file.py,sha256=w3Wyyn9ZkjfrvkT0SnTbh5mrTZJnjhTC2JIqLBpb6-g,3583
315
- paasta_tools-1.22.0.data/scripts/generate_services_yaml.py,sha256=XyIUsHa1BPLqeklayaFewX69-6GT_luaSLS_TMDLkQ0,991
316
- paasta_tools-1.22.0.data/scripts/get_running_task_allocation.py,sha256=rV2IFGWU2sEYAVDCwKZgeseOAewFzfDiFeCnsPXdGXY,10890
317
- paasta_tools-1.22.0.data/scripts/habitat_fixer.py,sha256=hCC7fEnxrBOmiCJj4rPwhGlae9JsYg_gltk10l-FwaE,2625
318
- paasta_tools-1.22.0.data/scripts/ide_helper.py,sha256=YxHHqbnrJ88XI9Pmlup2QSvp15qVN5ugLuPYkEsmBCw,12334
319
- paasta_tools-1.22.0.data/scripts/is_pod_healthy_in_proxy.py,sha256=MiY85MJDXcN9oS8d840WG1iYDIzzO9lmk_NC0i_CrQg,4321
320
- paasta_tools-1.22.0.data/scripts/is_pod_healthy_in_smartstack.py,sha256=z3uP9sgwLwg94BubFgBKare2t1L5qhcY48MWsJxjxPY,1697
321
- paasta_tools-1.22.0.data/scripts/kill_bad_containers.py,sha256=oNY5x0Zg0eu34cXhFy60I7WRlqg4PKD_6xWi0eoRTCA,3832
322
- paasta_tools-1.22.0.data/scripts/kubernetes_remove_evicted_pods.py,sha256=D9Ovdc9Xer_Qf3vM5CtPVcKvnMwLiC0H-WQmQGXrBKM,5274
323
- paasta_tools-1.22.0.data/scripts/mass-deploy-tag.sh,sha256=cfPgDDvAOhy3ijTUocklogzoIY8hfoE6T5QI-0aqcfM,1578
324
- paasta_tools-1.22.0.data/scripts/mock_patch_checker.py,sha256=Q6Je8QjmfLzdnv_6JR6ehh2kA5SUxmeZGeLI2WC3BSY,2559
325
- paasta_tools-1.22.0.data/scripts/paasta_cleanup_remote_run_resources.py,sha256=4oN9UwnR7q6aEEyFUhVrT41VSeQJ2YS3upFpbZQXNUI,4558
326
- paasta_tools-1.22.0.data/scripts/paasta_cleanup_stale_nodes.py,sha256=C-DmEVgtienoMgJnIeESvFqWcJOW2SOGoS1l8RXA8NE,6304
327
- paasta_tools-1.22.0.data/scripts/paasta_deploy_tron_jobs,sha256=fFN2aP5FNSm5WfDV3yvLpihXaKkAF65MRXFcN2iD7S4,106
328
- paasta_tools-1.22.0.data/scripts/paasta_execute_docker_command.py,sha256=6kh7h2bleQbNULc37MiRsfnk9MDHqVv30UQdg3rF3kQ,4086
329
- paasta_tools-1.22.0.data/scripts/paasta_secrets_sync.py,sha256=sMdyWMt9BU5CmWHIRwzhpFKve7zxFHkygt_SNTJutWM,28766
330
- paasta_tools-1.22.0.data/scripts/paasta_tabcomplete.sh,sha256=qbQKSriz_L4MogA12L_8i-tg0Lplpshbk_FUMjK6uG0,929
331
- paasta_tools-1.22.0.data/scripts/paasta_update_soa_memcpu.py,sha256=1LOHMb4Gp3DcfkOzdCr9rcLa4mZXIv1p93sFvt7h96s,17871
332
- paasta_tools-1.22.0.data/scripts/render_template.py,sha256=KcKfeSP2a9f6fMDRhnjX7OJaHmFIBtCJcHhUI_B7p9Y,3975
333
- paasta_tools-1.22.0.data/scripts/rightsizer_soaconfigs_update.py,sha256=0UPVtDyX6wXXurv7l5fiKuzXH8VEszKx_V7UqDm6Ck0,10493
334
- paasta_tools-1.22.0.data/scripts/service_shard_remove.py,sha256=WCvCxu3GTYEa3cYnWybTOiuHN14axj0x5_-snVd-mqE,4927
335
- paasta_tools-1.22.0.data/scripts/service_shard_update.py,sha256=AajuRS4s-HXhEcIIYK2dsyBSdCjZbh4x6Po48ipl7M4,13346
336
- paasta_tools-1.22.0.data/scripts/setup_istio_mesh.py,sha256=LbLxeI_DnhNXkyCgG-GxutlNu9_vcIitorYr4I9x4CY,11575
337
- paasta_tools-1.22.0.data/scripts/setup_kubernetes_cr.py,sha256=8Jj362SLgoR6k0ZwzZ4bkJc3RJrxk-f2dpHD5zJXCuo,14625
338
- paasta_tools-1.22.0.data/scripts/setup_kubernetes_crd.py,sha256=QCiFOcSmE0nMEheIb7IUnYMUn0heh1kHyMFBCm7XIRU,4020
339
- paasta_tools-1.22.0.data/scripts/setup_kubernetes_internal_crd.py,sha256=dDyAOKFow7yeHWGa197angYwGTDWNyR7vZ6Cx5JlS6k,4629
340
- paasta_tools-1.22.0.data/scripts/setup_kubernetes_job.py,sha256=iGuGjDoevjpmdV3SXnAg65AwljkqC_c5yzTVvEsJ1xc,16929
341
- paasta_tools-1.22.0.data/scripts/setup_prometheus_adapter_config.py,sha256=51iFbtMu7MZzv9PVuQftJ59BUVBKdeC7G_zkt9-IXdc,40728
342
- paasta_tools-1.22.0.data/scripts/shared_ip_check.py,sha256=dbMwCwDLy9hCIbVWV1rk0FKuBkZNuQtM59hGVKxV2B4,2464
343
- paasta_tools-1.22.0.data/scripts/synapse_srv_namespaces_fact.py,sha256=HFX0zIXkXIjtAw8zrA7mUiy6NOKR11eBzE39R3aZv_E,1408
344
- paasta_tools-1.22.0.data/scripts/timeouts_metrics_prom.py,sha256=icK1j72-e-hvbUGs3LtcaMn9KBMopD9cGv5UUVo-OSc,2607
345
- paasta_tools-1.22.0.dist-info/LICENSE,sha256=Tcxn8PpeSjHDwUTemLW_thUNxcOOm612dK_no2ebEpo,10837
346
- paasta_tools-1.22.0.dist-info/METADATA,sha256=z8FeMjrqz1LpSqffcruUVtW_yzz5vFs1CPQigXzR5ds,2169
347
- paasta_tools-1.22.0.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
348
- paasta_tools-1.22.0.dist-info/entry_points.txt,sha256=5osYZ62iLdhb63d3P8e9ujafe97kisiB3K-geR5IdH8,1076
349
- paasta_tools-1.22.0.dist-info/top_level.txt,sha256=6vZZAZ7bbaDxuXZjNYixDwzkrezpNgDQHpS0ikvFOk4,24
350
- paasta_tools-1.22.0.dist-info/RECORD,,
293
+ paasta_tools-1.23.1.data/scripts/apply_external_resources.py,sha256=BOIdCQ5Md9RI3enzqbIWQge3clkXhPybAmLE3hqfDwQ,3347
294
+ paasta_tools-1.23.1.data/scripts/bounce_log_latency_parser.py,sha256=dC06a0a5LdtPJ8xo88QWe5DMH_vwVB1BNbkFH7kJ3j0,2225
295
+ paasta_tools-1.23.1.data/scripts/check_autoscaler_max_instances.py,sha256=2z6ifSU26-ULOK-FXp75b45mCdjSJnuvU8TxvapB8Wk,9423
296
+ paasta_tools-1.23.1.data/scripts/check_cassandracluster_services_replication.py,sha256=mKlCK9pRNzxnOt41wA6CtDQIHhcky438i044kA6pbEc,1127
297
+ paasta_tools-1.23.1.data/scripts/check_flink_services_health.py,sha256=ElYa1hr6KUcXuu0B8Nf-dt2Vfyo5FrwF5gVV4QBX7Lg,7162
298
+ paasta_tools-1.23.1.data/scripts/check_kubernetes_api.py,sha256=BhOqJkkKNJPfonfIPonW5dlIubd1ji-3ppjXHomNwzM,1522
299
+ paasta_tools-1.23.1.data/scripts/check_kubernetes_services_replication.py,sha256=LCLlumReRdy9Cw_sPpqanjPcBlbcrJDiECaYYru5Cwk,5751
300
+ paasta_tools-1.23.1.data/scripts/check_manual_oapi_changes.sh,sha256=1IdphwXP7xnMNS7huZ3FeEHy67-nY4n3ydHmbojQvJg,879
301
+ paasta_tools-1.23.1.data/scripts/check_oom_events.py,sha256=tUr14T2LYEgqwpAq4vkZ_Z0VTPOfQg7yrSSkwGQ86Hg,7801
302
+ paasta_tools-1.23.1.data/scripts/check_orphans.py,sha256=zVC5ShFY7LUnPDUytRNsMgvqXkECHvyZlc3qZMpxLko,9985
303
+ paasta_tools-1.23.1.data/scripts/check_spark_jobs.py,sha256=pVUdWmZSBuh4CbpW7cZ1Loq8FX0QFS0LQk2b24TGRyE,7317
304
+ paasta_tools-1.23.1.data/scripts/cleanup_kubernetes_cr.py,sha256=m-w_wuTuVG9FlwQQkxXYgri5DTGac9Nc2pbK4k1FNDE,4659
305
+ paasta_tools-1.23.1.data/scripts/cleanup_kubernetes_crd.py,sha256=p9eLk-0-pU-hcVg-GAM92h1ZdQqlvmYhBzUFCiMPYR8,4478
306
+ paasta_tools-1.23.1.data/scripts/cleanup_kubernetes_jobs.py,sha256=7LHB4tsz1kt-zygssIfQbBY6c3LSqXYDUILvHkSfBog,12433
307
+ paasta_tools-1.23.1.data/scripts/create_dynamodb_table.py,sha256=9wJftWGgNtvLnpXeUqpoMXBIIep1hNySf0YiQmzpl5c,1167
308
+ paasta_tools-1.23.1.data/scripts/create_paasta_playground.py,sha256=jzoE5e1pxWeVXwCEkD9O0jefOhEnIlSa3QMP9PC2f0M,3239
309
+ paasta_tools-1.23.1.data/scripts/delete_kubernetes_deployments.py,sha256=de4C-5yqEuCeJXp6zhbc0v-c0LOElr4qabLnOTRcX4o,3124
310
+ paasta_tools-1.23.1.data/scripts/emit_allocated_cpu_metrics.py,sha256=Cjd3xoOJoYSP3ciSAlZ7fh6_z678KpYt43Xh-WVCY1M,1859
311
+ paasta_tools-1.23.1.data/scripts/generate_all_deployments,sha256=Qr5B0zogTOr8Lcn_7dpORixpGIJcXZ_pWz_ZlWnmsik,248
312
+ paasta_tools-1.23.1.data/scripts/generate_authenticating_services.py,sha256=r5AQyquVm8_rbAhBETUU2ZHZvolpqZZTakW3lKFiOqw,2982
313
+ paasta_tools-1.23.1.data/scripts/generate_deployments_for_service.py,sha256=FAFzIAtKY7GsA13s-ssCMH7T-_p9B1pBtyyYFzsCZ6k,9822
314
+ paasta_tools-1.23.1.data/scripts/generate_services_file.py,sha256=w3Wyyn9ZkjfrvkT0SnTbh5mrTZJnjhTC2JIqLBpb6-g,3583
315
+ paasta_tools-1.23.1.data/scripts/generate_services_yaml.py,sha256=XyIUsHa1BPLqeklayaFewX69-6GT_luaSLS_TMDLkQ0,991
316
+ paasta_tools-1.23.1.data/scripts/get_running_task_allocation.py,sha256=rV2IFGWU2sEYAVDCwKZgeseOAewFzfDiFeCnsPXdGXY,10890
317
+ paasta_tools-1.23.1.data/scripts/habitat_fixer.py,sha256=hCC7fEnxrBOmiCJj4rPwhGlae9JsYg_gltk10l-FwaE,2625
318
+ paasta_tools-1.23.1.data/scripts/ide_helper.py,sha256=YxHHqbnrJ88XI9Pmlup2QSvp15qVN5ugLuPYkEsmBCw,12334
319
+ paasta_tools-1.23.1.data/scripts/is_pod_healthy_in_proxy.py,sha256=MiY85MJDXcN9oS8d840WG1iYDIzzO9lmk_NC0i_CrQg,4321
320
+ paasta_tools-1.23.1.data/scripts/is_pod_healthy_in_smartstack.py,sha256=z3uP9sgwLwg94BubFgBKare2t1L5qhcY48MWsJxjxPY,1697
321
+ paasta_tools-1.23.1.data/scripts/kill_bad_containers.py,sha256=oNY5x0Zg0eu34cXhFy60I7WRlqg4PKD_6xWi0eoRTCA,3832
322
+ paasta_tools-1.23.1.data/scripts/kubernetes_remove_evicted_pods.py,sha256=D9Ovdc9Xer_Qf3vM5CtPVcKvnMwLiC0H-WQmQGXrBKM,5274
323
+ paasta_tools-1.23.1.data/scripts/mass-deploy-tag.sh,sha256=cfPgDDvAOhy3ijTUocklogzoIY8hfoE6T5QI-0aqcfM,1578
324
+ paasta_tools-1.23.1.data/scripts/mock_patch_checker.py,sha256=Q6Je8QjmfLzdnv_6JR6ehh2kA5SUxmeZGeLI2WC3BSY,2559
325
+ paasta_tools-1.23.1.data/scripts/paasta_cleanup_remote_run_resources.py,sha256=4oN9UwnR7q6aEEyFUhVrT41VSeQJ2YS3upFpbZQXNUI,4558
326
+ paasta_tools-1.23.1.data/scripts/paasta_cleanup_stale_nodes.py,sha256=C-DmEVgtienoMgJnIeESvFqWcJOW2SOGoS1l8RXA8NE,6304
327
+ paasta_tools-1.23.1.data/scripts/paasta_deploy_tron_jobs,sha256=fFN2aP5FNSm5WfDV3yvLpihXaKkAF65MRXFcN2iD7S4,106
328
+ paasta_tools-1.23.1.data/scripts/paasta_execute_docker_command.py,sha256=6kh7h2bleQbNULc37MiRsfnk9MDHqVv30UQdg3rF3kQ,4086
329
+ paasta_tools-1.23.1.data/scripts/paasta_secrets_sync.py,sha256=sMdyWMt9BU5CmWHIRwzhpFKve7zxFHkygt_SNTJutWM,28766
330
+ paasta_tools-1.23.1.data/scripts/paasta_tabcomplete.sh,sha256=qbQKSriz_L4MogA12L_8i-tg0Lplpshbk_FUMjK6uG0,929
331
+ paasta_tools-1.23.1.data/scripts/paasta_update_soa_memcpu.py,sha256=5fShpZYpb7EeoC70cWdICnNHjHAaNU5mTHaAc3mloIs,20813
332
+ paasta_tools-1.23.1.data/scripts/render_template.py,sha256=KcKfeSP2a9f6fMDRhnjX7OJaHmFIBtCJcHhUI_B7p9Y,3975
333
+ paasta_tools-1.23.1.data/scripts/rightsizer_soaconfigs_update.py,sha256=0UPVtDyX6wXXurv7l5fiKuzXH8VEszKx_V7UqDm6Ck0,10493
334
+ paasta_tools-1.23.1.data/scripts/service_shard_remove.py,sha256=WCvCxu3GTYEa3cYnWybTOiuHN14axj0x5_-snVd-mqE,4927
335
+ paasta_tools-1.23.1.data/scripts/service_shard_update.py,sha256=AajuRS4s-HXhEcIIYK2dsyBSdCjZbh4x6Po48ipl7M4,13346
336
+ paasta_tools-1.23.1.data/scripts/setup_istio_mesh.py,sha256=LbLxeI_DnhNXkyCgG-GxutlNu9_vcIitorYr4I9x4CY,11575
337
+ paasta_tools-1.23.1.data/scripts/setup_kubernetes_cr.py,sha256=8Jj362SLgoR6k0ZwzZ4bkJc3RJrxk-f2dpHD5zJXCuo,14625
338
+ paasta_tools-1.23.1.data/scripts/setup_kubernetes_crd.py,sha256=QCiFOcSmE0nMEheIb7IUnYMUn0heh1kHyMFBCm7XIRU,4020
339
+ paasta_tools-1.23.1.data/scripts/setup_kubernetes_internal_crd.py,sha256=dDyAOKFow7yeHWGa197angYwGTDWNyR7vZ6Cx5JlS6k,4629
340
+ paasta_tools-1.23.1.data/scripts/setup_kubernetes_job.py,sha256=iGuGjDoevjpmdV3SXnAg65AwljkqC_c5yzTVvEsJ1xc,16929
341
+ paasta_tools-1.23.1.data/scripts/setup_prometheus_adapter_config.py,sha256=51iFbtMu7MZzv9PVuQftJ59BUVBKdeC7G_zkt9-IXdc,40728
342
+ paasta_tools-1.23.1.data/scripts/shared_ip_check.py,sha256=dbMwCwDLy9hCIbVWV1rk0FKuBkZNuQtM59hGVKxV2B4,2464
343
+ paasta_tools-1.23.1.data/scripts/synapse_srv_namespaces_fact.py,sha256=HFX0zIXkXIjtAw8zrA7mUiy6NOKR11eBzE39R3aZv_E,1408
344
+ paasta_tools-1.23.1.data/scripts/timeouts_metrics_prom.py,sha256=icK1j72-e-hvbUGs3LtcaMn9KBMopD9cGv5UUVo-OSc,2607
345
+ paasta_tools-1.23.1.dist-info/LICENSE,sha256=Tcxn8PpeSjHDwUTemLW_thUNxcOOm612dK_no2ebEpo,10837
346
+ paasta_tools-1.23.1.dist-info/METADATA,sha256=_wHfbWhMpiO20i9t_rWx-njbHJHSVEsA_OByYKlgKAQ,2169
347
+ paasta_tools-1.23.1.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
348
+ paasta_tools-1.23.1.dist-info/entry_points.txt,sha256=5osYZ62iLdhb63d3P8e9ujafe97kisiB3K-geR5IdH8,1076
349
+ paasta_tools-1.23.1.dist-info/top_level.txt,sha256=6vZZAZ7bbaDxuXZjNYixDwzkrezpNgDQHpS0ikvFOk4,24
350
+ paasta_tools-1.23.1.dist-info/RECORD,,