Соединение с агентом сервера.DeleteServiceSetting

Методы · DeleteServiceSetting

Удаляет настройку сервиса кластера.

Синтаксис

DeleteServiceSetting(<Кластер>, <Сервер>, <Настройка>)
Полное описание, параметры и ограничения

Соединение с агентом сервера.DeleteServiceSetting (IServerAgentConnection.DeleteServiceSetting)

Соединение с агентом сервера (IServerAgentConnection)

DeleteServiceSetting (DeleteServiceSetting)

Доступен, начиная с версии 8.3.26.

Синтаксис:
DeleteServiceSetting(<Кластер>, <Сервер>, <Настройка>)
Параметры:

<Кластер> (обязательный)
Тип: Кластер серверов.
Кластер, для которого требуется удалить настройку.

<Сервер> (обязательный)
Тип: Рабочий сервер.
Рабочий сервер, на котором требуется удалить настройку.

<Настройка> (обязательный)
Тип: Настройка сервиса.
Настройка сервиса кластера.
Описание:

Удаляет настройку сервиса кластера.

Доступность:

Интеграция.

Использование в версии:

Доступен, начиная с версии 8.3.26.

Методическая информация

Практические примеры

Создать свою UUID-настройку глобального сервиса, применить пустой набор и удалить только неактивную

CreateServiceSetting/RegServiceSetting/ApplyServiceSettings/DeleteServiceSetting с настоящим именем сервиса, отдельным собственным каталогом и строгим запретом переноса данных.

Где и как запускать

Полный серверный общий модуль УчебныйCOM85 и полный модуль управляемой формы в отдельной файловой учебной ИБ. Свой Windows-агент/RAS, точная платформа8.5.1.1343; перечисленные записи являются только авторским учебным кодом, фактических запусков0.

Подготовка

  1. Работайте только в новой отдельной Windows-VM без рабочих процессов/кластеров. Установленная платформа и заранее зарегистрированный V85.COMConnector должны быть8.5.1.1343 соответствующей разрядности. Регистрацию COM и запуск служб этот BSL не выполняет.

  2. Создайте отдельную файловую ИБ с именем конфигурации УчебныйЖизненныйЦиклCOM85: без данных, каталогов, документов, регистров, подписок, фоновых заданий и расширений. В ней создайте общий модуль УчебныйCOM85: Сервер=Истина, ВызовСервера=Истина, Глобальный=Ложь, Клиент/ВнешнееСоединение=Ложь. Вставьте полностью код одного урока, не смешивайте одинаковые функции разных уроков.

  3. Создайте обработку и управляемую форму с командой Выполнить и полным модулем формы из дополнительного блока. Строковые реквизиты: Операция, ИмяАгента, ПарольАгента, ИмяАдминистратора, ПарольАдминистратора, UUIDОпыта, UUIDКластера, Дополнительно; числовые ПортАгента, ПортRAS, ПортКластера; булевый ПодтвержденСвойСтенд. Поля всех паролей и Дополнительно переведите в режим пароля, значения не сохраняйте в настройках.

  4. В своей VM вручную поднимите один отдельный ragent и один ras с отдельным новым каталогом реестров. RAS должен обслуживать именно этот агент, а не другой локальный сервис. Из реально выбранных администратором свободных портов впишите три разные величины: agent-port для ConnectAgent, ras-port для АдминистрированиеСервера, manager-port для своего кластера. Не подставляйте1545 в ConnectAgent.

  5. До первого создания кластера вручную удалите только автоматически созданный пустой кластер своей новой VM, если он появился. Консоль должна показывать0кластеров; никакие чужие кластеры не допускаются. Первый урок также проверяет нулевой список обоими интерфейсами до RegCluster.

  6. Заведите постоянного своего администратора агента и после создания кластера постоянного своего администратора кластера через консоль. Их реальные новые учебные пароли передавайте форме; учебные временные администраторы в уроке никогда не заменяют постоянных.

  7. Один раз самостоятельно получите UUIDОпыта в своей файловой ИБ выражением Строка(Новый УникальныйИдентификатор), сохраните текст в собственном журнале опыта. Имя кластера: own-com85-cluster-<UUIDОпыта>. После создания сохраните фактический RAS UUIDКластера из результата; имя не заменяет UUID.

  8. Читающая команда Каталог85 не равна доказательству отсутствия production. Изоляция VM и новый реестр обязательны до любого подключения. COM не предоставляет UUID в интерфейсе IClusterInfo: пример сопоставляет его с прочитанным UUID RAS по sole-кластеру, точным loopback/имени/порту.

  9. Запись/применение/отмена регистрации выполняются только отдельной явно выбранной строкой Операция. Не добавляйте автоматические повторы, очистку при исключении или откат чужого состояния. В случае частичного выполнения сохраните UUID и сначала прочитайте фактическое состояние.

  10. Пароли очищаются из реквизитов и локальной структуры, но это не гарантирует стирания строк из памяти. Не выводите ОписаниеОшибки, строки подключения, Password или аргументы операций. Код статически проверяется здесь, но COM/RAS/1С, сеть и процессы не запускались.

  11. На той же новой VM вручную поднимите второй отдельный ragent8.5.1.1343 с отдельным новым каталогом реестров и другой парой agent/ras-портов. Ни один агент не должен обслуживать production. В его новом реестре0кластеров и нет администраторов; нулевой вход разрешен только на этом отдельно подготовленном учебном вторичном агенте.

  12. Для вторичного сервера заранее выберите и зарезервируйте свободную собственную полосу TCP-портов, не пересекающую служебные порты обоих агентов/RAS/manager и фактические диапазоны главного сервера. Проверку свободных портов/межсетевого экрана выполняет человек; BSL никакие порты ОС не резервирует.

  13. В Дополнительно введите JSON-объект с числовыми ПортВторогоАгента, ПортВторогоRAS, НижнийПорт, ВерхнийПорт и строковым UUIDСервера. Перед первым созданием UUIDСервера=""; остальные числа реальные, а не копируемые примерные. После создания впишите фактический UUID из ответа.

  14. Свой вторичный сервер создается MainServer=Ложь и RegWorkingServer(...,Истина), чтобы автоматически запретить назначение любой функциональности. Основной сервер, его диапазоны и процессы не изменяются.

  15. Впишите фактический UUID своего вторичного нецентрального сервера. На своем основном сервере через консоль заранее подготовьте настоящую глобальную настройку реального сервиса из GetClusterServices, где InfoBaseName="". Это доказательство, что именно этот сервис допускает глобальную настройку; имя не выдумывается.

  16. В собственном новом каталоге C:\OwnedCOM85\<UUIDОпыта> вручную создайте отдельную пустую папку service-data, дайте сервисному пользователю своего стенда необходимые права. Не используйте junction, symlink или папку рабочих данных. BSL не создает каталог и не копирует/удаляет файлы.

  17. В тот же JSON рабочего сервера добавьте строки ИмяСервиса=точное реальное имя из собственной глобальной настройки и UUIDНастройки="" до создания. После ответа впишите фактический UUIDНастройки. Перед СоздатьНастройку85 список настроек вторичного сервера пуст.

  18. Команды отдельно: СоздатьНастройку85, Каталог85, ПрименитьНастройку85, УдалитьНастройку85. Непустой GetServiceDataDirectoriesForTransfer запрещает применение: перенос данных в этом уроке не выполняется. Для удаления ранее активированной настройки сначала вручную деактивируйте только свою настройку в консоли.

Функция Выполнить85(Операция, Данные, Подтверждение) Экспорт
    Если СтрРазделить("СоздатьНастройку85,Каталог85,ПрименитьНастройку85,УдалитьНастройку85", ",").Найти(Операция) = Неопределено Тогда
        ВызватьИсключение "Неизвестная отдельная команда каталога сервиса";
    КонецЕсли;
    Связь = СоединитьсяСоСвоимАгентом85(Данные, Подтверждение);
    Стенд = ПолучитьСвойКластер85(Связь, Данные);
    Паспорт = ПрочитатьСвойJSON85(Данные.Дополнительно);
    ПроверитьПаспортРабочего85(Паспорт, Данные);
    ПроверитьПоля85(Паспорт, "ИмяСервиса,UUIDНастройки");
    Если ТипЗнч(Паспорт.ИмяСервиса) <> Тип("Строка") Или ПустаяСтрока(Паспорт.ИмяСервиса)
        Или ТипЗнч(Паспорт.UUIDНастройки) <> Тип("Строка") Или ПустаяСтрока(Паспорт.UUIDСервера) Тогда
        ВызватьИсключение "Нужны собственный UUID-сервер и фактическое имя глобального сервиса";
    КонецЕсли;
    Рабочий = НайтиСвойРабочийСервер85(Связь, Стенд, Данные, Паспорт);
    Если Рабочий.COM = Неопределено Тогда
        ВызватьИсключение "Собственный вторичный UUID-сервер не найден";
    КонецЕсли;
    ИмяНайдено = Ложь;
    Для Каждого Сервис Из Связь.Агент.GetClusterServices(Стенд.COM) Цикл
        Если Сервис.Name = Паспорт.ИмяСервиса Тогда
            ИмяНайдено = Истина;
        КонецЕсли;
    КонецЦикла;
    Если Не ИмяНайдено Тогда
        ВызватьИсключение "Нельзя выдумывать имя сервиса: используйте фактический список своего кластера";
    КонецЕсли;
    Настройки = Связь.Агент.GetServiceSettings(Стенд.COM, Рабочий.COM);
    Каталог = "C:\OwnedCOM85\" + Данные.UUIDОпыта + "\service-data";
    Своя = Неопределено;
    Для Каждого Кандидат Из Настройки Цикл
        Если Своя <> Неопределено Или Кандидат.ServiceName <> Паспорт.ИмяСервиса Или Кандидат.InfoBaseName <> ""
            Или Кандидат.ServiceDataDir <> Каталог Тогда
            ВызватьИсключение "На own-сервере разрешена только наша одна глобальная настройка со своим каталогом";
        КонецЕсли;
        Если ПустаяСтрока(Паспорт.UUIDНастройки) Тогда
            ВызватьИсключение "Для существующей настройки сохраните её фактический UUID";
        КонецЕсли;
        ПроверитьUUID85(Паспорт.UUIDНастройки);
        Если Строка(Кандидат.SettingID) <> Паспорт.UUIDНастройки Тогда
            ВызватьИсключение "Фактический own-UUID настройки не совпал";
        КонецЕсли;
        Своя = Кандидат;
    КонецЦикла;
    Если Операция = "СоздатьНастройку85" Тогда
        Если Настройки.Количество() <> 0 Тогда
            ВызватьИсключение "Не перезаписывайте существующую настройку";
        КонецЕсли;
        ШаблоновГлобальногоСервиса = 0;
        Для Каждого Основной Из Связь.Агент.GetWorkingServers(Стенд.COM) Цикл
            Если Основной.MainServer И Основной.HostName = "127.0.0.1" И Основной.MainPort = Данные.ПортАгента Тогда
                Для Каждого Шаблон Из Связь.Агент.GetServiceSettings(Стенд.COM, Основной) Цикл
                    Если Шаблон.ServiceName = Паспорт.ИмяСервиса И Шаблон.InfoBaseName = "" Тогда
                        ШаблоновГлобальногоСервиса = ШаблоновГлобальногоСервиса + 1;
                    КонецЕсли;
                КонецЦикла;
            КонецЕсли;
        КонецЦикла;
        Если ШаблоновГлобальногоСервиса <> 1 Тогда
            ВызватьИсключение "Вручную подготовьте реальную глобальную настройку этого сервиса на собственном основном сервере";
        КонецЕсли;
        ФайлКаталога = Новый Файл(Каталог);
        Если Не ФайлКаталога.Существует() Или Не ФайлКаталога.ЭтоКаталог() Тогда
            ВызватьИсключение "Вручную подготовьте отдельный собственный каталог данных сервиса";
        КонецЕсли;
        Настройка = Связь.Агент.CreateServiceSetting(Паспорт.ИмяСервиса, "");
        Настройка.ServiceDataDir = Каталог;
        Связь.Агент.RegServiceSetting(Стенд.COM, Рабочий.COM, Настройка);
        После = Связь.Агент.GetServiceSettings(Стенд.COM, Рабочий.COM);
        Если После.Количество() <> 1 Тогда
            ВызватьИсключение "Регистрация own-настройки не подтверждена";
        КонецЕсли;
        Созданная = После.Получить(0);
        Если Созданная.ServiceName <> Паспорт.ИмяСервиса Или Созданная.InfoBaseName <> "" Или Созданная.ServiceDataDir <> Каталог Тогда
            ВызватьИсключение "Свой фактический паспорт настройки отличается";
        КонецЕсли;
        Возврат "Собственная глобальная настройка зарегистрирована. UUIDНастройки=" + Строка(Созданная.SettingID)
            + ". Каталоги/данные не переносились; применение выбирается отдельно";
    ИначеЕсли Операция = "ПрименитьНастройку85" Тогда
        Если Своя = Неопределено Тогда
            ВызватьИсключение "Сначала зарегистрируйте собственную настройку";
        КонецЕсли;
        План = Связь.Агент.GetServiceDataDirectoriesForTransfer(Стенд.COM, Рабочий.COM, Паспорт.ИмяСервиса);
        Если План.Количество() <> 0 Тогда
            ВызватьИсключение "Обнаружен фактический перенос данных: в этом полном уроке перенос запрещен";
        КонецЕсли;
        Если Связь.Агент.GetServerWorkingProcesses(Стенд.COM, Рабочий.COM).Количество() <> 0 Тогда
            ВызватьИсключение "Свой вторичный сервер не должен обслуживать процессы";
        КонецЕсли;
        Связь.Агент.ApplyServiceSettings(Стенд.COM, Рабочий.COM);
        Активна = Связь.Агент.GetSettingActive(Стенд.COM, Рабочий.COM, Своя);
        Возврат "Применение собственного пустого серверного набора выполнено; фактическая активность=" + Строка(Активна)
            + ". Активность не означает наличие данных или перенос файлов";
    ИначеЕсли Операция = "УдалитьНастройку85" Тогда
        Если Своя = Неопределено Тогда
            Возврат "Собственная настройка отсутствует";
        КонецЕсли;
        Если Связь.Агент.GetSettingActive(Стенд.COM, Рабочий.COM, Своя) Тогда
            ВызватьИсключение "Сначала вручную деактивируйте свой сервиси/назначение на пустом стенде; активную настройку не удаляем";
        КонецЕсли;
        Связь.Агент.DeleteServiceSetting(Стенд.COM, Рабочий.COM, Своя);
        Если Связь.Агент.GetServiceSettings(Стенд.COM, Рабочий.COM).Количество() <> 0 Тогда
            ВызватьИсключение "Отмена своей настройки не подтверждена";
        КонецЕсли;
        Возврат "Удалена только регистрация своей неактивной UUID-настройки; физический каталог и файлы не удалялись";
    КонецЕсли;
    Возврат "Собственных настроек=" + Формат(Настройки.Количество(), "ЧГ=0");
КонецФункции

Функция СоединитьсяСоСвоимАгентом85(Данные, Подтверждение)
    ПроверитьСвойПустойСтенд();
    Если ТипЗнч(Подтверждение) <> Тип("Булево") Или Не Подтверждение Тогда
        ВызватьИсключение "Подтвердите отдельную собственную VM без рабочих кластеров";
    КонецЕсли;
    Для Каждого Поле Из СтрРазделить("ПортАгента,ПортRAS,ПортКластера", ",") Цикл
        Порт = Данные[Поле];
        Если ТипЗнч(Порт) <> Тип("Число") Тогда
            ВызватьИсключение "Порт своего процесса должен быть числом";
        КонецЕсли;
        Если Порт < 1 Или Порт > 65535 Или Порт <> Цел(Порт) Тогда
            ВызватьИсключение "Недопустимый фактический порт";
        КонецЕсли;
    КонецЦикла;
    Если Данные.ПортАгента = Данные.ПортRAS Или Данные.ПортАгента = Данные.ПортКластера
        Или Данные.ПортRAS = Данные.ПортКластера Тогда
        ВызватьИсключение "Порты агента, менеджера кластера и ras различаются";
    КонецЕсли;
    Для Каждого Поле Из СтрРазделить("ИмяАгента,ПарольАгента,ИмяАдминистратора,ПарольАдминистратора,UUIDОпыта,UUIDКластера,Дополнительно", ",") Цикл
        Если ТипЗнч(Данные[Поле]) <> Тип("Строка") Тогда
            ВызватьИсключение "Имена, пароли и UUID должны быть строками";
        КонецЕсли;
    КонецЦикла;
    ПроверитьUUID85(Данные.UUIDОпыта);
    СерверRAS = Новый АдминистрированиеСервера("127.0.0.1", Данные.ПортRAS);
    СерверRAS.ВыполнитьАутентификацию(Данные.ПарольАгента, Данные.ИмяАгента);
    Если СерверRAS.ПолучитьВерсию() <> "8.5.1.1343" Тогда
        ВызватьИсключение "RAS обязан обслуживать ровно собственный агент8.5.1.1343";
    КонецЕсли;
    Соединитель = Новый COMОбъект("V85.COMConnector");
    Агент = Соединитель.ConnectAgent("127.0.0.1:" + Формат(Данные.ПортАгента, "ЧГ=0"));
    Агент.AuthenticateAgent(Данные.ИмяАгента, Данные.ПарольАгента);
    Возврат Новый Структура("Агент,RAS,Соединитель", Агент, СерверRAS, Соединитель);
КонецФункции

Процедура ПроверитьUUID85(UUID)
    Проверенный = Новый УникальныйИдентификатор(UUID);
    Если UUID <> Строка(Проверенный) Или UUID = "00000000-0000-0000-0000-000000000000" Тогда
        ВызватьИсключение "Введите канонический собственный ненулевой UUID";
    КонецЕсли;
КонецПроцедуры

Функция ПолучитьСвойКластер85(Связь, Данные, РазрешенаСвояБаза = Ложь)
    ПроверитьUUID85(Данные.UUIDКластера);
    КластерыRAS = Связь.RAS.ПолучитьКластеры();
    Если КластерыRAS.Количество() <> 1 Тогда
        ВызватьИсключение "В агенте должен быть только один собственный кластер";
    КонецЕсли;
    КластерRAS = КластерыRAS[0];
    ИмяКластера = "own-com85-cluster-" + Данные.UUIDОпыта;
    Если Строка(КластерRAS.ИдентификаторКластера) <> Данные.UUIDКластера
        Или КластерRAS.Имя <> ИмяКластера Или КластерRAS.Порт <> Данные.ПортКластера
        Или КластерRAS.ИмяКомпьютера <> "127.0.0.1" Тогда
        ВызватьИсключение "RAS UUID, имя, loopback или порт своего кластера не совпали";
    КонецЕсли;
    КластерRAS.ВыполнитьАутентификацию(Данные.ИмяАдминистратора, Данные.ПарольАдминистратора);
    БазыRAS = КластерRAS.ПолучитьИнформационныеБазы();
    Если Не РазрешенаСвояБаза И БазыRAS.Количество() <> 0 Тогда
        ВызватьИсключение "Этот урок требует полностью пустой кластер";
    КонецЕсли;
    Если РазрешенаСвояБаза Тогда
        Если БазыRAS.Количество() <> 1 Тогда
            ВызватьИсключение "Разрешена только одна специально подготовленная собственная ИБ";
        КонецЕсли;
        Если БазыRAS[0].Имя <> "own-com85-base-" + Данные.UUIDОпыта
            Или (БазыRAS[0].Описание <> "owned-com85-lifecycle:" + Данные.UUIDОпыта
                И БазыRAS[0].Описание <> "owned-com85-lifecycle:" + Данные.UUIDОпыта + ":checked") Тогда
            ВызватьИсключение "Чужая ИБ или неверный маркер собственного стенда";
        КонецЕсли;
    КонецЕсли;
    КластерыCOM = Связь.Агент.GetClusters();
    Если КластерыCOM.Количество() <> 1 Тогда
        ВызватьИсключение "COM и RAS должны видеть один и тот же sole кластер";
    КонецЕсли;
    Кластер = КластерыCOM.Получить(0);
    Если Кластер.ClusterName <> КластерRAS.Имя Или Кластер.HostName <> КластерRAS.ИмяКомпьютера
        Или Кластер.MainPort <> КластерRAS.Порт Тогда
        ВызватьИсключение "Нельзя сопоставить COM-описание с собственным RAS UUID";
    КонецЕсли;
    Связь.Агент.Authenticate(Кластер, Данные.ИмяАдминистратора, Данные.ПарольАдминистратора);
    БазыCOM = Связь.Агент.GetInfoBases(Кластер);
    Если БазыCOM.Количество() <> БазыRAS.Количество() Тогда
        ВызватьИсключение "Состояние собственных ИБ изменилось между чтениями";
    КонецЕсли;
    Основных = 0;
    Вторичных = 0;
    Для Каждого Рабочий Из КластерRAS.ПолучитьРабочиеСерверы() Цикл
        Если Рабочий.ИмяКомпьютера <> "127.0.0.1" Тогда
            ВызватьИсключение "В своём UUID-кластере появился нелокальный рабочий сервер";
        КонецЕсли;
        Если Рабочий.ЦентральныйСервер И Рабочий.Порт = Данные.ПортАгента Тогда
            Основных = Основных + 1;
        ИначеЕсли Не Рабочий.ЦентральныйСервер И Рабочий.Имя = "own-com85-worker-" + Данные.UUIDОпыта
            И Рабочий.Порт <> Данные.ПортАгента Тогда
            Вторичных = Вторичных + 1;
        Иначе
            ВызватьИсключение "Разрешены только собственные основной и UUID-вторичный рабочие серверы";
        КонецЕсли;
    КонецЦикла;
    Если Основных <> 1 Или Вторичных > 1 Тогда
        ВызватьИсключение "Own-топология рабочего стенда изменилась";
    КонецЕсли;
    Возврат Новый Структура("COM,RAS,БазыCOM,БазыRAS", Кластер, КластерRAS, БазыCOM, БазыRAS);
КонецФункции
Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Функция ПрочитатьСвойJSON85(Текст)
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(Текст);
    Попытка
        Значение = ПрочитатьJSON(Чтение);
    Исключение
        Чтение.Закрыть();
        ВызватьИсключение "Некорректный собственный JSON-паспорт";
    КонецПопытки;
    Чтение.Закрыть();
    Если ТипЗнч(Значение) <> Тип("Структура") Тогда
        ВызватьИсключение "Собственный JSON должен содержать объект";
    КонецЕсли;
    Возврат Значение;
КонецФункции

Процедура ПроверитьПоля85(Данные, Поля)
    Для Каждого Поле Из СтрРазделить(Поля, ",") Цикл
        Если Не Данные.Свойство(Поле) Тогда
            ВызватьИсключение "Заполните фактическое собственное поле " + Поле;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Функция НайтиСвойРабочийСервер85(Связь, Стенд, Данные, Паспорт)
    НайденныйRAS = Неопределено;
    Для Каждого Кандидат Из Стенд.RAS.ПолучитьРабочиеСерверы() Цикл
        Если Кандидат.Имя = "own-com85-worker-" + Данные.UUIDОпыта Тогда
            Если НайденныйRAS <> Неопределено Или Кандидат.ИмяКомпьютера <> "127.0.0.1"
                Или Кандидат.Порт <> Паспорт.ПортВторогоАгента Или Кандидат.ЦентральныйСервер Тогда
                ВызватьИсключение "Нельзя воздействовать на чужой или центральный рабочий сервер";
            КонецЕсли;
            НайденныйRAS = Кандидат;
        КонецЕсли;
    КонецЦикла;
    НайденныйCOM = Неопределено;
    Для Каждого Кандидат Из Связь.Агент.GetWorkingServers(Стенд.COM) Цикл
        Если Кандидат.Name = "own-com85-worker-" + Данные.UUIDОпыта Тогда
            Если НайденныйCOM <> Неопределено Или Кандидат.HostName <> "127.0.0.1"
                Или Кандидат.MainPort <> Паспорт.ПортВторогоАгента Или Кандидат.MainServer Тогда
                ВызватьИсключение "COM-паспорт собственного вторичного сервера не совпал";
            КонецЕсли;
            НайденныйCOM = Кандидат;
        КонецЕсли;
    КонецЦикла;
    Если (НайденныйRAS = Неопределено) <> (НайденныйCOM = Неопределено) Тогда
        ВызватьИсключение "Состояние рабочего сервера различается между RAS и COM";
    КонецЕсли;
    Если НайденныйRAS <> Неопределено И Не ПустаяСтрока(Паспорт.UUIDСервера) Тогда
        ПроверитьUUID85(Паспорт.UUIDСервера);
        Если Строка(НайденныйRAS.ИдентификаторРабочегоСервера) <> Паспорт.UUIDСервера Тогда
            ВызватьИсключение "Новый экземпляр сервера не совпадает с ранее сохраненным own-UUID";
        КонецЕсли;
    КонецЕсли;
    Возврат Новый Структура("COM,RAS", НайденныйCOM, НайденныйRAS);
КонецФункции

Процедура ПроверитьПаспортРабочего85(Паспорт, Данные)
    ПроверитьПоля85(Паспорт, "ПортВторогоАгента,ПортВторогоRAS,НижнийПорт,ВерхнийПорт,UUIDСервера");
    Для Каждого ИмяПоля Из СтрРазделить("ПортВторогоАгента,ПортВторогоRAS,НижнийПорт,ВерхнийПорт", ",") Цикл
        Порт = Паспорт[ИмяПоля];
        Если ТипЗнч(Порт) <> Тип("Число") Или Порт < 1 Или Порт > 65535 Или Порт <> Цел(Порт) Тогда
            ВызватьИсключение "Недопустимый фактический порт второго собственного агента или диапазона";
        КонецЕсли;
    КонецЦикла;
    Если Паспорт.ПортВторогоАгента = Данные.ПортАгента Или Паспорт.ПортВторогоRAS = Данные.ПортRAS
        Или Паспорт.ПортВторогоАгента = Паспорт.ПортВторогоRAS Или Паспорт.НижнийПорт > Паспорт.ВерхнийПорт
        Или ТипЗнч(Паспорт.UUIDСервера) <> Тип("Строка") Тогда
        ВызватьИсключение "Нужны отдельные реальные own-порты и корректный диапазон";
    КонецЕсли;
    ЗанятыеПорты = Новый Массив;
    ЗанятыеПорты.Добавить(Данные.ПортАгента);
    ЗанятыеПорты.Добавить(Данные.ПортRAS);
    ЗанятыеПорты.Добавить(Данные.ПортКластера);
    ЗанятыеПорты.Добавить(Паспорт.ПортВторогоАгента);
    ЗанятыеПорты.Добавить(Паспорт.ПортВторогоRAS);
    Уникальные = Новый Соответствие;
    Для Каждого Порт Из ЗанятыеПорты Цикл
        Если Уникальные.Получить(Порт) <> Неопределено Тогда
            ВызватьИсключение "Порты обоих собственных агентов, RAS и менеджера должны различаться";
        КонецЕсли;
        Уникальные.Вставить(Порт, Истина);
        Если Порт >= Паспорт.НижнийПорт И Порт <= Паспорт.ВерхнийПорт Тогда
            ВызватьИсключение "Своя полоса динамических портов пересекает служебный порт";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры
Модуль управляемой формы обработки: команда Выполнить

Обработка.УчебныйCOM85.Форма.Форма: полный модуль формы

Клиентский/серверный модуль управляемой формы отдельной файловой ИБ; процедуры уже содержат директивы. Поля созданы согласно подготовке.

&НаКлиенте
Процедура Выполнить(Команда)
    Данные = Новый Структура;
    Данные.Вставить("ПортАгента", ПортАгента);
    Данные.Вставить("ПортRAS", ПортRAS);
    Данные.Вставить("ПортКластера", ПортКластера);
    Данные.Вставить("ИмяАгента", ИмяАгента);
    Данные.Вставить("ПарольАгента", ПарольАгента);
    Данные.Вставить("ИмяАдминистратора", ИмяАдминистратора);
    Данные.Вставить("ПарольАдминистратора", ПарольАдминистратора);
    Данные.Вставить("UUIDОпыта", UUIDОпыта);
    Данные.Вставить("UUIDКластера", UUIDКластера);
    Данные.Вставить("Дополнительно", Дополнительно);
    ПарольАгента = "";
    ПарольАдминистратора = "";
    Дополнительно = "";
    Попытка
        Ответ = ВыполнитьНаСервере(Операция, Данные, ПодтвержденСвойСтенд);
    Исключение
        Данные.ПарольАгента = "";
        Данные.ПарольАдминистратора = "";
        Данные.Дополнительно = "";
        Сообщить("Операция не подтверждена. Не повторяйте запись автоматически. Проверьте только свой изолированный стенд и ранее записанные UUID.");
        Возврат;
    КонецПопытки;
    Данные.ПарольАгента = "";
    Данные.ПарольАдминистратора = "";
    Данные.Дополнительно = "";
    Сообщить(Ответ);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ВыполнитьНаСервере(Операция, Данные, ПодтвержденСвойСтенд)
    Возврат УчебныйCOM85.Выполнить85(Операция, Данные, ПодтвержденСвойСтенд);
КонецФункции

Разбор по шагам

  1. СоединитьсяСоСвоимАгентом85 проверяет точную платформу, новую пустую конфигурацию и явное подтверждение VM; только затем создает свои два административных подключения.

  2. RAS выполняет проверку точной версии обслуживаемого агента. COM и RAS получают разные порты; COM AuthenticateAgent принимает имя, затем пароль, тогда как RAS ВыполнитьАутентификацию принимает пароль, затем имя.

  3. ПолучитьСвойКластер85 принимает только один кластер: собственный UUID, имя с UUIDОпыта, loopback127.0.0.1 и фактический порт. UUID берется из RAS, не выдумывается как свойство COM-кластера.

  4. До операции повторно проверяется допустимый набор ИБ; по умолчанию0. Постоянная кластерная аутентификация отделена от агентской и не заменяется учетными данными временного создаваемого объекта.

  5. ИмяСервиса проверяется по GetClusterServices и реальной глобальной настройке своего основного сервера с InfoBaseName="". Пустая строка не подставляется для неизвестного сервиса ИБ.

  6. CreateServiceSetting принимает реальное сервисное имя и пустую InfoBaseName глобальной настройки. Readonly ServiceName, InfoBaseName и SettingID напрямую не записываются.

  7. ServiceDataDir — отдельная собственная папка UUID, заранее созданная человеком. RegServiceSetting сохраняет описание. Повторное чтение подтверждает имя, каталог и область; сообщается фактический SettingID.

  8. ПрименитьНастройку85 требует сохраненный UUID, нулевой план переноса и отсутствие рабочих процессов вторичного сервера. ApplyServiceSettings применяет только его набор; GetSettingActive дает фактический Булево, не выдуманный успех запуска сервиса.

  9. DeleteServiceSetting получает оригинальный COM-объект нашего UUID и отказывает при активной настройке. Повторное GetServiceSettings должно быть пустым. Физическое содержимое каталога не удаляется.

Как проверить результат

  1. Создана одна настройка своего вторичного сервера; UUID, ServiceDataDir и InfoBaseName повторно читаются.

  2. Непустой план переноса, другой UUID, иной каталог или активная настройка запрещают соответствующий изменяющий шаг.

  3. После явного удаления неактивной регистрации список пуст; своя папка и шаблон основного сервера остаются.

Ожидаемый результат

Ученик отличает регистрацию настройки, применение, фактическую активность и перенос реальных данных; ни один файл примером не переносится.

На что обратить внимание

  1. Это будущий ручной учебный запуск на собственной VM, а не уже выполненная операция. runtimeVerifiedScenarios остается0; статические проверки не гарантируют COM-регистрацию, лицензии или успешный ответ агента.

  2. Проверки выполняются перед вызовами, но не образуют распределенную транзакцию и не исключают гонку. Только один оператор может менять стенд; при любом несоответствии остановитесь.

  3. Не используйте production, копию рабочего реестра или имена чужих пользователей. Нельзя расширять разрешения рабочей базы ради COM-подключения.

  4. Пустой план не доказывает права папки или отсутствие данных в production. Вывод ограничен новым собственным сервером с0ИБ.

  5. RegServiceSetting не может при обновлении менять ServiceName/InfoBaseName. Создается новый собственный объект, readonly поля берутся из фабрики.

  6. Если реальная VM не подтверждает native-поведение, остановитесь без автоматического повтора вызова.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.