paasta-tools 1.30.8__py3-none-any.whl → 1.30.10__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.
- paasta_tools/__init__.py +1 -1
- paasta_tools/api/views/instance.py +9 -2
- paasta_tools/async_utils.py +4 -1
- paasta_tools/bounce_lib.py +8 -5
- paasta_tools/check_services_replication_tools.py +10 -4
- paasta_tools/check_spark_jobs.py +1 -1
- paasta_tools/cli/cli.py +4 -4
- paasta_tools/cli/cmds/logs.py +29 -7
- paasta_tools/cli/cmds/mark_for_deployment.py +2 -2
- paasta_tools/cli/cmds/mesh_status.py +1 -1
- paasta_tools/cli/cmds/remote_run.py +1 -1
- paasta_tools/cli/cmds/rollback.py +1 -1
- paasta_tools/cli/cmds/spark_run.py +3 -3
- paasta_tools/cli/cmds/status.py +24 -21
- paasta_tools/cli/cmds/validate.py +3 -3
- paasta_tools/cli/utils.py +32 -19
- paasta_tools/contrib/check_orphans.py +1 -1
- paasta_tools/contrib/get_running_task_allocation.py +1 -1
- paasta_tools/instance/kubernetes.py +2 -1
- paasta_tools/kubernetes_tools.py +2 -40
- paasta_tools/metrics/metastatus_lib.py +0 -24
- paasta_tools/metrics/metrics_lib.py +12 -3
- paasta_tools/setup_kubernetes_job.py +1 -1
- paasta_tools/setup_tron_namespace.py +2 -2
- paasta_tools/tron_tools.py +1 -1
- paasta_tools/utils.py +2 -9
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_orphans.py +1 -1
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_spark_jobs.py +1 -1
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/get_running_task_allocation.py +1 -1
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/setup_kubernetes_job.py +1 -1
- {paasta_tools-1.30.8.dist-info → paasta_tools-1.30.10.dist-info}/METADATA +2 -2
- {paasta_tools-1.30.8.dist-info → paasta_tools-1.30.10.dist-info}/RECORD +84 -89
- paasta_tools/frameworks/adhoc_scheduler.py +0 -71
- paasta_tools/frameworks/native_scheduler.py +0 -652
- paasta_tools/frameworks/task_store.py +0 -245
- paasta_tools/mesos_maintenance.py +0 -848
- paasta_tools/paasta_native_serviceinit.py +0 -21
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/apply_external_resources.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/bounce_log_latency_parser.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_autoscaler_max_instances.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_cassandracluster_services_replication.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_flink_services_health.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_kubernetes_api.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_kubernetes_services_replication.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_manual_oapi_changes.sh +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/check_oom_events.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/cleanup_kubernetes_cr.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/cleanup_kubernetes_crd.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/cleanup_kubernetes_jobs.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/create_dynamodb_table.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/create_paasta_playground.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/delete_kubernetes_deployments.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/emit_allocated_cpu_metrics.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/generate_all_deployments +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/generate_authenticating_services.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/generate_deployments_for_service.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/generate_services_file.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/generate_services_yaml.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/habitat_fixer.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/ide_helper.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/is_pod_healthy_in_proxy.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/is_pod_healthy_in_smartstack.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/kill_bad_containers.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/kubernetes_remove_evicted_pods.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/mass-deploy-tag.sh +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/mock_patch_checker.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/paasta_cleanup_remote_run_resources.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/paasta_cleanup_stale_nodes.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/paasta_deploy_tron_jobs +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/paasta_execute_docker_command.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/paasta_secrets_sync.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/paasta_tabcomplete.sh +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/paasta_update_soa_memcpu.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/render_template.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/rightsizer_soaconfigs_update.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/service_shard_remove.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/service_shard_update.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/setup_istio_mesh.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/setup_kubernetes_cr.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/setup_kubernetes_crd.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/setup_kubernetes_internal_crd.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/setup_prometheus_adapter_config.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/shared_ip_check.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/synapse_srv_namespaces_fact.py +0 -0
- {paasta_tools-1.30.8.data → paasta_tools-1.30.10.data}/scripts/timeouts_metrics_prom.py +0 -0
- {paasta_tools-1.30.8.dist-info → paasta_tools-1.30.10.dist-info}/WHEEL +0 -0
- {paasta_tools-1.30.8.dist-info → paasta_tools-1.30.10.dist-info}/entry_points.txt +0 -0
- {paasta_tools-1.30.8.dist-info → paasta_tools-1.30.10.dist-info}/licenses/LICENSE +0 -0
- {paasta_tools-1.30.8.dist-info → paasta_tools-1.30.10.dist-info}/top_level.txt +0 -0
paasta_tools/__init__.py
CHANGED
|
@@ -26,6 +26,7 @@ from typing import Mapping
|
|
|
26
26
|
from typing import Optional
|
|
27
27
|
|
|
28
28
|
import a_sync
|
|
29
|
+
from pyramid.request import Request
|
|
29
30
|
from pyramid.response import Response
|
|
30
31
|
from pyramid.view import view_config
|
|
31
32
|
|
|
@@ -139,7 +140,10 @@ def no_configuration_for_service_message(cluster, service, instance):
|
|
|
139
140
|
@view_config(
|
|
140
141
|
route_name="service.instance.status", request_method="GET", renderer="json"
|
|
141
142
|
)
|
|
142
|
-
def instance_status(
|
|
143
|
+
def instance_status(
|
|
144
|
+
request: Request,
|
|
145
|
+
) -> dict[str, Any]: # godspeed to anyone typing the retval here
|
|
146
|
+
# NOTE: swagger_data is populated by pyramid_swagger
|
|
143
147
|
service = request.swagger_data.get("service")
|
|
144
148
|
instance = request.swagger_data.get("instance")
|
|
145
149
|
verbose = request.swagger_data.get("verbose") or 0
|
|
@@ -353,7 +357,10 @@ def get_deployment_version(
|
|
|
353
357
|
request_method="GET",
|
|
354
358
|
renderer="json",
|
|
355
359
|
)
|
|
356
|
-
def instance_mesh_status(
|
|
360
|
+
def instance_mesh_status(
|
|
361
|
+
request: Request,
|
|
362
|
+
) -> dict[str, Any]: # godspeed to anyone typing the retval here
|
|
363
|
+
# NOTE: swagger_data is populated by pyramid_swagger
|
|
357
364
|
service = request.swagger_data.get("service")
|
|
358
365
|
instance = request.swagger_data.get("instance")
|
|
359
366
|
include_envoy = request.swagger_data.get("include_envoy")
|
paasta_tools/async_utils.py
CHANGED
|
@@ -3,9 +3,11 @@ import functools
|
|
|
3
3
|
import time
|
|
4
4
|
import weakref
|
|
5
5
|
from collections import defaultdict
|
|
6
|
+
from typing import Any
|
|
6
7
|
from typing import AsyncIterable
|
|
7
8
|
from typing import Awaitable
|
|
8
9
|
from typing import Callable
|
|
10
|
+
from typing import Coroutine
|
|
9
11
|
from typing import Dict
|
|
10
12
|
from typing import List
|
|
11
13
|
from typing import Optional
|
|
@@ -97,7 +99,8 @@ async def aiter_to_list(
|
|
|
97
99
|
def async_timeout(
|
|
98
100
|
seconds: int = 10,
|
|
99
101
|
) -> Callable[
|
|
100
|
-
[Callable[...,
|
|
102
|
+
[Callable[..., Coroutine[Any, Any, T]]],
|
|
103
|
+
Callable[..., Coroutine[Any, Any, T]], # wrapped # inner
|
|
101
104
|
]:
|
|
102
105
|
def outer(wrapped):
|
|
103
106
|
@functools.wraps(wrapped)
|
paasta_tools/bounce_lib.py
CHANGED
|
@@ -42,11 +42,14 @@ BounceMethodResult = TypedDict(
|
|
|
42
42
|
|
|
43
43
|
BounceMethod = Callable[
|
|
44
44
|
[
|
|
45
|
-
Arg(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
Arg(
|
|
46
|
+
BounceMethodConfigDict,
|
|
47
|
+
"new_config", # noqa: F821 # flake8 false-positive, these are not var references
|
|
48
|
+
),
|
|
49
|
+
Arg(bool, "new_app_running"), # noqa: F821 # flake8 false-positive
|
|
50
|
+
Arg(Collection, "happy_new_tasks"), # noqa: F821 # flake8 false-positive
|
|
51
|
+
Arg(Sequence, "old_non_draining_tasks"), # noqa: F821 # flake8 false-positive
|
|
52
|
+
DefaultArg(float, "margin_factor"), # noqa: F821 # flake8 false-positive
|
|
50
53
|
],
|
|
51
54
|
BounceMethodResult,
|
|
52
55
|
]
|
|
@@ -56,10 +56,16 @@ log = logging.getLogger(__name__)
|
|
|
56
56
|
|
|
57
57
|
CheckServiceReplication = Callable[
|
|
58
58
|
[
|
|
59
|
-
Arg(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
Arg(
|
|
60
|
+
InstanceConfig_T,
|
|
61
|
+
"instance_config", # noqa: F821 # flake8 false-positive, these are not var references
|
|
62
|
+
),
|
|
63
|
+
Arg(
|
|
64
|
+
Dict[str, Dict[str, List[V1Pod]]],
|
|
65
|
+
"pods_by_service_instance", # noqa: F821 # flake8 false-positive
|
|
66
|
+
),
|
|
67
|
+
Arg(Any, "replication_checker"), # noqa: F821 # flake8 false-positive
|
|
68
|
+
NamedArg(bool, "dry_run"), # noqa: F821 # flake8 false-positive
|
|
63
69
|
],
|
|
64
70
|
Optional[bool],
|
|
65
71
|
]
|
paasta_tools/check_spark_jobs.py
CHANGED
|
@@ -124,7 +124,7 @@ def format_framework(info):
|
|
|
124
124
|
def format_message_for_service(service, frameworks):
|
|
125
125
|
output = f"Found the following long-running Spark frameworks associated with service {service}.\n"
|
|
126
126
|
output += (
|
|
127
|
-
|
|
127
|
+
"Please check why they are still running and terminate if appropriate.\n\n"
|
|
128
128
|
)
|
|
129
129
|
output += "\n".join(format_framework(f) for f in frameworks)
|
|
130
130
|
return output
|
paasta_tools/cli/cli.py
CHANGED
|
@@ -68,7 +68,7 @@ class PrintsHelpOnErrorArgumentParser(argparse.ArgumentParser):
|
|
|
68
68
|
def list_external_commands():
|
|
69
69
|
p = subprocess.check_output(["/bin/bash", "-p", "-c", "compgen -A command paasta-"])
|
|
70
70
|
lines = p.decode("utf-8").strip().split("\n")
|
|
71
|
-
return {
|
|
71
|
+
return {line.replace("paasta-", "", 1) for line in lines}
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
def calling_external_command():
|
|
@@ -132,10 +132,10 @@ PAASTA_SUBCOMMANDS = {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
|
|
135
|
-
def get_argparser(commands=None):
|
|
135
|
+
def get_argparser(commands: list[str] | None = None) -> argparse.ArgumentParser:
|
|
136
136
|
"""Create and return argument parser for a set of subcommands.
|
|
137
137
|
|
|
138
|
-
:param commands:
|
|
138
|
+
:param commands: list[str] | None: If `commands` argument is `None`,
|
|
139
139
|
add full parsers for all subcommands, if `commands` is empty list -
|
|
140
140
|
add thin parsers for all subcommands, otherwise - add full parsers for
|
|
141
141
|
subcommands in the argument.
|
|
@@ -170,7 +170,7 @@ def get_argparser(commands=None):
|
|
|
170
170
|
|
|
171
171
|
# Adding a separate help subparser allows us to respond to "help" without --help
|
|
172
172
|
help_parser = subparsers.add_parser(
|
|
173
|
-
"help", help=
|
|
173
|
+
"help", help="run `paasta <subcommand> -h` for help"
|
|
174
174
|
)
|
|
175
175
|
help_parser.set_defaults(command=None)
|
|
176
176
|
|
paasta_tools/cli/cmds/logs.py
CHANGED
|
@@ -30,6 +30,7 @@ from typing import Callable
|
|
|
30
30
|
from typing import ContextManager
|
|
31
31
|
from typing import Dict
|
|
32
32
|
from typing import Iterable
|
|
33
|
+
from typing import Iterator
|
|
33
34
|
from typing import List
|
|
34
35
|
from typing import Mapping
|
|
35
36
|
from typing import MutableSequence
|
|
@@ -52,10 +53,31 @@ try:
|
|
|
52
53
|
except ImportError:
|
|
53
54
|
scribereader = None
|
|
54
55
|
|
|
56
|
+
# NOTE: this is an internal-only package, so we won't be able to typecheck against it with mypy
|
|
57
|
+
# without these hacky inlined stubs
|
|
55
58
|
try:
|
|
56
59
|
from logreader.readers import S3LogsReader
|
|
60
|
+
|
|
61
|
+
s3reader_available = True
|
|
57
62
|
except ImportError:
|
|
58
|
-
|
|
63
|
+
s3reader_available = False
|
|
64
|
+
|
|
65
|
+
class S3LogsReader: # type: ignore[no-redef] # stub class for internal-only package
|
|
66
|
+
def __init__(self, superregion: str) -> None:
|
|
67
|
+
raise ImportError(
|
|
68
|
+
"logreader (internal Yelp package) is not available - unable to display logs."
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def get_log_reader(
|
|
72
|
+
self,
|
|
73
|
+
log_name: str,
|
|
74
|
+
start_datetime: datetime.datetime,
|
|
75
|
+
end_datetime: datetime.datetime,
|
|
76
|
+
) -> Iterator[str]:
|
|
77
|
+
raise NotImplementedError(
|
|
78
|
+
"logreader (internal Yelp package) is not available - unable to display logs."
|
|
79
|
+
)
|
|
80
|
+
|
|
59
81
|
|
|
60
82
|
from pytimeparse.timeparse import timeparse
|
|
61
83
|
|
|
@@ -156,7 +178,7 @@ def add_subparser(subparsers) -> None:
|
|
|
156
178
|
dest="soa_dir",
|
|
157
179
|
metavar="SOA_DIR",
|
|
158
180
|
default=DEFAULT_SOA_DIR,
|
|
159
|
-
help=
|
|
181
|
+
help="Define a different soa config directory. Defaults to %(default)s.",
|
|
160
182
|
)
|
|
161
183
|
|
|
162
184
|
status_parser.add_argument(
|
|
@@ -1174,7 +1196,7 @@ class VectorLogsReader(LogReader):
|
|
|
1174
1196
|
) -> None:
|
|
1175
1197
|
super().__init__()
|
|
1176
1198
|
|
|
1177
|
-
if
|
|
1199
|
+
if not s3reader_available:
|
|
1178
1200
|
raise Exception("yelp_clog package must be available to use S3LogsReader")
|
|
1179
1201
|
|
|
1180
1202
|
self.cluster_map = cluster_map
|
|
@@ -1226,16 +1248,16 @@ class VectorLogsReader(LogReader):
|
|
|
1226
1248
|
except ValueError:
|
|
1227
1249
|
timestamp = pytz.utc.localize(datetime.datetime.min)
|
|
1228
1250
|
|
|
1229
|
-
|
|
1230
|
-
aggregated_logs.append(
|
|
1251
|
+
formatted_line = {"raw_line": line, "sort_key": timestamp}
|
|
1252
|
+
aggregated_logs.append(formatted_line)
|
|
1231
1253
|
|
|
1232
1254
|
aggregated_logs = list(
|
|
1233
1255
|
{line["raw_line"]: line for line in aggregated_logs}.values()
|
|
1234
1256
|
)
|
|
1235
1257
|
aggregated_logs.sort(key=lambda log_line: log_line["sort_key"])
|
|
1236
1258
|
|
|
1237
|
-
for
|
|
1238
|
-
print_log(
|
|
1259
|
+
for formatted_line in aggregated_logs:
|
|
1260
|
+
print_log(formatted_line["raw_line"], levels, raw_mode, strip_headers)
|
|
1239
1261
|
|
|
1240
1262
|
def tail_logs(
|
|
1241
1263
|
self,
|
|
@@ -1157,7 +1157,7 @@ class MarkForDeploymentProcess(RollbackSlackDeploymentProcess):
|
|
|
1157
1157
|
|
|
1158
1158
|
def on_enter_deploy_errored(self) -> None:
|
|
1159
1159
|
report_waiting_aborted(self.service, self.deploy_group)
|
|
1160
|
-
self.update_slack_status(
|
|
1160
|
+
self.update_slack_status("Deploy aborted, but it will still try to converge.")
|
|
1161
1161
|
self.send_manual_rollback_instructions()
|
|
1162
1162
|
if self.deploy_group_is_set_to_notify("notify_after_abort"):
|
|
1163
1163
|
self.ping_authors("Deploy errored")
|
|
@@ -1317,7 +1317,7 @@ class MarkForDeploymentProcess(RollbackSlackDeploymentProcess):
|
|
|
1317
1317
|
inactive_button_texts = {
|
|
1318
1318
|
"forward": f"Continue Forward to {version_short_str} :arrow_forward:",
|
|
1319
1319
|
"complete": f"Complete deploy to {version_short_str} :white_check_mark:",
|
|
1320
|
-
"snooze":
|
|
1320
|
+
"snooze": "Reset countdown",
|
|
1321
1321
|
"enable_auto_rollbacks": "Enable auto rollbacks :eyes:",
|
|
1322
1322
|
"disable_auto_rollbacks": "Disable auto rollbacks :close_eyes_monkey:",
|
|
1323
1323
|
}
|
|
@@ -124,7 +124,7 @@ def paasta_mesh_status_on_api_endpoint(
|
|
|
124
124
|
[PaastaColors.red(f"Could not connect to API: {exc.__class__.__name__}")],
|
|
125
125
|
)
|
|
126
126
|
except Exception as e:
|
|
127
|
-
output = [PaastaColors.red(
|
|
127
|
+
output = [PaastaColors.red("Exception when talking to the API:")]
|
|
128
128
|
output.extend(str(e).split("\n"))
|
|
129
129
|
return 1, output
|
|
130
130
|
|
|
@@ -116,7 +116,7 @@ def paasta_remote_run_copy(
|
|
|
116
116
|
)
|
|
117
117
|
if poll_response.status != 200:
|
|
118
118
|
print(
|
|
119
|
-
|
|
119
|
+
"Unable to find running remote-run pod: have you started one with `paasta remote-run start`?"
|
|
120
120
|
)
|
|
121
121
|
return 1
|
|
122
122
|
|
|
@@ -340,7 +340,7 @@ def paasta_rollback(args: argparse.Namespace) -> int:
|
|
|
340
340
|
)
|
|
341
341
|
print(
|
|
342
342
|
PaastaColors.yellow(
|
|
343
|
-
|
|
343
|
+
"WARNING: Failing to do so means that Jenkins will redeploy the latest code on the next scheduled build!"
|
|
344
344
|
)
|
|
345
345
|
)
|
|
346
346
|
|
|
@@ -902,15 +902,15 @@ def configure_and_run_docker_container(
|
|
|
902
902
|
environment["YELP_SVC_AUTHZ_TOKEN"] = get_service_auth_token()
|
|
903
903
|
|
|
904
904
|
webui_url = get_webui_url(spark_conf["spark.ui.port"])
|
|
905
|
-
webui_url_msg = PaastaColors.green(
|
|
905
|
+
webui_url_msg = PaastaColors.green("\nSpark monitoring URL: ") + f"{webui_url}\n"
|
|
906
906
|
|
|
907
907
|
docker_cmd = get_docker_cmd(args, instance_config, spark_conf_str)
|
|
908
908
|
if "history-server" in docker_cmd:
|
|
909
|
-
print(PaastaColors.green(
|
|
909
|
+
print(PaastaColors.green("\nSpark history server URL: ") + f"{webui_url}\n")
|
|
910
910
|
elif any(c in docker_cmd for c in ["pyspark", "spark-shell", "spark-submit"]):
|
|
911
911
|
grafana_url = get_grafana_url(spark_conf)
|
|
912
912
|
dashboard_url_msg = (
|
|
913
|
-
PaastaColors.green(
|
|
913
|
+
PaastaColors.green("\nGrafana dashboard: ") + f"{grafana_url}\n"
|
|
914
914
|
)
|
|
915
915
|
print(webui_url_msg)
|
|
916
916
|
print(dashboard_url_msg)
|
paasta_tools/cli/cmds/status.py
CHANGED
|
@@ -123,12 +123,15 @@ DEPLOYMENT_INSTANCE_CONFIG: Sequence[Type[InstanceConfig]] = [
|
|
|
123
123
|
|
|
124
124
|
InstanceStatusWriter = Callable[
|
|
125
125
|
[
|
|
126
|
-
Arg(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
Arg(
|
|
127
|
+
str,
|
|
128
|
+
"cluster", # noqa: F821 # flake8 false-positive, these are not var references
|
|
129
|
+
),
|
|
130
|
+
Arg(str, "service"), # noqa: F821 # flake8 false-positive
|
|
131
|
+
Arg(str, "instance"), # noqa: F821 # flake8 false-positive
|
|
132
|
+
Arg(List[str], "output"), # noqa: F821 # flake8 false-positive
|
|
130
133
|
Arg(Any),
|
|
131
|
-
Arg(int, "verbose"),
|
|
134
|
+
Arg(int, "verbose"), # noqa: F821 # flake8 false-positive
|
|
132
135
|
],
|
|
133
136
|
int,
|
|
134
137
|
]
|
|
@@ -328,7 +331,7 @@ def paasta_status_on_api_endpoint(
|
|
|
328
331
|
)
|
|
329
332
|
return 1
|
|
330
333
|
except Exception as e:
|
|
331
|
-
output.append(PaastaColors.red(
|
|
334
|
+
output.append(PaastaColors.red("Exception when talking to the API:"))
|
|
332
335
|
output.append(str(e))
|
|
333
336
|
return 1
|
|
334
337
|
|
|
@@ -528,7 +531,7 @@ def get_smartstack_status_human(
|
|
|
528
531
|
|
|
529
532
|
output = ["Smartstack:"]
|
|
530
533
|
output.append(f" Haproxy Service Name: {registration}")
|
|
531
|
-
output.append(
|
|
534
|
+
output.append(" Backends:")
|
|
532
535
|
for location in locations:
|
|
533
536
|
backend_status = haproxy_backend_report(
|
|
534
537
|
expected_backends_per_location, location.running_backends_count
|
|
@@ -586,7 +589,7 @@ def get_envoy_status_human(
|
|
|
586
589
|
|
|
587
590
|
output = ["Envoy:"]
|
|
588
591
|
output.append(f" Service Name: {registration}")
|
|
589
|
-
output.append(
|
|
592
|
+
output.append(" Backends:")
|
|
590
593
|
for location in locations:
|
|
591
594
|
backend_status = envoy_backend_report(
|
|
592
595
|
expected_backends_per_location, location.running_backends_count
|
|
@@ -829,7 +832,7 @@ def _print_flink_status_from_job_manager(
|
|
|
829
832
|
service=service, instance=instance, client=client
|
|
830
833
|
)
|
|
831
834
|
except Exception as e:
|
|
832
|
-
output.append(PaastaColors.red(
|
|
835
|
+
output.append(PaastaColors.red("Exception when talking to the API:"))
|
|
833
836
|
output.append(str(e))
|
|
834
837
|
return 1
|
|
835
838
|
|
|
@@ -858,7 +861,7 @@ def _print_flink_status_from_job_manager(
|
|
|
858
861
|
output.append(f"{OUTPUT_HORIZONTAL_RULE}")
|
|
859
862
|
|
|
860
863
|
# Print Flink Log Commands
|
|
861
|
-
output.append(
|
|
864
|
+
output.append(" Flink Log Commands:")
|
|
862
865
|
output.append(
|
|
863
866
|
f" Service: paasta logs -a 1h -c {cluster} -s {service} -i {instance}"
|
|
864
867
|
)
|
|
@@ -875,7 +878,7 @@ def _print_flink_status_from_job_manager(
|
|
|
875
878
|
output.append(f"{OUTPUT_HORIZONTAL_RULE}")
|
|
876
879
|
|
|
877
880
|
# Print Flink Metrics Links
|
|
878
|
-
output.append(
|
|
881
|
+
output.append(" Flink Monitoring:")
|
|
879
882
|
output.append(
|
|
880
883
|
f" Job Metrics: https://grafana.yelpcorp.com/d/flink-metrics/flink-job-metrics?orgId=1&var-datasource=Prometheus-flink&var-region=uswest2-{ecosystem}&var-service={service}&var-instance={instance}&var-job=All&from=now-24h&to=now"
|
|
881
884
|
)
|
|
@@ -1316,7 +1319,7 @@ def get_version_table_entry(
|
|
|
1316
1319
|
(state, pod) for state, pod in replica_states if state.is_unhealthy()
|
|
1317
1320
|
]
|
|
1318
1321
|
if unhealthy_replicas:
|
|
1319
|
-
entry.append(
|
|
1322
|
+
entry.append(" Unhealthy Replicas:")
|
|
1320
1323
|
replica_table = create_replica_table(
|
|
1321
1324
|
unhealthy_replicas, service, instance, cluster, verbose
|
|
1322
1325
|
)
|
|
@@ -1523,7 +1526,7 @@ def create_replica_table(
|
|
|
1523
1526
|
f" OOM Killed {human_oom_kill_timestamp} ({oom_kill_timestamp})."
|
|
1524
1527
|
),
|
|
1525
1528
|
PaastaColors.red(
|
|
1526
|
-
|
|
1529
|
+
" Check y/check-oom-events and consider increasing memory in yelpsoa_configs"
|
|
1527
1530
|
),
|
|
1528
1531
|
]
|
|
1529
1532
|
)
|
|
@@ -1587,7 +1590,7 @@ def create_replica_table(
|
|
|
1587
1590
|
elif state == ReplicaState.UNKNOWN:
|
|
1588
1591
|
table.append(
|
|
1589
1592
|
PaastaColors.red(
|
|
1590
|
-
|
|
1593
|
+
" Cannot determine pod state, please try again. If you continue to see this state, please contact #paasta"
|
|
1591
1594
|
)
|
|
1592
1595
|
)
|
|
1593
1596
|
return format_table(table)
|
|
@@ -1607,7 +1610,7 @@ def get_autoscaling_table(
|
|
|
1607
1610
|
table.append(f" Last scale time: {autoscaling_status['last_scale_time']}")
|
|
1608
1611
|
NA = PaastaColors.red("N/A")
|
|
1609
1612
|
if len(autoscaling_status["metrics"]) > 0:
|
|
1610
|
-
table.append(
|
|
1613
|
+
table.append(" Metrics:")
|
|
1611
1614
|
|
|
1612
1615
|
metrics_table: List[List[str]] = [["Metric", "Current", "Target"]]
|
|
1613
1616
|
for metric in autoscaling_status["metrics"]:
|
|
@@ -1695,10 +1698,10 @@ def print_kubernetes_status(
|
|
|
1695
1698
|
output.append(
|
|
1696
1699
|
f" Last scale time: {autoscaling_status['last_scale_time']}"
|
|
1697
1700
|
)
|
|
1698
|
-
output.append(
|
|
1701
|
+
output.append(" Dashboard: y/was-it-the-autoscaler")
|
|
1699
1702
|
NA = PaastaColors.red("N/A")
|
|
1700
1703
|
if len(autoscaling_status["metrics"]) > 0:
|
|
1701
|
-
output.append(
|
|
1704
|
+
output.append(" Metrics:")
|
|
1702
1705
|
|
|
1703
1706
|
metrics_table: List[List[str]] = [["Metric", "Current", "Target"]]
|
|
1704
1707
|
for metric in autoscaling_status["metrics"]:
|
|
@@ -2201,15 +2204,15 @@ def apply_args_filters(
|
|
|
2201
2204
|
if args.service or args.instances:
|
|
2202
2205
|
print(
|
|
2203
2206
|
PaastaColors.red(
|
|
2204
|
-
|
|
2205
|
-
|
|
2207
|
+
"Invalid command. Do not include optional arguments -s or -i "
|
|
2208
|
+
"when using shorthand notation."
|
|
2206
2209
|
)
|
|
2207
2210
|
)
|
|
2208
2211
|
return clusters_services_instances
|
|
2209
2212
|
if "." in args.service_instance:
|
|
2210
2213
|
args.service, args.instances = args.service_instance.split(".", 1)
|
|
2211
2214
|
else:
|
|
2212
|
-
print(PaastaColors.red(
|
|
2215
|
+
print(PaastaColors.red('Use a "." to separate service and instance name'))
|
|
2213
2216
|
return clusters_services_instances
|
|
2214
2217
|
if args.service:
|
|
2215
2218
|
try:
|
|
@@ -2221,7 +2224,7 @@ def apply_args_filters(
|
|
|
2221
2224
|
args.service, all_services, n=5, cutoff=0.5
|
|
2222
2225
|
)
|
|
2223
2226
|
if suggestions:
|
|
2224
|
-
print(PaastaColors.red(
|
|
2227
|
+
print(PaastaColors.red("Did you mean any of these?"))
|
|
2225
2228
|
for suggestion in suggestions:
|
|
2226
2229
|
print(PaastaColors.red(f" {suggestion}"))
|
|
2227
2230
|
return clusters_services_instances
|
|
@@ -573,7 +573,7 @@ def validate_paasta_objects(service_path):
|
|
|
573
573
|
errors = "\n".join(messages)
|
|
574
574
|
print(failure((f"There were failures validating {service}: {errors}"), ""))
|
|
575
575
|
else:
|
|
576
|
-
print(success(
|
|
576
|
+
print(success("All PaaSTA Instances for are valid for all clusters"))
|
|
577
577
|
|
|
578
578
|
return returncode
|
|
579
579
|
|
|
@@ -741,7 +741,7 @@ def validate_autoscaling_configs(service_path: str) -> bool:
|
|
|
741
741
|
and configured_provider_count > 1
|
|
742
742
|
):
|
|
743
743
|
raise AutoscalingValidationError(
|
|
744
|
-
|
|
744
|
+
"cannot use bespoke autoscaling with HPA autoscaling"
|
|
745
745
|
)
|
|
746
746
|
if metrics_provider["type"] in seen_provider_types:
|
|
747
747
|
raise AutoscalingValidationError(
|
|
@@ -808,7 +808,7 @@ def validate_autoscaling_configs(service_path: str) -> bool:
|
|
|
808
808
|
):
|
|
809
809
|
link = "y/override-cpu-autotune"
|
|
810
810
|
raise AutoscalingValidationError(
|
|
811
|
-
|
|
811
|
+
"CPU override detected for a CPU-autoscaled instance; "
|
|
812
812
|
"see the following link for next steps:"
|
|
813
813
|
)
|
|
814
814
|
except AutoscalingValidationError as e:
|
paasta_tools/cli/utils.py
CHANGED
|
@@ -26,6 +26,7 @@ import socket
|
|
|
26
26
|
import subprocess
|
|
27
27
|
from collections import defaultdict
|
|
28
28
|
from shlex import quote
|
|
29
|
+
from typing import Any
|
|
29
30
|
from typing import Callable
|
|
30
31
|
from typing import Collection
|
|
31
32
|
from typing import Generator
|
|
@@ -378,7 +379,7 @@ def list_service_instances(soa_dir: str = DEFAULT_SOA_DIR):
|
|
|
378
379
|
return the_list
|
|
379
380
|
|
|
380
381
|
|
|
381
|
-
def list_instances(**kwargs):
|
|
382
|
+
def list_instances(**kwargs: Any) -> list[str]:
|
|
382
383
|
"""Returns a sorted list of all possible instance names
|
|
383
384
|
for tab completion. We try to guess what service you might be
|
|
384
385
|
operating on, otherwise we just provide *all* of them
|
|
@@ -597,42 +598,54 @@ def get_jenkins_build_output_url():
|
|
|
597
598
|
|
|
598
599
|
InstanceListerSig = Callable[
|
|
599
600
|
[
|
|
600
|
-
NamedArg(
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
601
|
+
NamedArg(
|
|
602
|
+
str,
|
|
603
|
+
"service", # noqa: F821 # flake8 false-positive, these are not var references
|
|
604
|
+
),
|
|
605
|
+
NamedArg(Optional[str], "cluster"), # noqa: F821 # flake8 false-positive
|
|
606
|
+
NamedArg(str, "instance_type"), # noqa: F821 # flake8 false-positive
|
|
607
|
+
NamedArg(str, "soa_dir"), # noqa: F821 # flake8 false-positive
|
|
604
608
|
],
|
|
605
609
|
List[Tuple[str, str]],
|
|
606
610
|
]
|
|
607
611
|
|
|
608
612
|
InstanceLoaderSig = Callable[
|
|
609
613
|
[
|
|
610
|
-
NamedArg(
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
NamedArg(str, "
|
|
614
|
+
NamedArg(
|
|
615
|
+
str,
|
|
616
|
+
"service", # noqa: F821 # flake8 false-positive, these are not var references
|
|
617
|
+
),
|
|
618
|
+
NamedArg(str, "instance"), # noqa: F821 # flake8 false-positive
|
|
619
|
+
NamedArg(str, "cluster"), # noqa: F821 # flake8 false-positive
|
|
620
|
+
NamedArg(bool, "load_deployments"), # noqa: F821 # flake8 false-positive
|
|
621
|
+
NamedArg(str, "soa_dir"), # noqa: F821 # flake8 false-positive
|
|
615
622
|
],
|
|
616
623
|
InstanceConfig,
|
|
617
624
|
]
|
|
618
625
|
|
|
619
626
|
LongRunningServiceListerSig = Callable[
|
|
620
627
|
[
|
|
621
|
-
NamedArg(
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
628
|
+
NamedArg(
|
|
629
|
+
str,
|
|
630
|
+
"service", # noqa: F821 # flake8 false-positive, these are not var references
|
|
631
|
+
),
|
|
632
|
+
NamedArg(Optional[str], "cluster"), # noqa: F821 # flake8 false-positive
|
|
633
|
+
NamedArg(str, "instance_type"), # noqa: F821 # flake8 false-positive
|
|
634
|
+
NamedArg(str, "soa_dir"), # noqa: F821 # flake8 false-positive
|
|
625
635
|
],
|
|
626
636
|
List[Tuple[str, str]],
|
|
627
637
|
]
|
|
628
638
|
|
|
629
639
|
LongRunningServiceLoaderSig = Callable[
|
|
630
640
|
[
|
|
631
|
-
NamedArg(
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
NamedArg(str, "
|
|
641
|
+
NamedArg(
|
|
642
|
+
str,
|
|
643
|
+
"service", # noqa: F821 # flake8 false-positive, these are not var references
|
|
644
|
+
),
|
|
645
|
+
NamedArg(str, "instance"), # noqa: F821 # flake8 false-positive
|
|
646
|
+
NamedArg(str, "cluster"), # noqa: F821 # flake8 false-positive
|
|
647
|
+
NamedArg(bool, "load_deployments"), # noqa: F821 # flake8 false-positive
|
|
648
|
+
NamedArg(str, "soa_dir"), # noqa: F821 # flake8 false-positive
|
|
636
649
|
],
|
|
637
650
|
LongRunningServiceConfig,
|
|
638
651
|
]
|
|
@@ -56,7 +56,7 @@ def get_zk_data(ignored_services: Set[str]) -> SmartstackData:
|
|
|
56
56
|
zk = KazooClient(hosts=zk_hosts)
|
|
57
57
|
zk.start()
|
|
58
58
|
|
|
59
|
-
logger.debug(
|
|
59
|
+
logger.debug("pulling smartstack data from zookeeper")
|
|
60
60
|
zk_data = {}
|
|
61
61
|
services = zk.get_children(PREFIX)
|
|
62
62
|
for service in services:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/opt/venvs/paasta-tools/bin/python
|
|
2
2
|
import argparse
|
|
3
|
+
import json
|
|
3
4
|
import time
|
|
4
5
|
from typing import Any
|
|
5
6
|
from typing import Dict
|
|
@@ -12,7 +13,6 @@ from typing import Optional
|
|
|
12
13
|
from typing import Tuple
|
|
13
14
|
|
|
14
15
|
import a_sync
|
|
15
|
-
import simplejson as json
|
|
16
16
|
from kubernetes.client import V1Pod
|
|
17
17
|
from kubernetes.client import V1ResourceRequirements
|
|
18
18
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
from asyncio.tasks import Task
|
|
2
3
|
from collections import defaultdict
|
|
3
4
|
from enum import Enum
|
|
4
5
|
from typing import Any
|
|
@@ -1156,7 +1157,7 @@ async def kubernetes_status(
|
|
|
1156
1157
|
|
|
1157
1158
|
# this task is necessary for mesh_status, but most other use cases want
|
|
1158
1159
|
# just the list of pods
|
|
1159
|
-
pods_task = asyncio.create_task(
|
|
1160
|
+
pods_task: Task[Sequence[V1Pod]] = asyncio.create_task(
|
|
1160
1161
|
kubernetes_tools.pods_for_service_instance(
|
|
1161
1162
|
service=job_config.service,
|
|
1162
1163
|
instance=job_config.instance,
|