nginx-lens 0.1.7__py3-none-any.whl → 0.1.9__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/graph.py CHANGED
@@ -3,6 +3,7 @@ from rich.console import Console
3
3
  from parser.nginx_parser import parse_nginx_config
4
4
  from exporter.graph import tree_to_dot, tree_to_mermaid
5
5
  from rich.text import Text
6
+ import os
6
7
 
7
8
  app = typer.Typer()
8
9
  console = Console()
@@ -28,9 +29,8 @@ def graph(
28
29
  # Для каждого server/location строим маршрут
29
30
  def walk(d, chain, upstreams):
30
31
  if d.get('block') == 'server':
31
- srv = d.get('arg','') or '[no arg]'
32
32
  for sub in d.get('directives', []):
33
- walk(sub, chain + [('server', srv)], upstreams)
33
+ walk(sub, chain + [('server', None)], upstreams)
34
34
  elif d.get('block') == 'location':
35
35
  loc = d.get('arg','')
36
36
  for sub in d.get('directives', []):
@@ -65,6 +65,7 @@ def graph(
65
65
  if not routes:
66
66
  console.print("[yellow]Не найдено ни одного маршрута[/yellow]")
67
67
  return
68
+ main_file = os.path.abspath(config_path)
68
69
  # Красивый вывод
69
70
  seen = set()
70
71
  for route in routes:
@@ -78,25 +79,44 @@ def graph(
78
79
  # Получаем label для server
79
80
  server_val = route[0][1]
80
81
  server_block = None
81
- # Найти сам блок server по arg
82
82
  for d in tree.directives:
83
- if d.get('block') == 'server' and (d.get('arg','') == server_val or (not d.get('arg') and (server_val == '[no arg]' or not server_val))):
83
+ if d.get('block') == 'server':
84
84
  server_block = d
85
85
  break
86
- label = get_server_label(server_block) if server_block else (server_val or 'default')
86
+ label = get_server_label(server_block) if server_block else 'default'
87
+ server_file = server_block.get('__file__') if server_block else None
87
88
  t.append(f"[", style="white")
88
89
  t.append(f"server: {label}", style="bold blue")
90
+ if server_file and os.path.abspath(server_file) != main_file:
91
+ t.append(f" ({server_file})", style="grey50")
89
92
  t.append("]", style="white")
90
93
  for i, (typ, val) in enumerate(route[1:]):
94
+ block = None
95
+ if typ == 'location' and server_block:
96
+ # Найти location-блок внутри server
97
+ for sub in server_block.get('directives', []):
98
+ if sub.get('block') == 'location' and sub.get('arg') == val:
99
+ block = sub
100
+ break
101
+ elif typ == 'upstream':
102
+ # Найти upstream-блок
103
+ for d in tree.directives:
104
+ if d.get('upstream') == val:
105
+ block = d
106
+ break
91
107
  if typ == 'location':
92
108
  t.append(f" -> [", style="white")
93
109
  t.append(f"location: {val}", style="yellow")
110
+ if block and block.get('__file__') and os.path.abspath(block['__file__']) != main_file:
111
+ t.append(f" ({block['__file__']})", style="grey50")
94
112
  t.append("]", style="white")
95
113
  elif typ == 'proxy_pass':
96
114
  t.append(f" -> proxy_pass: {val}", style="green")
97
115
  elif typ == 'upstream':
98
116
  t.append(f" -> [", style="white")
99
117
  t.append(f"upstream: {val}", style="magenta")
118
+ if block and block.get('__file__') and os.path.abspath(block['__file__']) != main_file:
119
+ t.append(f" ({block['__file__']})", style="grey50")
100
120
  t.append("]", style="white")
101
121
  elif typ == 'upstream_server':
102
122
  t.append(f" -> [", style="white")
commands/route.py CHANGED
@@ -46,11 +46,19 @@ def route(
46
46
  location = res['location']
47
47
  proxy_pass = res['proxy_pass']
48
48
  text = f"[bold]Config:[/bold] {conf}\n"
49
- text += f"[bold]Server:[/bold] {server.get('arg','') or '[no arg]'}\n"
49
+ if server:
50
+ text += f"[bold]Server:[/bold] {server.get('arg','') or '[no arg]'}"
51
+ if server.get('__file__'):
52
+ text += f" ([dim]{server.get('__file__')}[/dim])"
53
+ text += "\n"
50
54
  if location:
51
- text += f"[bold]Location:[/bold] {location.get('arg','')}\n"
55
+ text += f"[bold]Location:[/bold] {location.get('arg','')}"
56
+ if location.get('__file__'):
57
+ text += f" ([dim]{location.get('__file__')}[/dim])"
58
+ text += "\n"
52
59
  if proxy_pass:
53
60
  text += f"[bold]proxy_pass:[/bold] {proxy_pass}\n"
54
61
  console.print(Panel(text, title="Route", style="green"))
55
62
  return
56
- console.print(Panel(f"Ни один ваш конфиг в /etc/nginx не обрабатывает этот URL", style="red"))
63
+ search_dir = os.path.dirname(configs[0]) if configs else '/etc/nginx'
64
+ console.print(Panel(f"Маршрут для {url} не найден ни в одном .conf в {search_dir}", style="yellow"))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nginx-lens
3
- Version: 0.1.7
3
+ Version: 0.1.9
4
4
  Summary: CLI-инструмент для анализа, визуализации и диагностики конфигураций Nginx
5
5
  Author: Daniil Astrouski
6
6
  Author-email: shelovesuastra@gmail.com
@@ -14,24 +14,24 @@ commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  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
- commands/graph.py,sha256=8CnpKqVx9yUpDMcjDX-kN_SqUrS9dFqCUTrsalm-iMg,4967
17
+ commands/graph.py,sha256=xB6KjXBkLmm5gII3e-5BMRGO7WeTwc7EFxRGzYgnme4,5947
18
18
  commands/health.py,sha256=SuD2gOeMf9ZaoUfeqx1Nip0xQDBkDus6z872Fhw2Z9w,1682
19
19
  commands/include.py,sha256=5PTYG5C00-AlWfIgpQXLq9E7C9yTFSv7HrZkM5ogDps,2224
20
20
  commands/logs.py,sha256=RkPUdIpbO9dOVL56lemreYRuAjMjcqqMxRCKOFv2gC4,3691
21
- commands/route.py,sha256=DfevWTwJfup1Ifmd99pYeuRteFNaldkAvISV8hC5a-c,2650
21
+ commands/route.py,sha256=GzpHUqOwDOzhWlKcNf177Vq4OB6g--_8npZXPMDRNGg,3034
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.1.7.dist-info/licenses/LICENSE,sha256=g8QXKdvZZC56rU8E12vIeYF6R4jeTWOsblOnYAda3K4,1073
28
+ nginx_lens-0.1.9.dist-info/licenses/LICENSE,sha256=g8QXKdvZZC56rU8E12vIeYF6R4jeTWOsblOnYAda3K4,1073
29
29
  parser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- parser/nginx_parser.py,sha256=JqZ3clNy4Nf-bmbsx_rJUL7EgRoB79b87eEu_isMeqg,3577
30
+ parser/nginx_parser.py,sha256=Sa9FtGAkvTqNzoehBvgLUWPJHLLIZYWH9ugSHW50X8s,3699
31
31
  upstream_checker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  upstream_checker/checker.py,sha256=9-6CMUTN7gXUACP8EwX722QogfujZyV-WWWUeM3a79k,455
33
- nginx_lens-0.1.7.dist-info/METADATA,sha256=eN2OiSpnQpDN8kRzVdynuAwJamWiMme1UlIr-cXvfC4,520
34
- nginx_lens-0.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
- nginx_lens-0.1.7.dist-info/entry_points.txt,sha256=qEcecjSyLqcJjbIVlNlTpqAhPqDyaujUV5ZcBTAr3po,48
36
- nginx_lens-0.1.7.dist-info/top_level.txt,sha256=mxLJO4rZg0rbixVGhplF3fUNFs8vxDIL25ronZNvRy4,51
37
- nginx_lens-0.1.7.dist-info/RECORD,,
33
+ nginx_lens-0.1.9.dist-info/METADATA,sha256=QzOKmE5929PAk0mSjFEH7xVF2DXXQxdGq-eAsaZSxfw,520
34
+ nginx_lens-0.1.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
+ nginx_lens-0.1.9.dist-info/entry_points.txt,sha256=qEcecjSyLqcJjbIVlNlTpqAhPqDyaujUV5ZcBTAr3po,48
36
+ nginx_lens-0.1.9.dist-info/top_level.txt,sha256=mxLJO4rZg0rbixVGhplF3fUNFs8vxDIL25ronZNvRy4,51
37
+ nginx_lens-0.1.9.dist-info/RECORD,,
parser/nginx_parser.py CHANGED
@@ -14,7 +14,7 @@ class NginxConfigTree:
14
14
  def _strip_comments(line: str) -> str:
15
15
  return line.split('#', 1)[0].strip()
16
16
 
17
- def _parse_block(lines, base_dir) -> (List[Any], Dict[str, List[str]]):
17
+ def _parse_block(lines, base_dir, source_file=None) -> (List[Any], Dict[str, List[str]]):
18
18
  directives = []
19
19
  upstreams = {}
20
20
  i = 0
@@ -29,7 +29,7 @@ def _parse_block(lines, base_dir) -> (List[Any], Dict[str, List[str]]):
29
29
  for inc_path in glob.glob(pattern):
30
30
  with open(inc_path) as f:
31
31
  inc_lines = f.readlines()
32
- inc_directives, inc_upstreams = _parse_block(inc_lines, os.path.dirname(inc_path))
32
+ inc_directives, inc_upstreams = _parse_block(inc_lines, os.path.dirname(inc_path), inc_path)
33
33
  directives.extend(inc_directives)
34
34
  for k, v in inc_upstreams.items():
35
35
  upstreams.setdefault(k, []).extend(v)
@@ -56,7 +56,7 @@ def _parse_block(lines, base_dir) -> (List[Any], Dict[str, List[str]]):
56
56
  if m_srv:
57
57
  servers.append(m_srv.group(1).strip())
58
58
  upstreams[name] = servers
59
- directives.append({'upstream': name, 'servers': servers})
59
+ directives.append({'upstream': name, 'servers': servers, '__file__': source_file})
60
60
  continue
61
61
  # Блоки (например, server, http, location)
62
62
  m = re.match(r'(\S+)\s*(\S+)?\s*{', line)
@@ -75,15 +75,15 @@ def _parse_block(lines, base_dir) -> (List[Any], Dict[str, List[str]]):
75
75
  if depth > 0:
76
76
  block_lines.append(l)
77
77
  i += 1
78
- sub_directives, sub_upstreams = _parse_block(block_lines, base_dir)
79
- directives.append({'block': block_name, 'arg': block_arg, 'directives': sub_directives})
78
+ sub_directives, sub_upstreams = _parse_block(block_lines, base_dir, source_file)
79
+ directives.append({'block': block_name, 'arg': block_arg, 'directives': sub_directives, '__file__': source_file})
80
80
  for k, v in sub_upstreams.items():
81
81
  upstreams.setdefault(k, []).extend(v)
82
82
  continue
83
83
  # Обычная директива
84
84
  m = re.match(r'(\S+)\s+([^;]+);', line)
85
85
  if m:
86
- directives.append({'directive': m.group(1), 'args': m.group(2)})
86
+ directives.append({'directive': m.group(1), 'args': m.group(2), '__file__': source_file})
87
87
  i += 1
88
88
  return directives, upstreams
89
89
 
@@ -91,5 +91,5 @@ def parse_nginx_config(path: str) -> NginxConfigTree:
91
91
  base_dir = os.path.dirname(os.path.abspath(path))
92
92
  with open(path) as f:
93
93
  lines = f.readlines()
94
- directives, upstreams = _parse_block(lines, base_dir)
94
+ directives, upstreams = _parse_block(lines, base_dir, path)
95
95
  return NginxConfigTree(directives, upstreams)