Обзор — что делает этот экран
Проекты — это реестр, который собирает метаданные всех проектов вашей команды в одном общем месте. Для каждого проекта вы регистрируете его репозиторий исходного кода (GitHub и т. п.), конвейер CI/CD (Jenkins), используемые им веб-службы и базы данных, цели резервного копирования и — что особенно важно — где хранятся его секреты. После этого любой участник команды может с одного взгляда ответить: «из чего состоит этот проект, куда он развёртывается и какой секрет где лежит?»
Этот экран не является инструментом развёртывания. Реальные сборки и развёртывания выполняются в Jenkins. InfraGuard не запускает отсюда ни одного конвейера; зарегистрированные данные — это общая документация. Сохраняемые URL, имена Job и ветки служат лишь справочными ссылками и подписями — ничего не выполняется.
Ключевые принципы устройства:
- Значения секретов никогда не хранятся здесь в открытом виде. Фактические значения паролей, токенов и ключей тут не содержатся. Вместо этого вы либо (1) ссылаетесь на ключ, хранящийся в хранилище инвентаря (
infr_vault_key), либо (2) фиксируете только «какой секрет где лежит» в маскированном контрольном списке. - Всё редактируется в одном модальном окне с вкладками (Обзор · Исходный код · CI/CD · Связи · Резервное копирование · Секреты).
- Создание, изменение и удаление, а также показ значений из хранилища записываются в журнал аудита (
infr_audit_log).
Когда использовать
- При вводе в курс дела нового коллеги, которому нужно быстро понять: «какой у этого проекта репозиторий, URL развёртывания и база данных?»
- Чтобы разложить зависимости web/db каждого проекта и мгновенно оценивать радиус поражения во время инцидента.
- Чтобы документировать карту секретов, от которых зависит проект (какой ключ где лежит, какая запись хранилища относится к этому проекту).
- Чтобы фиксировать цели и периодичность резервного копирования как метаданные проекта, увязанные с вашей политикой резервного копирования.
Компоновка
Полоса KPI
| Ячейка | Значение |
|---|---|
| Проекты | Всего зарегистрированных проектов |
| Внешние | Проекты с accessible=1 (есть внешний URL) |
| Внутренние | Проекты с accessible=0 (только внутренние, наружу не открыты) |
| В архиве | Проекты со status=archived |
Карточки проектов
На каждой карточке отображаются:
- Значок и название — доступные извне проекты используют
mdi-web, только внутренние —mdi-folder-lock-outline. - Ссылка URL — если задан
accessibleи есть URL, показывается ссылка, открывающаяся в новой вкладке; иначе — значокinternal. - Значок состояния — active / paused / archived.
- Однострочная сводка.
- Чипы состава — показываются только зарегистрированные элементы: Исходный код · Jenkins · Среды N · Веб N · БД N · Резервные копии N · Секреты N.
- Метка группы (категория) и кнопки редактирования/удаления (если у вас есть право записи).
Окно редактирования (6 вкладок)
Широкое модальное окно (.infr-modal__panel--wide), в котором ввод разнесён по вкладкам.
| Вкладка | Поля ввода |
|---|---|
| Обзор | Название (обязательно) · Ключ (slug) · Состояние · Группа · Переключатель внешнего доступа · URL · Сводка · Теги |
| Исходный код | Поставщик репозитория (GitHub/GitLab/Gitea/Bitbucket/Другой) · URL репозитория · Ветка по умолчанию · Видимость (public/private/internal) |
| CI/CD | URL Jenkins и повторитель сред (для каждой из dev/staging/prod: URL развёртывания · ветка · Job Jenkins · заметка) |
| Связи | Флажки веб-служб (зарегистрированные infr_web_service) и флажки БД (коллектор) (коллекторы с access=database) |
| Резервное копирование | Повторитель целей резервного копирования (вид · цель · расписание · заметка) |
| Секреты | Ссылки на ключи хранилища (отметить и показать значение) и повторитель контрольного списка секретов (элемент · расположение · ссылка · заметка) |
Как пользоваться
Зарегистрировать проект
- Нажмите [Добавить проект] в правом верхнем углу (требуется право записи).
- На вкладке Обзор введите название (обязательно). Ключ (slug) необязателен и должен соответствовать
^[a-z0-9_-]+$(например,coin-market). - Если служба достижима извне, включите переключатель Доступен извне и введите её URL. Для сугубо внутренних проектов оставьте его выключенным — поле URL при этом заблокировано.
- Заполните остальные вкладки (Исходный код, CI/CD, Связи, Резервное копирование, Секреты) по необходимости — все они необязательны.
- [Сохранить] — сервер выполняет проверку, делает upsert в
infr_projectи обновляет карточку.
Зарегистрировать среды CI/CD
На вкладке CI/CD введите URL Jenkins, затем кнопкой [Добавить среду] добавляйте цели развёртывания построчно:
{
"env": "prod",
"url": "https://coin.example.com",
"branch": "main",
"jenkins_job": "coin_market-deploy-prod",
"note": "blue/green"
}
envпринимает только значения из белого спискаdev/staging/prod(любое другое значение сервер принудительно заменяет наdev).- Каждое строковое поле обрезается по длине (URL 255 · ветка 120 · Job 191 · заметка 255).
- Не более 20 сред.
Связать web/db
На вкладке Связи отметьте ресурсы, которые использует этот проект.
- Веб-службы — выбираются из списка
infr_web_service(название · домен), зарегистрированных в разделе Сервисы ▸ Веб. Сохраняются как массив id web_service. - БД (коллектор) — массив ключей коллекторов, зарегистрированных с access=database (Администрирование ▸ Коллекторы / Сервисы ▸ База данных).
Каждая связь вмещает до 50 записей.
Объявить цели резервного копирования
С помощью повторителя на вкладке Резервное копирование задокументируйте политику резервного копирования этого проекта (вид · цель · расписание · заметка). Это справочные метаданные, они не исполняются — реальные задания резервного копирования управляются на Доске расписания.
Управление конфиденциальными сведениями (ключевая функция)
Для секретов совместно работают два механизма. Ни один из них не сохраняет настоящее значение секрета в infr_project.
1) Ссылки на ключи хранилища (vault_key_ids)
- На вкладке Секреты отметьте ключи из хранилища инвентаря (Активы ▸ Инвентарь ▸ Хранилище ключей,
infr_vault_key), чтобы связать их с проектом. - Список передаётся в маскированном виде (только id · категория · заголовок · имя пользователя — без значения).
- Нажатие [Показать] для связанного ключа вызывает
POST /service/projects/vault-reveal, который расшифровывает значение только в этот момент и возвращает его.
Показ значений хранилища фиксируется в аудите. При каждом показе в
infr_audit_logзаписываетсяvault_key.reveal(target=vault_key, via=project). Значение отображается ненадолго и по щелчку копируется в буфер обмена — показывайте его только тогда, когда он действительно нужен. Сохранённая запись проекта содержит лишь ссылку на id ключа.
2) Контрольный список секретов (secrets, маскированный)
Для секретов, которых нет в хранилище (или которые хранятся во внешней системе), фиксируйте только расположение. Значение не сохраняется никогда.
| Поле | Пример |
|---|---|
label |
STRIPE_SECRET_KEY |
location |
.env (prod server /var/www) |
ref |
1Password › Coin › prod |
note |
rotate quarterly |
Серверная функция cleanList() оставляет только разрешённые ключи (label/location/ref/note) и обрезает каждый до 255 символов. Если все четыре поля пусты, строка отбрасывается.
Удаление
Удаляйте из левого нижнего угла окна редактирования или кнопкой [Удалить] на карточке. После подтверждения POST /service/projects/delete удаляет строку infr_project и записывает project.delete.
Источники данных
| Данные | Источник |
|---|---|
| Записи проектов | infr_project (миграция 000715) |
| Группы (категории) | infr_asset_group (через group_id) |
| Варианты веб-служб | infr_web_service (название · домен) |
| Варианты БД (коллектор) | infr_collector с access=database (key · title · host_alias) |
| Варианты ключей хранилища | infr_vault_key — маскированные (id · категория · заголовок · имя пользователя, без значения) |
| Показ значения хранилища | infr_vault_key.revealSecret() (расшифровка, только при показе) |
| Журнал аудита | infr_audit_log (project.create/update/delete, vault_key.reveal) |
Схема хранения (infr_project, фрагмент)
key varchar(60) unique nullable # slug
group_id int -> infr_asset_group
name varchar(160) # обязательное
status enum(active,paused,archived)
accessible boolean default 1
url varchar(255) # открыт наружу, когда accessible=1
summary text
repo_provider enum(github,gitlab,gitea,bitbucket,other)
repo_url / default_branch / visibility(public,private,internal)
jenkins_url varchar(255)
environments json [{env,url,branch,jenkins_job,note}]
web_refs json -> infr_web_service id array
db_refs json -> infr_collector(database) key array
backup_targets json [{kind,target,schedule,note}]
vault_key_ids json -> infr_vault_key id array (values stay in the vault)
secrets json [{label,location,ref,note}] # контрольный список, значения не хранятся
tags / meta json
Этот экран не опрашивает данные в реальном времени. Список перезагружается только при сохранении, удалении или по кнопке обновления (
GET /service/projects/list). Состояние в реальном времени обеспечивают Сервисы ▸ Каталог и Сервисы ▸ Веб.
Доступ
| Действие | Маршрут | Минимальный уровень |
|---|---|---|
| Чтение (index/list) | GET /service/projects, /list |
1 (demo, infr.auth) |
| Показать значение хранилища | POST /service/projects/vault-reveal |
1 (+ аудит) |
| Сохранение (создание/изменение) | POST /service/projects/save |
2 (staff) |
| Удаление | POST /service/projects/delete |
2 (staff) |
- Проверка на запись сверяет
infr_user_level >= 2в сессии (canWrite()). При неудаче возвращается403иproject.err.forbidden. - При сохранении
vault_key_idsфильтруется так, чтобы остались только реально существующие id ключей хранилища (проверка существования черезInfrVaultKey::whereIn(...)). Поддельные id молча отбрасываются. - Уровни таковы: demo=1 · staff=5 · admin=10; отдельные области дополнительно закрыты промежуточным слоем
infr.level:N.
Устранение неполадок и частые вопросы
Q. Нажимаю «Сохранить» и получаю 403. Для записи нужен уровень 2 или выше. Учётная запись только для просмотра (уровень 1) может лишь читать и показывать значения хранилища. Попросите администратора повысить ваш уровень.
Q. [Показать] возвращает пустое значение.
Либо в этой записи хранилища нет секрета (hasSecret=false), либо не удалась расшифровка (например, изменился APP_KEY). Задайте значение заново в разделе Инвентарь ▸ Хранилище ключей. При ошибке revealSecret() возвращает null.
Q. В списках связей с веб/БД ничего нет. Веб-службы сначала должны существовать в разделе Сервисы ▸ Веб, а для вариантов БД нужны коллекторы с access=database. Зарегистрируйте их, затем снова откройте окно проекта — варианты появятся.
Q. При сохранении ключа (slug) возникает ошибка формата.
В ключе допустимы только строчные буквы, цифры, дефисы и подчёркивания (^[a-z0-9_-]+$, не более 60 символов). Уберите пробелы, заглавные буквы и прочие символы. Ключ необязателен, поэтому его можно оставить пустым.
Q. Могу ли я запустить отсюда развёртывание? Нет. Развёртывания выполняются в Jenkins. Этот экран хранит URL Jenkins и имена Job исключительно как документацию.
Q. Можно ли просто вписать значение секрета в заметку о секрете?
Ни в коем случае. secrets — это карта расположений, не хранящая значений. Поместите настоящее значение в зашифрованное хранилище Инвентарь ▸ Хранилище ключей и сошлитесь на него через vault_key_ids.
Смежные разделы
- Сервисы ▸ Веб — веб-службы, связанные через
web_refs. - Сервисы ▸ База данных — коллекторы БД, связанные через
db_refs. - Сервисы ▸ Каталог — живучесть демонов по инстансам (состояние в реальном времени находится там).
- Доска расписания — определение и запуск реальных заданий резервного копирования.
- Активы ▸ Инвентарь — исходный экран для ключей хранилища (
infr_vault_key). - Журнал аудита — проверьте записи project.create/update/delete и vault_key.reveal.
