first
This commit is contained in:
600
DCIManager6/dci6-support/server_info.go
Normal file
600
DCIManager6/dci6-support/server_info.go
Normal file
@@ -0,0 +1,600 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
// "bufio"
|
||||
// "fmt"
|
||||
// "io/ioutil"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// ОС серверов Платформа и Локации
|
||||
// (источник ОС)
|
||||
// - Серверная платформа
|
||||
// dmidecode -t system
|
||||
|
||||
func dmidecodeTSystem() (biosInfo, error) {
|
||||
var biosInfo biosInfo
|
||||
// нужно получить информацию из bios
|
||||
// cat /sys/firmware/dmi/entries/1-0/raw
|
||||
bi, err := os.ReadFile("/sys/firmware/dmi/entries/1-0/raw")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка получения dmi данных: %s", err)
|
||||
}
|
||||
biosInfo.Name = string(bi)
|
||||
return biosInfo, nil
|
||||
|
||||
}
|
||||
|
||||
// - Операционная система
|
||||
// cat /etc/os-release
|
||||
// cat /etc/astra_version
|
||||
// cat /etc/astra_license
|
||||
|
||||
func getOs() (operatingSystem, []error) {
|
||||
var opsys operatingSystem
|
||||
var errors []error
|
||||
|
||||
fOsInfo, err := os.ReadFile("/etc/os-release")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка чтения os-release: %s", err)
|
||||
errors = append(errors, err)
|
||||
} else {
|
||||
osInfoSpl := strings.Split(string(fOsInfo), "\n")
|
||||
for _, r := range osInfoSpl {
|
||||
capt, _ := regexp.MatchString("PRETTY_NAME*", r)
|
||||
if capt {
|
||||
opsys.OsRelease = strings.Split(r, "=")[1]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err = os.Stat("/etc/astra_version")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("ошибка чтения asrta_version")
|
||||
errors = append(errors, err)
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return opsys, errors
|
||||
}
|
||||
|
||||
// - Пакеты
|
||||
// apt list --installed
|
||||
|
||||
func getDebPackages() ([]installedPackage, error) {
|
||||
// читаем /var/lib/dpkg/status
|
||||
var debPackages []installedPackage
|
||||
|
||||
b_dpkgStatus, err := os.ReadFile("/var/lib/dpkg/status")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка чтения файла /var/lib/dpkg/status: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dpkgStatus := strings.Split(string(b_dpkgStatus), "\n\n")
|
||||
for _, ds := range dpkgStatus {
|
||||
var debPackage installedPackage
|
||||
if len(ds) == 0 {
|
||||
continue
|
||||
}
|
||||
ds_s := strings.Split(ds, "\n")
|
||||
for _, d := range ds_s {
|
||||
if strings.Contains(d, "Package: ") {
|
||||
debPackage.Name = strings.Split(d, ": ")[1]
|
||||
}
|
||||
if strings.Contains(d, "Version: ") {
|
||||
debPackage.Version = strings.Split(d, ": ")[1]
|
||||
}
|
||||
}
|
||||
debPackages = append(debPackages, debPackage)
|
||||
}
|
||||
|
||||
return debPackages, err
|
||||
}
|
||||
|
||||
func getRpmPackages() ([]installedPackage, error) {
|
||||
var rpmPackages []installedPackage
|
||||
|
||||
cmd := exec.Command("rpm", "-qa", "--queryformat", "%{NAME};%{VERSION}\n")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка выпонения команды rpm -qa: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
scanner := bufio.NewScanner(strings.NewReader(string(output)))
|
||||
for scanner.Scan() {
|
||||
var instpack installedPackage
|
||||
line := scanner.Text()
|
||||
parts := strings.Split(line, ";")
|
||||
instpack.Name = parts[0]
|
||||
instpack.Version = parts[1]
|
||||
rpmPackages = append(rpmPackages, instpack)
|
||||
}
|
||||
return rpmPackages, err
|
||||
}
|
||||
|
||||
// - Размер диска и объем свободного места на диске
|
||||
// lsblk
|
||||
// df
|
||||
// df -i
|
||||
|
||||
func getFsInfo() ([]fsInfo, error) {
|
||||
var fsInfoList []fsInfo
|
||||
fProcMounts, err := os.ReadFile("/proc/mounts")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка чтения файла /proc/mounts : %s", err)
|
||||
return fsInfoList, err
|
||||
}
|
||||
for _, mp := range strings.Split(string(fProcMounts), "\n") {
|
||||
var fi fsInfo
|
||||
var sysStatfs syscall.Statfs_t
|
||||
if len(mp) == 0 {
|
||||
continue
|
||||
}
|
||||
mp_s := strings.Split(mp, " ")
|
||||
fi.MountPointDevice = mp_s[0]
|
||||
fi.MountPointOsPath = mp_s[1]
|
||||
err = syscall.Statfs(fi.MountPointOsPath, &sysStatfs)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
} else {
|
||||
fi.MountPointSize = sysStatfs.Blocks * uint64(sysStatfs.Bsize)
|
||||
fi.MountPointFree = sysStatfs.Blocks * uint64(sysStatfs.Bfree)
|
||||
}
|
||||
fsInfoList = append(fsInfoList, fi)
|
||||
// fmt.Printf("Dev: %s Path: %s Size: %d Free: %d \n", fi.MountPointDevice, fi.MountPointOsPath, fi.MountPointSize, fi.MountPointFree)
|
||||
}
|
||||
return fsInfoList, err
|
||||
}
|
||||
|
||||
// - LA
|
||||
// top -bn1 | head -n 1
|
||||
// cat /proc/loadavg
|
||||
|
||||
func getLa() (loadAverage, error) {
|
||||
var la loadAverage
|
||||
laFile, err := os.ReadFile("/proc/loadavg")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("файл proc loadavg недоступен %s", err)
|
||||
return la, err
|
||||
}
|
||||
laFileSplit := strings.Split(string(laFile), " ")
|
||||
la.OneMin = laFileSplit[0]
|
||||
la.FiveMin = laFileSplit[1]
|
||||
la.FifteenMin = laFileSplit[2]
|
||||
la.Processes = laFileSplit[3]
|
||||
|
||||
return la, nil
|
||||
}
|
||||
|
||||
// - Процессор
|
||||
// cat /proc/cpuinfo
|
||||
// lscpu
|
||||
|
||||
// func getCpu() (cpu, error) {
|
||||
// var cpu cpu
|
||||
// cpuFile, err := os.ReadFile("/proc/cpuinfo")
|
||||
// if err != nil {
|
||||
// err = fmt.Errorf("Проблема с доступом к файлу proc cpuinfo %s", err)
|
||||
// return cpu, err
|
||||
// }
|
||||
// prevCpu := " "
|
||||
// for _, line := range strings.Split(string(cpuFile), "\n") {
|
||||
// matched, err := regexp.Match("model name", []byte(line))
|
||||
// if err != nil {
|
||||
// err = fmt.Errorf("Ошибка при оценке регулярного выражения %s", err)
|
||||
// return cpu, err
|
||||
// }
|
||||
// if matched {
|
||||
// cpuFound := strings.Split(line, ":")[1]
|
||||
// if cpuFound != prevCpu {
|
||||
// cpu.Model = append(cpu.Model, cpuFound)
|
||||
// prevCpu = cpuFound
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return cpu, nil
|
||||
// }
|
||||
func getCpuinfo() ([]cpu, error) {
|
||||
var cpus []cpu
|
||||
var err error
|
||||
rawCpuinfo, err := os.ReadFile("/proc/cpuinfo")
|
||||
|
||||
var c cpu
|
||||
var physId []string
|
||||
physId = append(physId, "a")
|
||||
for _, cpuLine := range strings.Split(string(rawCpuinfo), "\n") {
|
||||
if len(strings.TrimSpace(cpuLine)) == 0 {
|
||||
controlPoint := 0
|
||||
for _, arrayIndex := range physId {
|
||||
if c.PhysicalId == "" {
|
||||
controlPoint = 1
|
||||
}
|
||||
if arrayIndex == c.PhysicalId {
|
||||
controlPoint = 1
|
||||
}
|
||||
}
|
||||
if controlPoint == 0 {
|
||||
cpus = append(cpus, c)
|
||||
physId = append(physId, c.PhysicalId)
|
||||
c = cpu{}
|
||||
} else {
|
||||
c = cpu{}
|
||||
}
|
||||
} else {
|
||||
if strings.Contains(cpuLine, "vendor_id") {
|
||||
c.VendorId = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "cpu family") {
|
||||
c.CpuFamily = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "model") && !strings.Contains(cpuLine, "name") {
|
||||
c.Model = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "model name") {
|
||||
c.ModelName = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "stepping") {
|
||||
c.Stepping = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "microcode") {
|
||||
c.Microcode = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "cpu MHz") {
|
||||
c.CpuMhz = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "cache size") {
|
||||
c.CacheSize = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "physical id") {
|
||||
c.PhysicalId = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "cpu cores") {
|
||||
c.CpuCores = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "flags") {
|
||||
c.Flags = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "bugs") {
|
||||
c.Bugs = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "bogomips") {
|
||||
c.Bogomips = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "TLB size") {
|
||||
c.TlbSize = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "clflush size") {
|
||||
c.ClflushSize = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "cache_alignment") {
|
||||
c.CacheAlignment = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "address size") {
|
||||
c.AddressSize = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
if strings.Contains(cpuLine, "power management") {
|
||||
c.PowerManagement = strings.TrimSpace(strings.Split(cpuLine, ":")[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
return cpus, err
|
||||
}
|
||||
|
||||
// - Объём и тип ОЗУ, объём свободной памяти в моменте
|
||||
// vmstat -s
|
||||
// free
|
||||
// /proc/meminfo
|
||||
|
||||
func getRam() (ram, error) {
|
||||
var ram ram
|
||||
ramFile, err := os.ReadFile("/proc/meminfo")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Проблема с доступом к файлу proc meminfo %s", err)
|
||||
return ram, err
|
||||
}
|
||||
for _, line := range strings.Split(string(ramFile), "\n") {
|
||||
matched, _ := regexp.Match("MemTotal", []byte(line))
|
||||
if matched {
|
||||
ram.MemTotal = strings.Trim(strings.Split(line, ":")[1], " ")
|
||||
}
|
||||
matched, _ = regexp.Match("MemFree", []byte(line))
|
||||
if matched {
|
||||
ram.MemFree = strings.Trim(strings.Split(line, ":")[1], " ")
|
||||
}
|
||||
matched, _ = regexp.Match("Available", []byte(line))
|
||||
if matched {
|
||||
ram.MemAvailable = strings.Trim(strings.Split(line, ":")[1], " ")
|
||||
}
|
||||
}
|
||||
return ram, nil
|
||||
}
|
||||
|
||||
// - Uptime сервера
|
||||
// uptime
|
||||
|
||||
func getUptime() (uptime, error) {
|
||||
var uptime uptime
|
||||
uptimeFile, err := os.ReadFile("/proc/uptime")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка досутпа к файлу proc uptime: %s", err)
|
||||
return uptime, err
|
||||
}
|
||||
uptime.WorkSeconds = strings.Split(string(uptimeFile), " ")[0]
|
||||
return uptime, nil
|
||||
}
|
||||
|
||||
// - NTP (nrp ntpsec chrony)
|
||||
// Запущен ли сервис, выполнялась ли синхронизация
|
||||
// date -R на всех серверах инфраструктуры
|
||||
|
||||
func getTimeService() (timeService, []error) {
|
||||
var timeService timeService
|
||||
var errors []error
|
||||
cmd := exec.Command("timedatectl", "show", "--property=NTPSynchronized")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка получения данных timedatectl: %s", err)
|
||||
errors = append(errors, err)
|
||||
err = nil
|
||||
}
|
||||
timeService.TimeSync = strings.Trim(strings.Split(string(output), "=")[1], "\n")
|
||||
dir, err := os.ReadDir("/run/systemd/units")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка при получении содержимого run systemd units : %s", err)
|
||||
errors = append(errors, err)
|
||||
err = nil
|
||||
} else {
|
||||
for _, entry := range dir {
|
||||
matchedChrony, _ := regexp.Match("chrony", []byte(entry.Name()))
|
||||
if matchedChrony {
|
||||
timeService.TimeService = strings.Split(entry.Name(), ":")[1]
|
||||
break
|
||||
}
|
||||
matchedNtp, _ := regexp.Match("ntp", []byte(entry.Name()))
|
||||
if matchedNtp {
|
||||
timeService.TimeService = strings.Split(entry.Name(), ":")[1]
|
||||
break
|
||||
}
|
||||
timeService.TimeService = "nothing"
|
||||
}
|
||||
}
|
||||
return timeService, errors
|
||||
}
|
||||
|
||||
// - Стандартный сбор ошибок
|
||||
// journalctl -xe -p4 -o json-pretty
|
||||
// dmesg -T --level=err,warn
|
||||
|
||||
// dmesg \| grep -i -E 'error\|failed\|critical\|bug\|panic' или dmesg --level=warn,err
|
||||
// journalctl \| grep -i -E 'error\|failed\|critical\|bug\|panic' или journalctl -xe -p 4 можно since "1 day ago" -o json-pretty
|
||||
// journalctl -xe -p 4 --since "1 day ago" -o json-pretty
|
||||
|
||||
func getJournalctl() ([]journalctlEntry, error) {
|
||||
var jList []journalctlEntry
|
||||
cmd := exec.Command("journalctl", "-xe", "-p 4", "--since", "1 day ago", "-o", "json-pretty")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка выполнения команды journalctl -xe -p 4 --since '5 minutes ago' -o json-pretty : %s", err)
|
||||
return jList, err
|
||||
}
|
||||
|
||||
outputSplited := strings.Split(string(output), "}\n{")
|
||||
for _, event := range outputSplited {
|
||||
var je journalctlEntry
|
||||
if len(event) == 0 {
|
||||
continue
|
||||
}
|
||||
event = strings.Trim(event, "{}")
|
||||
eventFull := "{" + event + "}"
|
||||
// err = json.Unmarshal([]byte(eventFull), &je)
|
||||
buf := bytes.NewBuffer([]byte(eventFull))
|
||||
err = json.NewDecoder(buf).Decode(&je)
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка десериализации данных: %s в итерации %s", err, eventFull)
|
||||
return jList, err
|
||||
}
|
||||
jList = append(jList, je)
|
||||
}
|
||||
|
||||
return jList, nil
|
||||
}
|
||||
|
||||
// - Порты
|
||||
// nmap от Платформы к Локациям и наоборот
|
||||
// оставим пока, двигаем в самый низ, как реализовать пока не представляю. Нужны проверки портов с учетом фаерволов
|
||||
// возможно это будет выполнение в лоб команды docker exec -it dci_back dcissh -a "nmap"
|
||||
// пока вместо открытых портов проверим запущен ли фаервол
|
||||
|
||||
func getFirewalls() (firewalls, error) {
|
||||
var fwl firewalls
|
||||
units, err := os.ReadDir("/run/systemd/units")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка при получении содержимого run systemd units : %s", err)
|
||||
return fwl, err
|
||||
} else {
|
||||
for _, unit := range units {
|
||||
ufw, _ := regexp.Match("ufw", []byte(unit.Name()))
|
||||
if ufw {
|
||||
fwl.Ufw = "running"
|
||||
}
|
||||
nftables, _ := regexp.Match("nftables", []byte(unit.Name()))
|
||||
if nftables {
|
||||
fwl.Nftables = "running"
|
||||
}
|
||||
iptables, _ := regexp.Match("iptables", []byte(unit.Name()))
|
||||
if iptables {
|
||||
fwl.Iptables = "running"
|
||||
}
|
||||
firewalld, _ := regexp.Match("firewalld", []byte(unit.Name()))
|
||||
if firewalld {
|
||||
fwl.Firewalld = "running"
|
||||
}
|
||||
}
|
||||
}
|
||||
return fwl, nil
|
||||
}
|
||||
|
||||
// - Настройки сети
|
||||
// NetworkManager
|
||||
// настройки интерфейсов
|
||||
// etc/hosts
|
||||
// etc/resolv.conf
|
||||
|
||||
func getNetworkConf() (networkConfig, []error) {
|
||||
var networkConfig networkConfig
|
||||
var errors []error
|
||||
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка при получении сетевых интерфейсов: %s", err)
|
||||
errors = append(errors, err)
|
||||
err = nil
|
||||
} else {
|
||||
for _, interf := range interfaces {
|
||||
var netInterface netInterface
|
||||
netInterface.Device = interf.Name
|
||||
netInterface.Flags = interf.Flags.String()
|
||||
netInterface.HwAddr = interf.HardwareAddr.String()
|
||||
adrs, _ := interf.Addrs()
|
||||
for _, adr := range adrs {
|
||||
netInterface.IpAddr = append(netInterface.IpAddr, adr.String())
|
||||
}
|
||||
netInterface.Index = strconv.Itoa(interf.Index)
|
||||
netInterface.MTU = strconv.Itoa(interf.MTU)
|
||||
networkConfig.NetInterfaces = append(networkConfig.NetInterfaces, netInterface)
|
||||
// fmt.Printf("interf: %v\n", interf)
|
||||
}
|
||||
}
|
||||
|
||||
units, err := os.ReadDir("/run/systemd/units")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка при получении содержимого run systemd units : %s", err)
|
||||
errors = append(errors, err)
|
||||
err = nil
|
||||
} else {
|
||||
for _, unit := range units {
|
||||
// Полчить статус NetworkManager
|
||||
matched, _ := regexp.Match("NetworkManager.services", []byte(unit.Name()))
|
||||
if matched {
|
||||
networkConfig.NetworkManager = "running"
|
||||
}
|
||||
// Полчить статус networking
|
||||
matchedNetworking, _ := regexp.Match("networking", []byte(unit.Name()))
|
||||
if matchedNetworking {
|
||||
networkConfig.Networking = "running"
|
||||
}
|
||||
}
|
||||
}
|
||||
nmConns, err := os.ReadDir("/run/NetworkManager/system-connections")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка при получении содержимого run NetworkManager")
|
||||
errors = append(errors, err)
|
||||
err = nil
|
||||
} else {
|
||||
for _, nmConn := range nmConns {
|
||||
networkConfig.NetworkManagerConn = append(networkConfig.NetworkManagerConn, nmConn.Name())
|
||||
}
|
||||
}
|
||||
|
||||
// Содержимое /etc/hosts
|
||||
linesByte, err := os.ReadFile("/etc/hosts")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка при получении содержимого etc hosts : %s", err)
|
||||
errors = append(errors, err)
|
||||
err = nil
|
||||
} else {
|
||||
lines := strings.Split(string(linesByte), "\n")
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
} else {
|
||||
networkConfig.EtcHosts = append(networkConfig.EtcHosts, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
return networkConfig, errors
|
||||
}
|
||||
|
||||
// Возможность доступа к основным ресурсам в internet
|
||||
// docker-registry.ispsystem.com, download.docker.com — для доступа к Docker;
|
||||
// download.ispsystem.com — для обновления и установки платформы;
|
||||
// license6.ispsystem.com — для проверки лицензий;
|
||||
// metricreport.ispsystem.net — для работы сервера метрик.
|
||||
|
||||
func getInternetResource(ispUrl string) (internetResource, error) {
|
||||
var ir internetResource
|
||||
var outErr error
|
||||
ipList, err := net.LookupIP(ispUrl)
|
||||
if err != nil {
|
||||
return ir, err
|
||||
}
|
||||
ir.Name = ispUrl
|
||||
var i []string
|
||||
for _, ip := range ipList {
|
||||
i = append(i, ip.String())
|
||||
}
|
||||
ir.IpList = strings.Join(i, ",")
|
||||
|
||||
httpUrl := "http://" + ispUrl
|
||||
httpsUrl := "https://" + ispUrl
|
||||
|
||||
resp, err := http.Get(httpUrl)
|
||||
if err != nil {
|
||||
outErr = fmt.Errorf("Ошибка HTTP %s :: %s. ", httpUrl, err)
|
||||
ir.Http = err.Error()
|
||||
} else {
|
||||
ir.Http = strconv.Itoa(resp.StatusCode)
|
||||
}
|
||||
|
||||
resp, err = http.Get(httpsUrl)
|
||||
if err != nil {
|
||||
outErr = fmt.Errorf("%s Ошибка HTTPS %s :: %s", outErr, httpUrl, err)
|
||||
ir.Https = err.Error()
|
||||
} else {
|
||||
ir.Https = strconv.Itoa(resp.StatusCode)
|
||||
}
|
||||
return ir, outErr
|
||||
}
|
||||
|
||||
// 2026-02.5 получить историю. просто прочитаем файл с историей bash у root
|
||||
|
||||
func getRootHistory() ([]rootHistoryCommand, error) {
|
||||
var rootHistoryCommands []rootHistoryCommand
|
||||
rawHistory, err := os.ReadFile("/root/.bash_history")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Ошибка при открытии файла /root/.bash_history : %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
i := 0
|
||||
execTime := ""
|
||||
for _, line := range strings.Split(string(rawHistory), "\n") {
|
||||
var c rootHistoryCommand
|
||||
if strings.HasPrefix(line, "#") {
|
||||
execTime = strings.TrimLeft(line, "#")
|
||||
} else {
|
||||
c.Id = i
|
||||
i += 1
|
||||
c.ExecutionTime = execTime
|
||||
c.Command = line
|
||||
execTime = ""
|
||||
rootHistoryCommands = append(rootHistoryCommands, c)
|
||||
}
|
||||
|
||||
}
|
||||
return rootHistoryCommands, err
|
||||
}
|
||||
Reference in New Issue
Block a user