Init
This commit is contained in:
235
internal/rac/service_mode.go
Normal file
235
internal/rac/service_mode.go
Normal file
@@ -0,0 +1,235 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user