nginx-lens 0.3.0__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.
Files changed (49) hide show
  1. {nginx_lens-0.3.0/nginx_lens.egg-info → nginx_lens-0.3.1}/PKG-INFO +1 -1
  2. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/health.py +6 -4
  3. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/resolve.py +5 -2
  4. {nginx_lens-0.3.0 → nginx_lens-0.3.1/nginx_lens.egg-info}/PKG-INFO +1 -1
  5. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/setup.py +1 -1
  6. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/upstream_checker/checker.py +28 -15
  7. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/LICENSE +0 -0
  8. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/README.md +0 -0
  9. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/__init__.py +0 -0
  10. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/base.py +0 -0
  11. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/conflicts.py +0 -0
  12. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/dead_locations.py +0 -0
  13. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/diff.py +0 -0
  14. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/duplicates.py +0 -0
  15. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/empty_blocks.py +0 -0
  16. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/include.py +0 -0
  17. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/rewrite.py +0 -0
  18. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/route.py +0 -0
  19. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/unused.py +0 -0
  20. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/analyzer/warnings.py +0 -0
  21. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/__init__.py +0 -0
  22. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/analyze.py +0 -0
  23. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/cli.py +0 -0
  24. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/diff.py +0 -0
  25. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/graph.py +0 -0
  26. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/include.py +0 -0
  27. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/logs.py +0 -0
  28. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/route.py +0 -0
  29. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/syntax.py +0 -0
  30. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/commands/tree.py +0 -0
  31. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/exporter/__init__.py +0 -0
  32. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/exporter/graph.py +0 -0
  33. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/exporter/html.py +0 -0
  34. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/exporter/markdown.py +0 -0
  35. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/nginx_lens.egg-info/SOURCES.txt +0 -0
  36. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/nginx_lens.egg-info/dependency_links.txt +0 -0
  37. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/nginx_lens.egg-info/entry_points.txt +0 -0
  38. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/nginx_lens.egg-info/requires.txt +0 -0
  39. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/nginx_lens.egg-info/top_level.txt +0 -0
  40. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/parser/__init__.py +0 -0
  41. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/parser/nginx_parser.py +0 -0
  42. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/pyproject.toml +0 -0
  43. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/setup.cfg +0 -0
  44. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/tests/test_conflicts.py +0 -0
  45. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/tests/test_duplicates.py +0 -0
  46. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/tests/test_empty_blocks.py +0 -0
  47. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/tests/test_health.py +0 -0
  48. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/tests/test_parser.py +0 -0
  49. {nginx_lens-0.3.0 → nginx_lens-0.3.1}/upstream_checker/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nginx-lens
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: CLI-инструмент для анализа, визуализации и диагностики конфигураций Nginx
5
5
  Author: Daniil Astrouski
6
6
  Author-email: shelovesuastra@gmail.com
@@ -51,15 +51,17 @@ def health(
51
51
  color = "green" if srv["healthy"] else "red"
52
52
 
53
53
  if resolve:
54
- resolved = None
54
+ resolved_list = []
55
55
  if name in resolved_info:
56
56
  for resolved_srv in resolved_info[name]:
57
57
  if resolved_srv["address"] == srv["address"]:
58
- resolved = resolved_srv["resolved"]
58
+ resolved_list = resolved_srv["resolved"]
59
59
  break
60
60
 
61
- if resolved:
62
- table.add_row(srv["address"], f"[{color}]{status}[/{color}]", resolved)
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]")
63
65
  else:
64
66
  table.add_row(srv["address"], f"[{color}]{status}[/{color}]", "[yellow]Failed to resolve[/yellow]")
65
67
  else:
@@ -40,8 +40,11 @@ def resolve(
40
40
  for name, servers in results.items():
41
41
  for idx, srv in enumerate(servers):
42
42
  upstream_name = name if idx == 0 else ""
43
- if srv["resolved"]:
44
- table.add_row(upstream_name, srv["address"], f"[green]{srv['resolved']}[/green]")
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]")
45
48
  else:
46
49
  table.add_row(upstream_name, srv["address"], "[red]Failed to resolve[/red]")
47
50
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nginx-lens
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: CLI-инструмент для анализа, визуализации и диагностики конфигураций Nginx
5
5
  Author: Daniil Astrouski
6
6
  Author-email: shelovesuastra@gmail.com
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="nginx-lens",
5
- version="0.3.0",
5
+ version="0.3.1",
6
6
  description="CLI-инструмент для анализа, визуализации и диагностики конфигураций Nginx",
7
7
  author="Daniil Astrouski",
8
8
  author_email="shelovesuastra@gmail.com",
@@ -3,7 +3,7 @@
3
3
  import socket
4
4
  import time
5
5
  import http.client
6
- from typing import Dict, List, Optional
6
+ from typing import Dict, List
7
7
 
8
8
 
9
9
  def check_tcp(address: str, timeout: float, retries: int) -> bool:
@@ -49,48 +49,61 @@ def check_http(address: str, timeout: float, retries: int) -> bool:
49
49
  return False
50
50
 
51
51
 
52
- def resolve_address(address: str) -> Optional[str]:
52
+ def resolve_address(address: str) -> List[str]:
53
53
  """
54
- Резолвит адрес upstream сервера в IP-адрес.
54
+ Резолвит адрес upstream сервера в IP-адреса.
55
55
 
56
56
  Args:
57
57
  address: Адрес в формате "host:port" или "host:port параметры"
58
58
 
59
59
  Returns:
60
- IP-адрес в формате "ip:port" или None, если резолвинг не удался
60
+ Список IP-адресов в формате "ip:port" или пустой список, если резолвинг не удался
61
61
  """
62
62
  try:
63
63
  host_port = address.split()[0]
64
64
 
65
65
  if ":" not in host_port:
66
- return None
66
+ return []
67
67
 
68
68
  parts = host_port.rsplit(":", 1)
69
69
  if len(parts) != 2:
70
- return None
70
+ return []
71
71
  host, port = parts
72
72
 
73
+ # Если это уже IPv4 адрес, возвращаем как есть
73
74
  try:
74
75
  socket.inet_aton(host)
75
- return host_port
76
+ return [host_port]
76
77
  except socket.error:
77
78
  pass
78
79
 
80
+ # Проверяем IPv6 (в квадратных скобках)
79
81
  if host.startswith("[") and host.endswith("]"):
80
82
  ipv6_host = host[1:-1]
81
83
  try:
82
84
  socket.inet_pton(socket.AF_INET6, ipv6_host)
83
- return host_port
85
+ return [host_port]
84
86
  except (socket.error, OSError):
85
87
  pass
86
88
 
89
+ # Пытаемся резолвить DNS имя - получаем все IP-адреса
87
90
  try:
88
- ip = socket.gethostbyname(host)
89
- return f"{ip}:{port}"
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 []
90
103
  except (socket.gaierror, OSError):
91
- return None
104
+ return []
92
105
  except (ValueError, IndexError, AttributeError):
93
- return None
106
+ return []
94
107
 
95
108
 
96
109
  def resolve_upstreams(
@@ -102,9 +115,9 @@ def resolve_upstreams(
102
115
  Возвращает:
103
116
  {
104
117
  "backend": [
105
- {"address": "example.com:8080", "resolved": "192.168.1.1:8080"},
106
- {"address": "127.0.0.1:8080", "resolved": "127.0.0.1:8080"},
107
- {"address": "badhost:80", "resolved": None},
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": []},
108
121
  ...
109
122
  ]
110
123
  }
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