nginx-lens 0.2.0__py3-none-any.whl → 0.2.2__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.
commands/health.py CHANGED
@@ -10,14 +10,15 @@ console = Console()
10
10
  def health(
11
11
  config_path: str = typer.Argument(..., help="Путь к nginx.conf"),
12
12
  timeout: float = typer.Option(2.0, help="Таймаут проверки (сек)"),
13
- retries: int = typer.Option(1, help="Количество попыток")
13
+ retries: int = typer.Option(1, help="Количество попыток"),
14
+ mode: str = typer.Option("tcp", help="Режим проверки: tcp или http", case_sensitive=False),
14
15
  ):
15
16
  """
16
17
  Проверяет доступность upstream-серверов, определённых в nginx.conf. Выводит таблицу.
17
18
 
18
19
  Пример:
19
20
  nginx-lens health /etc/nginx/nginx.conf
20
- nginx-lens health /etc/nginx/nginx.conf --timeout 5 --retries 3
21
+ nginx-lens health /etc/nginx/nginx.conf --timeout 5 --retries 3 --mode http
21
22
  """
22
23
  try:
23
24
  tree = parse_nginx_config(config_path)
@@ -27,14 +28,18 @@ def health(
27
28
  except Exception as e:
28
29
  console.print(f"[red]Ошибка при разборе {config_path}: {e}[/red]")
29
30
  return
31
+
30
32
  upstreams = tree.get_upstreams()
31
- results = check_upstreams(upstreams, timeout=timeout, retries=retries)
33
+ results = check_upstreams(upstreams, timeout=timeout, retries=retries, mode=mode.lower())
34
+
32
35
  table = Table(show_header=True, header_style="bold blue")
33
36
  table.add_column("upstream_name")
34
37
  table.add_column("upstream_status")
38
+
35
39
  for name, servers in results.items():
36
40
  for srv in servers:
37
41
  status = "Healthy" if srv["healthy"] else "Unhealthy"
38
42
  color = "green" if srv["healthy"] else "red"
39
43
  table.add_row(srv["address"], f"[{color}]{status}[/{color}]")
40
- console.print(table)
44
+
45
+ console.print(table)
commands/route.py CHANGED
@@ -29,7 +29,7 @@ def route(
29
29
  else:
30
30
  configs = glob.glob("/etc/nginx/**/*.conf", recursive=True)
31
31
  if not configs:
32
- console.print(Panel("Не найдено ни одного .conf файла в /etc/nginx", style="red"))
32
+ console.print(Panel("Не найдено ни одного .conf файла в /etc/nginx. Если конфигурация находится в другом месте, используйте опцию -c/--config.", style="red"))
33
33
  return
34
34
  for conf in configs:
35
35
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nginx-lens
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: CLI-инструмент для анализа, визуализации и диагностики конфигураций Nginx
5
5
  Author: Daniil Astrouski
6
6
  Author-email: shelovesuastra@gmail.com
@@ -15,23 +15,23 @@ commands/analyze.py,sha256=W6begSgXNjgKJGoGeguR3WKgHPLkClWXxxpDcqvsJdc,8343
15
15
  commands/cli.py,sha256=9HwDJ-po5al0ceb4Wkyw5F2wzqxbJTo0CbHQ2AQ8obo,722
16
16
  commands/diff.py,sha256=C7gRIWh6DNWHzjiQBPVTn-rZ40m2KCY75Zd6Q4URJIE,2076
17
17
  commands/graph.py,sha256=xB6KjXBkLmm5gII3e-5BMRGO7WeTwc7EFxRGzYgnme4,5947
18
- commands/health.py,sha256=SuD2gOeMf9ZaoUfeqx1Nip0xQDBkDus6z872Fhw2Z9w,1682
18
+ commands/health.py,sha256=EV2M2Gt_LnA8WI_0gOBlRYr2u-fxpjq6FBd-tlQOSuI,1830
19
19
  commands/include.py,sha256=5PTYG5C00-AlWfIgpQXLq9E7C9yTFSv7HrZkM5ogDps,2224
20
20
  commands/logs.py,sha256=RkPUdIpbO9dOVL56lemreYRuAjMjcqqMxRCKOFv2gC4,3691
21
- commands/route.py,sha256=GzpHUqOwDOzhWlKcNf177Vq4OB6g--_8npZXPMDRNGg,3034
21
+ commands/route.py,sha256=-x_71u6ENl3iO-oxK3bdE8v5eZKf4xRCydeUyXMFVrY,3163
22
22
  commands/syntax.py,sha256=ZWFdaL8LVv9S694wlk2aV3HJKb0OSKjw3wNgTlNvFR8,3418
23
23
  commands/tree.py,sha256=mDfx0Aeg1EDQSYQoJ2nJIkSd_uP7ZR7pEqy7Cw3clQ0,2161
24
24
  exporter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  exporter/graph.py,sha256=WYUrqUgCaK6KihgxAcRHaQn4oMo6b7ybC8yb_36ZIsA,3995
26
26
  exporter/html.py,sha256=uquEM-WvBt2aV9GshgaI3UVhYd8sD0QQ-OmuNtvYUdU,798
27
27
  exporter/markdown.py,sha256=_0mXQIhurGEZ0dO-eq9DbsuKNrgEDIblgtL3DAgYNo8,724
28
- nginx_lens-0.2.0.dist-info/licenses/LICENSE,sha256=g8QXKdvZZC56rU8E12vIeYF6R4jeTWOsblOnYAda3K4,1073
28
+ nginx_lens-0.2.2.dist-info/licenses/LICENSE,sha256=g8QXKdvZZC56rU8E12vIeYF6R4jeTWOsblOnYAda3K4,1073
29
29
  parser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  parser/nginx_parser.py,sha256=Sa9FtGAkvTqNzoehBvgLUWPJHLLIZYWH9ugSHW50X8s,3699
31
31
  upstream_checker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- upstream_checker/checker.py,sha256=9-6CMUTN7gXUACP8EwX722QogfujZyV-WWWUeM3a79k,455
33
- nginx_lens-0.2.0.dist-info/METADATA,sha256=lLuwZ7f3S8BLDun8sm25Oq-9S8jNux_PPOnL_AIkcqg,520
34
- nginx_lens-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- nginx_lens-0.2.0.dist-info/entry_points.txt,sha256=qEcecjSyLqcJjbIVlNlTpqAhPqDyaujUV5ZcBTAr3po,48
36
- nginx_lens-0.2.0.dist-info/top_level.txt,sha256=mxLJO4rZg0rbixVGhplF3fUNFs8vxDIL25ronZNvRy4,51
37
- nginx_lens-0.2.0.dist-info/RECORD,,
32
+ upstream_checker/checker.py,sha256=_GiiNNO1U2CoFKmJP7rWwvCdyxsgB4keSS9y4IrSeEc,1961
33
+ nginx_lens-0.2.2.dist-info/METADATA,sha256=wyn9pvzpCJVnmjcdQjtE04udvjc9NOqZ_pWfx7BQGh8,520
34
+ nginx_lens-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
+ nginx_lens-0.2.2.dist-info/entry_points.txt,sha256=qEcecjSyLqcJjbIVlNlTpqAhPqDyaujUV5ZcBTAr3po,48
36
+ nginx_lens-0.2.2.dist-info/top_level.txt,sha256=mxLJO4rZg0rbixVGhplF3fUNFs8vxDIL25ronZNvRy4,51
37
+ nginx_lens-0.2.2.dist-info/RECORD,,
@@ -1,12 +1,62 @@
1
+ # upstream_checker/checker.py
2
+
1
3
  import socket
4
+ import time
5
+ import http.client
2
6
  from typing import Dict, List
3
7
 
4
- def check_upstreams(upstreams: Dict[str, List[str]], timeout=2.0, retries=1):
5
- # TODO: Реализовать реальную проверку TCP/HTTP
6
- # Сейчас возвращает все healthy
7
- result = {}
8
+
9
+ def check_tcp(address: str, timeout: float, retries: int) -> bool:
10
+ """Проверка доступности сервера по TCP"""
11
+ host, port = address.split(":")
12
+ port = int(port)
13
+ for _ in range(retries):
14
+ try:
15
+ with socket.create_connection((host, port), timeout=timeout):
16
+ return True
17
+ except (socket.timeout, ConnectionRefusedError, OSError):
18
+ time.sleep(0.2)
19
+ return False
20
+
21
+
22
+ def check_http(address: str, timeout: float, retries: int) -> bool:
23
+ """Проверка доступности сервера по HTTP (GET /)"""
24
+ host, port = address.split(":")
25
+ port = int(port)
26
+ for _ in range(retries):
27
+ try:
28
+ conn = http.client.HTTPConnection(host, port, timeout=timeout)
29
+ conn.request("GET", "/")
30
+ resp = conn.getresponse()
31
+ healthy = resp.status < 500
32
+ conn.close()
33
+ if healthy:
34
+ return True
35
+ except Exception:
36
+ time.sleep(0.2)
37
+ continue
38
+ return False
39
+
40
+
41
+ def check_upstreams(upstreams: Dict[str, List[str]], timeout=2.0, retries=1, mode="tcp") -> Dict[str, List[dict]]:
42
+ """
43
+ Проверяет доступность upstream-серверов.
44
+ mode: "tcp" (по умолчанию) или "http"
45
+ Возвращает:
46
+ {
47
+ "backend": [
48
+ {"address": "127.0.0.1:8080", "healthy": True},
49
+ ...
50
+ ]
51
+ }
52
+ """
53
+ results = {}
8
54
  for name, servers in upstreams.items():
9
- result[name] = []
55
+ results[name] = []
10
56
  for srv in servers:
11
- result[name].append({"address": srv, "healthy": True})
12
- return result
57
+ if mode.lower() == "http":
58
+ healthy = check_http(srv, timeout, retries)
59
+ else:
60
+ healthy = check_tcp(srv, timeout, retries)
61
+ results[name].append({"address": srv, "healthy": healthy})
62
+ return results