package main import ( "archive/zip" "encoding/json" "flag" "fmt" "log" "os" "strings" "time" ) func main() { var out outputServerStruct var err error var errs []error var showVer bool var verbose bool var isPlatform bool var isLocation bool version := "2603-01.8" ticketName := flag.String("ticket", "not_number", "номер тикета isp") flag.BoolVar(&showVer, "v", false, "версия") flag.BoolVar(&showVer, "version", false, "версия") flag.BoolVar(&verbose, "verbose", false, "подробно") flag.BoolVar(&isPlatform, "platform", false, "будет запущен сбор данных по платформе") flag.BoolVar(&isLocation, "location", false, "будет запущен сбор данных по локации") hwName := flag.String("hw", "", "исследуемое оборудование пример -hw switch:13") flag.Parse() if showVer { fmt.Println(version) return } now := time.Now() formatedNow := now.Format("2006-01-02_15-04") outputDir := "isp_" + *ticketName + "_" + formatedNow err = os.Mkdir(outputDir, 0644) if err != nil { log.Println(err) outputDir = "." } logInfo, logWarn, logErr := createLogger(outputDir, verbose) logInfo.Println("=====================СТАРТ СБОРА ДАННЫХ=====================") // флаг номер тикета logInfo.Println("Уточняем, что утилита запущена на сервере с платформой") logInfo.Println("Получаем информацию о BIOS : bios_info") out.BiosInfo, err = dmidecodeTSystem() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию об операционной системе: os_info") out.OperatingSystem, errs = getOs() // ставим OsRelease = NA значит вообще не получилось if len(errs) > 0 { for _, e := range errs { logWarn.Println(e) } } logInfo.Println("Получаем информацию об установленных пакетах: installed_packages") if strings.Contains(out.OperatingSystem.OsRelease, "Ubuntu") || out.OperatingSystem.AstraVersion != "" { out.InstalledPackages, err = getDebPackages() if err != nil { logWarn.Println(err) } } else { out.InstalledPackages, err = getRpmPackages() if err != nil { logWarn.Println(err) } } logInfo.Print("Получаем содержимое файла /root/.bash_history") out.RootHistory, err = getRootHistory() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию о файловой системе сервера: fs_informations") out.FsInformations, err = getFsInfo() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию о средней загрзке сервера: load_average") out.LoadAverage, err = getLa() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию о процессоре: cpu") out.Cpus, err = getCpuinfo() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию о памяти: ram") out.Ram, err = getRam() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию об аптайме: uptime") out.Uptime, err = getUptime() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию о службе времени: time_service") out.TimeService, errs = getTimeService() for _, e := range errs { logWarn.Println(e) } logInfo.Println("Получаем информацию о записях в journalctl xe p4 since 1 day ago: journalctl_entries") out.JournalctlEntries, err = getJournalctl() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию о фаерволах: firewalls") out.Firewalls, err = getFirewalls() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем информацию о правилах nftables nft list ruleset") out.NftRuleset, errs = getNftRuleset(outputDir) if err != nil { logWarn.Println(err) } for _, err := range errs { logWarn.Println(err) } logInfo.Println("Получаем информацию о сетевых настройках: network_config") out.NetworkConfig, errs = getNetworkConf() for _, e := range errs { logWarn.Println(e) } logInfo.Println("Получаем информацию о доступности необходимых интернет-ресурсов: internet_required") requiredResources := []string{"docker-registry.ispsystem.com", "download.docker.com", "download.ispsystem.com", "license.ispsystem.com", "metricreport.ispsystem.net"} for _, ispUrl := range requiredResources { ir, err := getInternetResource(ispUrl) if err != nil { logWarn.Println(err) } out.InternetRequired = append(out.InternetRequired, ir) } //TODO Тут проблемы, активные службы не попали в json logInfo.Println("Получаем информацию о настройках безопасности") if strings.Contains(out.OperatingSystem.OsRelease, "Ubuntu") { out.SecSetUbuntu, err = getSecSettingsUbuntu() if err != nil { logWarn.Println(err) } } else if strings.Contains(out.OperatingSystem.OsRelease, "Alma") { out.SecSetAlma, err = getSecSettingsAlma() if err != nil { logWarn.Println(err) } } else { out.SecSetALSE, errs = getSecSettingsAlse() for _, e := range errs { logWarn.Println(e) } } logInfo.Println("Получаем информацию docker ps -a") out.DockerPsA, err = getDockerPsA() if err != nil { logWarn.Println(err) } logInfo.Println("Информация о ресурсах контейнеров docker stats -a --no-stream") out.DockerStats, err = getDockerStats() if err != nil { logWarn.Println(err) } logInfo.Println("Получаем логи и статус supervisord") out.DockerSupervisor, errs = getDockerSupervisordLog(out, outputDir) for _, e := range errs { logWarn.Println(e) } // // // // // Запаковываем в json outJson, err := json.Marshal(out) err = os.WriteFile(outputDir+"/server_information.json", outJson, 0644) if err != nil { logErr.Println(err) } // // // // // // ПЛАТФОРМА // // // // // // // logInfo.Println("Начинаем сбор данных по ПЛАТФОРМЕ") isPlatform, errs = isDciPlatform() // // // // // НУЖНА ПРОВЕРКА // if len(errs) > 0 { for _, e := range errs { logWarn.Println(e) } logWarn.Println("В таком случае предположим, что сбор данных происходит на платформе") isPlatform = true } // // // // // // // if isPlatform { var platformStruct outputPlatformStruct runningSql, err := getRunningSqlServer() // Если я не смогу определить какой sql то тут придётся упасть, а значит файлы нужно скопировать раньше // И логи контейнеров получить тоже раньше if err != nil { logErr.Fatalln(err) } var ispDbname string if runningSql.Type == "pgsql" { ispDbname, err = checkIspDbname(runningSql) if err != nil { logErr.Fatalln(err) } } logInfo.Println("Получаем информацию из таблицы dci_location") platformStruct.DciLocations, errs = getDciLocationDB(ispDbname, runningSql) for _, e := range errs { logWarn.Println(e) } logInfo.Println("Получаем base64 docker-compose из таблицы dci_location") platformStruct.DciLocationDockerComposes, errs = getDciLocationComposeDB(ispDbname, runningSql) for _, e := range errs { logWarn.Println(e) } // logInfo.Println("Получаем информацию о задачах с ошибками за месяц") platformStruct.TaskManagerTask, errs = getDciTaskMonthErrorsDB(ispDbname, runningSql) for _, e := range errs { logWarn.Println(e) } // // Позволит прикинуть какие локации больше нагружены, и в целом нагрузку на платформу logInfo.Println("Получаем информацию о количестве оборудования по локациям") platformStruct.HwByLocations, errs = getDciLocationHWCountDB(ispDbname, runningSql, platformStruct) for _, e := range errs { logWarn.Println(e) } // logInfo.Println("Получаем информацию об установленных плагинах") platformStruct.InstalledPlugin, errs = getDciPluginsDB(ispDbname, runningSql) for _, e := range errs { logWarn.Println(e) } // // Получаем просто количество пользователей, получать какую то ещё информацию о пользователях вредно logInfo.Println("Получаем количество пользователей") platformStruct.Users, err = getDciUsersCountDB(ispDbname, runningSql) if err != nil { logWarn.Println(err) } // // Не забираем сами настройки ldap потому что они нам ничего особо не скажут, проверить мы их не можем, а сам факт передачи этой информации может смутить пользователя logInfo.Println("Проверяем наличие настроек ldap") platformStruct.Ldaps, errs = getDciLdapDB(ispDbname, runningSql) for _, e := range errs { logWarn.Println(e) } // // logInfo.Println("Получаем информацию о репозиториях операционных систем") platformStruct.Repos, errs = getDciRepoDB(ispDbname, runningSql) for _, e := range errs { logWarn.Println(e) } // logInfo.Println("Получаем шаблоны ОС из репозиториев не ispsystem") platformStruct.OsTemplates, errs = getDciOsTemplatesDB(ispDbname, runningSql, platformStruct) for _, e := range errs { logWarn.Println(e) } // logInfo.Println("Получаем инфорамцию о доверенных серверах в Real IP") platformStruct.RealIP, err = getDciRealIpDB(ispDbname, runningSql) if err != nil { logWarn.Println(err) } // // logInfo.Println("Получаем информацию о заданиях резервного копирования платформы") platformStruct.BackupTasks, errs = getDciBackupTask(ispDbname, runningSql) for _, e := range errs { logWarn.Println(e) } // //получаем информацию о лицензии dci licensse check и dci license info пока что оптимальные варианты, но было бы лучше получить непосредственно код этих флагов и встроить его сюда. logInfo.Println("Получаем информацию о лицензии") platformStruct.License, errs = getLicenseInlfo() for _, err := range errs { logWarn.Println(err) } // // Копируем файлы config.json и docker-compose.yaml, а также собираем имена всех файлов из /opt/ispsystem var copiedFiles copiedFiles logInfo.Println("Копируем config.json") err = copyFiles("/opt/ispsystem/dci/config.json", outputDir+"/config.json") if err != nil { copiedFiles.Config = "error" logWarn.Printf("Оибка при копировании файла config.json: %s", err) } else { copiedFiles.Config = "done" } logInfo.Println("Копируем install.log") err = copyFiles("/opt/ispsystem/dci/install.log", outputDir+"/config.json") if err != nil { copiedFiles.InstallLog = "error" logWarn.Printf("Оибка при копировании файла install.log: %s", err) } else { copiedFiles.InstallLog = "done" } logInfo.Println("Копируем docker-compose.yaml") err = copyFiles("/opt/ispsystem/dci/docker-compose.yaml", outputDir+"/docker-compose.yaml") if err != nil { copiedFiles.PlatformDockerCompose = "error" logWarn.Printf("Оибка при копировании файла docker-compose.yaml: %s", err) } else { copiedFiles.PlatformDockerCompose = "done" } logInfo.Println("Собираем названия файлов из директории /opt/ispsystem/") ispFiles, errs := getIspFileNames("/opt/ispsystem/") for _, er := range errs { logWarn.Printf("Ошибка получения имени файла: %err", er) } copiedFiles.FileNames = ispFiles platformStruct.CopiedFiles = copiedFiles // logInfo.Println("=====================КОНЕЦ СБОРА ДАННЫХ=====================") outJsonPlatform, err := json.Marshal(platformStruct) err = os.WriteFile(outputDir+"/dci_platform_information.json", outJsonPlatform, 0644) if err != nil { logErr.Println(err) } // // // // // HARDWARE // // // // if *hwName != "" { hw := strings.Split(*hwName, ":") if len(hw) == 1 { logErr.Printf("Оборудование %s указано неверно. Правильный формат оборудования \" -hw switch:13 \" где switch тип оборудования (switch, pdu, server, ups, san), а 13 его id", *hwName) } else { switch hw[0] { case "server": getHwServerInfo(runningSql, hw[1]) case "switch": getHwSwitchInfo(runningSql, hw[1]) } } } } else { logWarn.Fatalln("Утилитиа запущена не на сервере платформы.") } // // // // // // ЗАПАКОВКА РЕЗУЛЬТАТОВ В АРХИВ // // // // // outFiles, err := os.ReadDir(outputDir) if err != nil { fmt.Printf("Возникла ошибка %s при чтении %s из директории %s", err, outFiles, outputDir) } else { zipArchName := outputDir + ".zip" fmt.Printf("Создаём архив %s\n", zipArchName) newZipFile, err := os.Create(zipArchName) if err != nil { fmt.Printf("Ошибка %s создания архива %s", err, zipArchName) defer newZipFile.Close() } else { zipWriter := zip.NewWriter(newZipFile) for _, zFile := range outFiles { err = addToArchive(zipWriter, outputDir+"/"+zFile.Name()) if err != nil { fmt.Printf("Ошибка %s при добавлении файла %s в архив", err, zFile.Name()) } } err = zipWriter.Close() } defer newZipFile.Close() } }