Как произвести снятие назначения пользователя и последующее выключение виртуальной машины по действию Logoff (Logout)?¶
В данной статье рассматривается, как произвести снятие назначения (отвязку) пользователей, выключение, удаление виртуальных машин и другие действия, которые выполняются с помощью доставки сообщений из гостевой операционной системы на внешний источник, при выполнении действия Logoff (Logout) для пользователя.
Пример для операционной системы Windows¶
Установите зависимости. Скачайте архив :https://curl.se/windows/dl-7.85.0_1/curl-7.85.0_1-win64-mingw.zip.
Разархивируйте архив в директорию
C:/Programm Files
.Установите менеджер пакетов
Chocolatey
. Для этого откройте командную строку и выполните следующую команду:@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
Установите с помощью
Chocolatey
jQuery
. Для этого в командной строке выполните:chocolatey install -y jq
Перезагрузите виртуальную машину.
Для рестарта и удаления создайте файл скрипта «Рестарт, удаление виртуальной машины при событии Logout» - logout.bat. Пример скрипта приведен ниже. Поместите в
C:\scripts\
.Для логирования создайте файл скрипта «Логирование событий Login/Logout в базе данных» - journal.bat. Пример скрипта приведен ниже. Поместите в
C:\scripts\
.Важно
Пути нахождения скрипта и файлов токена (см. скрипт) должны быть доступны в правах на создание и редактирование новых файлов. Иначе скрипт не будет отрабатывать, так как при событии Logout он отрабатывает с правами пользователя, а не администратора!
Для запуска скрипта по событию Login/Logout необходимо:
Нажмите «Пуск» — «Выполнить» — введите gpedit.msc и нажмите «Enter»;
Перейдите в пункт «User Configuration» — «Windows Settings» — «Scripts (Logon/Logoff)» — «Logoff» и укажите путь к скрипту;
Перейдите в пункт «User Configuration» — «Windows Settings» — «Scripts (Logon/Logoff)» — «Logon» и укажите путь к скрипту. Учитывайте порядок выполнения скриптов при их установке.
Для автоматического завершения сессии авторизованного пользователя при отключении (по таймауту) необходимо:
Нажмите «Пуск» - «Выполнить» - введите gpedit.msc.
Далее настройте следующий параметр: Computer Configuration - Administrative Components - Windows Components - Remote Desktop Services - Remote Desktop Session - Session Time Limits - Set time limit for disconnected sessions - <set timeout> (выбрать желаемое время таймаута).
Пример скрипта для отвязки пользователя от TRS машины и последующего её выключения¶
Примечание
В скрипте должен использоваться администратор проекта домена или проекта, в котором находится виртуальная машина, так как другие, обычные пользователе не имеют права на выключение и отвязку пользователей от виртуальной машины! Также пользователь должен иметь право на чтение списка пользователей домена.
Текст скрипта:
(# при реализации комментарии стереть)
@echo off
setlocal enableextensions enabledelayedexpansion
rem set variables
# вставить IP контроллера
set controller=10.1.220.31
# логин
set login=jerry
# пароль
set pass=1pass
# проект
set tenant=testproject1
set hostname=%computername%
# функция преобразования в нижний регистр. По необходимости использования удалить «rem»
rem call :tolower hostname
# убедиться, что права на создание файлов у пользователей в каталоге есть
# лог скрипта
set logfile=c:\scripts\logout.log
set responsefile=c:\scripts\token.txt
# убедиться, что путь корректный
set curl=c:\progra~1\curl-7.84.0_9-win64-mingw\bin\curl.exe
set json="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"name\":\"msk\"},\"name\":\"%login%\",\"password\":\"%pass%\"}}},\"scope\":{\"project\":{\"domain\":{\"name\":\"msk\"},\"name\":\"%tenant%\"}}}}"
set json_adm="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"name\":\"msk\"},\"name\":\"jerry\",\"password\":\"13Qwerty\"}}},\"scope\":{\"project\":{\"domain\":{\"name\":\"msk\"},\"name\":\"testproject1\"}}}}"
rem write to log file
echo get command logout %username% at %date% %time% >> %logfile%
rem http request
%curl% -si -X POST -H "Content-type:application/json" -d %json% "http://%controller%:5000/v3/auth/tokens" | findstr X-Subject-Token > %responsefile%
rem get token
set /p response=<%responsefile%
set token=%response:~17%
echo - get token >> %logfile%
rem get userid
%curl% -s -X GET -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:5000/v3/users" | jq ".users[] | select(.name==\"%username%\").id" > %responsefile%
set /p userid=<%responsefile%
echo - get id user %username% - %userid% >> %logfile%
rem get tenantid
%curl% -s -X GET -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:5000/v3/projects" | jq ".projects[] | select(.name==\"%tenant%\").id" > %responsefile%
set /p tenantid=<%responsefile%
echo - get id tenant %tenant% - %tenantid% >> %logfile%
rem http request
%curl% -si -X POST -H "Content-type:application/json" -d %json% "http://%controller%:5000/v3/auth/tokens" | findstr X-Subject-Token > %responsefile%
rem get token
set /p response=<%responsefile%
set token=%response:~17%
echo - get token >> %logfile%
rem get id vm
%curl% -s -X GET -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:8774/v2.1/servers" | jq ".servers[] | select(.name==\"%hostname%\").id" > %responsefile%
set /p vm=<%responsefile%
echo - get id vm %hostname% - %vm% >> %logfile%
rem unassign user from vm
%curl% -X DELETE -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:9364/v1/servers/%vm%/users/%userid%" | jq ".users[] | select(.name==\"%username%\").id" > %responsefile%
echo - unassign user %username% from vm %vm% >> %logfile%
rem poweroff vm
%curl% -s -X POST -H "X-Auth-Token: %token%" -H "Content-type:application/json" -d "{\"os-stop\" : null}" "http://%controller%:8774/v2.1/servers/%vm%/action"
echo - shutoff vm %vm% >> %logfile%
rem delay and write to log file
timeout 30 > nul
echo after sleping 30 sec %date% %time% >> %logfile%
echo ----- >> %logfile%
rem delete temp files
del %responsefile%
goto :END
:tolower
for %%L in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set %1=!%1:%%L=%%L!
goto :EOF
:END
Пример скрипта для логирования события Logout в базе данных¶
Текст скрипта:
(# при реализации комментарии стереть)
@echo off
setlocal enableextensions enabledelayedexpansion
rem set variables
# вставить IP контроллера
set controller=10.1.220.31
# логин
set login=peppa
# пароль
set pass=13Qwerty
# проект
set tenant=testproject1
set hostname=%computername%
# функция преобразования в нижний регистр. По необходимости использования удалить «rem»
call :tolower hostname
# убедиться, что права на создание файлов у пользователей в каталоге есть
# лог скрипта
set logfile=c:\scripts\journal.log
set responsefile=c:\scripts\token.txt
# убедиться, что путь корректный
set curl=c:\progra~1\curl-7.84.0_9-win64-mingw\bin\curl.exe
set json_adm="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"name\":\"msk\"},\"name\":\"%login%\",\"password\":\"%pass%\"}}},\"scope\":{\"domain\":{\"name\":\"msk\"}}}}"
rem write to log file
echo get command logout %username% at %date% %time% >> %logfile%
rem http request
%curl% -si -X POST -H "Content-type:application/json" -d %json_adm% "http://%controller%:5000/v3/auth/tokens" | findstr X-Subject-Token > %responsefile%
rem get token
set /p response=<%responsefile%
set token=%response:~17%
echo - get token >> %logfile%
rem get ip
for /f "delims=[] tokens=2" %%a in ('ping -4 -n 1 %ComputerName% ^| findstr [') do set ip=%%a
rem get id vm
%curl% -s -X GET -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:8774/v2.1/servers" | jq ".servers[] | select(.name==\"%hostname%\").id" > %responsefile%
set /p vm=<%responsefile%
echo - get id vm %hostname% - %vm% >> %logfile%
rem add record to journal
set json_journal="{\"journal\":{\"object_id\": \"%vm%\",\"object_type\":\"server\",\"action\":\"logout\",\"status\":\"success\",\"user_name\":\"%username%\",\"message\":\"%ip%\",\"domain_id\":\"d1949bd531b24445921669165cf2813d\"}}"
%curl% -X POST -H "X-Auth-Token: %token%" -H "Content-type:application/json" -d %json_journal% "http://%controller%:9360/v1/journal/"
echo - add record to journal >> %logfile%
rem write to log file
echo ----- >> %logfile%
rem delete temp files
del %responsefile%
goto :END
:tolower
for %%L in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set %1=!%1:%%L=%%L!
goto :EOF
:END