improved launch process using cloudflare

This commit is contained in:
2025-06-20 19:34:37 +02:00
parent bb139a2b95
commit e85d91d1f4
9 changed files with 878 additions and 69 deletions

View File

@@ -391,12 +391,14 @@ def init_routes(main_bp):
portainer_settings = KeyValueSettings.get_value('portainer_settings')
nginx_settings = KeyValueSettings.get_value('nginx_settings')
git_settings = KeyValueSettings.get_value('git_settings')
cloudflare_settings = KeyValueSettings.get_value('cloudflare_settings')
return render_template('main/instances.html',
instances=instances,
portainer_settings=portainer_settings,
nginx_settings=nginx_settings,
git_settings=git_settings)
git_settings=git_settings,
cloudflare_settings=cloudflare_settings)
@main_bp.route('/instances/add', methods=['POST'])
@login_required
@@ -950,6 +952,7 @@ def init_routes(main_bp):
portainer_settings = KeyValueSettings.get_value('portainer_settings')
nginx_settings = KeyValueSettings.get_value('nginx_settings')
git_settings = KeyValueSettings.get_value('git_settings')
cloudflare_settings = KeyValueSettings.get_value('cloudflare_settings')
# Get management API key for the connections tab
management_api_key = ManagementAPIKey.query.filter_by(is_active=True).first()
@@ -1020,6 +1023,7 @@ def init_routes(main_bp):
portainer_settings=portainer_settings,
nginx_settings=nginx_settings,
git_settings=git_settings,
cloudflare_settings=cloudflare_settings,
csrf_token=generate_csrf())
@main_bp.route('/settings/update-smtp', methods=['POST'])
@@ -1678,6 +1682,77 @@ def init_routes(main_bp):
except Exception as e:
return jsonify({'error': f'Connection failed: {str(e)}'}), 400
@main_bp.route('/settings/save-cloudflare-connection', methods=['POST'])
@login_required
def save_cloudflare_connection():
if not current_user.is_admin:
return jsonify({'error': 'Unauthorized'}), 403
data = request.get_json()
email = data.get('email')
api_key = data.get('api_key')
zone_id = data.get('zone_id')
server_ip = data.get('server_ip')
if not email or not api_key or not zone_id or not server_ip:
return jsonify({'error': 'Missing required fields'}), 400
try:
# Save Cloudflare settings
KeyValueSettings.set_value('cloudflare_settings', {
'email': email,
'api_key': api_key,
'zone_id': zone_id,
'server_ip': server_ip
})
return jsonify({'message': 'Settings saved successfully'})
except Exception as e:
return jsonify({'error': str(e)}), 500
@main_bp.route('/settings/test-cloudflare-connection', methods=['POST'])
@login_required
def test_cloudflare_connection():
if not current_user.is_admin:
return jsonify({'error': 'Unauthorized'}), 403
data = request.get_json()
email = data.get('email')
api_key = data.get('api_key')
zone_id = data.get('zone_id')
server_ip = data.get('server_ip')
if not email or not api_key or not zone_id or not server_ip:
return jsonify({'error': 'Missing required fields'}), 400
try:
# Test Cloudflare connection by getting zone details
headers = {
'X-Auth-Email': email,
'X-Auth-Key': api_key,
'Content-Type': 'application/json'
}
# Try to get zone information
response = requests.get(
f'https://api.cloudflare.com/client/v4/zones/{zone_id}',
headers=headers,
timeout=10
)
if response.status_code == 200:
zone_data = response.json()
if zone_data.get('success'):
return jsonify({'message': 'Connection successful'})
else:
return jsonify({'error': f'API error: {zone_data.get("errors", [{}])[0].get("message", "Unknown error")}'}), 400
else:
return jsonify({'error': f'Connection failed: HTTP {response.status_code}'}), 400
except Exception as e:
return jsonify({'error': f'Connection failed: {str(e)}'}), 400
@main_bp.route('/instances/launch-progress')
@login_required
@require_password_change
@@ -1690,10 +1765,13 @@ def init_routes(main_bp):
nginx_settings = KeyValueSettings.get_value('nginx_settings')
# Get Portainer settings
portainer_settings = KeyValueSettings.get_value('portainer_settings')
# Get Cloudflare settings
cloudflare_settings = KeyValueSettings.get_value('cloudflare_settings')
return render_template('main/launch_progress.html',
nginx_settings=nginx_settings,
portainer_settings=portainer_settings)
portainer_settings=portainer_settings,
cloudflare_settings=cloudflare_settings)
@main_bp.route('/api/check-dns', methods=['POST'])
@login_required
@@ -1728,6 +1806,145 @@ def init_routes(main_bp):
'results': results
})
@main_bp.route('/api/check-cloudflare-connection', methods=['POST'])
@login_required
@require_password_change
def check_cloudflare_connection():
if not os.environ.get('MASTER', 'false').lower() == 'true':
return jsonify({'error': 'Unauthorized'}), 403
# Get Cloudflare settings
cloudflare_settings = KeyValueSettings.get_value('cloudflare_settings')
if not cloudflare_settings:
return jsonify({'error': 'Cloudflare settings not configured'}), 400
try:
# Test Cloudflare connection by getting zone details
headers = {
'X-Auth-Email': cloudflare_settings['email'],
'X-Auth-Key': cloudflare_settings['api_key'],
'Content-Type': 'application/json'
}
# Try to get zone information
response = requests.get(
f'https://api.cloudflare.com/client/v4/zones/{cloudflare_settings["zone_id"]}',
headers=headers,
timeout=10
)
if response.status_code == 200:
zone_data = response.json()
if zone_data.get('success'):
return jsonify({
'success': True,
'message': 'Cloudflare connection successful',
'zone_name': zone_data['result']['name']
})
else:
return jsonify({'error': f'API error: {zone_data.get("errors", [{}])[0].get("message", "Unknown error")}'}), 400
else:
return jsonify({'error': f'Connection failed: HTTP {response.status_code}'}), 400
except Exception as e:
return jsonify({'error': f'Connection failed: {str(e)}'}), 400
@main_bp.route('/api/create-dns-records', methods=['POST'])
@login_required
@require_password_change
def create_dns_records():
if not os.environ.get('MASTER', 'false').lower() == 'true':
return jsonify({'error': 'Unauthorized'}), 403
data = request.get_json()
if not data or 'domains' not in data:
return jsonify({'error': 'No domains provided'}), 400
domains = data['domains']
# Get Cloudflare settings
cloudflare_settings = KeyValueSettings.get_value('cloudflare_settings')
if not cloudflare_settings:
return jsonify({'error': 'Cloudflare settings not configured'}), 400
try:
headers = {
'X-Auth-Email': cloudflare_settings['email'],
'X-Auth-Key': cloudflare_settings['api_key'],
'Content-Type': 'application/json'
}
results = {}
for domain in domains:
# Check if DNS record already exists
response = requests.get(
f'https://api.cloudflare.com/client/v4/zones/{cloudflare_settings["zone_id"]}/dns_records',
headers=headers,
params={'name': domain},
timeout=10
)
if response.status_code == 200:
dns_data = response.json()
existing_records = dns_data.get('result', [])
# Filter for A records
a_records = [record for record in existing_records if record['type'] == 'A' and record['name'] == domain]
if a_records:
# Update existing A record
record_id = a_records[0]['id']
update_data = {
'type': 'A',
'name': domain,
'content': cloudflare_settings['server_ip'],
'ttl': 1, # Auto TTL
'proxied': True
}
update_response = requests.put(
f'https://api.cloudflare.com/client/v4/zones/{cloudflare_settings["zone_id"]}/dns_records/{record_id}',
headers=headers,
json=update_data,
timeout=10
)
if update_response.status_code == 200:
results[domain] = {'status': 'updated', 'message': 'DNS record updated'}
else:
results[domain] = {'status': 'error', 'message': f'Failed to update DNS record: {update_response.status_code}'}
else:
# Create new A record
create_data = {
'type': 'A',
'name': domain,
'content': cloudflare_settings['server_ip'],
'ttl': 1, # Auto TTL
'proxied': True
}
create_response = requests.post(
f'https://api.cloudflare.com/client/v4/zones/{cloudflare_settings["zone_id"]}/dns_records',
headers=headers,
json=create_data,
timeout=10
)
if create_response.status_code == 200:
results[domain] = {'status': 'created', 'message': 'DNS record created'}
else:
results[domain] = {'status': 'error', 'message': f'Failed to create DNS record: {create_response.status_code}'}
else:
results[domain] = {'status': 'error', 'message': f'Failed to check existing records: {response.status_code}'}
return jsonify({
'success': True,
'results': results
})
except Exception as e:
return jsonify({'error': f'DNS operation failed: {str(e)}'}), 400
@main_bp.route('/api/mails/<int:mail_id>')
@login_required
def get_mail_details(mail_id):