checking portainer connection
This commit is contained in:
107
app/routes/admin_api.py
Normal file
107
app/routes/admin_api.py
Normal 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
|
||||
Binary file not shown.
@@ -1684,8 +1684,12 @@ def init_routes(main_bp):
|
||||
|
||||
# Get 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'])
|
||||
@login_required
|
||||
|
||||
@@ -193,7 +193,7 @@ function initializeSteps() {
|
||||
`;
|
||||
stepsContainer.appendChild(nginxStep);
|
||||
|
||||
// Add SSL Certificate generation step (now step 3)
|
||||
// Add SSL Certificate generation step
|
||||
const sslStep = document.createElement('div');
|
||||
sslStep.className = 'step-item';
|
||||
sslStep.innerHTML = `
|
||||
@@ -205,7 +205,7 @@ function initializeSteps() {
|
||||
`;
|
||||
stepsContainer.appendChild(sslStep);
|
||||
|
||||
// Add Proxy Host creation step (now step 4)
|
||||
// Add Proxy Host creation step
|
||||
const proxyStep = document.createElement('div');
|
||||
proxyStep.className = 'step-item';
|
||||
proxyStep.innerHTML = `
|
||||
@@ -216,6 +216,18 @@ function initializeSteps() {
|
||||
</div>
|
||||
`;
|
||||
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) {
|
||||
@@ -234,7 +246,7 @@ async function startLaunch(data) {
|
||||
}
|
||||
|
||||
// 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.add('completed');
|
||||
|
||||
@@ -294,7 +306,7 @@ async function startLaunch(data) {
|
||||
nginxStep.classList.add('completed');
|
||||
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...');
|
||||
const sslResult = await generateSSLCertificate(data.webAddresses);
|
||||
|
||||
@@ -302,7 +314,7 @@ async function startLaunch(data) {
|
||||
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...');
|
||||
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');
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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 = '') {
|
||||
const statusElement = document.getElementById(`${step}Status`);
|
||||
const detailsElement = document.getElementById(`${step}Details`);
|
||||
@@ -508,7 +594,7 @@ async function createProxyHost(domains, port, sslCertificateId) {
|
||||
forward_host: '192.168.68.124',
|
||||
forward_port: parseInt(port),
|
||||
ssl_forced: true,
|
||||
caching_enabled: false,
|
||||
caching_enabled: true,
|
||||
block_exploits: true,
|
||||
allow_websocket_upgrade: true,
|
||||
http2_support: true,
|
||||
|
||||
Reference in New Issue
Block a user