# GitOps RAC - 1C Service Mode Management Го-библиотека и CLI-утилита для управления сервисным режимом информационных баз 1С:Предприятие через утилиту RAC (Remote Administration Client). ## Возможности - ✅ Включение и выключение сервисного режима 1С - ✅ Принудительное отключение всех пользователей при включении сервисного режима - ✅ Верификация операций - ✅ Поддержка retry-логики при сбоях - ✅ Маскирование паролей в логах - ✅ CLI интерфейс с поддержкой флагов - ✅ **Библиотечный API для интеграции в другие проекты** - ✅ Comprehensive logging с использованием log/slog - ✅ Конфигурация через YAML файлы (трехфайловая структура) - ✅ Поддержка контекстов для управления таймаутами - ✅ Полное покрытие тестами ## Установка ### Как CLI утилита ```bash go build -o benadis-rac.exe ./cmd ``` ### Как библиотека ```bash go get benadis-rac ``` ## Быстрый старт ### Использование как библиотека ```go package main import ( "context" "fmt" "log" "time" benadisrac "git.benadis.ru/gitops/benadis-rac/" ) func main() { // Создание клиента client, err := benadisrac.NewClient(benadisrac.Config{ ConfigPath: "config.yaml", SecretPath: "secret.yaml", ProjectPath: "project.yaml", LogLevel: "Info", }) if err != nil { log.Fatal(err) } ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Получение статуса status, err := client.GetServiceModeStatus(ctx) if err != nil { log.Fatal(err) } fmt.Printf("Service mode status: %t\n", status) // Включение сервисного режима if err := client.EnableServiceMode(ctx); err != nil { log.Fatal(err) } // Выключение сервисного режима if err := client.DisableServiceMode(ctx); err != nil { log.Fatal(err) } } ``` ### Использование как CLI ```bash # Проверка статуса ./benadis-rac.exe status # Включение сервисного режима ./benadis-rac.exe enable # Выключение сервисного режима ./benadis-rac.exe disable ``` ## Конфигурация Проект использует трехфайловую структуру конфигурации: ### config.yaml - Основная конфигурация ```yaml # Путь к rac.exe rac_path: "C:/Program Files/1cv8/8.3.27.1606/bin/rac.exe" # Таймауты connection_timeout: "30s" command_timeout: "60s" # Настройки повторных попыток retry_count: 3 retry_delay: "5s" ``` ### secret.yaml - Учетные данные ```yaml # Глобальные учетные данные cluster_admin: "admin" cluster_admin_password: "password" db_admin: "dbadmin" db_admin_password: "dbpassword" # Учетные данные для конкретных проектов projects: project1: cluster_admin: "project1_admin" cluster_admin_password: "project1_password" ``` ### project.yaml - Настройки проекта ```yaml service-mode: server_host: "localhost" server_port: 1540 rac_port: 1545 log_level: "Info" server_name: "1c-server" base_name: "test-base" command: "enable" # enable, disable, status ``` ### secret.yaml ```yaml # Настройки для аутентификации cluster_admin: "gitops" cluster_admin_password: "password" db_admin: "gitops" db_admin_password: "password" ``` ## Использование ### CLI интерфейс ```bash # Включить сервисный режим benadis-rac -command enable # Выключить сервисный режим benadis-rac -command disable # Проверить статус сервисного режима benadis-rac -command status # Использовать кастомные пути к конфигурации benadis-rac -config /path/to/config.yaml -secret /path/to/secret.yaml -command enable # Показать справку benadis-rac -help # Показать версию benadis-rac -version ``` ### Библиотечный API #### Основные типы ```go // Config конфигурация для создания клиента type Config struct { ConfigPath string // Путь к файлу конфигурации SecretPath string // Путь к файлу с секретами ProjectPath string // Путь к файлу проекта LogLevel string // Уровень логирования (Debug, Info, Warn, Error) } // ServiceModeManager интерфейс для управления сервисным режимом type ServiceModeManager interface { EnableServiceMode(ctx context.Context) error DisableServiceMode(ctx context.Context) error GetServiceModeStatus(ctx context.Context) (bool, error) } ``` #### Создание клиента ```go // Создание клиента с конфигурацией client, err := benadisrac.NewClient(benadisrac.Config{ ConfigPath: "config.yaml", SecretPath: "secret.yaml", ProjectPath: "project.yaml", LogLevel: "Info", }) if err != nil { log.Fatal(err) } // Создание клиента из готовой конфигурации appConfig, err := config.LoadConfig("config.yaml", "secret.yaml", "project.yaml") if err != nil { log.Fatal(err) } client, err := benadisrac.NewClientFromConfig(appConfig, "Debug") if err != nil { log.Fatal(err) } ``` #### Методы клиента ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Получение статуса сервисного режима status, err := client.GetServiceModeStatus(ctx) if err != nil { log.Printf("Error getting status: %v", err) } else { fmt.Printf("Service mode enabled: %t\n", status) } // Включение сервисного режима if err := client.EnableServiceMode(ctx); err != nil { log.Printf("Error enabling service mode: %v", err) } else { fmt.Println("Service mode enabled successfully") } // Выключение сервисного режима if err := client.DisableServiceMode(ctx); err != nil { log.Printf("Error disabling service mode: %v", err) } else { fmt.Println("Service mode disabled successfully") } ``` #### Обработка ошибок ```go // Пример с обработкой различных типов ошибок status, err := client.GetServiceModeStatus(ctx) if err != nil { switch { case errors.Is(err, context.DeadlineExceeded): log.Println("Operation timed out") case errors.Is(err, context.Canceled): log.Println("Operation was canceled") default: log.Printf("Unexpected error: %v", err) } return } ``` #### Полный пример ```go package main import ( "context" "fmt" "log" "time" benadisrac "git.benadis.ru/gitops/benadis-rac/" ) func main() { // Создаем клиент client, err := benadisrac.NewClient(benadisrac.Config{ ConfigPath: "config.yaml", SecretPath: "secret.yaml", ProjectPath: "project.yaml", LogLevel: "Info", }) if err != nil { log.Fatalf("Failed to create client: %v", err) } ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() // Включаем сервисный режим if err := client.EnableServiceMode(ctx); err != nil { log.Fatalf("Failed to enable service mode: %v", err) } // Проверяем статус status, err := client.GetServiceModeStatus(ctx) if err != nil { log.Fatalf("Failed to get status: %v", err) } fmt.Printf("Service mode enabled: %v\n", status) // Выключаем сервисный режим if err := client.DisableServiceMode(ctx); err != nil { log.Fatalf("Failed to disable service mode: %v", err) } } ``` ## Архитектура Проект следует принципам SOLID и использует модульную архитектуру: ``` benadis-rac/ ├── cmd/ # CLI приложение │ └── main.go ├── internal/ # Внутренние пакеты │ ├── config/ # Управление конфигурацией │ ├── constants/ # Константы │ ├── logger/ # Логирование с маскированием паролей │ ├── rac/ # Взаимодействие с RAC │ └── service/ # Бизнес-логика ├── gitops_rac.go # Публичный API ├── integration_test.go # Интеграционные тесты └── *_test.go # Unit тесты ``` ## Тестирование ### Unit тесты ```bash go test ./... ``` ### Интеграционные тесты ```bash # Запуск интеграционных тестов (требует настроенной среды) go test -tags=integration ./... # Запуск тестов с покрытием go test -cover ./... # Запуск бенчмарков go test -bench=. ./... ``` ### Пример использования Полный рабочий пример находится в директории `example/`: ```bash cd example go run main.go ``` ## Разработка ### Требования - Go 1.21+ - Доступ к кластеру 1С:Предприятие 8 - Настроенные файлы конфигурации ### Сборка ```bash # Сборка для текущей платформы go build -o benadis-rac ./cmd # Кросс-компиляция для Windows GOOS=windows GOARCH=amd64 go build -o benadis-rac.exe ./cmd # Сборка с оптимизацией размера go build -ldflags="-s -w" -o benadis-rac ./cmd ``` ### Линтинг ```bash # Установка golangci-lint go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest # Запуск линтера golangci-lint run ``` ## Лицензия MIT License - см. файл LICENSE для подробностей. ## Вклад в проект 1. Форкните репозиторий 2. Создайте ветку для новой функции (`git checkout -b feature/amazing-feature`) 3. Зафиксируйте изменения (`git commit -m 'Add amazing feature'`) 4. Отправьте в ветку (`git push origin feature/amazing-feature`) 5. Откройте Pull Request ## Поддержка Для вопросов и поддержки создайте issue в репозитории проекта.