haproxy map

This commit is contained in:
Mateusz Gruszczyński
2026-02-23 13:10:16 +01:00
parent d82926a4d1
commit bf02af0192
7 changed files with 348 additions and 142 deletions

95
api.py
View File

@@ -350,6 +350,8 @@ def generate_preview():
'apache_24': ConfigGenerator.generate_apache_24,
'haproxy_acl': ConfigGenerator.generate_haproxy_acl,
'haproxy_lua': ConfigGenerator.generate_haproxy_lua,
"haproxy_map": ConfigGenerator.generate_haproxy_map,
}
generator_key = f"{app_type}_{app_variant}"
@@ -398,40 +400,56 @@ def generate_preview():
traceback.print_exc()
return jsonify({'success': False, 'error': str(e)}), 500
@api_blueprint.route('/api/generate/raw', methods=['POST'])
def generate_raw_cidr():
try:
clear_progress()
data = request.get_json()
countries = data.get('countries', [])
aggregate = data.get('aggregate', True)
app_type = data.get('app_type', 'raw-cidr_txt')
use_cache = data.get('use_cache', True)
as_js = bool(data.get('as_js', False))
js_var = data.get('js_var', 'geoipBlocklist')
if app_type == 'raw-cidr':
app_type = 'raw-cidr_txt'
if not countries:
return jsonify({'success': False, 'error': 'No countries selected'}), 400
if use_cache and redis_cache:
cached = redis_cache.get_cached_config(countries, app_type, aggregate)
if cached:
if 'json' in app_type:
extension = 'json'
mimetype = 'application/json'
if as_js:
extension = 'js'
mimetype = 'application/javascript'
filename = f"blocklist_{'_'.join(sorted(countries))}.{extension}"
body = f"const {js_var} = {cached['config']};\n"
else:
extension = 'json'
mimetype = 'application/json'
filename = f"blocklist_{'_'.join(sorted(countries))}.{extension}"
body = cached['config']
elif 'csv' in app_type:
extension = 'csv'
mimetype = 'text/csv'
filename = f"blocklist_{'_'.join(sorted(countries))}.{extension}"
body = cached['config']
else:
extension = 'txt'
mimetype = 'text/plain'
filename = f"blocklist_{'_'.join(sorted(countries))}.{extension}"
filename = f"blocklist_{'_'.join(sorted(countries))}.{extension}"
body = cached['config']
return Response(
cached['config'],
body,
mimetype=mimetype,
headers={
'Content-Disposition': f'attachment; filename="{filename}"',
@@ -443,22 +461,22 @@ def generate_raw_cidr():
'Expires': '0'
}
)
if handler.needs_update():
handler.check_and_update()
update_progress(f'Loading data for {len(countries)} countries...', 0, 100)
country_networks = {}
cache_sources = {}
total_countries = len(countries)
for idx, country in enumerate(countries, 1):
base_progress = int((idx - 1) / total_countries * 80)
update_progress(f'[{idx}/{total_countries}] Loading {country}...', base_progress, 100)
networks, source = get_country_networks_cached(country, use_cache=use_cache)
if networks:
country_networks[country] = networks
cache_sources[country] = source
@@ -468,65 +486,72 @@ def generate_raw_cidr():
next_progress,
100
)
if not country_networks:
clear_progress()
return jsonify({'success': False, 'error': 'No networks found'}), 404
update_progress('Generating file...', 85, 100)
if 'txt' in app_type or 'cidr' in app_type or 'newline' in app_type:
config_text = ConfigGenerator.generate_raw_cidr(country_networks, aggregate=aggregate, redis_ips=None)
filename = f"blocklist_{'_'.join(sorted(countries))}.txt"
mimetype = 'text/plain'
elif 'json' in app_type:
all_networks = []
for nets in country_networks.values():
all_networks.extend(nets)
if aggregate:
all_networks = ConfigGenerator.aggregate_networks(all_networks)
all_networks = ConfigGenerator._aggregate_networks(all_networks)
else:
all_networks = sorted(list(set(all_networks)))
config_text = json.dumps({
json_text = json.dumps({
'countries': countries,
'networks': all_networks,
'count': len(all_networks),
'aggregated': aggregate
}, indent=2)
filename = f"blocklist_{'_'.join(sorted(countries))}.json"
mimetype = 'application/json'
if as_js:
config_text = f"const {js_var} = {json_text};\n"
filename = f"blocklist_{'_'.join(sorted(countries))}.js"
mimetype = 'application/javascript'
else:
config_text = json_text
filename = f"blocklist_{'_'.join(sorted(countries))}.json"
mimetype = 'application/json'
elif 'csv' in app_type:
config_text = ConfigGenerator.generate_csv(country_networks, aggregate=aggregate, redis_ips=None)
filename = f"blocklist_{'_'.join(sorted(countries))}.csv"
mimetype = 'text/csv'
else:
clear_progress()
return jsonify({'success': False, 'error': f'Unknown format: {app_type}'}), 400
total_networks = sum(len(nets) for nets in country_networks.values())
stats = {
'countries': len(country_networks),
'total_networks': total_networks,
'per_country': {cc: len(nets) for cc, nets in country_networks.items()}
}
if redis_cache:
update_progress('Saving to Redis cache...', 95, 100)
redis_cache.save_config(countries, app_type, aggregate, config_text, stats)
update_progress('Complete!', 100, 100)
clear_progress()
cache_type = 'hybrid'
if cache_sources:
most_common = max(set(cache_sources.values()), key=list(cache_sources.values()).count)
cache_type = most_common
return Response(
config_text,
mimetype=mimetype,
@@ -540,13 +565,14 @@ def generate_raw_cidr():
'Expires': '0'
}
)
except Exception as e:
clear_progress()
import traceback
traceback.print_exc()
return jsonify({'success': False, 'error': str(e)}), 500
@api_blueprint.route('/api/generate', methods=['POST'])
def generate_config():
try:
@@ -622,6 +648,7 @@ def generate_config():
'apache_24': ConfigGenerator.generate_apache_24,
'haproxy_acl': ConfigGenerator.generate_haproxy_acl,
'haproxy_lua': ConfigGenerator.generate_haproxy_lua,
'haproxy_map': ConfigGenerator.generate_haproxy_map,
}
generator_key = f"{app_type}_{app_variant}"