diff --git a/internal/lkgateway/licenseclient.go b/internal/lkgateway/licenseclient.go index dee3424..90567eb 100644 --- a/internal/lkgateway/licenseclient.go +++ b/internal/lkgateway/licenseclient.go @@ -106,6 +106,25 @@ func licenseCall(ctx context.Context, path string, body map[string]string) (*lic return &r, nil } +// licenseDeactivate — сервер отключён от лицензии в портале клиента (или лицензия отозвана): ключ +// удаляется сразу, не дожидаясь его срока, — модули и обновления отключаются. Вернуть: ввести ключ +// продукта заново (если в лицензии есть свободное место). +func licenseDeactivate(rc *RuntimeConfig, reason string) { + s := rc.Snapshot().License + if s.Key == "" { + return + } + s.Key = "" + s.LastAttempt, s.LastOK, s.LastMsg = time.Now(), false, "лицензия отключена: "+reason + if err := rc.SaveLicense(s); err != nil { + log.Printf("lk-gateway: отключение лицензии: %v", err) + return + } + log.Printf("lk-gateway: лицензия на этом сервере отключена: %s", reason) + raiseSystemAlert(rc, "Лицензия на этом сервере отключена", + "Причина: "+reason+". Модули по лицензии и обновления отключены. Если это ошибка — введите ключ продукта заново в «Настройка → Лицензия» (нужно свободное место в лицензии) или обратитесь в ZETIT.") +} + // licenseRecord — итог обращения к серверу лицензий (для карточки); token != "" — новый ключ. func licenseRecord(rc *RuntimeConfig, token, msg string, ok bool) error { s := rc.Snapshot().License @@ -161,6 +180,10 @@ func LicenseRenew(ctx context.Context, rc *RuntimeConfig) error { if err != nil { _ = licenseRecord(rc, "", "продление не удалось: "+err.Error(), false) var ae *licenseAPIError + if errors.As(err, &ae) && (ae.Code == "install_released" || ae.Code == "revoked") { + licenseDeactivate(rc, ae.Message) + return err + } if errors.As(err, &ae) && time.Since(licenseAlertAt) > 12*time.Hour { licenseAlertAt = time.Now() raiseSystemAlert(rc, "Лицензия: сервер лицензий отказал в продлении",