Documentation
¶
Overview ¶
Пакет iamctl — инструмент оператора над каталогом прав модуля: пять действий, не двенадцать (задача #1036).
validate форма манифестов дерева — без базы и сети, годится в pre-commit plan что применение СДЕЛАЛО БЫ: последствия числом плюс отпечаток apply применение под подтверждаемый отпечаток export действующий каталог, с НАЗВАННЫМ источником doctor разбор состояния предикатом, а не мнением
Инструмент — КЛИЕНТ платформы, а не её часть ¶
Ни одно действие не повторяет логику, у которой уже есть производитель:
validate → services/iam/internal/manifestcheckrun (тот же исполнитель, что
у сборочной цели module-manifest-check)
plan → InternalModuleService/Plan
apply → InternalModuleService/Apply
export → InternalModuleService/List + /Get
doctor → композиция List и Plan; своей проверки не заводит
В базу инструмент не ходит и решений службы не воспроизводит: план и применение — её глаголы. Вторая реализация любого из них разошлась бы со службой молча и выдавала бы разрешение, которого служба не подтвердит.
Исходов ЧЕТЫРЕ, и третий не вычитается из вердикта ¶
0 годно 1 находка — вердикт о предмете получен, и он отрицательный 2 VOID — предмета нет: проверять и выгружать нечего 3 НЕ ИСПОЛНЯЛОСЬ — вердикта не получено вовсе
Разведение находки и «не выполнилось» здесь несущее: недоступность службы, невыданное право и устаревший образ — НЕ вердикты о манифесте, и объявить их находкой значило бы приписать дереву чужое состояние. Полосу выбирает classifyRefusal, и правило у неё одно: получен ли вердикт О ПРЕДМЕТЕ.
Всякий отказ называет СЛЕДУЮЩИЙ ШАГ ¶
Связывающее требование продукта: отказ, не восстанавливающий следующий шаг клиента, — находка. Поэтому у каждого отказа здесь есть строка «что сделать», и она называет команду либо место починки, а не «обратитесь к администратору».
Index ¶
Constants ¶
const ( ExitOK = 0 ExitFinding = 1 ExitVoid = 2 ExitNotRun = 3 )
Коды возврата. Смысл каждого — в комментарии пакета.
Variables ¶
This section is empty.
Functions ¶
func Connector ¶
func Connector(cfg DialConfig) func(context.Context) (ModuleService, func() error, error)
Connector отдаёт Deps.Connect поверх сгенерированного клиента.
Посадка проверяется ВНУТРИ замыкания, а не при сборке: validate обязан работать там, где ни адреса, ни сертификатов нет вовсе, и разбор посадки на старте отнял бы у него эту способность.
Types ¶
type Deps ¶
type Deps struct {
// Connect — соединение со службой. Зовётся ТОЛЬКО теми действиями, которым
// служба нужна: validate обязан работать там, где сети нет вовсе.
Connect func(ctx context.Context) (ModuleService, func() error, error)
// Validate — локальная проверка дерева. Порт, а не прямой вызов: проба
// инструмента не должна обходить дерево, чтобы судить разбор аргументов.
// Единственный производитель — manifestcheckrun.Run.
Validate func(root string, stdout, stderr io.Writer) int
// Endpoint — адрес службы. Называется в отказах соединения: «сосед не
// ответил» без адреса не восстанавливает следующий шаг.
Endpoint string
}
Deps — что вносит композиционный корень.
type DialConfig ¶
type DialConfig struct {
// Endpoint — адрес ВНУТРЕННЕГО слушателя iam. Глаголы каталога модуля
// внешним маршрутизатором не обслуживаются by construction.
Endpoint string
// ServerName сверяется с SAN сертификата службы.
ServerName string
// CAFiles — корни доверия, которыми проверяется сертификат службы.
CAFiles []string
// CertFile, KeyFile — СВОЁ удостоверение: служба принимает решение по
// личности вызывающего, а не по факту достижимости.
CertFile string
KeyFile string
// Timeout — срок КАЖДОГО вызова. Без него неотвечающий сосед вешает
// инструмент навсегда.
Timeout time.Duration
}
DialConfig — что нужно, чтобы дойти до службы применения.
func (DialConfig) Validate ¶
func (c DialConfig) Validate() error
Validate — fail-closed разбор посадки: неполная пара не доезжает до сети.
Отказ называет ФЛАГ, а не поле структуры: читает его оператор, а не тот, кто правит эту строку.
type ModuleService ¶
type ModuleService interface {
Plan(ctx context.Context, in *iamv1.PlanModuleRequest) (*iamv1.PlanModuleResponse, error)
Apply(ctx context.Context, in *iamv1.ApplyModuleRequest) (*operationv1.Operation, error)
Get(ctx context.Context, in *iamv1.GetModuleRequest) (*iamv1.ModuleCatalog, error)
List(ctx context.Context, in *iamv1.ListModulesRequest) (*iamv1.ListModulesResponse, error)
}
ModuleService — порт службы применения. Ровно четыре её глагола и ни одного своего: инструмент вправе звать службу, но не вправе решать за неё.
Реализация — сгенерированный gRPC-клиент (её вносит композиционный корень); в пробах — дублёр, отдающий те же коды и те же сообщения контракта.