init
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					__pycache__
 | 
				
			||||||
 | 
					data/
 | 
				
			||||||
 | 
					instance/
 | 
				
			||||||
 | 
					venv/
 | 
				
			||||||
							
								
								
									
										19
									
								
								hosts_app.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								hosts_app.service
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					[Unit]
 | 
				
			||||||
 | 
					Description=Hosts Application
 | 
				
			||||||
 | 
					After=network.target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Service]
 | 
				
			||||||
 | 
					#User=www-data  # Zmień na odpowiedniego użytkownika
 | 
				
			||||||
 | 
					#Group=www-data
 | 
				
			||||||
 | 
					WorkingDirectory=/opt/hosts_app
 | 
				
			||||||
 | 
					Environment="PATH=/opt/hosts_app/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 | 
				
			||||||
 | 
					Environment="FLASK_APP=app.py"
 | 
				
			||||||
 | 
					Environment="FLASK_ENV=production"  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ExecStart=/opt/hosts_app/venv/bin/gunicorn -c /opt/hosts_app/gunicorn_config.py app:app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Restart=always
 | 
				
			||||||
 | 
					RestartSec=5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Install]
 | 
				
			||||||
 | 
					WantedBy=multi-user.target
 | 
				
			||||||
							
								
								
									
										149
									
								
								templates/backups.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								templates/backups.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>Backups</title>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body {
 | 
				
			||||||
 | 
					      font-family: Arial, sans-serif;
 | 
				
			||||||
 | 
					      background: #f1f1f1;
 | 
				
			||||||
 | 
					      margin: 0;
 | 
				
			||||||
 | 
					      padding: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .container {
 | 
				
			||||||
 | 
					      max-width: 800px;
 | 
				
			||||||
 | 
					      margin: 40px auto;
 | 
				
			||||||
 | 
					      background: #fff;
 | 
				
			||||||
 | 
					      padding: 20px;
 | 
				
			||||||
 | 
					      border-radius: 8px;
 | 
				
			||||||
 | 
					      box-shadow: 0 0 10px #ccc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    h1 {
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .backup-all-container {
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					      margin-bottom: 20px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .backup-all-btn {
 | 
				
			||||||
 | 
					      display: inline-block;
 | 
				
			||||||
 | 
					      padding: 15px 25px;
 | 
				
			||||||
 | 
					      background-color: #28a745;
 | 
				
			||||||
 | 
					      color: #fff;
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					      text-decoration: none;
 | 
				
			||||||
 | 
					      font-size: 1.2em;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      max-width: 90%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .backup-all-btn:hover {
 | 
				
			||||||
 | 
					      background-color: #218838;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    table {
 | 
				
			||||||
 | 
					      width: 100%;
 | 
				
			||||||
 | 
					      border-collapse: collapse;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    th, td {
 | 
				
			||||||
 | 
					      padding: 8px 12px;
 | 
				
			||||||
 | 
					      border: 1px solid #ddd;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    th {
 | 
				
			||||||
 | 
					      background: #f4f4f4;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .btn-sm {
 | 
				
			||||||
 | 
					      display: inline-block;
 | 
				
			||||||
 | 
					      padding: 4px 8px; 
 | 
				
			||||||
 | 
					      font-size: 0.85em; 
 | 
				
			||||||
 | 
					      text-decoration: none;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      margin-right: 5px;
 | 
				
			||||||
 | 
					      color: #fff; 
 | 
				
			||||||
 | 
					      border: none;  
 | 
				
			||||||
 | 
					      cursor: pointer;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .btn-view {
 | 
				
			||||||
 | 
					      background-color: #007bff; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .btn-view:hover {
 | 
				
			||||||
 | 
					      background-color: #0056b3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .btn-restore {
 | 
				
			||||||
 | 
					      background-color: #17a2b8; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .btn-restore:hover {
 | 
				
			||||||
 | 
					      background-color: #138496;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .btn-delete {
 | 
				
			||||||
 | 
					      background-color: #dc3545; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .btn-delete:hover {
 | 
				
			||||||
 | 
					      background-color: #c82333;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links {
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					      margin-top: 10px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .links a {
 | 
				
			||||||
 | 
					      color: #007bff;
 | 
				
			||||||
 | 
					      text-decoration: none;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .links a:hover {
 | 
				
			||||||
 | 
					      text-decoration: underline;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>Backups</h1>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <div class="backup-all-container">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('backup_all') }}" class="backup-all-btn">Backup All Hosts</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <table>
 | 
				
			||||||
 | 
					      <tr>
 | 
				
			||||||
 | 
					        <th>ID</th>
 | 
				
			||||||
 | 
					        <th>Host</th>
 | 
				
			||||||
 | 
					        <th>Created At</th>
 | 
				
			||||||
 | 
					        <th>Description</th>
 | 
				
			||||||
 | 
					        <th>Actions</th>
 | 
				
			||||||
 | 
					      </tr>
 | 
				
			||||||
 | 
					      {% for backup in backups %}
 | 
				
			||||||
 | 
					      <tr>
 | 
				
			||||||
 | 
					        <td>{{ backup.id }}</td>
 | 
				
			||||||
 | 
					        <td>{{ backup.host.hostname if backup.host else 'Default Configuration' }}</td>
 | 
				
			||||||
 | 
					        <td>{{ backup.created_at }}</td>
 | 
				
			||||||
 | 
					        <td>{{ backup.description or '' }}</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					          <!-- View jako przycisk niebieski -->
 | 
				
			||||||
 | 
					          <a href="{{ url_for('view_backup', backup_id=backup.id) }}"
 | 
				
			||||||
 | 
					             class="btn-sm btn-view">View</a>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <!-- Restore jako przycisk ciemny cyjan -->
 | 
				
			||||||
 | 
					          <a href="{{ url_for('restore_backup', backup_id=backup.id) }}"
 | 
				
			||||||
 | 
					             class="btn-sm btn-restore">Restore</a>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <!-- Delete jako przycisk czerwony, w formie (method=POST) -->
 | 
				
			||||||
 | 
					          <form action="{{ url_for('delete_backup', backup_id=backup.id) }}" method="POST" style="display:inline;">
 | 
				
			||||||
 | 
					            <button type="submit"
 | 
				
			||||||
 | 
					                    class="btn-sm btn-delete"
 | 
				
			||||||
 | 
					                    onclick="return confirm('Delete this backup?')">
 | 
				
			||||||
 | 
					              Delete
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					          </form>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					      </tr>
 | 
				
			||||||
 | 
					      {% endfor %}
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										58
									
								
								templates/change_password.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								templates/change_password.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>Change Password</title>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body {
 | 
				
			||||||
 | 
					      font-family: Arial, sans-serif;
 | 
				
			||||||
 | 
					      margin: 0; padding: 0;
 | 
				
			||||||
 | 
					      display: flex; justify-content: center; align-items: center;
 | 
				
			||||||
 | 
					      height: 100vh; background: #f1f1f1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .container {
 | 
				
			||||||
 | 
					      max-width: 400px; width: 100%;
 | 
				
			||||||
 | 
					      background: #fff; padding: 20px;
 | 
				
			||||||
 | 
					      border-radius: 8px; box-shadow: 0 0 10px #ccc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    h1 { text-align: center; margin-bottom: 1em; }
 | 
				
			||||||
 | 
					    label { display: block; margin-top: 1em; }
 | 
				
			||||||
 | 
					    input[type="password"] {
 | 
				
			||||||
 | 
					      width: 100%; padding: 8px; margin-top: 4px;
 | 
				
			||||||
 | 
					      box-sizing: border-box;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    button {
 | 
				
			||||||
 | 
					      margin-top: 1em; width: 100%; padding: 10px;
 | 
				
			||||||
 | 
					      background: #007bff; border: none; color: #fff;
 | 
				
			||||||
 | 
					      cursor: pointer; border-radius: 4px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					    .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					    .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					    .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    .flash-messages { margin-top: 10px; color: #b30000; text-align: center; }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>Change Password</h1>
 | 
				
			||||||
 | 
					    {% with messages = get_flashed_messages(category_filter=["danger","success","info"]) %}
 | 
				
			||||||
 | 
					      {% if messages %}
 | 
				
			||||||
 | 
					        <div class="flash-messages">
 | 
				
			||||||
 | 
					          {% for message in messages %}
 | 
				
			||||||
 | 
					            <p>{{ message }}</p>
 | 
				
			||||||
 | 
					          {% endfor %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      {% endif %}
 | 
				
			||||||
 | 
					    {% endwith %}
 | 
				
			||||||
 | 
					    <form method="POST" action="{{ url_for('change_password') }}">
 | 
				
			||||||
 | 
					      <label for="password">New Password:</label>
 | 
				
			||||||
 | 
					      <input type="password" name="password" id="password" required />
 | 
				
			||||||
 | 
					      <button type="submit">Change Password</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										32
									
								
								templates/clear_hosts.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								templates/clear_hosts.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>Clear Hosts Files</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body { font-family: Arial, sans-serif; background: #f1f1f1; padding: 20px; }
 | 
				
			||||||
 | 
					        .container { max-width: 500px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					        h1 { text-align: center; }
 | 
				
			||||||
 | 
					        button { margin-top: 1em; padding: 10px 20px; background: #007bff; border: none; color: #fff; cursor: pointer; border-radius: 4px; }
 | 
				
			||||||
 | 
					        button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					        .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					        .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					        .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>Clear /etc/hosts* Files</h1>
 | 
				
			||||||
 | 
					    <form method="POST" action="{{ url_for('clear_all_hosts') }}">
 | 
				
			||||||
 | 
					        <p>Select which types of hosts to clear:</p>
 | 
				
			||||||
 | 
					        <label><input type="checkbox" name="linux" value="1"> Linux Server/s</label><br>
 | 
				
			||||||
 | 
					        <label><input type="checkbox" name="mikrotik" value="1"> Mikrotik Router/s</label><br>
 | 
				
			||||||
 | 
					        <button type="submit">Clear /etc/hosts* on selected servers</button>
 | 
				
			||||||
 | 
					        <p>* - or MikroTik Router</p>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					        <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										297
									
								
								templates/dashboard.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								templates/dashboard.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,297 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>/etc/hosts file manager</title>
 | 
				
			||||||
 | 
					  <!-- Dodajemy FontAwesome dla ikon -->
 | 
				
			||||||
 | 
					  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body { font-family: Arial, sans-serif; background: #f1f1f1; margin: 0; padding: 0; }
 | 
				
			||||||
 | 
					    .container { max-width: 800px; margin: 40px auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					    h1 { text-align: center; margin-bottom: 1em; }
 | 
				
			||||||
 | 
					    .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					    .links a { color: #007bff; text-decoration: none; margin: 0 10px; font-size: 1.1em; }
 | 
				
			||||||
 | 
					    .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    .links i { margin-right: 5px; }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    /* Style dla bloku Statistics */
 | 
				
			||||||
 | 
					    .stats {
 | 
				
			||||||
 | 
					      margin: 20px 0;
 | 
				
			||||||
 | 
					      background: #e9ecef;
 | 
				
			||||||
 | 
					      padding: 10px;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .stats h2 {
 | 
				
			||||||
 | 
					      margin-top: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .stats ul {
 | 
				
			||||||
 | 
					      list-style: none;
 | 
				
			||||||
 | 
					      padding-left: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .stats li {
 | 
				
			||||||
 | 
					      margin-bottom: 5px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    /* Style dla bloku Recent Deploy Logs */
 | 
				
			||||||
 | 
					    .logs {
 | 
				
			||||||
 | 
					      margin-top: 20px;
 | 
				
			||||||
 | 
					      background: #fafafa;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      border: 1px solid #ddd;
 | 
				
			||||||
 | 
					      padding: 10px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .log-entry {
 | 
				
			||||||
 | 
					      border-bottom: 1px solid #ccc;
 | 
				
			||||||
 | 
					      padding: 5px 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .log-entry:last-child {
 | 
				
			||||||
 | 
					      border-bottom: none;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .user-info {
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .log-entry {
 | 
				
			||||||
 | 
					      background: #f9f9f9;
 | 
				
			||||||
 | 
					      margin: 8px 0;
 | 
				
			||||||
 | 
					      padding: 8px 12px;
 | 
				
			||||||
 | 
					      border-left: 4px solid #007bff;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .log-timestamp {
 | 
				
			||||||
 | 
					      font-weight: bold;
 | 
				
			||||||
 | 
					      margin-right: 10px;
 | 
				
			||||||
 | 
					      color: #555;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .log-details {
 | 
				
			||||||
 | 
					      display: inline;
 | 
				
			||||||
 | 
					      color: #333;
 | 
				
			||||||
 | 
					      margin: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .stats-graphic {
 | 
				
			||||||
 | 
					      margin: 20px 0;
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .bar-container {
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      height: 30px;
 | 
				
			||||||
 | 
					      background: #ddd;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      overflow: hidden;
 | 
				
			||||||
 | 
					      margin: 10px auto;
 | 
				
			||||||
 | 
					      max-width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .bar-success {
 | 
				
			||||||
 | 
					      background: #28a745;
 | 
				
			||||||
 | 
					      color: #fff;
 | 
				
			||||||
 | 
					      line-height: 30px;
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					      white-space: nowrap;
 | 
				
			||||||
 | 
					      overflow: hidden;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .bar-failed {
 | 
				
			||||||
 | 
					      background: #dc3545;
 | 
				
			||||||
 | 
					      color: #fff;
 | 
				
			||||||
 | 
					      line-height: 30px;
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					      white-space: nowrap;
 | 
				
			||||||
 | 
					      overflow: hidden;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .flash-messages {
 | 
				
			||||||
 | 
					      margin: 20px 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .flash-messages p {
 | 
				
			||||||
 | 
					      margin: 0 0 5px 0;
 | 
				
			||||||
 | 
					      padding: 10px;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Dla kategorii success */
 | 
				
			||||||
 | 
					    .flash-messages p.success {
 | 
				
			||||||
 | 
					      background-color: #d4edda; /* Jasnozielone tło */
 | 
				
			||||||
 | 
					      color: #155724;           /* Zielony tekst */
 | 
				
			||||||
 | 
					      border: 1px solid #c3e6cb;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Dla kategorii danger */
 | 
				
			||||||
 | 
					    .flash-messages p.danger {
 | 
				
			||||||
 | 
					      background-color: #f8d7da; /* Jasnoczerwone tło */
 | 
				
			||||||
 | 
					      color: #721c24;           /* Czerwony tekst */
 | 
				
			||||||
 | 
					      border: 1px solid #f5c6cb;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Dla kategorii info */
 | 
				
			||||||
 | 
					    .flash-messages p.info {
 | 
				
			||||||
 | 
					      background-color: #d1ecf1; /* Jasnoniebieskie tło */
 | 
				
			||||||
 | 
					      color: #0c5460;           /* Niebieski tekst */
 | 
				
			||||||
 | 
					      border: 1px solid #bee5eb;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links-nav ul {
 | 
				
			||||||
 | 
					      /* Usuwamy domyślne wcięcia i kuleczki */
 | 
				
			||||||
 | 
					      list-style: none;
 | 
				
			||||||
 | 
					      margin: 0;
 | 
				
			||||||
 | 
					      padding: 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /* Rozmieszczenie linków w elastyczny sposób */
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      flex-wrap: wrap;      /* Pozwoli zawijać się wierszom przy małym ekranie */
 | 
				
			||||||
 | 
					      justify-content: center;
 | 
				
			||||||
 | 
					      gap: 10px;            /* Odstęp między przyciskami */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links-nav li {
 | 
				
			||||||
 | 
					      margin: 0;
 | 
				
			||||||
 | 
					      padding: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links-nav li a {
 | 
				
			||||||
 | 
					      display: inline-block;
 | 
				
			||||||
 | 
					      color: #007bff;
 | 
				
			||||||
 | 
					      text-decoration: none;
 | 
				
			||||||
 | 
					      padding: 8px 12px;
 | 
				
			||||||
 | 
					      background: #f8f8f8;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      border: 1px solid #ddd;
 | 
				
			||||||
 | 
					      transition: background 0.2s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links-nav li a:hover {
 | 
				
			||||||
 | 
					      background: #e2e6ea;
 | 
				
			||||||
 | 
					      text-decoration: none;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .deploy-container {
 | 
				
			||||||
 | 
					      margin: 20px auto;     /* odstęp u góry i dołu */
 | 
				
			||||||
 | 
					      text-align: center;    /* środek strony */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .deploy-now-btn {
 | 
				
			||||||
 | 
					      display: inline-block;
 | 
				
			||||||
 | 
					      width: 60%;            /* szeroki przycisk - możesz dostosować */
 | 
				
			||||||
 | 
					      max-width: 400px;      /* by się za bardzo nie rozciągał na dużym ekranie */
 | 
				
			||||||
 | 
					      padding: 15px;
 | 
				
			||||||
 | 
					      font-size: 1.2em;
 | 
				
			||||||
 | 
					      text-decoration: none;
 | 
				
			||||||
 | 
					      color: #fff;
 | 
				
			||||||
 | 
					      background: #007bff;
 | 
				
			||||||
 | 
					      border-radius: 6px;
 | 
				
			||||||
 | 
					      border: 1px solid #007bff;
 | 
				
			||||||
 | 
					      transition: background 0.2s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .deploy-now-btn:hover {
 | 
				
			||||||
 | 
					      background: #0056b3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links-nav ul {
 | 
				
			||||||
 | 
					      list-style: none;
 | 
				
			||||||
 | 
					      margin: 0;
 | 
				
			||||||
 | 
					      padding: 0;
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      flex-wrap: wrap;
 | 
				
			||||||
 | 
					      justify-content: center;
 | 
				
			||||||
 | 
					      gap: 10px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links-nav li {
 | 
				
			||||||
 | 
					      margin: 0;
 | 
				
			||||||
 | 
					      padding: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links-nav li a {
 | 
				
			||||||
 | 
					      display: inline-block;
 | 
				
			||||||
 | 
					      color: #007bff;
 | 
				
			||||||
 | 
					      text-decoration: none;
 | 
				
			||||||
 | 
					      padding: 8px 12px;
 | 
				
			||||||
 | 
					      background: #f8f8f8;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      border: 1px solid #ddd;
 | 
				
			||||||
 | 
					      transition: background 0.2s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .links-nav li a:hover {
 | 
				
			||||||
 | 
					      background: #e2e6ea;
 | 
				
			||||||
 | 
					      text-decoration: none;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>/etc/hosts file manager</h1>
 | 
				
			||||||
 | 
					    {% with messages = get_flashed_messages(with_categories=true) %}
 | 
				
			||||||
 | 
					    {% if messages %}
 | 
				
			||||||
 | 
					      <div class="flash-messages">
 | 
				
			||||||
 | 
					        {% for category, message in messages %}
 | 
				
			||||||
 | 
					          <p class="{{ category }}">{{ message }}</p>
 | 
				
			||||||
 | 
					        {% endfor %}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    {% endif %}
 | 
				
			||||||
 | 
					  {% endwith %}
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    <div class="user-info">
 | 
				
			||||||
 | 
					      <p><h2>Welcome, <b>{{ user.username }}</b>!</h2></p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="deploy-container">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('deploy_now') }}" class="deploy-now-btn">
 | 
				
			||||||
 | 
					        <i class="fas fa-rocket"></i> Deploy Now
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <div class="links-nav">
 | 
				
			||||||
 | 
					      <ul>
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('manage_hosts') }}"><i class="fas fa-server"></i> Manage remote servers</a></li>
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('clear_all_hosts') }}"><i class="fas fa-trash-alt"></i> Clear /etc/hosts on remote</a></li>
 | 
				
			||||||
 | 
					    <!--    <li><a href="{{ url_for('list_hosts_files') }}"><i class="fas fa-list"></i> List /etc/hosts files</a></li> -->
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('edit_local_hosts') }}"><i class="fas fa-edit"></i> Edit /etc/hosts</a></li>
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('list_regex_hosts') }}"><i class="fas fa-network-wired"></i> Manage Regex/CIDR</a></li>
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('new_regex_host') }}"><i class="fas fa-plus-circle"></i> Add new CIDR entry</a></li>
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('backups') }}"><i class="fas fa-archive"></i> Backups</a></li>
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('settings') }}"><i class="fas fa-cog"></i> Settings</a></li>
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('change_password') }}"><i class="fas fa-key"></i> Change Password</a></li>
 | 
				
			||||||
 | 
					        <li><a href="{{ url_for('logout') }}"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
 | 
				
			||||||
 | 
					      </ul>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <div class="stats">
 | 
				
			||||||
 | 
					      <h2>Statistics</h2>
 | 
				
			||||||
 | 
					      <ul>
 | 
				
			||||||
 | 
					        <li>Number of managed server: <b>{{ stats.host_count }}</b></li>
 | 
				
			||||||
 | 
					        <li>Total deployments: <b>{{ stats.total_deployments }}</b></li>
 | 
				
			||||||
 | 
					        <li>Successful deployments: <b>{{ stats.successful_deployments }}</b></li>
 | 
				
			||||||
 | 
					        <li>Failed deployments: <b>{{ stats.failed_deployments }}</b></li>
 | 
				
			||||||
 | 
					      </ul>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="stats-graphic">
 | 
				
			||||||
 | 
					      <h2>Deployment Success Rate</h2>
 | 
				
			||||||
 | 
					      <div class="bar-container">
 | 
				
			||||||
 | 
					        <div class="bar-success" style="width: {{ (stats.successful_deployments / stats.total_deployments * 100) if stats.total_deployments else 0 }}%;">
 | 
				
			||||||
 | 
					          {{ stats.successful_deployments }} Successful
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="bar-failed" style="width: {{ (stats.failed_deployments / stats.total_deployments * 100) if stats.total_deployments else 0 }}%;">
 | 
				
			||||||
 | 
					          {{ stats.failed_deployments }} Failed
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="logs">
 | 
				
			||||||
 | 
					      <h2>Recent Deploy Logs</h2>
 | 
				
			||||||
 | 
					      {% if logs %}
 | 
				
			||||||
 | 
					        {% for log in logs %}
 | 
				
			||||||
 | 
					          <div class="log-entry">
 | 
				
			||||||
 | 
					            <span class="log-timestamp">{{ log.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}</span>
 | 
				
			||||||
 | 
					            <p class="log-details">{{ log.details }}</p>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        {% endfor %}
 | 
				
			||||||
 | 
					      {% else %}
 | 
				
			||||||
 | 
					        <p>No deployment logs available yet.</p>
 | 
				
			||||||
 | 
					      {% endif %}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										41
									
								
								templates/deploy_hosts_file.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								templates/deploy_hosts_file.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>Deploy /etc/hosts File - {{ file.title }}</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body { font-family: Arial, sans-serif; background: #f1f1f1; padding: 20px; }
 | 
				
			||||||
 | 
					        .container { max-width: 600px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					        h1 { text-align: center; }
 | 
				
			||||||
 | 
					        form { margin-top: 20px; }
 | 
				
			||||||
 | 
					        .host-list { margin: 20px 0; }
 | 
				
			||||||
 | 
					        .host-item { margin-bottom: 10px; }
 | 
				
			||||||
 | 
					        button { padding: 10px 20px; background: #007bff; border: none; color: #fff; cursor: pointer; border-radius: 4px; display: block; margin: 0 auto; }
 | 
				
			||||||
 | 
					        button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					        .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					        .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					        .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>Deploy "{{ file.title }}"</h1>
 | 
				
			||||||
 | 
					    <p>Select the hosts to which you want to deploy this file:</p>
 | 
				
			||||||
 | 
					    <form method="POST" action="">
 | 
				
			||||||
 | 
					        <div class="host-list">
 | 
				
			||||||
 | 
					            {% for host in hosts %}
 | 
				
			||||||
 | 
					            <div class="host-item">
 | 
				
			||||||
 | 
					                <label>
 | 
				
			||||||
 | 
					                    <input type="checkbox" name="hosts" value="{{ host.id }}"> {{ host.hostname }} ({{ host.type }})
 | 
				
			||||||
 | 
					                </label>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            {% endfor %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <button type="submit">Deploy</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					        <a href="{{ url_for('list_hosts_files') }}">Back to /etc/hosts Files</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										62
									
								
								templates/edit_host.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								templates/edit_host.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>Edit server {{ host.hostname }}</title>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body { font-family: Arial, sans-serif; background: #f1f1f1; margin: 0; padding: 0; }
 | 
				
			||||||
 | 
					    .container { max-width: 600px; margin: 40px auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					    label { display: block; margin-top: 1em; }
 | 
				
			||||||
 | 
					    input[type="text"], input[type="password"], textarea { width: 100%; padding: 8px; margin-top: 4px; box-sizing: border-box; }
 | 
				
			||||||
 | 
					    button { margin-top: 1em; padding: 10px 20px; background: #007bff; border: none; color: #fff; cursor: pointer; border-radius: 4px; }
 | 
				
			||||||
 | 
					    button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					    .flash-messages { margin-top: 10px; color: #b30000; text-align: center; }
 | 
				
			||||||
 | 
					    .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					    .links a { color: #007bff; text-decoration: none; margin: 0 10px; }
 | 
				
			||||||
 | 
					    .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>Edit server {{ host.hostname }}</h1>
 | 
				
			||||||
 | 
					    {% with messages = get_flashed_messages(category_filter=["danger","success","info"]) %}
 | 
				
			||||||
 | 
					      {% if messages %}
 | 
				
			||||||
 | 
					        <div class="flash-messages">
 | 
				
			||||||
 | 
					          {% for message in messages %}
 | 
				
			||||||
 | 
					            <p>{{ message }}</p>
 | 
				
			||||||
 | 
					          {% endfor %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      {% endif %}
 | 
				
			||||||
 | 
					    {% endwith %}
 | 
				
			||||||
 | 
					    <form method="POST" action="{{ url_for('edit_host', id=host.id) }}">
 | 
				
			||||||
 | 
					      <label for="hostname">Hostname (IP or domain):</label>
 | 
				
			||||||
 | 
					      <input type="text" name="hostname" id="hostname" value="{{ host.hostname }}" required />
 | 
				
			||||||
 | 
					      <label for="username">SSH Username:</label>
 | 
				
			||||||
 | 
					      <input type="text" name="username" id="username" value="{{ host.username }}" required />
 | 
				
			||||||
 | 
					      <label for="password">SSH Password:</label>
 | 
				
			||||||
 | 
					      <input type="password" name="password" id="password" value="{{ host.password }}" />
 | 
				
			||||||
 | 
					      <label for="port">SSH Port:</label>
 | 
				
			||||||
 | 
					      <input type="text" name="port" id="port" value="{{ host.port }}" />
 | 
				
			||||||
 | 
					      <label for="host_type">Type:</label>
 | 
				
			||||||
 | 
					      <select name="host_type" id="host_type">
 | 
				
			||||||
 | 
					        <option value="linux" {% if host.type == 'linux' %}selected{% endif %}>Linux</option>
 | 
				
			||||||
 | 
					        <option value="mikrotik" {% if host.type == 'mikrotik' %}selected{% endif %}>Mikrotik</option>
 | 
				
			||||||
 | 
					      </select>
 | 
				
			||||||
 | 
					      <label for="auth_method">Authentication Method:</label>
 | 
				
			||||||
 | 
					      <select name="auth_method" id="auth_method">
 | 
				
			||||||
 | 
					        <option value="password" {% if host.auth_method == 'password' %}selected{% endif %}>Password</option>
 | 
				
			||||||
 | 
					        <option value="ssh_key" {% if host.auth_method == 'ssh_key' %}selected{% endif %}>SSH Key</option>
 | 
				
			||||||
 | 
					      </select>
 | 
				
			||||||
 | 
					      <label for="private_key">Private Key (if using SSH Key):</label>
 | 
				
			||||||
 | 
					      <textarea name="private_key" id="private_key" rows="5">{{ host.private_key }}</textarea>
 | 
				
			||||||
 | 
					      <label for="key_passphrase">Key Passphrase (if encrypted key):</label>
 | 
				
			||||||
 | 
					      <input type="password" name="key_passphrase" id="key_passphrase" value="{{ host.key_passphrase }}" />
 | 
				
			||||||
 | 
					      <button type="submit">Save Changes</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('manage_hosts') }}">Back Remote server management</a> |
 | 
				
			||||||
 | 
					      <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										41
									
								
								templates/edit_hosts.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								templates/edit_hosts.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>Edit Global /etc/hosts File</title>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body { font-family: Arial, sans-serif; background: #f1f1f1; margin: 0; padding: 0; }
 | 
				
			||||||
 | 
					    .container { max-width: 800px; margin: 40px auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					    h1 { text-align: center; margin-bottom: 1em; }
 | 
				
			||||||
 | 
					    textarea { width: 100%; height: 400px; box-sizing: border-box; font-family: monospace; padding: 10px; }
 | 
				
			||||||
 | 
					    button { margin-top: 1em; padding: 10px 20px; background: #007bff; border: none; color: #fff; cursor: pointer; border-radius: 4px; }
 | 
				
			||||||
 | 
					    button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					    .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					    .links a { color: #007bff; text-decoration: none; margin: 0 10px; }
 | 
				
			||||||
 | 
					    .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    .flash-messages { margin-top: 10px; color: #b30000; text-align: center; }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>Edit Global /etc/hosts File</h1>
 | 
				
			||||||
 | 
					    {% with messages = get_flashed_messages(category_filter=["danger","success","info"]) %}
 | 
				
			||||||
 | 
					      {% if messages %}
 | 
				
			||||||
 | 
					        <div class="flash-messages">
 | 
				
			||||||
 | 
					          {% for message in messages %}
 | 
				
			||||||
 | 
					            <p>{{ message }}</p>
 | 
				
			||||||
 | 
					          {% endfor %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      {% endif %}
 | 
				
			||||||
 | 
					    {% endwith %}
 | 
				
			||||||
 | 
					    <form method="POST" action="{{ url_for('edit_local_hosts') }}">
 | 
				
			||||||
 | 
					      <textarea name="hosts_content" id="hosts_content">{{ content }}</textarea>
 | 
				
			||||||
 | 
					      <br/>
 | 
				
			||||||
 | 
					      <button type="submit">Save Changes</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('dashboard') }}">Go to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										160
									
								
								templates/hosts.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								templates/hosts.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>Remote server management</title>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body { font-family: Arial, sans-serif; background: #f1f1f1; margin: 0; padding: 0; }
 | 
				
			||||||
 | 
					    .container { max-width: 800px; margin: 40px auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					    h1 { text-align: center; margin-bottom: 1em; }
 | 
				
			||||||
 | 
					    table { width: 100%; border-collapse: collapse; margin-bottom: 1em; }
 | 
				
			||||||
 | 
					    table th, table td { border: 1px solid #ccc; padding: 8px; text-align: left; }
 | 
				
			||||||
 | 
					    table th { background: #f7f7f7; }
 | 
				
			||||||
 | 
					    .form-section { margin-bottom: 20px; background: #fafafa; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
 | 
				
			||||||
 | 
					    label { display: block; margin-top: 1em; }
 | 
				
			||||||
 | 
					    input[type="text"], input[type="password"], textarea { width: 100%; padding: 8px; margin-top: 4px; box-sizing: border-box; }
 | 
				
			||||||
 | 
					    button { margin-top: 1em; padding: 10px 20px; background: #007bff; border: none; color: #fff; cursor: pointer; border-radius: 4px; }
 | 
				
			||||||
 | 
					    button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					    .delete-btn { background: #dc3545; margin-top: 0; }
 | 
				
			||||||
 | 
					    .delete-btn:hover { background: #c82333; }
 | 
				
			||||||
 | 
					    .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					    .links a { color: #007bff; text-decoration: none; margin: 0 10px; }
 | 
				
			||||||
 | 
					    .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    .flash-messages { margin-top: 10px; color: #b30000; text-align: center; }
 | 
				
			||||||
 | 
					    .btn {
 | 
				
			||||||
 | 
					          display: inline-block;
 | 
				
			||||||
 | 
					          padding: 4px 10px;
 | 
				
			||||||
 | 
					          margin: 0 3px;
 | 
				
			||||||
 | 
					          border-radius: 4px;
 | 
				
			||||||
 | 
					          border: none;
 | 
				
			||||||
 | 
					          cursor: pointer;
 | 
				
			||||||
 | 
					          text-decoration: none;
 | 
				
			||||||
 | 
					          color: #fff;
 | 
				
			||||||
 | 
					          font-size: 0.85em;
 | 
				
			||||||
 | 
					          vertical-align: middle;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Kolorowe warianty */
 | 
				
			||||||
 | 
					        .btn-primary {
 | 
				
			||||||
 | 
					          background-color: #007bff;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .btn-primary:hover {
 | 
				
			||||||
 | 
					          background-color: #0056b3;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .btn-info {
 | 
				
			||||||
 | 
					          background-color: #17a2b8;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .btn-info:hover {
 | 
				
			||||||
 | 
					          background-color: #138496;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .btn-success {
 | 
				
			||||||
 | 
					          background-color: #28a745;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .btn-success:hover {
 | 
				
			||||||
 | 
					          background-color: #218838;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .btn-danger {
 | 
				
			||||||
 | 
					          background-color: #dc3545;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .btn-danger:hover {
 | 
				
			||||||
 | 
					          background-color: #c82333;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    .resolved-hostname {
 | 
				
			||||||
 | 
					      display: none;
 | 
				
			||||||
 | 
					      font-size: 0.7em;
 | 
				
			||||||
 | 
					      color: #777;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    td:hover .resolved-hostname {
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>Remote server management</h1>
 | 
				
			||||||
 | 
					    {% with messages = get_flashed_messages(category_filter=["danger","success","info"]) %}
 | 
				
			||||||
 | 
					      {% if messages %}
 | 
				
			||||||
 | 
					        <div class="flash-messages">
 | 
				
			||||||
 | 
					          {% for message in messages %}
 | 
				
			||||||
 | 
					            <p>{{ message }}</p>
 | 
				
			||||||
 | 
					          {% endfor %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      {% endif %}
 | 
				
			||||||
 | 
					    {% endwith %}
 | 
				
			||||||
 | 
					    <div class="form-section">
 | 
				
			||||||
 | 
					      <h2>Add new server</h2>
 | 
				
			||||||
 | 
					      <form method="POST" action="{{ url_for('manage_hosts') }}">
 | 
				
			||||||
 | 
					        <label for="hostname">Hostname (IP or domain):</label>
 | 
				
			||||||
 | 
					        <input type="text" name="hostname" id="hostname" required />
 | 
				
			||||||
 | 
					        <label for="username">SSH Username:</label>
 | 
				
			||||||
 | 
					        <input type="text" name="username" id="username" required />
 | 
				
			||||||
 | 
					        <label for="password">SSH Password:</label>
 | 
				
			||||||
 | 
					        <input type="password" name="password" id="password" />
 | 
				
			||||||
 | 
					        <label for="port">SSH Port:</label>
 | 
				
			||||||
 | 
					        <input type="text" name="port" id="port" value="22" />
 | 
				
			||||||
 | 
					        <label for="host_type">Type:</label>
 | 
				
			||||||
 | 
					        <select name="host_type" id="host_type" required>
 | 
				
			||||||
 | 
					          <option value="linux">Linux</option>
 | 
				
			||||||
 | 
					          <option value="mikrotik">Mikrotik</option>
 | 
				
			||||||
 | 
					        </select>
 | 
				
			||||||
 | 
					        <label for="auth_method">Authentication Method:</label>
 | 
				
			||||||
 | 
					        <select name="auth_method" id="auth_method">
 | 
				
			||||||
 | 
					          <option value="password">Password</option>
 | 
				
			||||||
 | 
					          <option value="ssh_key">SSH Key</option>
 | 
				
			||||||
 | 
					        </select>
 | 
				
			||||||
 | 
					        <label for="private_key">Private Key (if using SSH Key):</label>
 | 
				
			||||||
 | 
					        <textarea name="private_key" id="private_key" rows="5"></textarea>
 | 
				
			||||||
 | 
					        <label for="key_passphrase">Key Passphrase (if encrypted key):</label>
 | 
				
			||||||
 | 
					        <input type="password" name="key_passphrase" id="key_passphrase" />
 | 
				
			||||||
 | 
					        <button type="submit">Add Host</button>
 | 
				
			||||||
 | 
					      </form>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <table>
 | 
				
			||||||
 | 
					      <thead>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <th>ID</th>
 | 
				
			||||||
 | 
					          <th>Hostname</th>
 | 
				
			||||||
 | 
					          <th>SSH User</th>
 | 
				
			||||||
 | 
					          <th>Port</th>
 | 
				
			||||||
 | 
					          <th>Type</th>
 | 
				
			||||||
 | 
					          <th>Auth Method</th>
 | 
				
			||||||
 | 
					          <th>Actions</th>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					      </thead>
 | 
				
			||||||
 | 
					      <tbody>
 | 
				
			||||||
 | 
					        {% for h in hosts %}
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <td>{{ h.id }}</td>
 | 
				
			||||||
 | 
					          <td>
 | 
				
			||||||
 | 
					            <span class="primary-hostname">{{ h.hostname }}</span>
 | 
				
			||||||
 | 
					            <br>
 | 
				
			||||||
 | 
					            <span class="resolved-hostname">{{ h.resolved_hostname }}</span>
 | 
				
			||||||
 | 
					          </td>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <td>{{ h.username }}</td>
 | 
				
			||||||
 | 
					          <td>{{ h.port }}</td>
 | 
				
			||||||
 | 
					          <td>{{ h.type }}</td>
 | 
				
			||||||
 | 
					          <td>{{ h.auth_method }}</td>
 | 
				
			||||||
 | 
					          <td>
 | 
				
			||||||
 | 
					            <a href="{{ url_for('edit_host', id=h.id) }}" class="btn btn-primary">Edit</a>
 | 
				
			||||||
 | 
					            <a href="{{ url_for('test_host', id=h.id) }}" class="btn btn-info">Test</a>
 | 
				
			||||||
 | 
					            <a href="{{ url_for('backup_host', host_id=h.id) }}" class="btn btn-success">Backup</a>
 | 
				
			||||||
 | 
					            <form method="GET" action="{{ url_for('delete_host', id=h.id) }}" style="display:inline;">
 | 
				
			||||||
 | 
					              <button type="submit" class="btn btn-danger">Delete</button>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					          </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        {% endfor %}
 | 
				
			||||||
 | 
					      </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('import_hosts') }}">Import Servers from CSV</a> |
 | 
				
			||||||
 | 
					      <a href="{{ url_for('export_hosts') }}">Export Servers to CSV</a> |
 | 
				
			||||||
 | 
					      <a href="{{ url_for('dashboard') }}">Go to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										48
									
								
								templates/hosts_files.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								templates/hosts_files.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>/etc/hosts Files Management</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body { font-family: Arial, sans-serif; background: #f1f1f1; padding: 20px; }
 | 
				
			||||||
 | 
					        .container { max-width: 800px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					        table { width: 100%; border-collapse: collapse; margin-bottom: 1em; }
 | 
				
			||||||
 | 
					        table th, table td { border: 1px solid #ccc; padding: 8px; text-align: left; }
 | 
				
			||||||
 | 
					        table th { background: #f7f7f7; }
 | 
				
			||||||
 | 
					        .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					        .links a { color: #007bff; text-decoration: none; margin: 0 10px; }
 | 
				
			||||||
 | 
					        .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>Your /etc/hosts Files</h1>
 | 
				
			||||||
 | 
					    <table>
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>ID</th>
 | 
				
			||||||
 | 
					                <th>Title</th>
 | 
				
			||||||
 | 
					                <th>Actions</th>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            {% for file in files %}
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>{{ file.id }}</td>
 | 
				
			||||||
 | 
					                <td>{{ file.title }}</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <a href="{{ url_for('edit_hosts_file', file_id=file.id) }}">Edit</a> |
 | 
				
			||||||
 | 
					                    <a href="{{ url_for('deploy_hosts_file', file_id=file.id) }}">Deploy</a> |
 | 
				
			||||||
 | 
					                    <a href="{{ url_for('delete_hosts_file', file_id=file.id) }}">Delete</a>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            {% endfor %}
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					        <a href="{{ url_for('new_hosts_file') }}">Create /etc/hosts File</a> |
 | 
				
			||||||
 | 
					        <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										31
									
								
								templates/import_hosts.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								templates/import_hosts.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>Import Hosts</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body { font-family: Arial, sans-serif; background: #f1f1f1; padding: 20px; }
 | 
				
			||||||
 | 
					        .container { max-width: 500px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					        h1 { text-align: center; }
 | 
				
			||||||
 | 
					        input[type="file"] { display: block; margin: 20px auto; }
 | 
				
			||||||
 | 
					        button { margin-top: 1em; padding: 10px 20px; background: #007bff; border: none; color: #fff; cursor: pointer; border-radius: 4px; display: block; margin: 0 auto; }
 | 
				
			||||||
 | 
					        button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					        .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					        .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					        .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>Import Hosts</h1>
 | 
				
			||||||
 | 
					    <form method="POST" action="{{ url_for('import_hosts') }}" enctype="multipart/form-data">
 | 
				
			||||||
 | 
					        <input type="file" name="file" accept=".csv" required>
 | 
				
			||||||
 | 
					        <button type="submit">Import Hosts</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					        <a href="{{ url_for('manage_hosts') }}">Back to Hosts Management</a> | 
 | 
				
			||||||
 | 
					        <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										121
									
								
								templates/list_regex_hosts.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								templates/list_regex_hosts.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>Regex /etc/hosts Entries</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body {
 | 
				
			||||||
 | 
					            font-family: Arial, sans-serif;
 | 
				
			||||||
 | 
					            background: #f1f1f1;
 | 
				
			||||||
 | 
					            padding: 20px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .container {
 | 
				
			||||||
 | 
					            max-width: 700px;
 | 
				
			||||||
 | 
					            margin: 0 auto;
 | 
				
			||||||
 | 
					            background: #fff;
 | 
				
			||||||
 | 
					            padding: 20px;
 | 
				
			||||||
 | 
					            border-radius: 8px;
 | 
				
			||||||
 | 
					            box-shadow: 0 0 10px rgba(0,0,0,0.1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        h1 {
 | 
				
			||||||
 | 
					            text-align: center;
 | 
				
			||||||
 | 
					            margin-bottom: 1em;
 | 
				
			||||||
 | 
					            color: #333;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        table {
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					            border-collapse: collapse;
 | 
				
			||||||
 | 
					            margin-bottom: 1em;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        th, td {
 | 
				
			||||||
 | 
					            text-align: left;
 | 
				
			||||||
 | 
					            border-bottom: 1px solid #ddd;
 | 
				
			||||||
 | 
					            padding: 8px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .actions {
 | 
				
			||||||
 | 
					            white-space: nowrap;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .btn {
 | 
				
			||||||
 | 
					            display: inline-block;
 | 
				
			||||||
 | 
					            padding: 6px 12px;
 | 
				
			||||||
 | 
					            background: #007bff;
 | 
				
			||||||
 | 
					            color: #fff;
 | 
				
			||||||
 | 
					            text-decoration: none;
 | 
				
			||||||
 | 
					            margin-right: 5px;
 | 
				
			||||||
 | 
					            border-radius: 4px;
 | 
				
			||||||
 | 
					            font-size: 0.9em;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .btn:hover {
 | 
				
			||||||
 | 
					            background: #0056b3;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .btn-delete {
 | 
				
			||||||
 | 
					            background: #dc3545;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .btn-delete:hover {
 | 
				
			||||||
 | 
					            background: #b52b37;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					        .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					       .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .button-big {
 | 
				
			||||||
 | 
					            margin-top: 0.5em;
 | 
				
			||||||
 | 
					            padding: 10px 20px;
 | 
				
			||||||
 | 
					            background: #0c7001;
 | 
				
			||||||
 | 
					            border: none;
 | 
				
			||||||
 | 
					            color: #fff;
 | 
				
			||||||
 | 
					            cursor: pointer;
 | 
				
			||||||
 | 
					            border-radius: 3px;
 | 
				
			||||||
 | 
					            font-size: 1.1em;
 | 
				
			||||||
 | 
					            text-decoration: none;
 | 
				
			||||||
 | 
					            display: block;
 | 
				
			||||||
 | 
					            width: 65%;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .button-big:hover {
 | 
				
			||||||
 | 
					            background: #104d09;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>Regex (CIDR) for /etc/hosts Entries</h1>
 | 
				
			||||||
 | 
					    <table>
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>ID</th>
 | 
				
			||||||
 | 
					                <th>Domain</th>
 | 
				
			||||||
 | 
					                <th>CIDR Range</th>
 | 
				
			||||||
 | 
					                <th>Comment</th>
 | 
				
			||||||
 | 
					                <th class="actions">Actions</th>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					        {% for e in entries %}
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>{{ e.id }}</td>
 | 
				
			||||||
 | 
					                <td>{{ e.domain_suffix }}</td>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <td>{{ e.cidr_range }}</td>
 | 
				
			||||||
 | 
					                <td>{{ e.comment }}</td>
 | 
				
			||||||
 | 
					                <td class="actions">
 | 
				
			||||||
 | 
					                    <a href="{{ url_for('edit_regex_host', entry_id=e.id) }}" class="btn">Edit</a>
 | 
				
			||||||
 | 
					                    <form action="{{ url_for('delete_regex_host', entry_id=e.id) }}" method="POST" style="display:inline;">
 | 
				
			||||||
 | 
					                        <button type="submit" class="btn btn-delete" onclick="return confirm('Are you sure you want to delete this entry?');">
 | 
				
			||||||
 | 
					                            Delete
 | 
				
			||||||
 | 
					                        </button>
 | 
				
			||||||
 | 
					                    </form>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        {% endfor %}
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <center><a href="{{ url_for('new_regex_host') }}" class="button-big">Add New Entry</a></center>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										60
									
								
								templates/login.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								templates/login.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>Login</title>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body {
 | 
				
			||||||
 | 
					      font-family: Arial, sans-serif;
 | 
				
			||||||
 | 
					      margin: 0; padding: 0;
 | 
				
			||||||
 | 
					      display: flex; justify-content: center; align-items: center;
 | 
				
			||||||
 | 
					      height: 100vh; background: #f1f1f1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .container {
 | 
				
			||||||
 | 
					      max-width: 400px; width: 100%;
 | 
				
			||||||
 | 
					      background: #fff; padding: 20px;
 | 
				
			||||||
 | 
					      border-radius: 8px; box-shadow: 0 0 10px #ccc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    h1 { text-align: center; margin-bottom: 1em; }
 | 
				
			||||||
 | 
					    label { display: block; margin-top: 1em; }
 | 
				
			||||||
 | 
					    input[type="text"], input[type="password"] {
 | 
				
			||||||
 | 
					      width: 100%; padding: 8px; margin-top: 4px;
 | 
				
			||||||
 | 
					      box-sizing: border-box;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    button {
 | 
				
			||||||
 | 
					      margin-top: 1em; width: 100%; padding: 10px;
 | 
				
			||||||
 | 
					      background: #007bff; border: none; color: #fff;
 | 
				
			||||||
 | 
					      cursor: pointer; border-radius: 4px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					    .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					    .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					    .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    .flash-messages { margin-top: 10px; color: #b30000; text-align: center; }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>Login</h1>
 | 
				
			||||||
 | 
					    {% with messages = get_flashed_messages(category_filter=["danger","success","info"]) %}
 | 
				
			||||||
 | 
					      {% if messages %}
 | 
				
			||||||
 | 
					        <div class="flash-messages">
 | 
				
			||||||
 | 
					          {% for message in messages %}
 | 
				
			||||||
 | 
					            <p>{{ message }}</p>
 | 
				
			||||||
 | 
					          {% endfor %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      {% endif %}
 | 
				
			||||||
 | 
					    {% endwith %}
 | 
				
			||||||
 | 
					    <form method="POST" action="{{ url_for('login') }}">
 | 
				
			||||||
 | 
					      <label for="username">Username:</label>
 | 
				
			||||||
 | 
					      <input type="text" name="username" id="username" required />
 | 
				
			||||||
 | 
					      <label for="password">Password:</label>
 | 
				
			||||||
 | 
					      <input type="password" name="password" id="password" required />
 | 
				
			||||||
 | 
					      <button type="submit">Log In</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('register') }}">Register</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										35
									
								
								templates/new_edit_hosts_file.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								templates/new_edit_hosts_file.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>{% if file %}Edit /etc/hosts File{% else %}New /etc/hosts File{% endif %}</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body { font-family: Arial, sans-serif; background: #f1f1f1; padding: 20px; }
 | 
				
			||||||
 | 
					        .container { max-width: 600px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					        label { display: block; margin-top: 1em; }
 | 
				
			||||||
 | 
					        input[type="text"], textarea { width: 100%; padding: 8px; margin-top: 4px; box-sizing: border-box; }
 | 
				
			||||||
 | 
					        button { margin-top: 1em; padding: 10px 20px; background: #007bff; border: none; color: #fff; cursor: pointer; border-radius: 4px; }
 | 
				
			||||||
 | 
					        button:hover { background: #0056b3; }
 | 
				
			||||||
 | 
					        .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					        .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					        .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>{% if file %}Edit /etc/hosts File{% else %}New /etc/hosts File{% endif %}</h1>
 | 
				
			||||||
 | 
					    <form method="POST" action="">
 | 
				
			||||||
 | 
					        <label for="title">Name:</label>
 | 
				
			||||||
 | 
					        <input type="text" name="title" id="title" value="{% if file %}{{ file.title }}{% endif %}" required>
 | 
				
			||||||
 | 
					        <label for="content">Content:</label>
 | 
				
			||||||
 | 
					        <textarea name="content" id="content" rows="15" required>{% if file %}{{ file.content }}{% endif %}</textarea>
 | 
				
			||||||
 | 
					        <button type="submit">{% if file %}Save Changes{% else %}Create File{% endif %}</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					        <a href="{{ url_for('list_hosts_files') }}">Back to /etc/hosts Files</a> |
 | 
				
			||||||
 | 
					        <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										106
									
								
								templates/new_edit_regex_host.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								templates/new_edit_regex_host.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>{% if entry %}Edit{% else %}New{% endif %} Regex/CIDR Entry</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body {
 | 
				
			||||||
 | 
					            font-family: Arial, sans-serif;
 | 
				
			||||||
 | 
					            background: #f1f1f1;
 | 
				
			||||||
 | 
					            padding: 20px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .container {
 | 
				
			||||||
 | 
					            max-width: 500px;
 | 
				
			||||||
 | 
					            margin: 0 auto;
 | 
				
			||||||
 | 
					            background: #fff;
 | 
				
			||||||
 | 
					            padding: 20px;
 | 
				
			||||||
 | 
					            border-radius: 8px;
 | 
				
			||||||
 | 
					            box-shadow: 0 0 10px rgba(0,0,0,0.1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        h1 {
 | 
				
			||||||
 | 
					            text-align: center;
 | 
				
			||||||
 | 
					            margin-bottom: 1em;
 | 
				
			||||||
 | 
					            color: #333;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        label {
 | 
				
			||||||
 | 
					            display: block;
 | 
				
			||||||
 | 
					            margin-top: 1em;
 | 
				
			||||||
 | 
					            color: #555;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        input[type="text"] {
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					            padding: 8px;
 | 
				
			||||||
 | 
					            margin-top: 4px;
 | 
				
			||||||
 | 
					            box-sizing: border-box;
 | 
				
			||||||
 | 
					            border: 1px solid #ccc;
 | 
				
			||||||
 | 
					            border-radius: 4px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        button {
 | 
				
			||||||
 | 
					            margin-top: 1em;
 | 
				
			||||||
 | 
					            padding: 10px 20px;
 | 
				
			||||||
 | 
					            background: #007bff;
 | 
				
			||||||
 | 
					            border: none;
 | 
				
			||||||
 | 
					            color: #fff;
 | 
				
			||||||
 | 
					            cursor: pointer;
 | 
				
			||||||
 | 
					            border-radius: 4px;
 | 
				
			||||||
 | 
					            font-size: 1em;
 | 
				
			||||||
 | 
					            display: block;
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        button:hover {
 | 
				
			||||||
 | 
					            background: #0056b3;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .links { 
 | 
				
			||||||
 | 
					            text-align: center; 
 | 
				
			||||||
 | 
					            margin-top: 10px; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .links a {
 | 
				
			||||||
 | 
					            color: #007bff;
 | 
				
			||||||
 | 
					            text-decoration: none;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .links a:hover {
 | 
				
			||||||
 | 
					            text-decoration: underline;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .setting-group {
 | 
				
			||||||
 | 
					            margin-bottom: 1em;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .setting-group span {
 | 
				
			||||||
 | 
					            font-size: 0.9em;
 | 
				
			||||||
 | 
					            color: #888;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					        .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					        .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>{% if entry %}Edit{% else %}New{% endif %} CIDR Entry</h1>
 | 
				
			||||||
 | 
					    <form method="POST">
 | 
				
			||||||
 | 
					        <label>CIDR Range</label>
 | 
				
			||||||
 | 
					        <input type="text" name="cidr_range" value="{{ entry.cidr_range if entry else '' }}" required>
 | 
				
			||||||
 | 
					        <label>Gateway IP (option)</label>
 | 
				
			||||||
 | 
					        <input type="text" name="gateway_ip" value="{{ entry.gateway_ip if entry else '' }}">
 | 
				
			||||||
 | 
					        <label>Gateway Hostname (ex. gw)</label>
 | 
				
			||||||
 | 
					        <input type="text" name="gateway_hostname" value="{{ entry.gateway_hostname if entry else '' }}">
 | 
				
			||||||
 | 
					        <label>
 | 
				
			||||||
 | 
					            <input type="checkbox" name="use_gateway_ip" value="1"
 | 
				
			||||||
 | 
					                   {% if entry and entry.use_gateway_ip %}checked{% endif %}>
 | 
				
			||||||
 | 
					            Use separate hostname for gateway
 | 
				
			||||||
 | 
					        </label>
 | 
				
			||||||
 | 
					        <label>Domain Suffix (ex. guest.r.local)</label>
 | 
				
			||||||
 | 
					        <input type="text" name="domain_suffix" value="{{ entry.domain_suffix if entry else '' }}">
 | 
				
			||||||
 | 
					        <label>Host Prefix (ex. user)</label>
 | 
				
			||||||
 | 
					        <input type="text" name="host_prefix" value="{{ entry.host_prefix if entry else '' }}">
 | 
				
			||||||
 | 
					        <label>Comment (option)</label>
 | 
				
			||||||
 | 
					        <input type="text" name="comment" value="{{ entry.comment if entry else '' }}">
 | 
				
			||||||
 | 
					        <button type="submit">Save</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					        <a href="{{ url_for('list_regex_hosts') }}">Back to CIDR List</a> |
 | 
				
			||||||
 | 
					        <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										60
									
								
								templates/register.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								templates/register.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>Register</title>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body {
 | 
				
			||||||
 | 
					      font-family: Arial, sans-serif;
 | 
				
			||||||
 | 
					      margin: 0; padding: 0;
 | 
				
			||||||
 | 
					      display: flex; justify-content: center; align-items: center;
 | 
				
			||||||
 | 
					      height: 100vh; background: #f1f1f1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .container {
 | 
				
			||||||
 | 
					      max-width: 400px; width: 100%;
 | 
				
			||||||
 | 
					      background: #fff; padding: 20px;
 | 
				
			||||||
 | 
					      border-radius: 8px; box-shadow: 0 0 10px #ccc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    h1 { text-align: center; margin-bottom: 1em; }
 | 
				
			||||||
 | 
					    label { display: block; margin-top: 1em; }
 | 
				
			||||||
 | 
					    input[type="text"], input[type="password"] {
 | 
				
			||||||
 | 
					      width: 100%; padding: 8px; margin-top: 4px;
 | 
				
			||||||
 | 
					      box-sizing: border-box;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    button {
 | 
				
			||||||
 | 
					      margin-top: 1em; width: 100%; padding: 10px;
 | 
				
			||||||
 | 
					      background: #28a745; border: none; color: #fff;
 | 
				
			||||||
 | 
					      cursor: pointer; border-radius: 4px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    button:hover { background: #218838; }
 | 
				
			||||||
 | 
					    .links { text-align: center; margin-top: 10px; }
 | 
				
			||||||
 | 
					    .links a { color: #007bff; text-decoration: none; }
 | 
				
			||||||
 | 
					    .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					    .flash-messages { margin-top: 10px; color: #b30000; text-align: center; }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>Register</h1>
 | 
				
			||||||
 | 
					    {% with messages = get_flashed_messages(category_filter=["danger","success","info"]) %}
 | 
				
			||||||
 | 
					      {% if messages %}
 | 
				
			||||||
 | 
					        <div class="flash-messages">
 | 
				
			||||||
 | 
					          {% for message in messages %}
 | 
				
			||||||
 | 
					            <p>{{ message }}</p>
 | 
				
			||||||
 | 
					          {% endfor %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      {% endif %}
 | 
				
			||||||
 | 
					    {% endwith %}
 | 
				
			||||||
 | 
					    <form method="POST" action="{{ url_for('register') }}">
 | 
				
			||||||
 | 
					      <label for="username">Username:</label>
 | 
				
			||||||
 | 
					      <input type="text" name="username" id="username" required />
 | 
				
			||||||
 | 
					      <label for="password">Password:</label>
 | 
				
			||||||
 | 
					      <input type="password" name="password" id="password" required />
 | 
				
			||||||
 | 
					      <button type="submit">Register</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('login') }}">Go to Login</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										122
									
								
								templates/settings.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								templates/settings.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,122 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <title>Settings</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        body { 
 | 
				
			||||||
 | 
					            font-family: Arial, sans-serif; 
 | 
				
			||||||
 | 
					            background: #f1f1f1; 
 | 
				
			||||||
 | 
					            padding: 20px; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .container { 
 | 
				
			||||||
 | 
					            max-width: 500px; 
 | 
				
			||||||
 | 
					            margin: 0 auto; 
 | 
				
			||||||
 | 
					            background: #fff; 
 | 
				
			||||||
 | 
					            padding: 20px; 
 | 
				
			||||||
 | 
					            border-radius: 8px; 
 | 
				
			||||||
 | 
					            box-shadow: 0 0 10px rgba(0,0,0,0.1); 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        h1 { 
 | 
				
			||||||
 | 
					            text-align: center; 
 | 
				
			||||||
 | 
					            margin-bottom: 1em; 
 | 
				
			||||||
 | 
					            color: #333;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        label { 
 | 
				
			||||||
 | 
					            display: block; 
 | 
				
			||||||
 | 
					            margin-top: 1em; 
 | 
				
			||||||
 | 
					            color: #555;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        input[type="checkbox"] { 
 | 
				
			||||||
 | 
					            margin-right: 5px; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        input[type="number"] { 
 | 
				
			||||||
 | 
					            width: 100%; 
 | 
				
			||||||
 | 
					            padding: 8px; 
 | 
				
			||||||
 | 
					            margin-top: 4px; 
 | 
				
			||||||
 | 
					            box-sizing: border-box; 
 | 
				
			||||||
 | 
					            border: 1px solid #ccc; 
 | 
				
			||||||
 | 
					            border-radius: 4px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        button { 
 | 
				
			||||||
 | 
					            margin-top: 1em; 
 | 
				
			||||||
 | 
					            padding: 10px 20px; 
 | 
				
			||||||
 | 
					            background: #007bff; 
 | 
				
			||||||
 | 
					            border: none; 
 | 
				
			||||||
 | 
					            color: #fff; 
 | 
				
			||||||
 | 
					            cursor: pointer; 
 | 
				
			||||||
 | 
					            border-radius: 4px; 
 | 
				
			||||||
 | 
					            font-size: 1em;
 | 
				
			||||||
 | 
					            display: block; 
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        button:hover { 
 | 
				
			||||||
 | 
					            background: #0056b3; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .links { 
 | 
				
			||||||
 | 
					            text-align: center; 
 | 
				
			||||||
 | 
					            margin-top: 10px; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .links a { 
 | 
				
			||||||
 | 
					            color: #007bff; 
 | 
				
			||||||
 | 
					            text-decoration: none; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .links a:hover { 
 | 
				
			||||||
 | 
					            text-decoration: underline; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .setting-group {
 | 
				
			||||||
 | 
					            margin-bottom: 1em;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .setting-group span {
 | 
				
			||||||
 | 
					            font-size: 0.9em;
 | 
				
			||||||
 | 
					            color: #888;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					    <h1>Settings</h1>
 | 
				
			||||||
 | 
					    <form method="POST" action="{{ url_for('settings') }}">
 | 
				
			||||||
 | 
					        <div class="setting-group">
 | 
				
			||||||
 | 
					            <label>
 | 
				
			||||||
 | 
					                <input type="checkbox" name="auto_deploy" value="1" {% if settings.auto_deploy_enabled %}checked{% endif %}>
 | 
				
			||||||
 | 
					                Enable Automatic Deployments
 | 
				
			||||||
 | 
					            </label>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="setting-group">
 | 
				
			||||||
 | 
					            <label>
 | 
				
			||||||
 | 
					                Deploy Interval (minutes):
 | 
				
			||||||
 | 
					                <input type="number" name="deploy_interval" value="{{ settings.deploy_interval }}" min="1">
 | 
				
			||||||
 | 
					                <span>Time between automatic deployments</span>
 | 
				
			||||||
 | 
					            </label>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="setting-group">
 | 
				
			||||||
 | 
					            <label>
 | 
				
			||||||
 | 
					                Automatic Backup Interval (minutes):
 | 
				
			||||||
 | 
					                <input type="number" name="backup_interval" value="{{ settings.backup_interval }}" min="1">
 | 
				
			||||||
 | 
					                <span>Set interval for automatic backups</span>
 | 
				
			||||||
 | 
					            </label>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="setting-group">
 | 
				
			||||||
 | 
					            <label>
 | 
				
			||||||
 | 
					                Backup Retention (days):
 | 
				
			||||||
 | 
					                <input type="number" name="backup_retention_days" value="{{ settings.backup_retention_days or 0 }}" min="0">
 | 
				
			||||||
 | 
					                <span>Older backups will be automatically removed</span>
 | 
				
			||||||
 | 
					            </label>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="setting-group">
 | 
				
			||||||
 | 
					            <label>
 | 
				
			||||||
 | 
					                <input type="checkbox" name="enable_regex_entries" value="1"
 | 
				
			||||||
 | 
					                       {% if settings.regex_deploy_enabled %}checked{% endif %}>
 | 
				
			||||||
 | 
					                Enable Regex/CIDR Entries
 | 
				
			||||||
 | 
					            </label>
 | 
				
			||||||
 | 
					            <span>Include CIDR-based entries in final /etc/hosts deploy</span>
 | 
				
			||||||
 | 
					        </div>        
 | 
				
			||||||
 | 
					        <button type="submit">Save Settings</button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					        <a href="{{ url_for('dashboard') }}">Back to Dashboard</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										33
									
								
								templates/view_backup.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								templates/view_backup.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <title>View Backup</title>
 | 
				
			||||||
 | 
					  <style>
 | 
				
			||||||
 | 
					    body { font-family: Arial, sans-serif; background: #f1f1f1; margin: 0; padding: 20px; }
 | 
				
			||||||
 | 
					    .container { max-width: 800px; margin: auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px #ccc; }
 | 
				
			||||||
 | 
					    h1 { text-align: center; }
 | 
				
			||||||
 | 
					    pre { background: #eee; padding: 10px; border-radius: 4px; overflow: auto; }
 | 
				
			||||||
 | 
					    .links { text-align: center; margin-top: 20px; }
 | 
				
			||||||
 | 
					    .links a { color: #007bff; text-decoration: none; margin: 0 10px; }
 | 
				
			||||||
 | 
					    .links a:hover { text-decoration: underline; }
 | 
				
			||||||
 | 
					  </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					  <div class="container">
 | 
				
			||||||
 | 
					    <h1>Backup Preview</h1>
 | 
				
			||||||
 | 
					    {% if host %}
 | 
				
			||||||
 | 
					      <p><strong>Host:</strong> {{ host.hostname }} ({{ host.type }})</p>
 | 
				
			||||||
 | 
					    {% else %}
 | 
				
			||||||
 | 
					      <p><strong>Default configuration</strong></p>
 | 
				
			||||||
 | 
					    {% endif %}
 | 
				
			||||||
 | 
					    <p><strong>Description:</strong> {{ backup.description }}</p>
 | 
				
			||||||
 | 
					    <p><strong>Created at:</strong> {{ backup.created_at }}</p>
 | 
				
			||||||
 | 
					    <h2>Content:</h2>
 | 
				
			||||||
 | 
					    <pre>{{ backup.content }}</pre>
 | 
				
			||||||
 | 
					    <div class="links">
 | 
				
			||||||
 | 
					      <a href="{{ url_for('backups') }}">Back to Backups</a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user