From 4fa357755b8256681a845fbc48f16a93ae95b070 Mon Sep 17 00:00:00 2001 From: naiba Date: Sat, 19 Mar 2022 17:22:15 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E5=8F=AF=E9=80=89=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E5=93=AA=E4=BA=9B=E5=88=86=E5=8C=BA=E5=8F=8A=E7=BD=91?= =?UTF-8?q?=E5=8D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- README.md | 8 +- cmd/agent/main.go | 150 +++++++++++++++++++++++++++-------- cmd/agent/monitor/monitor.go | 92 +++++++++++---------- go.mod | 17 ++-- go.sum | 40 +++++++--- model/config.go | 28 +++++++ 7 files changed, 243 insertions(+), 95 deletions(-) diff --git a/.gitignore b/.gitignore index 5f4404c..aa719e4 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ .DS_Store /main /cmd/agent/main -/cmd/dashboard/main \ No newline at end of file +/cmd/dashboard/main +/config.yml \ No newline at end of file diff --git a/README.md b/README.md index 0c6f059..bc5f939 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,13 @@ CN=true sudo ./nezha.sh _\* 使用 WatchTower 可以自动更新面板,Windows 终端可以使用 nssm 配置自启动(见尾部教程)_ -### 增强配置 +### Agent 自定义 + +#### 自定义监控的网卡和硬盘分区 + +执行 `/opt/nezha/agent/nezha-agent --edit-agent-config` 来选择自定义的网卡和分区,然后重启 Agent 即可 + +#### 运行参数 通过执行 `./nezha-agent --help` 查看支持的参数,如果你使用一键脚本,可以编辑 `/etc/systemd/system/nezha-agent.service`,在 `ExecStart=` 这一行的末尾加上 diff --git a/cmd/agent/main.go b/cmd/agent/main.go index b8f0da4..f9fcf50 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -10,17 +10,23 @@ import ( "net/http" "os" "os/exec" + "path/filepath" "runtime" + "strings" "time" + "github.com/AlecAivazis/survey/v2" "github.com/blang/semver" "github.com/go-ping/ping" "github.com/gorilla/websocket" "github.com/p14yground/go-github-selfupdate/selfupdate" + "github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/host" + psnet "github.com/shirou/gopsutil/v3/net" flag "github.com/spf13/pflag" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" "github.com/naiba/nezha/cmd/agent/monitor" "github.com/naiba/nezha/cmd/agent/processgroup" @@ -31,7 +37,7 @@ import ( "github.com/naiba/nezha/service/rpc" ) -type AgentConfig struct { +type AgentCliParam struct { SkipConnectionCount bool SkipProcsCount bool DisableAutoUpdate bool @@ -52,9 +58,10 @@ var ( ) var ( - agentConf AgentConfig - updateCh = make(chan struct{}) // Agent 自动更新间隔 - httpClient = &http.Client{ + agentCliParam AgentCliParam + agentConfig model.AgentConfig + updateCh = make(chan struct{}) // Agent 自动更新间隔 + httpClient = &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, @@ -70,6 +77,12 @@ const ( func init() { http.DefaultClient.Timeout = time.Second * 5 flag.CommandLine.ParseErrorsWhitelist.UnknownFlags = true + + ex, err := os.Executable() + if err != nil { + panic(err) + } + agentConfig.Read(filepath.Dir(ex) + "/config.yml") } func main() { @@ -95,24 +108,31 @@ func main() { // 来自于 GoReleaser 的版本号 monitor.Version = version - flag.BoolVarP(&agentConf.Debug, "debug", "d", false, "开启调试信息") - flag.StringVarP(&agentConf.Server, "server", "s", "localhost:5555", "管理面板RPC端口") - flag.StringVarP(&agentConf.ClientSecret, "password", "p", "", "Agent连接Secret") - flag.IntVar(&agentConf.ReportDelay, "report-delay", 1, "系统状态上报间隔") - flag.BoolVar(&agentConf.SkipConnectionCount, "skip-conn", false, "不监控连接数") - flag.BoolVar(&agentConf.SkipProcsCount, "skip-procs", false, "不监控进程数") - flag.BoolVar(&agentConf.DisableCommandExecute, "disable-command-execute", false, "禁止在此机器上执行命令") - flag.BoolVar(&agentConf.DisableAutoUpdate, "disable-auto-update", false, "禁用自动升级") - flag.BoolVar(&agentConf.DisableForceUpdate, "disable-force-update", false, "禁用强制升级") - flag.BoolVar(&agentConf.TLS, "tls", false, "启用SSL/TLS加密") + var isEditAgentConfig bool + flag.BoolVarP(&agentCliParam.Debug, "debug", "d", false, "开启调试信息") + flag.BoolVarP(&isEditAgentConfig, "edit-agent-config", "", false, "修改要监控的网卡/分区白名单") + flag.StringVarP(&agentCliParam.Server, "server", "s", "localhost:5555", "管理面板RPC端口") + flag.StringVarP(&agentCliParam.ClientSecret, "password", "p", "", "Agent连接Secret") + flag.IntVar(&agentCliParam.ReportDelay, "report-delay", 1, "系统状态上报间隔") + flag.BoolVar(&agentCliParam.SkipConnectionCount, "skip-conn", false, "不监控连接数") + flag.BoolVar(&agentCliParam.SkipProcsCount, "skip-procs", false, "不监控进程数") + flag.BoolVar(&agentCliParam.DisableCommandExecute, "disable-command-execute", false, "禁止在此机器上执行命令") + flag.BoolVar(&agentCliParam.DisableAutoUpdate, "disable-auto-update", false, "禁用自动升级") + flag.BoolVar(&agentCliParam.DisableForceUpdate, "disable-force-update", false, "禁用强制升级") + flag.BoolVar(&agentCliParam.TLS, "tls", false, "启用SSL/TLS加密") flag.Parse() - if agentConf.ClientSecret == "" { + if isEditAgentConfig { + editAgentConfig() + return + } + + if agentCliParam.ClientSecret == "" { flag.Usage() return } - if agentConf.ReportDelay < 1 || agentConf.ReportDelay > 4 { + if agentCliParam.ReportDelay < 1 || agentCliParam.ReportDelay > 4 { println("report-delay 的区间为 1-4") return } @@ -122,10 +142,10 @@ func main() { func run() { auth := rpc.AuthHandler{ - ClientSecret: agentConf.ClientSecret, + ClientSecret: agentCliParam.ClientSecret, } - if !agentConf.DisableCommandExecute { + if !agentCliParam.DisableCommandExecute { go pty.DownloadDependency() } // 上报服务器信息 @@ -133,7 +153,7 @@ func run() { // 更新IP信息 go monitor.UpdateIP() - if _, err := semver.Parse(version); err == nil && !agentConf.DisableAutoUpdate { + if _, err := semver.Parse(version); err == nil && !agentCliParam.DisableAutoUpdate { go func() { for range updateCh { go func() { @@ -164,12 +184,12 @@ func run() { for { timeOutCtx, cancel := context.WithTimeout(context.Background(), networkTimeOut) var securityOption grpc.DialOption - if agentConf.TLS { + if agentCliParam.TLS { securityOption = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12})) } else { - securityOption = grpc.WithInsecure() + securityOption = grpc.WithTransportCredentials(insecure.NewCredentials()) } - conn, err = grpc.DialContext(timeOutCtx, agentConf.Server, securityOption, grpc.WithPerRPCCredentials(&auth)) + conn, err = grpc.DialContext(timeOutCtx, agentCliParam.Server, securityOption, grpc.WithPerRPCCredentials(&auth)) if err != nil { println("与面板建立连接失败:", err) cancel() @@ -180,7 +200,7 @@ func run() { client = pb.NewNezhaServiceClient(conn) // 第一步注册 timeOutCtx, cancel = context.WithTimeout(context.Background(), networkTimeOut) - _, err = client.ReportSystemInfo(timeOutCtx, monitor.GetHost().PB()) + _, err = client.ReportSystemInfo(timeOutCtx, monitor.GetHost(&agentConfig).PB()) if err != nil { println("上报系统信息失败:", err) cancel() @@ -190,7 +210,7 @@ func run() { cancel() inited = true // 执行 Task - tasks, err := client.RequestTask(context.Background(), monitor.GetHost().PB()) + tasks, err := client.RequestTask(context.Background(), monitor.GetHost(&agentConfig).PB()) if err != nil { println("请求任务失败:", err) retry() @@ -254,9 +274,9 @@ func reportState() { for { // 为了更准确的记录时段流量,inited 后再上传状态信息 if client != nil && inited { - monitor.TrackNetworkSpeed() + monitor.TrackNetworkSpeed(&agentConfig) timeOutCtx, cancel := context.WithTimeout(context.Background(), networkTimeOut) - _, err = client.ReportSystemState(timeOutCtx, monitor.GetState(agentConf.SkipConnectionCount, agentConf.SkipProcsCount).PB()) + _, err = client.ReportSystemState(timeOutCtx, monitor.GetState(&agentConfig, agentCliParam.SkipConnectionCount, agentCliParam.SkipProcsCount).PB()) cancel() if err != nil { println("reportState error", err) @@ -264,10 +284,10 @@ func reportState() { } if lastReportHostInfo.Before(time.Now().Add(-10 * time.Minute)) { lastReportHostInfo = time.Now() - client.ReportSystemInfo(context.Background(), monitor.GetHost().PB()) + client.ReportSystemInfo(context.Background(), monitor.GetHost(&agentConfig).PB()) } } - time.Sleep(time.Second * time.Duration(agentConf.ReportDelay)) + time.Sleep(time.Second * time.Duration(agentCliParam.ReportDelay)) } } @@ -288,7 +308,7 @@ func doSelfUpdate(useLocalVersion bool) { } func handleUpgradeTask(task *pb.Task, result *pb.TaskResult) { - if agentConf.DisableForceUpdate { + if agentCliParam.DisableForceUpdate { return } doSelfUpdate(false) @@ -347,7 +367,7 @@ func handleHttpGetTask(task *pb.Task, result *pb.TaskResult) { } func handleCommandTask(task *pb.Task, result *pb.TaskResult) { - if agentConf.DisableCommandExecute { + if agentCliParam.DisableCommandExecute { result.Data = "此 Agent 已禁止命令执行" return } @@ -396,7 +416,7 @@ type WindowSize struct { } func handleTerminalTask(task *pb.Task) { - if agentConf.DisableCommandExecute { + if agentCliParam.DisableCommandExecute { println("此 Agent 已禁止命令执行") return } @@ -411,7 +431,7 @@ func handleTerminalTask(task *pb.Task) { protocol += "s" } header := http.Header{} - header.Add("Secret", agentConf.ClientSecret) + header.Add("Secret", agentCliParam.ClientSecret) conn, _, err := websocket.DefaultDialer.Dial(fmt.Sprintf("%s://%s/terminal/%s", protocol, terminal.Host, terminal.Session), header) if err != nil { println("Terminal 连接失败:", err) @@ -480,8 +500,72 @@ func handleTerminalTask(task *pb.Task) { } } +func editAgentConfig() { + nc, err := psnet.IOCounters(true) + if err != nil { + panic(err) + } + var nicAllowlistOptions []string + for _, v := range nc { + nicAllowlistOptions = append(nicAllowlistOptions, v.Name) + } + + var diskAllowlistOptions []string + diskList, err := disk.Partitions(false) + if err != nil { + panic(err) + } + for _, p := range diskList { + diskAllowlistOptions = append(diskAllowlistOptions, fmt.Sprintf("%s\t%s\t%s", p.Mountpoint, p.Fstype, p.Device)) + } + + var qs = []*survey.Question{ + { + Name: "nic", + Prompt: &survey.MultiSelect{ + Message: "选择要监控的网卡", + Options: nicAllowlistOptions, + }, + }, + { + Name: "disk", + Prompt: &survey.MultiSelect{ + Message: "选择要监控的硬盘分区", + Options: diskAllowlistOptions, + }, + }, + } + + answers := struct { + Nic []string + Disk []string + }{} + + err = survey.Ask(qs, &answers, survey.WithValidator(survey.Required)) + if err != nil { + fmt.Println("选择错误", err.Error()) + return + } + + agentConfig.HardDrivePartitionAllowlist = []string{} + for _, v := range answers.Disk { + agentConfig.HardDrivePartitionAllowlist = append(agentConfig.HardDrivePartitionAllowlist, strings.Split(v, "\t")[0]) + } + + agentConfig.NICAllowlist = make(map[string]bool) + for _, v := range answers.Nic { + agentConfig.NICAllowlist[v] = true + } + + if err = agentConfig.Save(); err != nil { + panic(err) + } + + fmt.Println("修改自定义配置成功,重启 Agnet 后生效") +} + func println(v ...interface{}) { - if agentConf.Debug { + if agentCliParam.Debug { fmt.Printf("NEZHA@%s>> ", time.Now().Format("2006-01-02 15:04:05")) fmt.Println(v...) } diff --git a/cmd/agent/monitor/monitor.go b/cmd/agent/monitor/monitor.go index 62507cd..30b170f 100644 --- a/cmd/agent/monitor/monitor.go +++ b/cmd/agent/monitor/monitor.go @@ -3,7 +3,6 @@ package monitor import ( "fmt" "os/exec" - "regexp" "runtime" "strconv" "strings" @@ -31,7 +30,6 @@ var ( excludeNetInterfaces = []string{ "lo", "tun", "docker", "veth", "br-", "vmbr", "vnet", "kube", } - getMacDiskNo = regexp.MustCompile(`\/dev\/disk(\d)s.*`) ) var ( @@ -39,7 +37,7 @@ var ( cachedBootTime time.Time ) -func GetHost() *model.Host { +func GetHost(agentConfig *model.AgentConfig) *model.Host { hi, _ := host.Info() var cpuType string if hi.VirtualizationSystem != "" { @@ -57,7 +55,7 @@ func GetHost() *model.Host { cpus = append(cpus, fmt.Sprintf("%s %d %s Core", model, count, cpuType)) } mv, _ := mem.VirtualMemory() - diskTotal, _ := getDiskTotalAndUsed() + diskTotal, _ := getDiskTotalAndUsed(agentConfig) var swapMemTotal uint64 if runtime.GOOS == "windows" { @@ -87,7 +85,7 @@ func GetHost() *model.Host { } } -func GetState(skipConnectionCount bool, skipProcsCount bool) *model.HostState { +func GetState(agentConfig *model.AgentConfig, skipConnectionCount bool, skipProcsCount bool) *model.HostState { var procs []int32 if !skipProcsCount { procs, _ = process.Pids() @@ -110,7 +108,7 @@ func GetState(skipConnectionCount bool, skipProcsCount bool) *model.HostState { cpuPercent = cp[0] } - _, diskUsed := getDiskTotalAndUsed() + _, diskUsed := getDiskTotalAndUsed(agentConfig) loadStat, _ := load.Avg() var tcpConnCount, udpConnCount uint64 @@ -157,13 +155,19 @@ func GetState(skipConnectionCount bool, skipProcsCount bool) *model.HostState { } } -func TrackNetworkSpeed() { +func TrackNetworkSpeed(agentConfig *model.AgentConfig) { var innerNetInTransfer, innerNetOutTransfer uint64 nc, err := net.IOCounters(true) if err == nil { for _, v := range nc { - if isListContainsStr(excludeNetInterfaces, v.Name) { - continue + if len(agentConfig.NICAllowlist) > 0 { + if !agentConfig.NICAllowlist[v.Name] { + continue + } + } else { + if isListContainsStr(excludeNetInterfaces, v.Name) { + continue + } } innerNetInTransfer += v.BytesRecv innerNetOutTransfer += v.BytesSent @@ -180,49 +184,49 @@ func TrackNetworkSpeed() { } } -func getDiskTotalAndUsed() (total uint64, used uint64) { - diskList, _ := disk.Partitions(false) +func getDiskTotalAndUsed(agentConfig *model.AgentConfig) (total uint64, used uint64) { devices := make(map[string]string) - countedDiskForMac := make(map[string]struct{}) - for _, d := range diskList { - fsType := strings.ToLower(d.Fstype) - // 不统计 K8s 的虚拟挂载点:https://github.com/shirou/gopsutil/issues/1007 - if devices[d.Device] == "" && isListContainsStr(expectDiskFsTypes, fsType) && !strings.Contains(d.Mountpoint, "/var/lib/kubelet") { - devices[d.Device] = d.Mountpoint + + if len(agentConfig.HardDrivePartitionAllowlist) > 0 { + // 如果配置了白名单,使用白名单的列表 + for i, v := range agentConfig.HardDrivePartitionAllowlist { + devices[strconv.Itoa(i)] = v + } + } else { + // 否则使用默认过滤规则 + diskList, _ := disk.Partitions(false) + for _, d := range diskList { + fsType := strings.ToLower(d.Fstype) + // 不统计 K8s 的虚拟挂载点:https://github.com/shirou/gopsutil/issues/1007 + if devices[d.Device] == "" && isListContainsStr(expectDiskFsTypes, fsType) && !strings.Contains(d.Mountpoint, "/var/lib/kubelet") { + devices[d.Device] = d.Mountpoint + } } } - for device, mountPath := range devices { - diskUsageOf, _ := disk.Usage(mountPath) - // 这里是针对 Mac 机器的处理,https://github.com/giampaolo/psutil/issues/1509 - matches := getMacDiskNo.FindStringSubmatch(device) - if len(matches) == 2 { - if _, has := countedDiskForMac[matches[1]]; !has { - countedDiskForMac[matches[1]] = struct{}{} - total += diskUsageOf.Total - } - } else { + + for _, mountPath := range devices { + diskUsageOf, err := disk.Usage(mountPath) + if err == nil { total += diskUsageOf.Total + used += diskUsageOf.Used } - used += diskUsageOf.Used } // Fallback 到这个方法,仅统计根路径,适用于OpenVZ之类的. - if runtime.GOOS == "linux" { - if total == 0 && used == 0 { - cmd := exec.Command("df") - out, err := cmd.CombinedOutput() - if err == nil { - s := strings.Split(string(out), "\n") - for _, c := range s { - info := strings.Fields(c) - if len(info) == 6 { - if info[5] == "/" { - total, _ = strconv.ParseUint(info[1], 0, 64) - used, _ = strconv.ParseUint(info[2], 0, 64) - // 默认获取的是1K块为单位的. - total = total * 1024 - used = used * 1024 - } + if runtime.GOOS == "linux" && total == 0 && used == 0 { + cmd := exec.Command("df") + out, err := cmd.CombinedOutput() + if err == nil { + s := strings.Split(string(out), "\n") + for _, c := range s { + info := strings.Fields(c) + if len(info) == 6 { + if info[5] == "/" { + total, _ = strconv.ParseUint(info[1], 0, 64) + used, _ = strconv.ParseUint(info[2], 0, 64) + // 默认获取的是1K块为单位的. + total = total * 1024 + used = used * 1024 } } } diff --git a/go.mod b/go.mod index e2c595d..73d32e6 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.17 require ( code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 + github.com/AlecAivazis/survey/v2 v2.3.2 github.com/Erope/goss v0.0.0-20211230093305-df3c03fd1ed4 github.com/artdarek/go-unzip v1.0.0 github.com/blang/semver v3.5.1+incompatible @@ -21,17 +22,17 @@ require ( github.com/p14yground/go-github-selfupdate v0.0.0-20220205132106-76a6d59b925b github.com/patrickmn/go-cache v2.1.0+incompatible github.com/robfig/cron/v3 v3.0.1 - github.com/shirou/gopsutil/v3 v3.22.1 + github.com/shirou/gopsutil/v3 v3.22.2 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.10.1 - github.com/stretchr/testify v1.7.0 - golang.org/x/crypto v0.0.0-20220214200702-86341886e292 - golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b - google.golang.org/grpc v1.44.0 + github.com/stretchr/testify v1.7.1 + golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a + google.golang.org/grpc v1.45.0 google.golang.org/protobuf v1.27.1 gopkg.in/yaml.v2 v2.4.0 gorm.io/driver/sqlite v1.3.1 - gorm.io/gorm v1.23.1 + gorm.io/gorm v1.23.3 ) require ( @@ -48,11 +49,14 @@ require ( github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.4 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.5 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-sqlite3 v1.14.11 // indirect + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -73,6 +77,7 @@ require ( golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220204002441-d6cc3cc0770e // indirect diff --git a/go.sum b/go.sum index dcbc280..144cc64 100644 --- a/go.sum +++ b/go.sum @@ -50,11 +50,15 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 h1:tM5+dn2C9xZw1RzgI6WTQW1rGqdUimKB3RFbyu4h6Hc= code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5/go.mod h1:v4VVB6oBMz/c9fRY6vZrwr5xKRWOH5NPDjQZlPk0Gbs= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO4gCnU8= +github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Erope/goss v0.0.0-20211230093305-df3c03fd1ed4 h1:X35U3bryt+j2a9RZyXyBPISNIYQsfNKWC/d/B8J861I= github.com/Erope/goss v0.0.0-20211230093305-df3c03fd1ed4/go.mod h1:gl55GUYOV6rvsL/V23GdfRNdnreh+McD5Yo1sNc+Qe0= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -274,6 +278,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= +github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iamacarpet/go-winpty v1.0.2 h1:jwPVTYrjAHZx6Mcm6K5i9G4opMp5TblEHH5EQCl/Gzw= github.com/iamacarpet/go-winpty v1.0.2/go.mod h1:/GHKJicG/EVRQIK1IQikMYBakBkhj/3hTjLgdzYsmpI= @@ -294,6 +300,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -305,6 +313,8 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ= +github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -317,9 +327,11 @@ github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc8 github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -332,6 +344,8 @@ github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A github.com/mattn/go-sqlite3 v1.14.11 h1:gt+cp9c0XGqe9S/wAHTL3n/7MqY+siPWgWJgqdsFrzQ= github.com/mattn/go-sqlite3 v1.14.11/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= @@ -408,8 +422,8 @@ github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6po github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shirou/gopsutil/v3 v3.22.1 h1:33y31Q8J32+KstqPfscvFwBlNJ6xLaBy4xqBXzlYV5w= -github.com/shirou/gopsutil/v3 v3.22.1/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= +github.com/shirou/gopsutil/v3 v3.22.2 h1:wCrArWFkHYIdDxx/FSfF5RB4dpJYW6t7rcp3+zL8uks= +github.com/shirou/gopsutil/v3 v3.22.2/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -427,13 +441,15 @@ github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk= github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw= @@ -476,6 +492,7 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= @@ -485,8 +502,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -587,8 +604,8 @@ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -681,6 +698,8 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a h1:ppl5mZgokTT8uPkmYOyEUmPTr3ypaKkg5eFOGrAmxxE= golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -888,8 +907,8 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -932,8 +951,9 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.3.1 h1:bwfE+zTEWklBYoEodIOIBwuWHpnx52Z9zJFW5F33WLk= gorm.io/driver/sqlite v1.3.1/go.mod h1:wJx0hJspfycZ6myN38x1O/AqLtNS6c5o9TndewFbELg= -gorm.io/gorm v1.23.1 h1:aj5IlhDzEPsoIyOPtTRVI+SyaN1u6k613sbt4pwbxG0= gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.3 h1:jYh3nm7uLZkrMVfA8WVNjDZryKfr7W+HTlInVgKFJAg= +gorm.io/gorm v1.23.3/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/model/config.go b/model/config.go index e9e90b8..11927c2 100644 --- a/model/config.go +++ b/model/config.go @@ -20,6 +20,34 @@ const ( ConfigCoverIgnoreAll ) +type AgentConfig struct { + HardDrivePartitionAllowlist []string + NICAllowlist map[string]bool + v *viper.Viper +} + +func (c *AgentConfig) Read(path string) error { + c.v = viper.New() + c.v.SetConfigFile(path) + err := c.v.ReadInConfig() + if err != nil { + return err + } + err = c.v.Unmarshal(c) + if err != nil { + return err + } + return nil +} + +func (c *AgentConfig) Save() error { + data, err := yaml.Marshal(c) + if err != nil { + return err + } + return ioutil.WriteFile(c.v.ConfigFileUsed(), data, os.ModePerm) +} + type Config struct { Debug bool Site struct {