feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile
- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
This commit is contained in:
196
app/templates/pages/deploy/inventory.html
Normal file
196
app/templates/pages/deploy/inventory.html
Normal file
@@ -0,0 +1,196 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Inventory - DevOpsLab{% endblock %}
|
||||
{% block page_title %}Управление Inventory{% endblock %}
|
||||
|
||||
{% block header_actions %}
|
||||
<a href="/deploy" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-arrow-left me-2"></i>
|
||||
Назад к деплою
|
||||
</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<!-- Информация -->
|
||||
<div class="alert alert-info mb-3">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
<strong>Информация:</strong> Inventory файл определяет серверы для деплоя.
|
||||
Используйте стандартный формат Ansible inventory (INI или YAML).
|
||||
</div>
|
||||
|
||||
<!-- Редактор inventory -->
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">Редактор inventory/hosts.ini</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form
|
||||
id="inventory-form"
|
||||
hx-post="/api/v1/deploy/inventory"
|
||||
hx-target="#result"
|
||||
hx-swap="innerHTML"
|
||||
>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Содержимое inventory</label>
|
||||
<textarea
|
||||
id="inventory-editor"
|
||||
name="content"
|
||||
class="form-control"
|
||||
rows="20"
|
||||
placeholder="[webservers]
|
||||
web1 ansible_host=192.168.1.10 ansible_user=root
|
||||
web2 ansible_host=192.168.1.11 ansible_user=root
|
||||
|
||||
[database]
|
||||
db1 ansible_host=192.168.1.20 ansible_user=root
|
||||
|
||||
[all:vars]
|
||||
ansible_python_interpreter=/usr/bin/python3"
|
||||
>{{ inventory_content }}</textarea>
|
||||
<div class="form-text">
|
||||
<i class="fas fa-info-circle me-1"></i>
|
||||
Поддерживается формат INI и YAML. Редактор автоматически определит формат.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Результат -->
|
||||
<div id="result" class="mb-3"></div>
|
||||
|
||||
<!-- Кнопки -->
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save me-2"></i>
|
||||
Сохранить Inventory
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary" onclick="validateInventory()">
|
||||
<i class="fas fa-check me-2"></i>
|
||||
Проверить синтаксис
|
||||
</button>
|
||||
<a href="/deploy" class="btn btn-secondary">
|
||||
Отмена
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Примеры -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">Примеры Inventory</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-md-6">
|
||||
<h6 class="fw-semibold mb-2">Простой пример (INI)</h6>
|
||||
<pre class="bg-dark text-light p-3 rounded"><code>[webservers]
|
||||
web1 ansible_host=192.168.1.10
|
||||
web2 ansible_host=192.168.1.11
|
||||
|
||||
[database]
|
||||
db1 ansible_host=192.168.1.20
|
||||
|
||||
[all:vars]
|
||||
ansible_user=root
|
||||
ansible_python_interpreter=/usr/bin/python3</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6">
|
||||
<h6 class="fw-semibold mb-2">С SSH ключами (INI)</h6>
|
||||
<pre class="bg-dark text-light p-3 rounded"><code>[webservers]
|
||||
web1 ansible_host=192.168.1.10 ansible_ssh_private_key_file=~/.ssh/id_rsa
|
||||
web2 ansible_host=192.168.1.11 ansible_ssh_private_key_file=~/.ssh/id_rsa
|
||||
|
||||
[database]
|
||||
db1 ansible_host=192.168.1.20 ansible_ssh_private_key_file=~/.ssh/id_rsa
|
||||
|
||||
[all:vars]
|
||||
ansible_user=ubuntu
|
||||
ansible_python_interpreter=/usr/bin/python3</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<h6 class="fw-semibold mb-2">YAML формат</h6>
|
||||
<pre class="bg-dark text-light p-3 rounded"><code>all:
|
||||
children:
|
||||
webservers:
|
||||
hosts:
|
||||
web1:
|
||||
ansible_host: 192.168.1.10
|
||||
web2:
|
||||
ansible_host: 192.168.1.11
|
||||
database:
|
||||
hosts:
|
||||
db1:
|
||||
ansible_host: 192.168.1.20
|
||||
vars:
|
||||
ansible_user: root
|
||||
ansible_python_interpreter: /usr/bin/python3</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
if (typeof CodeMirror !== 'undefined') {
|
||||
const inventoryEditor = CodeMirror.fromTextArea(
|
||||
document.getElementById('inventory-editor'),
|
||||
{
|
||||
mode: 'yaml', // Начинаем с YAML, но можно переключить на INI
|
||||
theme: 'monokai',
|
||||
lineNumbers: true,
|
||||
indentUnit: 2,
|
||||
lineWrapping: true,
|
||||
autofocus: true
|
||||
}
|
||||
);
|
||||
|
||||
// Определяем формат по содержимому
|
||||
const content = inventoryEditor.getValue();
|
||||
if (content.trim().startsWith('[') || content.includes('ansible_host=')) {
|
||||
// Это INI формат
|
||||
inventoryEditor.setOption('mode', 'ini');
|
||||
}
|
||||
|
||||
// Обновляем textarea перед отправкой формы
|
||||
document.getElementById('inventory-form').addEventListener('submit', function() {
|
||||
inventoryEditor.save();
|
||||
});
|
||||
|
||||
// Сохраняем editor в глобальной переменной для доступа из других функций
|
||||
window.inventoryEditor = inventoryEditor;
|
||||
}
|
||||
});
|
||||
|
||||
function validateInventory() {
|
||||
const editor = window.inventoryEditor;
|
||||
if (!editor) {
|
||||
alert('Редактор не инициализирован');
|
||||
return;
|
||||
}
|
||||
|
||||
const content = editor.getValue();
|
||||
|
||||
// Простая валидация
|
||||
if (!content.trim()) {
|
||||
alert('Inventory пуст');
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем наличие групп
|
||||
if (content.includes('[') && !content.match(/\[.*\]/)) {
|
||||
alert('⚠️ Предупреждение: Не найдено групп в формате [group_name]');
|
||||
return;
|
||||
}
|
||||
|
||||
alert('✅ Синтаксис inventory корректен');
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user