nginx-lens 0.2.3__tar.gz → 0.3.1__tar.gz
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.
Potentially problematic release.
This version of nginx-lens might be problematic. Click here for more details.
- {nginx_lens-0.2.3/nginx_lens.egg-info → nginx_lens-0.3.1}/PKG-INFO +1 -1
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/cli.py +2 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/health.py +29 -4
- nginx_lens-0.3.1/commands/resolve.py +52 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1/nginx_lens.egg-info}/PKG-INFO +1 -1
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/nginx_lens.egg-info/SOURCES.txt +1 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/setup.py +1 -1
- nginx_lens-0.3.1/upstream_checker/checker.py +164 -0
- nginx_lens-0.2.3/upstream_checker/checker.py +0 -79
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/LICENSE +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/README.md +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/__init__.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/base.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/conflicts.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/dead_locations.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/diff.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/duplicates.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/empty_blocks.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/include.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/rewrite.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/route.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/unused.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/analyzer/warnings.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/__init__.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/analyze.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/diff.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/graph.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/include.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/logs.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/route.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/syntax.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/commands/tree.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/exporter/__init__.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/exporter/graph.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/exporter/html.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/exporter/markdown.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/nginx_lens.egg-info/dependency_links.txt +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/nginx_lens.egg-info/entry_points.txt +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/nginx_lens.egg-info/requires.txt +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/nginx_lens.egg-info/top_level.txt +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/parser/__init__.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/parser/nginx_parser.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/pyproject.toml +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/setup.cfg +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/tests/test_conflicts.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/tests/test_duplicates.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/tests/test_empty_blocks.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/tests/test_health.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/tests/test_parser.py +0 -0
- {nginx_lens-0.2.3 → nginx_lens-0.3.1}/upstream_checker/__init__.py +0 -0
|
@@ -9,6 +9,7 @@ from commands.include import include_tree
|
|
|
9
9
|
from commands.graph import graph
|
|
10
10
|
from commands.logs import logs
|
|
11
11
|
from commands.syntax import syntax
|
|
12
|
+
from commands.resolve import resolve
|
|
12
13
|
|
|
13
14
|
app = typer.Typer(help="nginx-lens — анализ и диагностика конфигураций Nginx")
|
|
14
15
|
console = Console()
|
|
@@ -22,6 +23,7 @@ app.command()(include_tree)
|
|
|
22
23
|
app.command()(graph)
|
|
23
24
|
app.command()(logs)
|
|
24
25
|
app.command()(syntax)
|
|
26
|
+
app.command()(resolve)
|
|
25
27
|
|
|
26
28
|
if __name__ == "__main__":
|
|
27
29
|
app()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
from rich.console import Console
|
|
3
3
|
from rich.table import Table
|
|
4
|
-
from upstream_checker.checker import check_upstreams
|
|
4
|
+
from upstream_checker.checker import check_upstreams, resolve_upstreams
|
|
5
5
|
from parser.nginx_parser import parse_nginx_config
|
|
6
6
|
|
|
7
7
|
app = typer.Typer()
|
|
@@ -12,6 +12,7 @@ def health(
|
|
|
12
12
|
timeout: float = typer.Option(2.0, help="Таймаут проверки (сек)"),
|
|
13
13
|
retries: int = typer.Option(1, help="Количество попыток"),
|
|
14
14
|
mode: str = typer.Option("tcp", help="Режим проверки: tcp или http", case_sensitive=False),
|
|
15
|
+
resolve: bool = typer.Option(False, "--resolve", "-r", help="Показать резолвленные IP-адреса"),
|
|
15
16
|
):
|
|
16
17
|
"""
|
|
17
18
|
Проверяет доступность upstream-серверов, определённых в nginx.conf. Выводит таблицу.
|
|
@@ -19,6 +20,7 @@ def health(
|
|
|
19
20
|
Пример:
|
|
20
21
|
nginx-lens health /etc/nginx/nginx.conf
|
|
21
22
|
nginx-lens health /etc/nginx/nginx.conf --timeout 5 --retries 3 --mode http
|
|
23
|
+
nginx-lens health /etc/nginx/nginx.conf --resolve
|
|
22
24
|
"""
|
|
23
25
|
try:
|
|
24
26
|
tree = parse_nginx_config(config_path)
|
|
@@ -31,15 +33,38 @@ def health(
|
|
|
31
33
|
|
|
32
34
|
upstreams = tree.get_upstreams()
|
|
33
35
|
results = check_upstreams(upstreams, timeout=timeout, retries=retries, mode=mode.lower())
|
|
36
|
+
|
|
37
|
+
# Если нужно показать резолвленные IP-адреса
|
|
38
|
+
resolved_info = {}
|
|
39
|
+
if resolve:
|
|
40
|
+
resolved_info = resolve_upstreams(upstreams)
|
|
34
41
|
|
|
35
42
|
table = Table(show_header=True, header_style="bold blue")
|
|
36
|
-
table.add_column("
|
|
37
|
-
table.add_column("
|
|
43
|
+
table.add_column("Address")
|
|
44
|
+
table.add_column("Status")
|
|
45
|
+
if resolve:
|
|
46
|
+
table.add_column("Resolved IP")
|
|
38
47
|
|
|
39
48
|
for name, servers in results.items():
|
|
40
49
|
for srv in servers:
|
|
41
50
|
status = "Healthy" if srv["healthy"] else "Unhealthy"
|
|
42
51
|
color = "green" if srv["healthy"] else "red"
|
|
43
|
-
|
|
52
|
+
|
|
53
|
+
if resolve:
|
|
54
|
+
resolved_list = []
|
|
55
|
+
if name in resolved_info:
|
|
56
|
+
for resolved_srv in resolved_info[name]:
|
|
57
|
+
if resolved_srv["address"] == srv["address"]:
|
|
58
|
+
resolved_list = resolved_srv["resolved"]
|
|
59
|
+
break
|
|
60
|
+
|
|
61
|
+
if resolved_list:
|
|
62
|
+
# Показываем все IP-адреса через запятую
|
|
63
|
+
resolved_str = ", ".join(resolved_list)
|
|
64
|
+
table.add_row(srv["address"], f"[{color}]{status}[/{color}]", f"[green]{resolved_str}[/green]")
|
|
65
|
+
else:
|
|
66
|
+
table.add_row(srv["address"], f"[{color}]{status}[/{color}]", "[yellow]Failed to resolve[/yellow]")
|
|
67
|
+
else:
|
|
68
|
+
table.add_row(srv["address"], f"[{color}]{status}[/{color}]")
|
|
44
69
|
|
|
45
70
|
console.print(table)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from rich.console import Console
|
|
3
|
+
from rich.table import Table
|
|
4
|
+
from upstream_checker.checker import resolve_upstreams
|
|
5
|
+
from parser.nginx_parser import parse_nginx_config
|
|
6
|
+
|
|
7
|
+
app = typer.Typer()
|
|
8
|
+
console = Console()
|
|
9
|
+
|
|
10
|
+
def resolve(
|
|
11
|
+
config_path: str = typer.Argument(..., help="Путь к nginx.conf"),
|
|
12
|
+
):
|
|
13
|
+
"""
|
|
14
|
+
Резолвит DNS имена upstream-серверов в IP-адреса.
|
|
15
|
+
|
|
16
|
+
Пример:
|
|
17
|
+
nginx-lens resolve /etc/nginx/nginx.conf
|
|
18
|
+
"""
|
|
19
|
+
try:
|
|
20
|
+
tree = parse_nginx_config(config_path)
|
|
21
|
+
except FileNotFoundError:
|
|
22
|
+
console.print(f"[red]Файл {config_path} не найден. Проверьте путь к конфигу.[/red]")
|
|
23
|
+
return
|
|
24
|
+
except Exception as e:
|
|
25
|
+
console.print(f"[red]Ошибка при разборе {config_path}: {e}[/red]")
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
upstreams = tree.get_upstreams()
|
|
29
|
+
if not upstreams:
|
|
30
|
+
console.print("[yellow]Не найдено ни одного upstream в конфигурации.[/yellow]")
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
results = resolve_upstreams(upstreams)
|
|
34
|
+
|
|
35
|
+
table = Table(show_header=True, header_style="bold blue")
|
|
36
|
+
table.add_column("Upstream Name")
|
|
37
|
+
table.add_column("Address")
|
|
38
|
+
table.add_column("Resolved IP")
|
|
39
|
+
|
|
40
|
+
for name, servers in results.items():
|
|
41
|
+
for idx, srv in enumerate(servers):
|
|
42
|
+
upstream_name = name if idx == 0 else ""
|
|
43
|
+
resolved_list = srv["resolved"]
|
|
44
|
+
if resolved_list:
|
|
45
|
+
# Показываем все IP-адреса через запятую
|
|
46
|
+
resolved_str = ", ".join(resolved_list)
|
|
47
|
+
table.add_row(upstream_name, srv["address"], f"[green]{resolved_str}[/green]")
|
|
48
|
+
else:
|
|
49
|
+
table.add_row(upstream_name, srv["address"], "[red]Failed to resolve[/red]")
|
|
50
|
+
|
|
51
|
+
console.print(table)
|
|
52
|
+
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="nginx-lens",
|
|
5
|
-
version="0.
|
|
5
|
+
version="0.3.1",
|
|
6
6
|
description="CLI-инструмент для анализа, визуализации и диагностики конфигураций Nginx",
|
|
7
7
|
author="Daniil Astrouski",
|
|
8
8
|
author_email="shelovesuastra@gmail.com",
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# upstream_checker/checker.py
|
|
2
|
+
|
|
3
|
+
import socket
|
|
4
|
+
import time
|
|
5
|
+
import http.client
|
|
6
|
+
from typing import Dict, List
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def check_tcp(address: str, timeout: float, retries: int) -> bool:
|
|
10
|
+
"""
|
|
11
|
+
Проверка доступности сервера по TCP.
|
|
12
|
+
Ignores extra upstream options like 'max_fails' or 'fail_timeout'.
|
|
13
|
+
"""
|
|
14
|
+
# Берем только host:port, игнорируем параметры
|
|
15
|
+
host_port = address.split()[0]
|
|
16
|
+
host, port = host_port.split(":")
|
|
17
|
+
port = int(port)
|
|
18
|
+
|
|
19
|
+
for _ in range(retries):
|
|
20
|
+
try:
|
|
21
|
+
with socket.create_connection((host, port), timeout=timeout):
|
|
22
|
+
return True
|
|
23
|
+
except (socket.timeout, ConnectionRefusedError, OSError):
|
|
24
|
+
time.sleep(0.2)
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def check_http(address: str, timeout: float, retries: int) -> bool:
|
|
29
|
+
"""
|
|
30
|
+
Проверка доступности сервера по HTTP (GET /).
|
|
31
|
+
Ignores extra upstream options like 'max_fails' or 'fail_timeout'.
|
|
32
|
+
"""
|
|
33
|
+
host_port = address.split()[0]
|
|
34
|
+
host, port = host_port.split(":")
|
|
35
|
+
port = int(port)
|
|
36
|
+
|
|
37
|
+
for _ in range(retries):
|
|
38
|
+
try:
|
|
39
|
+
conn = http.client.HTTPConnection(host, port, timeout=timeout)
|
|
40
|
+
conn.request("GET", "/")
|
|
41
|
+
resp = conn.getresponse()
|
|
42
|
+
healthy = resp.status < 500
|
|
43
|
+
conn.close()
|
|
44
|
+
if healthy:
|
|
45
|
+
return True
|
|
46
|
+
except Exception:
|
|
47
|
+
time.sleep(0.2)
|
|
48
|
+
continue
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def resolve_address(address: str) -> List[str]:
|
|
53
|
+
"""
|
|
54
|
+
Резолвит адрес upstream сервера в IP-адреса.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
address: Адрес в формате "host:port" или "host:port параметры"
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Список IP-адресов в формате "ip:port" или пустой список, если резолвинг не удался
|
|
61
|
+
"""
|
|
62
|
+
try:
|
|
63
|
+
host_port = address.split()[0]
|
|
64
|
+
|
|
65
|
+
if ":" not in host_port:
|
|
66
|
+
return []
|
|
67
|
+
|
|
68
|
+
parts = host_port.rsplit(":", 1)
|
|
69
|
+
if len(parts) != 2:
|
|
70
|
+
return []
|
|
71
|
+
host, port = parts
|
|
72
|
+
|
|
73
|
+
# Если это уже IPv4 адрес, возвращаем как есть
|
|
74
|
+
try:
|
|
75
|
+
socket.inet_aton(host)
|
|
76
|
+
return [host_port]
|
|
77
|
+
except socket.error:
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
# Проверяем IPv6 (в квадратных скобках)
|
|
81
|
+
if host.startswith("[") and host.endswith("]"):
|
|
82
|
+
ipv6_host = host[1:-1]
|
|
83
|
+
try:
|
|
84
|
+
socket.inet_pton(socket.AF_INET6, ipv6_host)
|
|
85
|
+
return [host_port]
|
|
86
|
+
except (socket.error, OSError):
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
# Пытаемся резолвить DNS имя - получаем все IP-адреса
|
|
90
|
+
try:
|
|
91
|
+
# gethostbyname_ex возвращает (hostname, aliaslist, ipaddrlist)
|
|
92
|
+
_, _, ipaddrlist = socket.gethostbyname_ex(host)
|
|
93
|
+
# Фильтруем только IPv4 адреса (IPv6 обрабатываются отдельно)
|
|
94
|
+
resolved_ips = []
|
|
95
|
+
for ip in ipaddrlist:
|
|
96
|
+
try:
|
|
97
|
+
# Проверяем, что это IPv4
|
|
98
|
+
socket.inet_aton(ip)
|
|
99
|
+
resolved_ips.append(f"{ip}:{port}")
|
|
100
|
+
except socket.error:
|
|
101
|
+
pass
|
|
102
|
+
return resolved_ips if resolved_ips else []
|
|
103
|
+
except (socket.gaierror, OSError):
|
|
104
|
+
return []
|
|
105
|
+
except (ValueError, IndexError, AttributeError):
|
|
106
|
+
return []
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def resolve_upstreams(
|
|
110
|
+
upstreams: Dict[str, List[str]]
|
|
111
|
+
) -> Dict[str, List[dict]]:
|
|
112
|
+
"""
|
|
113
|
+
Резолвит DNS имена upstream-серверов в IP-адреса.
|
|
114
|
+
|
|
115
|
+
Возвращает:
|
|
116
|
+
{
|
|
117
|
+
"backend": [
|
|
118
|
+
{"address": "example.com:8080", "resolved": ["192.168.1.1:8080", "192.168.1.2:8080"]},
|
|
119
|
+
{"address": "127.0.0.1:8080", "resolved": ["127.0.0.1:8080"]},
|
|
120
|
+
{"address": "badhost:80", "resolved": []},
|
|
121
|
+
...
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
"""
|
|
125
|
+
results = {}
|
|
126
|
+
for name, servers in upstreams.items():
|
|
127
|
+
results[name] = []
|
|
128
|
+
for srv in servers:
|
|
129
|
+
resolved = resolve_address(srv)
|
|
130
|
+
results[name].append({
|
|
131
|
+
"address": srv,
|
|
132
|
+
"resolved": resolved
|
|
133
|
+
})
|
|
134
|
+
return results
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def check_upstreams(
|
|
138
|
+
upstreams: Dict[str, List[str]],
|
|
139
|
+
timeout: float = 2.0,
|
|
140
|
+
retries: int = 1,
|
|
141
|
+
mode: str = "tcp"
|
|
142
|
+
) -> Dict[str, List[dict]]:
|
|
143
|
+
"""
|
|
144
|
+
Проверяет доступность upstream-серверов.
|
|
145
|
+
mode: "tcp" (по умолчанию) или "http"
|
|
146
|
+
|
|
147
|
+
Возвращает:
|
|
148
|
+
{
|
|
149
|
+
"backend": [
|
|
150
|
+
{"address": "127.0.0.1:8080", "healthy": True},
|
|
151
|
+
...
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
"""
|
|
155
|
+
results = {}
|
|
156
|
+
for name, servers in upstreams.items():
|
|
157
|
+
results[name] = []
|
|
158
|
+
for srv in servers:
|
|
159
|
+
if mode.lower() == "http":
|
|
160
|
+
healthy = check_http(srv, timeout, retries)
|
|
161
|
+
else:
|
|
162
|
+
healthy = check_tcp(srv, timeout, retries)
|
|
163
|
+
results[name].append({"address": srv, "healthy": healthy})
|
|
164
|
+
return results
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# upstream_checker/checker.py
|
|
2
|
-
|
|
3
|
-
import socket
|
|
4
|
-
import time
|
|
5
|
-
import http.client
|
|
6
|
-
from typing import Dict, List
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def check_tcp(address: str, timeout: float, retries: int) -> bool:
|
|
10
|
-
"""
|
|
11
|
-
Проверка доступности сервера по TCP.
|
|
12
|
-
Ignores extra upstream options like 'max_fails' or 'fail_timeout'.
|
|
13
|
-
"""
|
|
14
|
-
# Берем только host:port, игнорируем параметры
|
|
15
|
-
host_port = address.split()[0]
|
|
16
|
-
host, port = host_port.split(":")
|
|
17
|
-
port = int(port)
|
|
18
|
-
|
|
19
|
-
for _ in range(retries):
|
|
20
|
-
try:
|
|
21
|
-
with socket.create_connection((host, port), timeout=timeout):
|
|
22
|
-
return True
|
|
23
|
-
except (socket.timeout, ConnectionRefusedError, OSError):
|
|
24
|
-
time.sleep(0.2)
|
|
25
|
-
return False
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def check_http(address: str, timeout: float, retries: int) -> bool:
|
|
29
|
-
"""
|
|
30
|
-
Проверка доступности сервера по HTTP (GET /).
|
|
31
|
-
Ignores extra upstream options like 'max_fails' or 'fail_timeout'.
|
|
32
|
-
"""
|
|
33
|
-
host_port = address.split()[0]
|
|
34
|
-
host, port = host_port.split(":")
|
|
35
|
-
port = int(port)
|
|
36
|
-
|
|
37
|
-
for _ in range(retries):
|
|
38
|
-
try:
|
|
39
|
-
conn = http.client.HTTPConnection(host, port, timeout=timeout)
|
|
40
|
-
conn.request("GET", "/")
|
|
41
|
-
resp = conn.getresponse()
|
|
42
|
-
healthy = resp.status < 500
|
|
43
|
-
conn.close()
|
|
44
|
-
if healthy:
|
|
45
|
-
return True
|
|
46
|
-
except Exception:
|
|
47
|
-
time.sleep(0.2)
|
|
48
|
-
continue
|
|
49
|
-
return False
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def check_upstreams(
|
|
53
|
-
upstreams: Dict[str, List[str]],
|
|
54
|
-
timeout: float = 2.0,
|
|
55
|
-
retries: int = 1,
|
|
56
|
-
mode: str = "tcp"
|
|
57
|
-
) -> Dict[str, List[dict]]:
|
|
58
|
-
"""
|
|
59
|
-
Проверяет доступность upstream-серверов.
|
|
60
|
-
mode: "tcp" (по умолчанию) или "http"
|
|
61
|
-
|
|
62
|
-
Возвращает:
|
|
63
|
-
{
|
|
64
|
-
"backend": [
|
|
65
|
-
{"address": "127.0.0.1:8080", "healthy": True},
|
|
66
|
-
...
|
|
67
|
-
]
|
|
68
|
-
}
|
|
69
|
-
"""
|
|
70
|
-
results = {}
|
|
71
|
-
for name, servers in upstreams.items():
|
|
72
|
-
results[name] = []
|
|
73
|
-
for srv in servers:
|
|
74
|
-
if mode.lower() == "http":
|
|
75
|
-
healthy = check_http(srv, timeout, retries)
|
|
76
|
-
else:
|
|
77
|
-
healthy = check_tcp(srv, timeout, retries)
|
|
78
|
-
results[name].append({"address": srv, "healthy": healthy})
|
|
79
|
-
return results
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|