Skip to content

Commit c110c9a

Browse files
authored
Merge pull request #54 from CESNET/jirivrany-patch-1
Update python-app.yml Updated Whitelist Service code to work in Python 3.9 updated Rule Service code to work in Python 3.9
2 parents 4484bc3 + 42e9310 commit c110c9a

File tree

5 files changed

+63
-75
lines changed

5 files changed

+63
-75
lines changed

.github/workflows/python-app.yml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,25 @@
1-
# This workflow will install Python dependencies, run tests and lint with a single version of Python
1+
# This workflow will install Python dependencies, run tests and lint with multiple versions of Python
22
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3-
43
name: Python application
5-
64
on:
75
push:
86
branches: [ "master", "develop" ]
97
pull_request:
108
branches: [ "master", "develop" ]
11-
129
permissions:
1310
contents: read
14-
1511
jobs:
1612
build:
17-
1813
runs-on: ubuntu-latest
19-
14+
strategy:
15+
matrix:
16+
python-version: ["3.9", "3.10", "3.11", "3.12"]
2017
steps:
2118
- uses: actions/checkout@v3
22-
- name: Set up Python 3.11
19+
- name: Set up Python ${{ matrix.python-version }}
2320
uses: actions/setup-python@v3
2421
with:
25-
python-version: "3.11"
22+
python-version: ${{ matrix.python-version }}
2623
- name: Setup timezone
2724
uses: zcong1993/setup-timezone@master
2825
with:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ See how is ExaFS integrated into the network in the picture below.
3636

3737
![ExaFS schema](./docs/app_schema_en.png)
3838

39-
The central part of the ExaFS is a web application, written in Python3.6 with Flask framework. It provides a user interface for ExaBGP rule CRUD operations. The application also provides the REST API with CRUD operations for the configuration rules. The web app uses Shibboleth authorization; the REST API is using token-based authorization.
39+
The central part of the ExaFS is a web application, written in Python with Flask framework. It provides a user interface for ExaBGP rule CRUD operations. The application also provides the REST API with CRUD operations for the configuration rules. The web app uses Shibboleth authorization; the REST API is using token-based authorization.
4040

4141
The app creates the ExaBGP commands and forwards them to ExaBGP process. All rules are carefully validated, and only valid rules are stored in the database and sent to the ExaBGP connector.
4242

flowapp/services/rule_service.py

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -352,35 +352,30 @@ def evaluate_rtbh_against_whitelists_check_results(
352352
Process all results for cases where rule is whitelisted by several whitelists.
353353
"""
354354
for rule, whitelist_key, relation in results:
355-
match relation:
356-
case Relation.EQUAL:
357-
model = whitelist_rtbh_rule(model, wl_cache[whitelist_key])
358-
msg = f"RTBH Rule {model.id} {model} is equal to active whitelist {whitelist_key}. Rule is whitelisted."
355+
if relation == Relation.EQUAL:
356+
model = whitelist_rtbh_rule(model, wl_cache[whitelist_key])
357+
msg = f"RTBH Rule {model.id} {model} is equal to active whitelist {whitelist_key}. Rule is whitelisted."
358+
flashes.append(msg)
359+
current_app.logger.info(msg)
360+
elif relation == Relation.SUBNET:
361+
parts = subtract_network(target=str(model), whitelist=whitelist_key)
362+
wl_id = wl_cache[whitelist_key].id
363+
msg = f"RTBH Rule {model.id} {model} is supernet of active whitelist {whitelist_key}. Rule is whitelisted, {len(parts)} subnet rules created."
364+
flashes.append(msg)
365+
current_app.logger.info(msg)
366+
for network in parts:
367+
new_rule = create_rtbh_from_whitelist_parts(model, wl_id, whitelist_key, network, author, user_id)
368+
msg = f"Created RTBH rule {new_rule.id} {new_rule} for {network} parted by whitelist {whitelist_key}"
359369
flashes.append(msg)
360370
current_app.logger.info(msg)
361-
case Relation.SUBNET:
362-
parts = subtract_network(target=str(model), whitelist=whitelist_key)
363-
wl_id = wl_cache[whitelist_key].id
364-
msg = f"RTBH Rule {model.id} {model} is supernet of active whitelist {whitelist_key}. Rule is whitelisted, {len(parts)} subnet rules created."
365-
flashes.append(msg)
366-
current_app.logger.info(msg)
367-
for network in parts:
368-
new_rule = create_rtbh_from_whitelist_parts(model, wl_id, whitelist_key, network, author, user_id)
369-
msg = (
370-
f"Created RTBH rule {new_rule.id} {new_rule} for {network} parted by whitelist {whitelist_key}"
371-
)
372-
flashes.append(msg)
373-
current_app.logger.info(msg)
374-
model.rstate_id = 4
375-
add_rtbh_rule_to_cache(model, wl_id, RuleOrigin.USER)
376-
db.session.commit()
377-
case Relation.SUPERNET:
378-
model = whitelist_rtbh_rule(model, wl_cache[whitelist_key])
379-
msg = (
380-
f"RTBH Rule {model.id} {model} is subnet of active whitelist {whitelist_key}. Rule is whitelisted."
381-
)
382-
current_app.logger.info(msg)
383-
flashes.append(msg)
371+
model.rstate_id = 4
372+
add_rtbh_rule_to_cache(model, wl_id, RuleOrigin.USER)
373+
db.session.commit()
374+
elif relation == Relation.SUPERNET:
375+
model = whitelist_rtbh_rule(model, wl_cache[whitelist_key])
376+
msg = f"RTBH Rule {model.id} {model} is subnet of active whitelist {whitelist_key}. Rule is whitelisted."
377+
current_app.logger.info(msg)
378+
flashes.append(msg)
384379
return model
385380

386381

flowapp/services/whitelist_common.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from enum import Enum, auto
22
from functools import lru_cache
33
import ipaddress
4-
from typing import List, Tuple
4+
from typing import List, Tuple, Union
55
from flowapp import db
66
from flowapp.constants import RuleOrigin, RuleTypes
77
from flowapp.models import RTBH, RuleWhitelistCache, Whitelist
@@ -59,7 +59,7 @@ def _is_same_ip_version(addr1: str, addr2: str) -> bool:
5959

6060

6161
@lru_cache(maxsize=1024)
62-
def get_network(address: str) -> ipaddress.IPv4Network | ipaddress.IPv6Network:
62+
def get_network(address: str) -> Union[ipaddress.IPv4Network, ipaddress.IPv6Network]:
6363
"""
6464
Create and cache an IP network object.
6565

flowapp/services/whitelist_service.py

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -84,37 +84,34 @@ def evaluate_whitelist_against_rtbh_check_results(
8484

8585
for rule_key, whitelist_key, relation in results:
8686
current_app.logger.info(f"whitelist {whitelist_key} is {relation} to Rule {rule_key}")
87-
match relation:
88-
case Relation.EQUAL:
89-
whitelist_rtbh_rule(rtbh_rule_cache[rule_key], whitelist_model)
90-
withdraw_rtbh_route(rtbh_rule_cache[rule_key])
91-
msg = "Existing active rule {rule_key} is equal to whitelist {whitelist_key}. Rule is now whitelisted."
87+
if relation == Relation.EQUAL:
88+
whitelist_rtbh_rule(rtbh_rule_cache[rule_key], whitelist_model)
89+
withdraw_rtbh_route(rtbh_rule_cache[rule_key])
90+
msg = "Existing active rule {rule_key} is equal to whitelist {whitelist_key}. Rule is now whitelisted."
91+
flashes.append(msg)
92+
current_app.logger.info(msg)
93+
elif relation == Relation.SUBNET:
94+
parts = subtract_network(target=rule_key, whitelist=whitelist_key)
95+
wl_id = whitelist_model.id
96+
msg = f"Rule {rule_key} is supernet of whitelist {whitelist_key}. Rule is whitelisted, {len(parts)} subnet rules will be created."
97+
flashes.append(msg)
98+
current_app.logger.info(msg)
99+
for network in parts:
100+
rule_model = rtbh_rule_cache[rule_key]
101+
create_rtbh_from_whitelist_parts(rule_model, wl_id, whitelist_key, network)
102+
msg = f"Created RTBH rule from {rule_model.id} {network} parted by whitelist {whitelist_key}."
92103
flashes.append(msg)
93104
current_app.logger.info(msg)
94-
case Relation.SUBNET:
95-
parts = subtract_network(target=rule_key, whitelist=whitelist_key)
96-
wl_id = whitelist_model.id
97-
msg = f"Rule {rule_key} is supernet of whitelist {whitelist_key}. Rule is whitelisted, {len(parts)} subnet rules will be created."
98-
flashes.append(msg)
99-
current_app.logger.info(msg)
100-
for network in parts:
101-
rule_model = rtbh_rule_cache[rule_key]
102-
create_rtbh_from_whitelist_parts(rule_model, wl_id, whitelist_key, network)
103-
msg = f"Created RTBH rule from {rule_model.id} {network} parted by whitelist {whitelist_key}."
104-
flashes.append(msg)
105-
current_app.logger.info(msg)
106-
rule_model.rstate_id = 4
107-
add_rtbh_rule_to_cache(rule_model, wl_id, RuleOrigin.USER)
108-
db.session.commit()
109-
case Relation.SUPERNET:
110-
111-
whitelist_rtbh_rule(rtbh_rule_cache[rule_key], whitelist_model)
112-
withdraw_rtbh_route(rtbh_rule_cache[rule_key])
113-
msg = (
114-
f"Existing active rule {rule_key} is subnet of whitelist {whitelist_key}. Rule is now whitelisted."
115-
)
116-
current_app.logger.info(msg)
117-
flashes.append(msg)
105+
rule_model.rstate_id = 4
106+
add_rtbh_rule_to_cache(rule_model, wl_id, RuleOrigin.USER)
107+
db.session.commit()
108+
elif relation == Relation.SUPERNET:
109+
110+
whitelist_rtbh_rule(rtbh_rule_cache[rule_key], whitelist_model)
111+
withdraw_rtbh_route(rtbh_rule_cache[rule_key])
112+
msg = f"Existing active rule {rule_key} is subnet of whitelist {whitelist_key}. Rule is now whitelisted."
113+
current_app.logger.info(msg)
114+
flashes.append(msg)
118115

119116
return whitelist_model
120117

@@ -154,13 +151,12 @@ def delete_whitelist(whitelist_id: int) -> List[str]:
154151
for cached_rule in cached_rules:
155152
rule_model_type = RuleTypes(cached_rule.rtype)
156153
cache_entries_count = RuleWhitelistCache.count_by_rule(cached_rule.rid, rule_model_type)
157-
match rule_model_type:
158-
case RuleTypes.IPv4:
159-
rule_model = db.session.get(Flowspec4, cached_rule.rid)
160-
case RuleTypes.IPv6:
161-
rule_model = db.session.get(Flowspec6, cached_rule.rid)
162-
case RuleTypes.RTBH:
163-
rule_model = db.session.get(RTBH, cached_rule.rid)
154+
if rule_model_type == RuleTypes.IPv4:
155+
rule_model = db.session.get(Flowspec4, cached_rule.rid)
156+
elif rule_model_type == RuleTypes.IPv6:
157+
rule_model = db.session.get(Flowspec6, cached_rule.rid)
158+
elif rule_model_type == RuleTypes.RTBH:
159+
rule_model = db.session.get(RTBH, cached_rule.rid)
164160
rorigin_type = RuleOrigin(cached_rule.rorigin)
165161
current_app.logger.debug(f"Rule {rule_model} has origin {rorigin_type}")
166162
if rorigin_type == RuleOrigin.WHITELIST:

0 commit comments

Comments
 (0)