Skip to content

Commit 52db3a1

Browse files
Merge pull request #12 from AlexanderGrooff/show-neighbours-of-direct-match
2 parents 2f3644f + 36f437f commit 52db3a1

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

nginx_analysis/analysis.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,36 @@ def get_line_at_linenr(
9292
return None
9393

9494

95-
def is_direct_match(
95+
def is_partial_direct_match(
9696
line: NginxLineConfig, filters: List[DirectiveFilter]
9797
) -> Optional[DirectiveFilter]:
98+
"""
99+
Check if the line matches any of the filters. If it does, return the
100+
filter. If it doesn't, return None."""
98101
for dfilter in filters:
99102
if dfilter.match(line):
100-
logger.debug(f"Direct match: {line}")
103+
logger.debug(f"Direct match on filter {dfilter}: {line}")
101104
return dfilter
102105
return None
103106

104107

105108
def find_matches_in_children(
106109
line: NginxLineConfig, filters: List[DirectiveFilter]
107110
) -> Tuple[List[NginxLineConfig], List[DirectiveFilter]]:
108-
matched_filter = is_direct_match(line, filters)
111+
"""
112+
Check if the line matches filters. If it matches, return the line,
113+
the line's neighbours and all children. If it doesn't match, check
114+
if any of the children match the filters. If they do, return all
115+
descendants of the line that match the filters, including the current
116+
line.
117+
We also return a list of filters that matched, so we can check if
118+
all filters were matched eventually.
119+
If there are no matches, return an empty list for both the matching
120+
lines and the matched filters.
121+
"""
122+
matched_filter = is_partial_direct_match(line, filters)
109123
if matched_filter:
124+
logger.debug(f"Found match in children: {line}")
110125
all_matched_filters = set([matched_filter])
111126
# Search for remaining filters in children, as the parent
112127
# might still be looking for other filters
@@ -116,7 +131,9 @@ def find_matches_in_children(
116131
child, remaining_filters
117132
)
118133
all_matched_filters.update(child_matched_filters)
119-
return [line, *get_children_recursive(line)], list(all_matched_filters)
134+
return [line, *line.neighbours, *get_children_recursive(line)], list(
135+
all_matched_filters
136+
)
120137

121138
# All filters must match at least one child
122139
matched_filters = set()

nginx_analysis/dataclasses.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ def lineage(self) -> List[str]:
8787
return [self.directive]
8888
return self.parent.lineage + [self.directive]
8989

90+
@property
91+
def neighbours(self) -> List["NginxLineConfig"]:
92+
parent_children = self.parent.children if self.parent else []
93+
return [c for c in parent_children if c != self]
94+
9095
def __eq__(self, other: Any) -> bool:
9196
if not isinstance(other, NginxLineConfig):
9297
return False

runtests.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ export DEBIAN_FRONTEND=noninteractive
44

55
set -e
66

7-
NGINX_EXEC="docker-compose exec -T nginx"
7+
# Check if we're running in the Github Actions runner
8+
if [[ -z "$GITHUB_ACTIONS" ]]; then
9+
NGINX_EXEC="docker-compose exec nginx"
10+
else
11+
# Run without TTY in Github Actions
12+
NGINX_EXEC="docker-compose exec -T nginx"
13+
fi
814

915
if [[ ! $(docker-compose ps --services --filter status=running nginx | grep nginx) ]]; then
1016
docker-compose up -d nginx

scripts/integration_tests.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,10 @@ $NSA -d server_name -f server_name=example.com |& grep example.com || (echo "NOT
2626
$NSA -d server_name -f server_name=banaan.com |& grep example.com && (echo "NOT OK" && exit 1)
2727
# Multiple filters should show the most specific match
2828
$NSA -f location=/ -f server_name=example.com |& grep "/etc/nginx/servers/example.com.conf:8" || (echo "NOT OK" && exit 1)
29+
# Show directives next to the direct match
30+
$NSA -f server_name=example.com |& grep "listen" | grep -v "default_server" || (echo "NOT OK" && exit 1)
31+
$NSA -f server_name=testalex.hypernode.io |& grep "listen" | grep "default_server" || (echo "NOT OK" && exit 1)
32+
# Don't show nested children of neighbours of direct match
33+
$NSA -f server_name=testalex.hypernode.io -f location=/ |& grep "404" && (echo "NOT OK" && exit 1)
2934

3035
echo "All tests passed"

0 commit comments

Comments
 (0)