Files
Bridge-and-Join-s/deploy/linux/sbin/bj-igate-admin
T

311 lines
23 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# bj-igate-admin — установка и настройка интеграционного шлюза НРД (ИШ, igate) без графики.
# Вызывает root-демон bj-keymedia по запросу из bj (мастер, шаг «Шлюз НРД»); параметры — JSON в BJ_EXTRA.
# status — JSON: версия, служба, движок, каналы (контуры)
# install — установить или обновить ИШ из дистрибутива НРД (в фоне; ход — /var/lib/bj/igate-install-status.json)
# BJ_EXTRA: {"file": "<путь к igate-*.zip|.deb>"}, {"version": "107.0.930"} — скачать с nsd.ru,
# или {"bundled": "1"} — дистрибутив с образа (/var/lib/bj/igate-dist), без интернета
# install-now — сама установка (запускается через systemd-run)
# contour — создать или обновить канал контура и перезапустить ИШ
# BJ_EXTRA: {"contour": "test3|prod", "crypto": "gost|rsa", "deponent": "MC…", "profile": "<профиль Валидаты>"}
#
# ИШ 107 без графики (проверено 19.08.2026, см. deploy/ish/upgrade-ish-v107.sh): пароли — в gnome-keyring
# (разблокируется паролем из файла), движок — под xvfb-run, сессионная шина — dbus-run-session; настройки
# ИШ — в PostgreSQL (channels + parameters), канал ищется по составному коду <канал><депозитарный код>.
set -uo pipefail
IGATE_DIR=/opt/nsd/igate
SVC_USER=igate
HOME_DIR=/var/lib/igate
DB=${BJ_IGATE_DB:-igate} # переопределение — только для проверки на копии базы
DATA_DIR="$HOME_DIR/.local/share/NSD Integration Gateway"
WRAPPER=/usr/local/bin/igate-run.sh
UNIT=/etc/systemd/system/igate.service
STATUS=/var/lib/bj/igate-install-status.json
PARAMS=/run/bj-igate-install.json
WEB=http://localhost:8090
cmd=${1:-}
j() { python3 -c "import json,os,sys;print(json.loads(os.environ.get('BJ_EXTRA') or '{}').get(sys.argv[1],''))" "$1"; }
q() { python3 -c "import json,sys;print(json.dumps(sys.argv[1],ensure_ascii=False))" "$1"; }
ok() { echo "{\"ok\":true,\"output\":$(q "$1")}"; }
err() { echo "{\"ok\":false,\"error\":$(q "$1")}"; exit 0; }
psqlq() { (cd /tmp && runuser -u postgres -- psql -d "$DB" -v ON_ERROR_STOP=1 -qtA "$@"); }
# Адреса и отпечатки УЦ контуров НРД — «Обновление ИШ до версии 107» (НРД), разделы 1.1 и 1.2.
contour_params() { # contour crypto → CODE|NAME|ENDPOINT|FINGERPRINT|TYPE
case "$1-$2" in
test3-gost) echo "TEST3|TEST3 GOST|https://gost-t3.nsd.ru/onyx-ms|EB:C2:D6:CA:73:AC:22:69:44:09:07:ED:6A:58:2C:4E:55:29:5D:00:F8:0F:1D:1E:70:A0:85:25:32:0D:DC:BF|GOST" ;;
test3-rsa) echo "TEST3|TEST3 RSA|https://rsa-t3.nsd.ru/onyx-ms|5D:75:60:87:AA:1E:8D:E2:FA:F8:AF:DB:B0:43:FF:BD:E3:3C:B7:50|RSA" ;;
prod-gost) echo "PROD|PROD GOST|https://edog.nsd.ru/onyx|58:C6:77:5B:20:29:AE:CA:C0:5A:1C:6D:E2:72:4B:C4:C7:CC:45:3B:EB:07:E5:D1:1E:55:0C:FB:EC:1B:D4:8A|GOST" ;;
prod-rsa) echo "PROD|PROD RSA|https://edor.nsd.ru/onyx|C2:E1:6F:FB:5F:EF:2C:72:C4:F6:4A:07:24:87:B6:3F:ED:8D:DD:E9|RSA" ;;
*) return 1 ;;
esac
}
exchange_dir() { case "$1" in prod) echo "$HOME_DIR/exchange-prod" ;; *) echo "$HOME_DIR/exchange" ;; esac; }
igate_version() {
python3 - "$IGATE_DIR/igate-svc/igate-svc.deps.json" "$IGATE_DIR/igate/igate.deps.json" <<'PY' 2>/dev/null
import json,sys
for p in sys.argv[1:]:
try:
libs=json.load(open(p))['libraries']
for k in libs:
n,_,v=k.partition('/')
if n.lower() in ('igate','igate-svc','igate.svc'):
print(v); sys.exit(0)
except Exception: pass
PY
}
engine_state() { curl -s -m 4 "$WEB/api/admin/engine/state" 2>/dev/null | tr -d '"'; }
wait_engine() { # секунд
for _ in $(seq 1 $(( $1 / 3 ))); do
[ "$(engine_state)" = Running ] && return 0
sleep 3
done
return 1
}
run_as_igate_keyring() { # команда в сессии igate с разблокированным keyring (для igate-cli / igate-mig)
local uid; uid=$(id -u "$SVC_USER")
runuser -u "$SVC_USER" -- env HOME="$HOME_DIR" XDG_DATA_HOME="$HOME_DIR/.local/share" XDG_RUNTIME_DIR="/run/user/$uid" GIO_USE_VFS=local \
dbus-run-session -- bash -c 'eval "$(printf "%s\n" "$(cat "$HOME/.keyring-pass")" | gnome-keyring-daemon --replace --unlock --components=secrets,pkcs11 2>/dev/null)"; export GNOME_KEYRING_CONTROL; '"$1"
}
case "$cmd" in
status)
inst=false; [ -x "$IGATE_DIR/igate-svc/igate-svc" ] && inst=true
svc=$(systemctl is-active igate 2>/dev/null); st=$(engine_state)
chans="[]"
if runuser -u postgres -- psql -lqt 2>/dev/null | cut -d'|' -f1 | grep -qw "$DB"; then
chans=$(psqlq -c "select coalesce(json_agg(json_build_object('id',c.id,'code',c.code,'enabled',c.enable,
'endpoint',(select value from parameters p where p.chanel_id=c.id and p.name='wslEndpoint'),
'profile',(select value from parameters p where p.chanel_id=c.id and p.name='cryptography.profile'),
'crypto',(select value from parameters p where p.chanel_id=c.id and p.name='cryptography.type'),
'deponent',(select value from parameters p where p.chanel_id=c.id and p.name='repositoryCode'),
'dir',(select value from parameters p where p.chanel_id=c.id and p.name='dir')) order by c.id),'[]') from channels c" 2>/dev/null || echo "[]")
fi
echo "{\"ok\":true,\"installed\":$inst,\"version\":$(q "$(igate_version)"),\"service\":$(q "$svc"),\"engine\":$(q "$st"),\"channels\":${chans:-[]}}" ;;
install)
pgrep -f "bj-igate-admin install-now" >/dev/null && err "установка ИШ уже идёт"
file=$(j file); ver=$(j version)
[ "$(j bundled)" = 1 ] && [ -z "$file$ver" ] && { file=$(ls /var/lib/bj/igate-dist/igate-*-amd64.zip 2>/dev/null | sort -V | tail -1); [ -n "$file" ] || err "в образе нет дистрибутива ИШ"; BJ_EXTRA="{\"file\":\"$file\"}"; }
[ -n "$file$ver" ] || err "не указан дистрибутив ИШ (файл или версия)"
[ -z "$file" ] || [ -f "$file" ] || err "файл дистрибутива не найден: $file"
[[ -z "$ver" || "$ver" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || err "версия ИШ — вида 107.0.930"
(umask 077; printf '%s' "${BJ_EXTRA:-}" > "$PARAMS")
echo '{"stage":"start","msg":"установка запущена"}' > "$STATUS"; chown bj:bj "$STATUS" 2>/dev/null
systemd-run --unit="bj-igate-install-$(date +%s)" --collect /usr/local/sbin/bj-igate-admin install-now >/dev/null 2>&1 || err "не удалось запустить установку"
ok "установка ИШ запущена" ;;
install-now)
BJ_EXTRA=$(cat "$PARAMS" 2>/dev/null); export BJ_EXTRA="${BJ_EXTRA:-{\}}"; rm -f "$PARAMS"
LOG=/var/log/bj-igate-install.log; : > "$LOG"
st() { python3 - "$STATUS" "$1" "$2" "$LOG" <<'PY'
import json,sys,datetime
tail=open(sys.argv[4],errors='replace').read()[-1500:]
json.dump({"at":datetime.datetime.now().astimezone().isoformat(timespec="seconds"),"stage":sys.argv[2],"msg":sys.argv[3],"log":tail},open(sys.argv[1],"w"),ensure_ascii=False)
PY
chown bj:bj "$STATUS" 2>/dev/null; echo "== $2" >> "$LOG"; }
die() { st error "$1"; exit 1; }
exec >>"$LOG" 2>&1
W=$(mktemp -d /var/tmp/bj-igate.XXXXXX); trap 'rm -rf "$W"' EXIT
st deps "системные пакеты для работы ИШ без графики"
need=""
for p in gnome-keyring dbus xvfb xauth libsecret-tools unzip curl; do dpkg -s "$p" >/dev/null 2>&1 || need="$need $p"; done
if [ -n "$need" ]; then
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends $need || \
{ DEBIAN_FRONTEND=noninteractive apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends $need; } || die "не удалось установить пакеты:$need"
fi
st package "дистрибутив ИШ"
file=$(j file); ver=$(j version)
if [ -z "$file" ]; then
v=$(printf '%s' "$ver" | tr . -)
url="https://www.nsd.ru/media/integratsionnyj-shlyuz/$v/igate-$v-amd64.zip"
echo "скачивание $url"
curl -fsSL -m 600 -A 'Mozilla/5.0 (X11; Linux x86_64) bj-installer' -H 'Accept: */*' -o "$W/igate.zip" "$url" || die "не удалось скачать дистрибутив ИШ $ver с сайта НРД ($url)"
file="$W/igate.zip"
fi
case "$file" in
*.deb) deb="$file" ;;
*) unzip -o -q "$file" -d "$W/x" || die "архив дистрибутива не распаковывается"; deb=$(find "$W/x" -name 'igate_*.deb' | head -1) ;;
esac
[ -n "$deb" ] && [ -f "$deb" ] || die "в дистрибутиве нет пакета igate_*.deb"
echo "пакет $(basename "$deb"), версия $(dpkg-deb -f "$deb" Version), sha256 $(sha256sum "$deb" | cut -c1-16)…"
st user "пользователь igate и хранилище паролей"
id "$SVC_USER" >/dev/null 2>&1 || useradd --system --home-dir "$HOME_DIR" --create-home --shell /usr/sbin/nologin "$SVC_USER" || die "не создать пользователя igate"
install -d -o "$SVC_USER" -g "$SVC_USER" -m 755 "$HOME_DIR" "$HOME_DIR/.local" "$HOME_DIR/.local/share" "$DATA_DIR" "$HOME_DIR/profiles" "$HOME_DIR/.Validata" "$(exchange_dir test3)"
uid=$(id -u "$SVC_USER")
loginctl enable-linger "$SVC_USER" >/dev/null 2>&1 || true
[ -d "/run/user/$uid" ] || { install -d -o "$SVC_USER" -g "$SVC_USER" -m 700 "/run/user/$uid"; }
if [ ! -s "$HOME_DIR/.keyring-pass" ]; then
(umask 077; head -c 24 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | head -c 20 > "$HOME_DIR/.keyring-pass")
chown "$SVC_USER:$SVC_USER" "$HOME_DIR/.keyring-pass"; chmod 600 "$HOME_DIR/.keyring-pass"
fi
[ -f "$HOME_DIR/.Validata/zpki.ini" ] || { printf '[Profile]\nCount = 0\n' > "$HOME_DIR/.Validata/zpki.ini"; chown "$SVC_USER:$SVC_USER" "$HOME_DIR/.Validata/zpki.ini"; }
st db "база ИШ в PostgreSQL"
runuser -u postgres -- psql -tAc "select 1 from pg_roles where rolname='$SVC_USER'" | grep -q 1 || runuser -u postgres -- psql -qc "create role $SVC_USER login" || die "не создать роль igate"
runuser -u postgres -- psql -lqt | cut -d'|' -f1 | grep -qw "$DB" || runuser -u postgres -- createdb -O "$SVC_USER" "$DB" || die "не создать базу igate"
hba=$(runuser -u postgres -- psql -tAc "show hba_file")
if [ -f "$hba" ] && ! grep -q '^# bj-igate-trust' "$hba"; then
# ИШ хранит пароль БД зашифрованным — локальному igate доступ без пароля (только своя база, только с этого сервера)
cp -a "$hba" "$hba.bak-bj-igate"
{ printf '# bj-igate-trust\nlocal %s %s trust\nhost %s %s 127.0.0.1/32 trust\nhost %s %s ::1/128 trust\n' "$DB" "$SVC_USER" "$DB" "$SVC_USER" "$DB" "$SVC_USER"; cat "$hba.bak-bj-igate"; } > "$hba"
runuser -u postgres -- psql -qtAc "select pg_reload_conf()" >/dev/null
fi
st package "установка пакета ИШ"
systemctl stop igate >/dev/null 2>&1 || true
pkill -9 -u "$SVC_USER" -f igate-svc 2>/dev/null; pkill -9 -u "$SVC_USER" -f Xvfb 2>/dev/null; rm -f /tmp/CoreFxPipe_NSD.IGate.*
if [ -d "$IGATE_DIR" ]; then
BK=/var/backups/ish-$(date +%Y%m%d-%H%M%S); mkdir -p "$BK"
tar czf "$BK/opt-nsd-igate.tar.gz" -C "$(dirname "$IGATE_DIR")" "$(basename "$IGATE_DIR")" 2>/dev/null
runuser -u postgres -- pg_dump -Fc "$DB" > "$BK/igate-db.dump" 2>/dev/null
echo "$BK" > /var/backups/ish-last-backup.txt; echo "резервная копия прежнего ИШ: $BK"
fi
echo "igate igate/service boolean false" | debconf-set-selections
echo "igate igate/shortcut boolean false" | debconf-set-selections
DEBIAN_FRONTEND=noninteractive dpkg -i --force-confnew "$deb" || { DEBIAN_FRONTEND=noninteractive apt-get -f install -y -qq || die "пакет ИШ не установился (dpkg)"; }
[ -x "$IGATE_DIR/igate-svc/igate-svc" ] || die "после установки нет $IGATE_DIR/igate-svc/igate-svc"
st config "настройка ИШ для работы без графики"
cfg='{"db":{"databaseProvider":"Postgresql","sqlite":{"path":"'"$DATA_DIR"'/igate.db.dat"},"postgresql":{"host":"127.0.0.1","port":"5432","database":"'"$DB"'","userName":"'"$SVC_USER"'","extensions":null}},"migrationCompleted":true}'
for f in "$DATA_DIR/config.json" "$HOME_DIR/config.json"; do
[ -s "$f" ] || { printf '%s\n' "$cfg" > "$f"; chown "$SVC_USER:$SVC_USER" "$f"; chmod 600 "$f"; }
done
cat > "$WRAPPER" <<EOF
#!/usr/bin/env bash
# bj: запуск ИШ без графики — gnome-keyring (пароли ИШ 107) + виртуальный дисплей; из ExecStart через dbus-run-session.
export HOME=$HOME_DIR XDG_DATA_HOME="$HOME_DIR/.local/share" XDG_RUNTIME_DIR="/run/user/\$(id -u)" GIO_USE_VFS=local
eval "\$(printf '%s\n' "\$(cat "\$HOME/.keyring-pass")" | gnome-keyring-daemon --replace --unlock --components=secrets,pkcs11 2>/dev/null)"
export GNOME_KEYRING_CONTROL SSH_AUTH_SOCK
cd "\$HOME"
exec xvfb-run -a $IGATE_DIR/igate-svc/igate-svc
EOF
chmod 755 "$WRAPPER"
rm -f /etc/systemd/system/igate.service.d/override.conf
cat > "$UNIT" <<EOF
[Unit]
Description=Интеграционный шлюз НРД (ИШ)
After=network-online.target postgresql.service
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=8
[Service]
User=$SVC_USER
WorkingDirectory=$HOME_DIR
# самоочистка перед стартом: осиротевшие сокеты, keyring, X-локи — иначе перезапуски срываются
# каталог сеанса igate (XDG_RUNTIME_DIR): обычно его создаёт systemd-logind (linger), но без него keyring не стартует
ExecStartPre=+/usr/bin/install -d -o $SVC_USER -g $SVC_USER -m 700 /run/user/$uid
ExecStartPre=-/bin/bash -c 'rm -f /tmp/CoreFxPipe_NSD.IGate.* $HOME_DIR/.local/share/keyrings/login.keyring; find /tmp -maxdepth 1 -name ".X9*-lock" -delete 2>/dev/null; true'
ExecStart=/usr/bin/dbus-run-session -- $WRAPPER
Restart=on-failure
RestartSec=8
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
st schema "база ИШ: создание схемы"
if ! psqlq -c "select to_regclass('public.parameters') is not null" | grep -q t; then
run_as_igate_keyring "timeout 90 $IGATE_DIR/igate-cli/igate-cli --data $HOME_DIR </dev/null >/dev/null 2>&1; true"
psqlq -c "select to_regclass('public.parameters') is not null" | grep -q t || die "ИШ не создал схему базы (igate-cli). Журнал: $LOG"
fi
# Общие параметры ИШ. Обязательные для работы без графики и для bj (движок при старте, Web API на
# localhost:8090 без авторизации) — выставляем всегда; остальные — только если их ещё нет: настройки ИШ,
# который у клиента уже работает (очистка, хранение, прокси), не трогаем. Значения по умолчанию — эталон GUI.
psqlq <<'SQL' || die "не записаны параметры ИШ"
CREATE TEMP TABLE must(n text, v text);
INSERT INTO must VALUES ('runEngineOnStartApp','True'),('server.useServer','True'),('server.host','localhost'),
('server.port','8090'),('server.scheme','Http'),('server.authentication.enable','False');
CREATE TEMP TABLE dflt(n text, v text);
INSERT INTO dflt VALUES ('server.authentication.userName',''),('server.authentication.password',''),('server.certificate.storage','File'),
('server.certificate.store.location','CurrentUser'),('server.certificate.store.name','My'),('server.certificate.file.path',''),
('server.certificate.file.password',''),('wsl.httpsMode','Auto'),('wsl.maxConnsPerServer','4'),('wsl.proxy.mode','None'),
('wsl.proxy.address',''),('wsl.proxy.port','0'),('wsl.proxy.username',''),('wsl.proxy.password',''),('enableDbLogging','False'),
('cleanAutomatically','False'),('cleanAtTime','00:30:00'),('cleanWhenLarger','1024'),('cleanVacuum','False'),('storePeriod','15'),
('archiveAutomatically','False');
UPDATE parameters p SET value = m.v FROM must m WHERE p.chanel_id IS NULL AND p.name = m.n;
INSERT INTO parameters(name, value, chanel_id)
SELECT x.n, x.v, NULL FROM (SELECT * FROM must UNION ALL SELECT * FROM dflt) x
WHERE NOT EXISTS (SELECT 1 FROM parameters p WHERE p.chanel_id IS NULL AND p.name = x.n);
SQL
st start "запуск ИШ"
systemctl enable igate >/dev/null 2>&1
systemctl restart igate || die "служба igate не запустилась"
wait_engine 120 || die "ИШ запущен, но движок не перешёл в Running за 2 минуты. Журнал ИШ: $DATA_DIR/logs-svc/log.txt"
case "$(j file)" in /var/lib/bj/igate-upload/*) rm -f "$(j file)" ;; esac # загруженный архив больше не нужен (с образа — остаётся)
st done "ИШ $(igate_version) установлен и работает; дальше — канал контура (TEST3 или боевой)" ;;
contour)
contour=$(j contour); crypto=$(j crypto); dep=$(j deponent); prof=$(j profile)
crypto=${crypto:-gost}
IFS='|' read -r CODE NAME EP FP TYPE <<<"$(contour_params "$contour" "$crypto")" || true
[ -n "${CODE:-}" ] || err "неизвестный контур: $contour/$crypto"
[[ "$dep" =~ ^[A-Z]{2}[0-9]{10}$ ]] || err "депозитарный код — вида MC0000000000"
[[ -z "$prof" || "$prof" =~ ^[A-Za-z0-9_-]+$ ]] || err "недопустимое имя профиля Валидаты"
[ -x "$IGATE_DIR/igate-svc/igate-svc" ] || err "ИШ не установлен"
# ключ этого контура ставили раньше, чем канал: профиль запомнен установкой ключа
if [ -z "$prof" ] && [ -s "$HOME_DIR/.bj-profile-$CODE" ]; then prof=$(tr -cd 'A-Za-z0-9_-' < "$HOME_DIR/.bj-profile-$CODE"); fi
DIR=$(exchange_dir "$contour"); install -d -o "$SVC_USER" -g "$SVC_USER" -m 755 "$DIR"
psqlq -v code="$CODE$dep" -v name="$NAME" -v ep="$EP" -v fp="$FP" -v typ="$TYPE" -v dep="$dep" -v prof="$prof" -v dir="$DIR" <<'SQL' || err "канал не записан в базу ИШ"
BEGIN;
INSERT INTO channels(name, code, type, enable)
SELECT :'name', :'code', 'WSL', true WHERE NOT EXISTS (SELECT 1 FROM channels WHERE code = :'code');
CREATE TEMP TABLE want(n text, v text) ON COMMIT DROP;
INSERT INTO want VALUES
('enable','True'),('wslEndpoint',:'ep'),('cryptography.type',:'typ'),('cryptography.pincode',''),
('cryptography.clientCertificateSerialNumber',''),('repositoryCode',:'dep'),('fetchInterval','00:00:10'),('attemptInterval','30000'),
('sendAttempts','3'),('maxPartSize','500'),('loadOldMessagesDepth','3'),('isIncomingEnabled','True'),('isOutgoingEnabled','True'),
('isTransitTerminalChannel','False'),('useDirectories','True'),('dir',:'dir'),('inboxDirName','INBOX'),('outboxDirName','OUTBOX'),
('sentDirName','SENT'),('errorDirName','ERRORS'),('archive1042sDirName',:'dir' || '/Archives1042S'),('enableLockFile','True'),
('enableAutoResponse','True'),('enable1042ReportProcessing','True'),('RenameOutgoingFiles','True'),('generateReceivedPackageInfo','True'),
('generateSentPackageInfo','False'),('moveReceiptsToSentFolder','False'),('applyAddHashOfPackageToFolder','False'),
('ignorePackageDirectoryStructure','True'),('checkReceivedPackageNsdSign','False'),('checkReceivedPackageSenderSign','False'),
('autoUpdateTransitMember','False'),('automaticcalyLoadCrls','False'),('autoInPkgReportOffload','False'),('monitoringThreshold','00:00:01'),
('autoLoadCrlsTime',''),('fetchThreadCount',''),('forceCryPackageEncryption',''),('inPkgReportDirectory',''),
('inPkgReportOffloadInterval',''),('maxPackagesPerJob',''),('nsdCertificateSerialNumbers',''),('pkiDecryptMode',''),('pkiEncryptMode',''),
('pkiSignMode',''),('pkiVerifyMode',''),('receiveProcThreadCount',''),('sendProcThreadCount',''),('updateTransitMemberListTime',''),
('wslTlsCACertFingerprint',:'fp'),('wslTlsCertDN','*.nsd.ru'),('wslTlsCertChainLen','2'),('isM2M','True');
-- существующие значения канала не трогаем, кроме контурных (адрес, отпечаток, криптография, депозитарный код)
UPDATE parameters p SET value = w.v FROM want w, channels c
WHERE c.code = :'code' AND p.chanel_id = c.id AND p.name = w.n
AND w.n IN ('wslEndpoint','wslTlsCACertFingerprint','wslTlsCertDN','wslTlsCertChainLen','cryptography.type','repositoryCode','isM2M');
INSERT INTO parameters(name, value, chanel_id)
SELECT w.n, w.v, c.id FROM want w, channels c
WHERE c.code = :'code' AND NOT EXISTS (SELECT 1 FROM parameters p WHERE p.chanel_id = c.id AND p.name = w.n);
-- профиль Валидаты (ключ этого контура): задан — пишем; не задан — оставляем прежний или пустой до установки ключа
INSERT INTO parameters(name, value, chanel_id)
SELECT 'cryptography.profile', '', c.id FROM channels c
WHERE c.code = :'code' AND NOT EXISTS (SELECT 1 FROM parameters p WHERE p.chanel_id = c.id AND p.name = 'cryptography.profile');
UPDATE parameters p SET value = :'prof' FROM channels c
WHERE :'prof' <> '' AND c.code = :'code' AND p.chanel_id = c.id AND p.name = 'cryptography.profile';
-- канал включён, только когда для контура установлен ключ (профиль Валидаты): без ключа ИШ его не поднимет
UPDATE channels c SET enable = COALESCE((SELECT value <> '' FROM parameters p WHERE p.chanel_id = c.id AND p.name = 'cryptography.profile'), false)
WHERE c.code = :'code';
UPDATE parameters p SET value = CASE WHEN c.enable THEN 'True' ELSE 'False' END FROM channels c
WHERE c.code = :'code' AND p.chanel_id = c.id AND p.name = 'enable';
COMMIT;
SQL
en=$(psqlq -v code="$CODE$dep" <<<"select enable from channels where code = :'code'")
if [ -n "${BJ_IGATE_NORESTART:-}" ]; then ok "канал $CODE$dep записан (без перезапуска, enable=$en)"; exit 0; fi
systemctl restart igate >/dev/null 2>&1 || err "служба igate не перезапустилась"
if wait_engine 120; then
if [ "$en" = t ]; then ok "канал $CODE$dep ($NAME, $EP) настроен и включён, ИШ работает"
else ok "канал $CODE$dep ($NAME, $EP) записан и пока выключен — включится после установки ключа этого контура"; fi
else
err "канал $CODE$dep записан, но движок ИШ не перешёл в Running — см. журнал ИШ $DATA_DIR/logs-svc/log.txt (отпечаток УЦ, адрес контура, ключ)"
fi ;;
*) err "неизвестная команда: $cmd" ;;
esac