Expand architecture documentation: add SMTP integration, external service descriptions (Keycloak, AD FS, Kerberos), and new Archimate components.
This commit is contained in:
parent
2ca8360388
commit
c5f95ee66f
@ -16,15 +16,16 @@
|
||||
| `app-summaries.md` | короткие описания компонентов прикладного слоя (1–3 предложения) | вход для сборки; попадает в поле `Documentation` модели |
|
||||
| `app-docs.md` | развёрнутые описания тех же компонентов | справочник; в модель по умолчанию не идёт |
|
||||
|
||||
80 элементов, 318 отношений, 23 представления.
|
||||
86 элементов, 331 отношение, 25 представлений.
|
||||
|
||||
| Представление | Что показывает |
|
||||
|---|---|
|
||||
| T1 | Кластер, ПО внутри него, внешние узлы, технологические сервисы. Без приложений — обзорная схема |
|
||||
| T2 | Развёртывание по узлам: какая группа узлов какие компоненты несёт |
|
||||
| T3 | Внешние интеграции: чем контур связан с инфраструктурой заказчика — каталог предприятия, брокер идентификации, служба федерации, почтовый релей |
|
||||
| A1 | Ядро прикладного слоя: восемь самых связанных сервисов и вызовы между ними |
|
||||
| A2–A12 | По представлению на сервис с тремя и более потребителями: кто от него зависит |
|
||||
| T15–T23 | По одному представлению на технологический сервис: кто им пользуется |
|
||||
| T16–T25 | По одному представлению на технологический сервис: кто им пользуется |
|
||||
|
||||
Направление связи — как принято в ArchiMate: стрелка идёт от вызываемого к вызывающему (serving). Читается как «кого лишишься — тот и сломается».
|
||||
|
||||
@ -69,6 +70,7 @@
|
||||
| Приложение → Redis | env `REDIS_HOST`, `REDIS__*` |
|
||||
| Приложение → Vault | аннотации `vault.hashicorp.com/agent-inject*` |
|
||||
| Приложение → Zitadel | env `ZITADEL*`, `JWKS`, `OIDC`, секрет `jwt-public` |
|
||||
| Приложение → почтовый релей | env `SMTP_*_HOST`, `SMTP__HOST`, `FROM_EMAIL`, `EMAIL_FROM` |
|
||||
| Приложение → Istio | `service:` в маршрутах `infrastructure/istio-config/<контур>/istio-config.yaml` (закомментированные не считаются) |
|
||||
| Приложение → приложение | адрес `<сервис>.<namespace>` в манифестах вызывающего; либо переменная `<APP>_URL` / `_HOST` / `_BASE_URL` / `_ENDPOINT` |
|
||||
|
||||
@ -81,6 +83,17 @@
|
||||
|
||||
`matrix.example.json` и `calls.example.json` — снимки. В них только имена приложений и флаги связей; идентификаторов контура нет.
|
||||
|
||||
**Внешние интеграции — исключение: они из манифестов не выводятся.** В репозитории нет ни каталога предприятия, ни службы федерации, ни центра выдачи билетов — это инфраструктура заказчика, и в модель они попадают из профиля контура, блок `external`. Проверять их надо не грепом, а у того, кто разворачивает контур. Схем подключения каталога четыре, и в конкретной инсталляции работает одна:
|
||||
|
||||
| Схема | Цепочка | Когда нужна |
|
||||
|---|---|---|
|
||||
| прямая | каталог → провайдер идентификации | каталог доступен по LDAPS и источник пользователей один |
|
||||
| с брокером | каталог → Keycloak → провайдер идентификации | источников несколько либо каталог опубликован по SAML |
|
||||
| с доменным входом | каталог + центр выдачи билетов → Keycloak → провайдер идентификации | нужен вход без повторного пароля для рабочих станций домена; проверку билета по SPNEGO умеет только брокер |
|
||||
| через федерацию | каталог → AD FS → провайдер идентификации | у заказчика уже есть федеративная служба как штатная точка входа |
|
||||
|
||||
В представлении T3 показаны все четыре сразу — при сборке модели для конкретного контура лишние узлы из профиля убираются. Keycloak поставляется и чартом платформы (`infrastructure/keycloak`), поэтому брокер может стоять как у заказчика, так и внутри контура.
|
||||
|
||||
Описания компонентов в `app-docs.md` и `app-summaries.md` выведены не из этого репозитория, а из исходного кода компонентных репозиториев, и потому проверяются иначе — чтением кода, а не грепом по манифестам. Там, где доказательств не хватило, это сказано в самом описании; такие места стоит подтверждать у команды платформы, а не считать фактом.
|
||||
|
||||
## Про формат файлов
|
||||
|
||||
@ -73,15 +73,19 @@ for n in PROFILE.get("camunda_sub", []):
|
||||
el(T, cid, "SystemSoftware", n["name"], n.get("doc", ""))
|
||||
R("Composition", "ss-camunda", cid); cam_ids.append(cid)
|
||||
|
||||
def serves_of(x):
|
||||
"""serves — id обслуживаемого элемента, либо список: у каталога предприятия
|
||||
их несколько (провайдер идентификации, брокер, служба федерации)."""
|
||||
s = x.get("serves")
|
||||
return [] if not s else ([s] if isinstance(s, str) else list(s))
|
||||
|
||||
for x in PROFILE["external"]:
|
||||
el(T, x["id"], "Node", x["name"], x.get("doc", ""))
|
||||
for a in x.get("artifacts", []):
|
||||
el(T, a["id"], "Artifact", a["name"])
|
||||
R("Composition", x["id"], a["id"])
|
||||
if x.get("serves") == "cluster":
|
||||
R("Serving", x["id"], nd_cluster)
|
||||
elif x.get("serves"):
|
||||
R("Serving", x["id"], x["serves"])
|
||||
for tgt in serves_of(x):
|
||||
R("Serving", x["id"], nd_cluster if tgt == "cluster" else tgt)
|
||||
|
||||
fn = PROFILE["frontend_node"]
|
||||
el(T, fn["id"], "Node", fn["name"], fn.get("doc", ""))
|
||||
@ -154,12 +158,13 @@ if len(ids) > 9:
|
||||
for i, cid in enumerate(cam_ids):
|
||||
obj(v1, cid, 10 + i * 174, 50, 162, 60, o_ss[ids[9]])
|
||||
|
||||
o_ext = {}
|
||||
for i, x in enumerate(PROFILE["external"]):
|
||||
o_ext, ext_y = {}, 140
|
||||
for x in PROFILE["external"]:
|
||||
h = 130 if x.get("artifacts") else 70
|
||||
o_ext[x["id"]] = obj(v1, x["id"], 1320, 140 + i * 90, 330, h)
|
||||
o_ext[x["id"]] = obj(v1, x["id"], 1320, ext_y, 330, h)
|
||||
for j, a in enumerate(x.get("artifacts", [])):
|
||||
obj(v1, a["id"], 15 + j * 155, 50, 145, 60, o_ext[x["id"]])
|
||||
ext_y += h + 20
|
||||
o_front = obj(v1, fn["id"], 20, 570, 300, 60)
|
||||
|
||||
for ts in SERVICES:
|
||||
@ -169,10 +174,9 @@ for ts in SERVICES:
|
||||
conn("Serving", o_ts[ts["id"]], o_ss[ts["serves_software"]])
|
||||
conn("Assignment", o_front, o_ss[fn["assigned_to"]])
|
||||
for x in PROFILE["external"]:
|
||||
if x.get("serves") == "cluster":
|
||||
conn("Serving", o_ext[x["id"]], o_cluster)
|
||||
elif x.get("serves"):
|
||||
conn("Serving", o_ext[x["id"]], o_ss[x["serves"]])
|
||||
for tgt in serves_of(x):
|
||||
to = o_cluster if tgt == "cluster" else (o_ss.get(tgt) or o_ext[tgt])
|
||||
conn("Serving", o_ext[x["id"]], to)
|
||||
|
||||
# --- представление «Развёртывание по узлам»
|
||||
GROUPS, EXTRA_USES = PROFILE.get("node_groups", []), {}
|
||||
@ -235,6 +239,21 @@ if GROUPS:
|
||||
for i, a in enumerate(big["_apps"]):
|
||||
obj(vd, app_id[a], 14 + (i % per) * bw, yy + (i // per) * 62, bw - 15, 50, og)
|
||||
|
||||
# --- представление «Внешние интеграции»
|
||||
IV = PROFILE.get("integration_view")
|
||||
if IV:
|
||||
vi = view(f"T{len(views)+1}. {IV['name']}", IV.get("doc", ""))
|
||||
CW, CH = 320, 110
|
||||
shown = {}
|
||||
for ci, col in enumerate(IV["columns"]):
|
||||
for ri, eid in enumerate(col):
|
||||
shown[eid] = obj(vi, eid, 20 + ci * (CW + 60), 20 + ri * CH, CW, 70)
|
||||
# связи не перечисляем: берём те, что уже есть в модели между показанными
|
||||
# элементами, — иначе представление начнёт расходиться с моделью
|
||||
for _rid, rtype, src, tgt in relations:
|
||||
if src in shown and tgt in shown:
|
||||
conn(rtype, shown[src], shown[tgt])
|
||||
|
||||
# --- прикладной слой: межсервисные вызовы
|
||||
if CALLS:
|
||||
import math, collections
|
||||
|
||||
@ -126,6 +126,40 @@
|
||||
"doc": "Собранные образы сервисов. Тег образа в манифесте контура — это и есть версия сервиса, работающая в этом контуре; обновление сервиса сводится к смене тега и синхронизации Flux."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "nd-smtp",
|
||||
"name": "smtp.example.com — почтовый релей",
|
||||
"realizes": "ts-mail",
|
||||
"doc": "SMTP — протокол передачи почты. Релей заказчика принимает исходящие сообщения от приложений контура и доставляет их адресатам; приложение аутентифицируется логином и паролем сервисной учётной записи, транспорт защищается TLS — либо сразу (порт 465), либо через STARTTLS (порт 587).\n\nЕдинственный канал, которым платформа по своей инициативе выходит за периметр: уведомления о назначенных задачах, замечаниях, запросах и отправленных трансмитталах. Адрес релея, порт и учётные данные задаются переменными окружения приложений. Отказ релея не останавливает работу платформы — перестают доходить только письма, и это стоит проверять первым при жалобах «уведомления не приходят»."
|
||||
},
|
||||
{
|
||||
"id": "nd-keycloak",
|
||||
"name": "Keycloak — брокер идентификации",
|
||||
"serves": "ss-zitadel",
|
||||
"doc": "Keycloak — открытый сервер управления доступом: поддерживает OIDC, OAuth 2.0 и SAML, умеет подтягивать пользователей из LDAP и Active Directory и принимать доменный вход по Kerberos (механизм SPNEGO). В схеме интеграции работает брокером: для платформы это обычный OIDC-провайдер, а в сторону предприятия — клиент корпоративного каталога.\n\nПоявляется в контуре там, где провайдер идентификации платформы не может обратиться к каталогу заказчика напрямую: нужен прозрачный доменный вход, источников пользователей несколько или каталог опубликован по SAML. Платформа поставляет чарт keycloak-contour, поэтому брокер может стоять как на стороне заказчика, так и внутри контура. Цена варианта — лишнее звено в цепочке входа: при недоступности брокера вход невозможен, даже если каталог и провайдер идентификации работают."
|
||||
},
|
||||
{
|
||||
"id": "nd-adfs",
|
||||
"name": "AD FS — служба федерации",
|
||||
"serves": "ss-zitadel",
|
||||
"doc": "Active Directory Federation Services — служба федерации Microsoft поверх домена Active Directory. Выдаёт токены по SAML 2.0, WS-Federation и OIDC, а проверку самих учётных данных оставляет домену.\n\nАльтернатива брокеру в тех контурах, где федеративная служба у заказчика уже развёрнута и является штатной точкой входа для корпоративных систем. Для платформы подключается как внешний провайдер идентификации: собственных учётных записей платформа при этом не заводит, а получает утверждения о пользователе от службы федерации."
|
||||
},
|
||||
{
|
||||
"id": "nd-ad",
|
||||
"name": "Active Directory — каталог предприятия",
|
||||
"serves": [
|
||||
"ss-zitadel",
|
||||
"nd-keycloak",
|
||||
"nd-adfs"
|
||||
],
|
||||
"doc": "Active Directory — служба каталогов Microsoft: хранит учётные записи, группы и организационную структуру предприятия и отвечает на запросы по LDAP (порт 389) и LDAPS (порт 636). Для предприятия это источник истины о сотрудниках.\n\nКаталог заказчика — то, откуда пользователи попадают в платформу. Схем подключения четыре: напрямую к провайдеру идентификации платформы по LDAPS; через брокер Keycloak; через брокер с доменным входом по Kerberos; через службу федерации AD FS. Выбор делается при развёртывании и определяет, какие из внешних узлов этой группы вообще появятся в контуре. Общее у всех четырёх одно: учётные записи платформа не заводит, а получает, поэтому отключение сотрудника в каталоге закрывает ему и доступ в платформу."
|
||||
},
|
||||
{
|
||||
"id": "nd-kerberos",
|
||||
"name": "Kerberos KDC — центр выдачи билетов",
|
||||
"serves": "nd-keycloak",
|
||||
"doc": "Kerberos — протокол сетевой аутентификации на билетах, встроенный в домен Active Directory. Центр выдачи билетов работает на контроллерах домена и слушает порт 88 по TCP и UDP.\n\nНужен только ради прозрачного входа: пользователь, уже вошедший в домен на рабочей станции, попадает в платформу без повторного ввода пароля. Билет проверяет брокер по механизму SPNEGO, поэтому сценарий с Kerberos всегда предполагает брокер в цепочке. Работает лишь для рабочих станций внутри домена — внешние подрядчики в этом же контуре входят обычным паролем."
|
||||
}
|
||||
],
|
||||
"frontend_node": {
|
||||
@ -208,6 +242,29 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"_интеграции": "Необязательное представление внешних интеграций. columns — колонки слева направо, элементы в колонке идут сверху вниз. Связи не задаются: рисуются те, что уже есть в модели между показанными элементами.",
|
||||
"integration_view": {
|
||||
"name": "Внешние интеграции",
|
||||
"doc": "Системы за периметром контура, с которыми платформа обменивается данными, и направление зависимости. Слева — технологические сервисы, которые видят приложения; справа — то, чем эти сервисы обеспечены на стороне заказчика.\n\nСхем подключения каталога предприятия четыре, и в конкретном контуре работает одна: каталог напрямую к провайдеру идентификации платформы; каталог через брокер Keycloak; то же с доменным входом по Kerberos, который умеет проверять только брокер; либо служба федерации AD FS поверх того же каталога. Здесь показаны все четыре сразу — при развёртывании лишние узлы из профиля убираются.",
|
||||
"columns": [
|
||||
[
|
||||
"ts-oidc",
|
||||
"ts-mail"
|
||||
],
|
||||
[
|
||||
"ss-zitadel",
|
||||
"nd-smtp"
|
||||
],
|
||||
[
|
||||
"nd-keycloak",
|
||||
"nd-adfs"
|
||||
],
|
||||
[
|
||||
"nd-ad",
|
||||
"nd-kerberos"
|
||||
]
|
||||
]
|
||||
},
|
||||
"services": [
|
||||
{
|
||||
"id": "ts-ingress",
|
||||
@ -300,6 +357,15 @@
|
||||
],
|
||||
"key": "s3",
|
||||
"doc": "Хранение и выдача файлов: документов, чертежей, моделей, вложений и производных представлений. Базовый сервис для всех документоориентированных областей платформы — в реляционных базах лежат только метаданные, содержимое всегда здесь."
|
||||
},
|
||||
{
|
||||
"id": "ts-mail",
|
||||
"name": "Отправка почтовых уведомлений",
|
||||
"realizers": [
|
||||
"nd-smtp"
|
||||
],
|
||||
"key": "smtp",
|
||||
"doc": "Отправка исходящей почты приложениями контура. Собственного почтового сервера платформа не содержит — сервис реализуется релеем заказчика. Через него уходят уведомления о назначенных задачах, замечаниях, запросах и отправленных трансмитталах."
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user