236 lines
7.8 KiB
Go
236 lines
7.8 KiB
Go
package rac
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"strings"
|
||
|
||
"git.benadis.ru/gitops/benadis-rac/internal/constants"
|
||
)
|
||
|
||
// EnableServiceMode включает сервисный режим
|
||
func (c *Client) EnableServiceMode(ctx context.Context, params ServiceModeParams) error {
|
||
c.logger.Info(constants.LogMsgEnablingServiceMode, "cluster_uuid", params.ClusterUUID, "infobase_uuid", params.InfobaseUUID)
|
||
|
||
// Сначала отключаем всех пользователей
|
||
if err := c.TerminateAllSessions(ctx, params.ClusterUUID, params.InfobaseUUID); err != nil {
|
||
c.logger.Warn(constants.LogMsgFailedToTerminateAllSessions, "error", err)
|
||
// Продолжаем выполнение, так как это не критичная ошибка
|
||
}
|
||
|
||
// Получаем учетные данные
|
||
clusterUser, clusterPwd := c.config.GetClusterCredentials("")
|
||
dbUser, dbPwd := c.config.GetDBCredentials("")
|
||
|
||
// Включаем сервисный режим
|
||
args := []string{
|
||
c.config.GetRACAddress(),
|
||
"infobase", "update",
|
||
"--cluster=" + params.ClusterUUID,
|
||
"--infobase=" + params.InfobaseUUID,
|
||
"--sessions-deny=" + constants.SERVICE_MODE_ON,
|
||
"--scheduled-jobs-deny=" + constants.SERVICE_MODE_ON,
|
||
"--denied-message=" + params.DeniedMessage,
|
||
"--permission-code=" + params.PermissionCode,
|
||
"--cluster-user=" + clusterUser,
|
||
"--cluster-pwd=" + clusterPwd,
|
||
"--infobase-user=" + dbUser,
|
||
"--infobase-pwd=" + dbPwd,
|
||
}
|
||
|
||
_, err := c.ExecuteCommand(ctx, args)
|
||
if err != nil {
|
||
return fmt.Errorf(constants.ErrEnableServiceMode, err)
|
||
}
|
||
|
||
c.logger.Info(constants.LogMsgServiceModeEnabled)
|
||
|
||
// Верифицируем результат
|
||
return c.VerifyServiceMode(ctx, params.ClusterUUID, params.InfobaseUUID, true)
|
||
}
|
||
|
||
// DisableServiceMode выключает сервисный режим
|
||
func (c *Client) DisableServiceMode(ctx context.Context, params ServiceModeParams) error {
|
||
c.logger.Info(constants.LogMsgDisablingServiceMode, "cluster_uuid", params.ClusterUUID, "infobase_uuid", params.InfobaseUUID)
|
||
|
||
// Получаем учетные данные
|
||
clusterUser, clusterPwd := c.config.GetClusterCredentials("")
|
||
dbUser, dbPwd := c.config.GetDBCredentials("")
|
||
|
||
args := []string{
|
||
c.config.GetRACAddress(),
|
||
"infobase", "update",
|
||
"--cluster=" + params.ClusterUUID,
|
||
"--infobase=" + params.InfobaseUUID,
|
||
"--sessions-deny=" + constants.SERVICE_MODE_OFF,
|
||
"--scheduled-jobs-deny=" + constants.SERVICE_MODE_OFF,
|
||
"--cluster-user=" + clusterUser,
|
||
"--cluster-pwd=" + clusterPwd,
|
||
"--infobase-user=" + dbUser,
|
||
"--infobase-pwd=" + dbPwd,
|
||
}
|
||
|
||
_, err := c.ExecuteCommand(ctx, args)
|
||
if err != nil {
|
||
return fmt.Errorf(constants.ErrDisableServiceMode, err)
|
||
}
|
||
|
||
c.logger.Info(constants.LogMsgServiceModeDisabled)
|
||
|
||
// Верифицируем результат
|
||
return c.VerifyServiceMode(ctx, params.ClusterUUID, params.InfobaseUUID, false)
|
||
}
|
||
|
||
// TerminateAllSessions принудительно завершает все сессии пользователей
|
||
func (c *Client) TerminateAllSessions(ctx context.Context, clusterUUID, infobaseUUID string) error {
|
||
c.logger.Info(constants.LogMsgTerminatingAllSessions, "cluster_uuid", clusterUUID, "infobase_uuid", infobaseUUID)
|
||
|
||
// Получаем список сессий
|
||
sessions, err := c.GetSessions(ctx, clusterUUID, infobaseUUID)
|
||
if err != nil {
|
||
return fmt.Errorf(constants.ErrGetSessions, err)
|
||
}
|
||
|
||
if len(sessions) == 0 {
|
||
c.logger.Info(constants.LogMsgNoActiveSessions)
|
||
return nil
|
||
}
|
||
|
||
c.logger.Info(constants.LogMsgFoundActiveSessions, "count", len(sessions))
|
||
|
||
// Завершаем каждую сессию
|
||
for _, sessionUUID := range sessions {
|
||
if err := c.TerminateSession(ctx, clusterUUID, sessionUUID); err != nil {
|
||
c.logger.Warn(constants.LogMsgFailedToTerminateSession, "session_uuid", sessionUUID, "error", err)
|
||
// Продолжаем с другими сессиями
|
||
} else {
|
||
c.logger.Debug(constants.LogMsgSessionTerminated, "session_uuid", sessionUUID)
|
||
}
|
||
}
|
||
|
||
c.logger.Info(constants.LogMsgAllSessionsTerminated)
|
||
return nil
|
||
}
|
||
|
||
// GetSessions получает список активных сессий
|
||
func (c *Client) GetSessions(ctx context.Context, clusterUUID, infobaseUUID string) ([]string, error) {
|
||
// Получаем учетные данные кластера
|
||
clusterUser, clusterPwd := c.config.GetClusterCredentials("")
|
||
|
||
args := []string{
|
||
c.config.GetRACAddress(),
|
||
"session", "list",
|
||
"--cluster=" + clusterUUID,
|
||
"--infobase=" + infobaseUUID,
|
||
"--cluster-user=" + clusterUser,
|
||
"--cluster-pwd=" + clusterPwd,
|
||
}
|
||
|
||
output, err := c.ExecuteCommand(ctx, args)
|
||
if err != nil {
|
||
return nil, fmt.Errorf(constants.ErrGetSessionList, err)
|
||
}
|
||
|
||
var sessions []string
|
||
lines := strings.Split(output, "\n")
|
||
|
||
for _, line := range lines {
|
||
line = strings.TrimSpace(line)
|
||
// Ищем строки вида "session : <uuid>"
|
||
if strings.HasPrefix(line, "session") && strings.Contains(line, ":") {
|
||
parts := strings.SplitN(line, ":", 2)
|
||
if len(parts) == 2 {
|
||
sessionUUID := strings.TrimSpace(parts[1])
|
||
// Проверяем, что это действительно UUID (36 символов с дефисами)
|
||
if len(sessionUUID) == constants.UUIDLength && strings.Count(sessionUUID, "-") == constants.UUIDDashCount {
|
||
sessions = append(sessions, sessionUUID)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return sessions, nil
|
||
}
|
||
|
||
// TerminateSession завершает конкретную сессию
|
||
func (c *Client) TerminateSession(ctx context.Context, clusterUUID, sessionUUID string) error {
|
||
// Получаем учетные данные кластера
|
||
clusterUser, clusterPwd := c.config.GetClusterCredentials("")
|
||
|
||
args := []string{
|
||
c.config.GetRACAddress(),
|
||
"session", "terminate",
|
||
"--cluster=" + clusterUUID,
|
||
"--session=" + sessionUUID,
|
||
"--error-message=" + constants.TechnicalMaintenanceMessage,
|
||
"--cluster-user=" + clusterUser,
|
||
"--cluster-pwd=" + clusterPwd,
|
||
}
|
||
|
||
_, err := c.ExecuteCommand(ctx, args)
|
||
if err != nil {
|
||
return fmt.Errorf(constants.ErrTerminateSession, sessionUUID, err)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// VerifyServiceMode проверяет состояние сервисного режима
|
||
func (c *Client) VerifyServiceMode(ctx context.Context, clusterUUID, infobaseUUID string, expectedEnabled bool) error {
|
||
c.logger.Info(constants.LogMsgVerifyingServiceMode, "cluster_uuid", clusterUUID, "infobase_uuid", infobaseUUID, "expected_enabled", expectedEnabled)
|
||
|
||
// Получаем учетные данные
|
||
clusterUser, clusterPwd := c.config.GetClusterCredentials("")
|
||
dbUser, dbPwd := c.config.GetDBCredentials("")
|
||
|
||
args := []string{
|
||
c.config.GetRACAddress(),
|
||
"infobase", "info",
|
||
"--cluster=" + clusterUUID,
|
||
"--infobase=" + infobaseUUID,
|
||
"--cluster-user=" + clusterUser,
|
||
"--cluster-pwd=" + clusterPwd,
|
||
"--infobase-user=" + dbUser,
|
||
"--infobase-pwd=" + dbPwd,
|
||
}
|
||
|
||
output, err := c.ExecuteCommand(ctx, args)
|
||
if err != nil {
|
||
return fmt.Errorf(constants.ErrGetInfobaseInfo, err)
|
||
}
|
||
|
||
lines := strings.Split(output, "\n")
|
||
var sessionsDeny, scheduledJobsDeny string
|
||
|
||
for _, line := range lines {
|
||
line = strings.TrimSpace(line)
|
||
if strings.HasPrefix(line, "sessions-deny") {
|
||
parts := strings.Split(line, ":")
|
||
if len(parts) >= 2 {
|
||
sessionsDeny = strings.TrimSpace(parts[1])
|
||
}
|
||
} else if strings.HasPrefix(line, "scheduled-jobs-deny") {
|
||
parts := strings.Split(line, ":")
|
||
if len(parts) >= 2 {
|
||
scheduledJobsDeny = strings.TrimSpace(parts[1])
|
||
}
|
||
}
|
||
}
|
||
|
||
expectedState := constants.SERVICE_MODE_OFF
|
||
if expectedEnabled {
|
||
expectedState = constants.SERVICE_MODE_ON
|
||
}
|
||
|
||
if sessionsDeny != expectedState {
|
||
return fmt.Errorf(constants.ErrSessionsDenyVerification, expectedState, sessionsDeny)
|
||
}
|
||
|
||
if scheduledJobsDeny != expectedState {
|
||
return fmt.Errorf(constants.ErrScheduledJobsDenyVerification, expectedState, scheduledJobsDeny)
|
||
}
|
||
|
||
c.logger.Info(constants.LogMsgServiceModeVerificationSuccessful, "sessions_deny", sessionsDeny, "scheduled_jobs_deny", scheduledJobsDeny)
|
||
return nil
|
||
}
|