checking portainer connection

This commit is contained in:
2025-06-15 13:17:44 +02:00
parent 8fde46c157
commit 3f3dba8759
4 changed files with 204 additions and 7 deletions

107
app/routes/admin_api.py Normal file
View File

@@ -0,0 +1,107 @@
from flask import request, jsonify, current_app
from flask_login import login_required
import os
from datetime import datetime
from app.utils.gitea_api import GiteaAPI
from app.models.gitea_settings import GiteaSettings
@admin_api.route('/test-git-connection', methods=['POST'])
@login_required
def test_git_connection():
try:
data = request.get_json()
if not data:
return jsonify({'success': False, 'error': 'No data provided'}), 400
required_fields = ['gitea_url', 'username', 'api_token', 'repo_name']
for field in required_fields:
if field not in data:
return jsonify({'success': False, 'error': f'Missing required field: {field}'}), 400
# Test the connection using the provided credentials
gitea = GiteaAPI(
url=data['gitea_url'],
token=data['api_token']
)
# Try to get repository information
repo = gitea.get_repo(data['username'], data['repo_name'])
if not repo:
return jsonify({'success': False, 'error': 'Repository not found'}), 404
return jsonify({
'success': True,
'message': 'Successfully connected to Gitea',
'data': {
'repo_name': repo.name,
'description': repo.description,
'default_branch': repo.default_branch,
'created_at': repo.created_at,
'updated_at': repo.updated_at
}
})
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500
@admin_api.route('/check-docker-compose', methods=['POST'])
@login_required
def check_docker_compose():
try:
data = request.get_json()
if not data:
return jsonify({'success': False, 'error': 'No data provided'}), 400
required_fields = ['repository', 'branch']
for field in required_fields:
if field not in data:
return jsonify({'success': False, 'error': f'Missing required field: {field}'}), 400
# Get Gitea settings from database
gitea_settings = GiteaSettings.query.first()
if not gitea_settings:
return jsonify({'success': False, 'error': 'Gitea settings not configured'}), 400
# Initialize Gitea API
gitea = GiteaAPI(
url=gitea_settings.server_url,
token=gitea_settings.api_token
)
# Split repository into owner and repo name
owner, repo_name = data['repository'].split('/')
# Get the docker-compose.yml file content
try:
file_content = gitea.get_file_content(
owner=owner,
repo=repo_name,
filepath='docker-compose.yml',
ref=data['branch']
)
except Exception as e:
return jsonify({'success': False, 'error': f'Failed to get docker-compose.yml: {str(e)}'}), 404
# Save the file content to a temporary location
temp_dir = os.path.join(current_app.config['UPLOAD_FOLDER'], 'temp')
os.makedirs(temp_dir, exist_ok=True)
file_path = os.path.join(temp_dir, f'docker-compose-{owner}-{repo_name}.yml')
with open(file_path, 'w') as f:
f.write(file_content)
# Get file stats
file_stats = os.stat(file_path)
return jsonify({
'success': True,
'message': 'Successfully found and downloaded docker-compose.yml',
'data': {
'file_path': file_path,
'size': file_stats.st_size,
'last_modified': datetime.fromtimestamp(file_stats.st_mtime).isoformat()
}
})
except Exception as e:
return jsonify({'success': False, 'error': str(e)}), 500

View File

@@ -1684,8 +1684,12 @@ def init_routes(main_bp):
# Get NGINX settings # Get NGINX settings
nginx_settings = KeyValueSettings.get_value('nginx_settings') nginx_settings = KeyValueSettings.get_value('nginx_settings')
# Get Portainer settings
portainer_settings = KeyValueSettings.get_value('portainer_settings')
return render_template('main/launch_progress.html', nginx_settings=nginx_settings) return render_template('main/launch_progress.html',
nginx_settings=nginx_settings,
portainer_settings=portainer_settings)
@main_bp.route('/api/check-dns', methods=['POST']) @main_bp.route('/api/check-dns', methods=['POST'])
@login_required @login_required

View File

@@ -193,7 +193,7 @@ function initializeSteps() {
`; `;
stepsContainer.appendChild(nginxStep); stepsContainer.appendChild(nginxStep);
// Add SSL Certificate generation step (now step 3) // Add SSL Certificate generation step
const sslStep = document.createElement('div'); const sslStep = document.createElement('div');
sslStep.className = 'step-item'; sslStep.className = 'step-item';
sslStep.innerHTML = ` sslStep.innerHTML = `
@@ -205,7 +205,7 @@ function initializeSteps() {
`; `;
stepsContainer.appendChild(sslStep); stepsContainer.appendChild(sslStep);
// Add Proxy Host creation step (now step 4) // Add Proxy Host creation step
const proxyStep = document.createElement('div'); const proxyStep = document.createElement('div');
proxyStep.className = 'step-item'; proxyStep.className = 'step-item';
proxyStep.innerHTML = ` proxyStep.innerHTML = `
@@ -216,6 +216,18 @@ function initializeSteps() {
</div> </div>
`; `;
stepsContainer.appendChild(proxyStep); stepsContainer.appendChild(proxyStep);
// Add Portainer connection check step (now last)
const portainerStep = document.createElement('div');
portainerStep.className = 'step-item';
portainerStep.innerHTML = `
<div class="step-icon"><i class="fab fa-docker"></i></div>
<div class="step-content">
<h5>Checking Portainer Connection</h5>
<p class="step-status">Verifying connection to Portainer...</p>
</div>
`;
stepsContainer.appendChild(portainerStep);
} }
async function startLaunch(data) { async function startLaunch(data) {
@@ -234,7 +246,7 @@ async function startLaunch(data) {
} }
// Update the step to show success // Update the step to show success
const dnsStep = document.querySelector('.step-item'); const dnsStep = document.querySelectorAll('.step-item')[0];
dnsStep.classList.remove('active'); dnsStep.classList.remove('active');
dnsStep.classList.add('completed'); dnsStep.classList.add('completed');
@@ -294,7 +306,7 @@ async function startLaunch(data) {
nginxStep.classList.add('completed'); nginxStep.classList.add('completed');
nginxStep.querySelector('.step-status').textContent = 'Successfully connected to NGINX Proxy Manager'; nginxStep.querySelector('.step-status').textContent = 'Successfully connected to NGINX Proxy Manager';
// Step 3: Generate SSL Certificate (moved up) // Step 3: Generate SSL Certificate
await updateStep(3, 'Generating SSL Certificate', 'Setting up secure HTTPS connection...'); await updateStep(3, 'Generating SSL Certificate', 'Setting up secure HTTPS connection...');
const sslResult = await generateSSLCertificate(data.webAddresses); const sslResult = await generateSSLCertificate(data.webAddresses);
@@ -302,7 +314,7 @@ async function startLaunch(data) {
throw new Error(sslResult.error || 'Failed to generate SSL certificate'); throw new Error(sslResult.error || 'Failed to generate SSL certificate');
} }
// Step 4: Create Proxy Host (moved down) // Step 4: Create Proxy Host
await updateStep(4, 'Creating Proxy Host', 'Setting up NGINX proxy host configuration...'); await updateStep(4, 'Creating Proxy Host', 'Setting up NGINX proxy host configuration...');
const proxyResult = await createProxyHost(data.webAddresses, data.port, sslResult.data.certificate.id); const proxyResult = await createProxyHost(data.webAddresses, data.port, sslResult.data.certificate.id);
@@ -310,6 +322,20 @@ async function startLaunch(data) {
throw new Error(proxyResult.error || 'Failed to create proxy host'); throw new Error(proxyResult.error || 'Failed to create proxy host');
} }
// Step 5: Check Portainer connection
await updateStep(5, 'Checking Portainer Connection', 'Verifying connection to Portainer...');
const portainerResult = await checkPortainerConnection();
if (!portainerResult.success) {
throw new Error(portainerResult.error || 'Failed to connect to Portainer');
}
// Update the step to show success
const portainerStep = document.querySelectorAll('.step-item')[4];
portainerStep.classList.remove('active');
portainerStep.classList.add('completed');
portainerStep.querySelector('.step-status').textContent = 'Successfully connected to Portainer';
} catch (error) { } catch (error) {
showError(error.message); showError(error.message);
} }
@@ -391,6 +417,66 @@ async function checkNginxConnection() {
} }
} }
async function checkPortainerConnection() {
try {
// Get CSRF token from meta tag
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
// Get Portainer settings from the template
const portainerSettings = {
url: '{{ portainer_settings.url if portainer_settings else "" }}',
api_key: '{{ portainer_settings.api_key if portainer_settings else "" }}'
};
// Debug log the raw template values
console.log('Raw template values:', {
url: '{{ portainer_settings.url if portainer_settings else "" }}',
api_key: '{{ portainer_settings.api_key if portainer_settings else "" }}'
});
// Debug log the settings (without API key)
console.log('Portainer Settings:', {
url: portainerSettings.url,
hasApiKey: !!portainerSettings.api_key
});
// Check if any required field is missing
if (!portainerSettings.url || !portainerSettings.api_key) {
console.error('Missing Portainer settings:', portainerSettings);
return {
success: false,
error: 'Portainer settings are not configured. Please configure Portainer settings in the admin panel.'
};
}
const testResponse = await fetch('/api/admin/test-portainer-connection', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify(portainerSettings)
});
if (!testResponse.ok) {
const error = await testResponse.json();
console.error('Portainer connection error:', error);
return {
success: false,
error: error.error || 'Failed to connect to Portainer'
};
}
return { success: true };
} catch (error) {
console.error('Error checking Portainer connection:', error);
return {
success: false,
error: error.message || 'Error checking Portainer connection'
};
}
}
function updateStatus(step, message, type = 'info', details = '') { function updateStatus(step, message, type = 'info', details = '') {
const statusElement = document.getElementById(`${step}Status`); const statusElement = document.getElementById(`${step}Status`);
const detailsElement = document.getElementById(`${step}Details`); const detailsElement = document.getElementById(`${step}Details`);
@@ -508,7 +594,7 @@ async function createProxyHost(domains, port, sslCertificateId) {
forward_host: '192.168.68.124', forward_host: '192.168.68.124',
forward_port: parseInt(port), forward_port: parseInt(port),
ssl_forced: true, ssl_forced: true,
caching_enabled: false, caching_enabled: true,
block_exploits: true, block_exploits: true,
allow_websocket_upgrade: true, allow_websocket_upgrade: true,
http2_support: true, http2_support: true,