add sheduling agent
Change-Id: I89f35fb3984044c57f10727432755012542f9fd8
This commit is contained in:
parent
8f126a978f
commit
3f5f28d785
36
agent/Dockerfile
Normal file
36
agent/Dockerfile
Normal file
@ -0,0 +1,36 @@
|
||||
# Dockerfile for cicd
|
||||
FROM harbor.inspur.local/system/alpine:3.17.2-yq
|
||||
MAINTAINER yinchongbing yinchongbing@inspur.com
|
||||
WORKDIR /app
|
||||
ADD cmd/ /app/
|
||||
ADD config/config.yaml /app/config/
|
||||
ADD deploy/docker/run.sh /app/run.sh
|
||||
|
||||
ENV APP_ENV local
|
||||
ENV APP_DEBUG true
|
||||
ENV APP_LANGUAGE zh_CN
|
||||
ENV SERVER_HOST 0.0.0.0
|
||||
ENV SERVER_PORT 8899
|
||||
ENV POSTGRES_DATA_ENABLE false
|
||||
ENV POSTGRES_DATA_HOST postgres
|
||||
ENV POSTGRES_DATA_PORT 5432
|
||||
ENV POSTGRES_DATA_DATABASE postgres
|
||||
ENV POSTGRES_DATA_USERNAME postgres
|
||||
ENV POSTGRES_DATA_PASSWORD Mypostgres!23
|
||||
ENV POSTGRES_AUTH_ENABLE false
|
||||
ENV POSTGRES_AUTH_HOST postgres
|
||||
ENV POSTGRES_AUTH_PORT 5432
|
||||
ENV POSTGRES_AUTH_DATABASE auth
|
||||
ENV POSTGRES_AUTH_USERNAME postgres
|
||||
ENV POSTGRES_AUTH_PASSWORD Mypostgres!23
|
||||
ENV LOG_LEVEL 4
|
||||
ENV REDIS_EBABLE false
|
||||
ENV REDIS_HOST redis
|
||||
ENV REDIS_PORT 6379
|
||||
ENV REDIS_DATABASE 0
|
||||
ENV REDIS_PASSWORD ""
|
||||
|
||||
RUN chmod +x run.sh && chmod +x cfn-schedule-agent
|
||||
EXPOSE $SERVER_PORT
|
||||
|
||||
CMD ["./run.sh"]
|
151
agent/README.md
Normal file
151
agent/README.md
Normal file
@ -0,0 +1,151 @@
|
||||
# go project种子项目
|
||||
本项目基于 gin 框架为核心的一个脚手架搭建而成,可以基于本项目快速完成业务开发,开箱📦 即用。
|
||||
|
||||
HTTP 运行
|
||||
拉取代码后在项目根目录执行如下命令:
|
||||
|
||||
# 本地有 go 环境,版本 >= 1.18.1
|
||||
# 建议开启GO111MODULE
|
||||
# go env -w GO111MODULE=on
|
||||
|
||||
# 配置Go Mod引用私有库
|
||||
go env -w GOPRIVATE=git.inspur.com
|
||||
go env -w GOINSECURE=git.inspur.com
|
||||
go env -w GOPROXY="http://nexus.inspur.local/repository/go-public/,direct"
|
||||
|
||||
# 依赖管理
|
||||
go mod tidy
|
||||
# 依赖库下载
|
||||
go mod vendor
|
||||
|
||||
# 首次运行会自动复制一份示例配置(config/config.example.yaml)文件到config目录(config/config.yaml)
|
||||
go run main.go
|
||||
|
||||
# 项目起来后执行下面命令访问示例路由
|
||||
curl "http://127.0.0.1:8899/api/v1/hello-world"
|
||||
# {"code":0,"message":"OK","data":{"result":"hello gin-layout"},"cost":"6.151µs"}
|
||||
curl "http://127.0.0.1:8899/api/v1/hello-world?name=world"
|
||||
# {"code":0,"message":"OK","data":{"result":"hello world"},"cost":"6.87µs"}
|
||||
部署
|
||||
# 打包项目(如何打包其他os平台的包自行 google)
|
||||
CGO_ENABLED=0:禁用CGO
|
||||
GOOS=linux:编译后的操作系统是Linux
|
||||
GOARCH=amd64:编译后的CPU架构是amd64
|
||||
-a:强制编译所有package
|
||||
-installsuffix cgo:指定额外的后缀
|
||||
-o cfn-schedule-agent:将编译后的程序存储为cfn-schedule-agent
|
||||
.:编译当前路径下所有代码
|
||||
## linux平台上编译命令:
|
||||
### linux:
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -o cfn-schedule-agent .
|
||||
### windows:
|
||||
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -a -installsuffix cgo -o cfn-schedule-agent .
|
||||
|
||||
## windows平台上编译命令:
|
||||
### linux:
|
||||
set GOOS=linux
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
go env -w GOARCH=amd64
|
||||
go env -w GOOS=linux
|
||||
go env -w CGO_ENABLED=0
|
||||
|
||||
go build -a -installsuffix cgo -o cfn-schedule-agent .
|
||||
### windows:
|
||||
set GOOS=windows
|
||||
set GOARCH=amd64
|
||||
set CGO_ENABLED=0
|
||||
go env -w GOARCH=amd64
|
||||
go env -w GOOS=windows
|
||||
go env -w CGO_ENABLED=0
|
||||
|
||||
go build -a -installsuffix cgo -o cfn-schedule-agent .
|
||||
|
||||
|
||||
# 运行时请配置指定config文件的位置,否则可能会出现找不到配置的情况,修改完配置请重启
|
||||
cmd/main.go -c="指定配置文件位置(/home/config.yaml)"
|
||||
|
||||
# nginx 反向代理配置示例
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.xxx.com;
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://172.0.0.1:8899;
|
||||
}
|
||||
}
|
||||
目录结构
|
||||
.
|
||||
|——.gitignore
|
||||
|——go.mod
|
||||
|——go.sum
|
||||
|——main.go // 项目入口 main 包
|
||||
|——LICENSE
|
||||
|——README.md
|
||||
|——doc // 设计和用户文档
|
||||
|——db // 数据库脚本
|
||||
|——hack // 用于执行各种构建,安装,分析等操作的脚本。
|
||||
|——boot // 项目初始化目录
|
||||
| └──boot.go
|
||||
|——config // 这里通常维护一些本地调试用的样例配置文件
|
||||
| └──autoload // 配置文件的结构体定义包
|
||||
| └──app.go
|
||||
| └──logger.go
|
||||
| └──mysql.go
|
||||
| └──redis.go
|
||||
| └──server.go
|
||||
| └──config.example.ini // .ini 配置示例文件
|
||||
| └──config.example.yaml // .yaml 配置示例文件
|
||||
| └──config.go // 配置初始化文件
|
||||
|——data // 数据初始化目录
|
||||
| └──data.go
|
||||
| └──mysql.go
|
||||
| └──redis.go
|
||||
|——internal // 该服务所有不对外暴露的代码,通常的业务逻辑都在这下面,使用internal避免错误引用
|
||||
| └──controller // 控制器代码
|
||||
| └──v1
|
||||
| └──auth.go // 完整流程演示代码,包含数据库表的操作
|
||||
| └──helloword.go // 基础演示代码
|
||||
| └──base.go
|
||||
| └──middleware // 中间件目录
|
||||
| └──cors.go
|
||||
| └──logger.go
|
||||
| └──recovery.go
|
||||
| └──requestCost.go
|
||||
| └──model // 业务数据访问
|
||||
| └──admin_users.go
|
||||
| └──base.go
|
||||
| └──pkg // 内部使用包
|
||||
| └──errors // 错误定义
|
||||
| └──code.go
|
||||
| └──en-us.go
|
||||
| └──zh-cn.go
|
||||
| └──logger // 日志处理
|
||||
| └──logger.go
|
||||
| └──response // 统一响应输出
|
||||
| └──response.go
|
||||
| └──routers // 路由定义
|
||||
| └──apiRouter.go
|
||||
| └──router.go
|
||||
| └──service // 业务逻辑
|
||||
| └──auth.go
|
||||
| └──validator // 请求参数验证器
|
||||
| └──form // 表单参数定义
|
||||
| └──auth.go
|
||||
| └──validator.go
|
||||
|——pkg // 可以被外部使用的包
|
||||
| └──convert // 数据类型转换
|
||||
| └──convert.go
|
||||
| └──utils // 帮助函数
|
||||
| └──utils.go
|
||||
生产环境注意事项
|
||||
在构建生产环境时,请配置好 .yaml 文件中基础路径 base_path,所有的日志记录文件会保存在该目录下的 {base_path}/gin-layout/logs/ 里面,该基础路径默认为执行命令的目录
|
||||
|
||||
其他说明
|
||||
项目中使用到的包
|
||||
核心:gin
|
||||
配置:gopkg.in/yaml.v3、gopkg.in/ini.v1
|
||||
参数验证:github.com/go-playground/validator/v10
|
||||
日志:go.uber.org/zap、github.com/natefinch/lumberjack、github.com/lestrrat-go/file-rotatelogs
|
||||
数据库:gorm.io/gorm、go-redis/v8
|
||||
还有其他不一一列举,更多请查看go.mod文件
|
53
agent/boot/boot.go
Normal file
53
agent/boot/boot.go
Normal file
@ -0,0 +1,53 @@
|
||||
package boot
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
"os"
|
||||
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/data"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/validator"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
processManager "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/process-manager"
|
||||
)
|
||||
|
||||
var (
|
||||
configPath string
|
||||
printVersion bool
|
||||
Run string
|
||||
ProcessUnitDir string
|
||||
AssetConfigDir string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&Run, "r", "http", "执行命令默认运行http服务")
|
||||
flag.StringVar(&configPath, "c", "", "请输入配置文件绝对路径")
|
||||
flag.StringVar(&ProcessUnitDir, "process-unit-dir", "", "纳管进程配置文件目录绝对路径")
|
||||
flag.StringVar(&AssetConfigDir, "asset-config-dir", "", "资产配置文件目录绝对路径")
|
||||
|
||||
flag.BoolVar(&printVersion, "version", false, "查看版本")
|
||||
flag.Parse()
|
||||
|
||||
if printVersion {
|
||||
// 打印版本号
|
||||
println(version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// 1、初始化配置
|
||||
config.InitConfig(configPath)
|
||||
agent.InitAgentConfig(AssetConfigDir)
|
||||
|
||||
// 2、初始化zap日志
|
||||
log.InitLogger()
|
||||
|
||||
// 3、初始化数据库
|
||||
data.InitData()
|
||||
|
||||
// 4、初始化验证器
|
||||
validator.InitValidatorTrans("zh")
|
||||
|
||||
// 5、启动进程管理程序
|
||||
go processManager.Start(ProcessUnitDir)
|
||||
}
|
4
agent/boot/version.go
Normal file
4
agent/boot/version.go
Normal file
@ -0,0 +1,4 @@
|
||||
package boot
|
||||
|
||||
// version is the current gin-layout version.
|
||||
const version = "0.2.3"
|
BIN
agent/cfn-schedule-agent
Normal file
BIN
agent/cfn-schedule-agent
Normal file
Binary file not shown.
2
agent/cmd/.gitignore
vendored
Normal file
2
agent/cmd/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
63
agent/config/agent/agent.go
Normal file
63
agent/config/agent/agent.go
Normal file
@ -0,0 +1,63 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/bin_path"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/fs"
|
||||
"os"
|
||||
)
|
||||
|
||||
type AgentConfig struct {
|
||||
RID string `yaml:"rid" mapstructure:"rid"`
|
||||
Token string `yaml:"token" mapstructure:"token"`
|
||||
//AgentVersion string `yaml:"agent_version" mapstructure:"agent_version"`
|
||||
Role string `yaml:"role" mapstructure:"role"`
|
||||
NetInterface string `yaml:"net_interface" mapstructure:"net_interface"`
|
||||
|
||||
ScheduleServer string `yaml:"schedule_server" mapstructure:"schedule_server"`
|
||||
|
||||
Enterprise string `yaml:"enterprise" mapstructure:"enterprise"`
|
||||
Type string `yaml:"type"` // 0:应用一体机 1:调度一体机 2:纳管一体机
|
||||
}
|
||||
|
||||
var Agent = &AgentConfig{}
|
||||
|
||||
func InitAgentConfig(assetConfigDir string) {
|
||||
if assetConfigDir != "" {
|
||||
bin_path.ASSETCONFIGDIR = assetConfigDir
|
||||
}
|
||||
|
||||
file, err := os.ReadFile(bin_path.ASSETCONFIGDIR + "/agent.yaml")
|
||||
if err != nil {
|
||||
panic("Failed to read configuration file:" + err.Error())
|
||||
}
|
||||
|
||||
var config = &AgentConfig{}
|
||||
yaml.Unmarshal(file, config)
|
||||
|
||||
Agent = config
|
||||
|
||||
//放入环境变量
|
||||
os.Setenv("CFN_SCHEDULE_AGENT_RID", config.RID)
|
||||
os.Setenv("CFN_TELEGRAF_LOG_FILE", bin_path.TELEGRAFLOG)
|
||||
|
||||
// 如果 path 路径不存在,会有 err,然后通过 IsNotExist 判定文件路径是否存在,如果 true 则不存在,注意用 os.ModePerm 这样文件是可以写入的
|
||||
if _, err := os.Stat(bin_path.TELEGRAFLOG); os.IsNotExist(err) {
|
||||
// mkdir 创建目录,mkdirAll 可创建多层级目录
|
||||
os.MkdirAll(bin_path.TELEGRAFLOG, os.ModePerm)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func LoadAgentInfo(config AgentConfig) {
|
||||
// 更新内存
|
||||
Agent = &config
|
||||
|
||||
go func() {
|
||||
out, _ := yaml.Marshal(config)
|
||||
err := os.WriteFile(bin_path.ASSETCONFIGDIR+"/agent.yaml", out, fs.ModePerm)
|
||||
if err != nil {
|
||||
panic("Failed to write configuration file:" + err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
7
agent/config/agent/agent.yaml
Normal file
7
agent/config/agent/agent.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
rid: "DZ210900214"
|
||||
token: "afsdfasfasdccc "
|
||||
role: "Cache" # 枚举:Cache or Normal
|
||||
net_interface: "eth0" # 示例:eth0 for linux 以太网 4 for windows
|
||||
schedule_server: "localhost"
|
||||
enterprise: "SDLC"
|
||||
type: 1 # 1:应用一体机 2:调度一体机 3:纳管一体机
|
26
agent/config/app.go
Normal file
26
agent/config/app.go
Normal file
@ -0,0 +1,26 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/convert"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
)
|
||||
|
||||
type AppConfig struct {
|
||||
AppEnv string `ini:"app_env" yaml:"app_env" mapstructure:"app_env"`
|
||||
Debug bool `ini:"debug" yaml:"debug" mapstructure:"debug"`
|
||||
Language string `ini:"language" yaml:"language" mapstructure:"language"`
|
||||
StaticBasePath string `ini:"base_path" yaml:"base_path" mapstructure:"base_path"`
|
||||
}
|
||||
|
||||
var App = AppConfig{
|
||||
AppEnv: "local",
|
||||
Debug: true,
|
||||
Language: "zh_CN",
|
||||
StaticBasePath: getDefaultPath(),
|
||||
}
|
||||
|
||||
func getDefaultPath() (path string) {
|
||||
path, _ = utils.GetDefaultPath()
|
||||
path = convert.GetString(utils.If(path != "", path, "/tmp"))
|
||||
return
|
||||
}
|
28
agent/config/bin_path/bin_path.go
Normal file
28
agent/config/bin_path/bin_path.go
Normal file
@ -0,0 +1,28 @@
|
||||
package bin_path
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
BINDIR = "/root/cfn-schedule-agent/bin"
|
||||
UPGRADEDIR = "/root/cfn-schedule-agent/upgrade"
|
||||
ASSETCONFIGDIR = ""
|
||||
AGENTLOG = ""
|
||||
AGENTUPGRADELOG = ""
|
||||
TELEGRAFLOG = ""
|
||||
UPGRADEPLAN = ""
|
||||
)
|
||||
|
||||
func init() {
|
||||
BINDIR, _ = utils.GetCurrentPath()
|
||||
UPGRADEDIR = filepath.Join(BINDIR, "../upgrade")
|
||||
AGENTUPGRADELOG = filepath.Join(UPGRADEDIR, "/upgrade.log")
|
||||
TELEGRAFLOG = filepath.Join(BINDIR, "/data-collector/telegraf/log/", "telegraf.log")
|
||||
AGENTLOG = filepath.Join(BINDIR, "/logs/", config.Config.Logger.Filename)
|
||||
|
||||
UPGRADEPLAN = filepath.Join(UPGRADEDIR, "/upgradeplan")
|
||||
|
||||
}
|
5
agent/config/bin_path/bin_path_linux.go
Normal file
5
agent/config/bin_path/bin_path_linux.go
Normal file
@ -0,0 +1,5 @@
|
||||
package bin_path
|
||||
|
||||
func init() {
|
||||
ASSETCONFIGDIR = "/etc/cfn-schedule-agent"
|
||||
}
|
5
agent/config/bin_path/bing_path_windows.go
Normal file
5
agent/config/bin_path/bing_path_windows.go
Normal file
@ -0,0 +1,5 @@
|
||||
package bin_path
|
||||
|
||||
func init() {
|
||||
ASSETCONFIGDIR = "C:\\cfn-schedule-agent"
|
||||
}
|
111
agent/config/config.go
Normal file
111
agent/config/config.go
Normal file
@ -0,0 +1,111 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// Conf 配置项主结构体
|
||||
// mapstructure(配置文件属性名称无法与类属性名称直接对应)
|
||||
type Conf struct {
|
||||
AppConfig `yaml:"app" mapstructure:"app"`
|
||||
Server ServerConfig `yaml:"server" mapstructure:"server"`
|
||||
PostgreSql PostgreSqlConfigMap `yaml:"postgres" mapstructure:"postgres"`
|
||||
Redis RedisConfig `yaml:"redis" mapstructure:"redis"`
|
||||
Nats NatsConfig `yaml:"nats_config" mapstructure:"nats_config"`
|
||||
//Minio MinioConfig `yaml:"minio" mapstructure:"minio"`
|
||||
Logger LoggerConfig `yaml:"logger" mapstructure:"logger"`
|
||||
Schedule ScheduleServer `yaml:"schedule" mapstructure:"schedule"`
|
||||
AgentVersion string `yaml:"agent_version" mapstructure:"agent_version"`
|
||||
ZombieCleaner bool `yaml:"zombie_cleaner" mapstructure:"zombie_cleaner"`
|
||||
}
|
||||
|
||||
var Config = &Conf{
|
||||
AppConfig: App,
|
||||
Server: Server,
|
||||
PostgreSql: PostgreSql,
|
||||
Redis: Redis,
|
||||
Nats: Nats,
|
||||
//Minio: Minio,
|
||||
Logger: Logger,
|
||||
Schedule: Schedule,
|
||||
}
|
||||
|
||||
var once sync.Once
|
||||
|
||||
func InitConfig(configPath string) {
|
||||
once.Do(func() {
|
||||
// 加载 .yaml 配置
|
||||
loadYaml(configPath)
|
||||
})
|
||||
}
|
||||
|
||||
// todo 环境变量注入配置 or 与nacos集成
|
||||
func loadYaml(configPath string) {
|
||||
var yamlConfig string
|
||||
if configPath == "" {
|
||||
runDirectory, _ := utils.GetCurrentPath()
|
||||
yamlConfig = filepath.Join(runDirectory, "/config.yaml")
|
||||
} else {
|
||||
yamlConfig = filepath.Join(configPath)
|
||||
}
|
||||
|
||||
viper.SetConfigFile(yamlConfig)
|
||||
viper.SetConfigType("yaml")
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
panic("Failed to read configuration file:" + err.Error())
|
||||
}
|
||||
for _, key := range viper.AllKeys() {
|
||||
value := viper.GetString(key)
|
||||
realValue := expandValueEnv(value)
|
||||
if value != realValue {
|
||||
viper.Set(key, realValue)
|
||||
}
|
||||
}
|
||||
|
||||
err = viper.Unmarshal(Config)
|
||||
if err != nil {
|
||||
panic("Failed to load configuration:" + err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func expandValueEnv(value string) (realValue string) {
|
||||
realValue = value
|
||||
|
||||
vLen := len(value)
|
||||
// 3 = ${}
|
||||
if vLen < 3 {
|
||||
return
|
||||
}
|
||||
// Need start with "${" and end with "}", then return.
|
||||
if value[0] != '$' || value[1] != '{' || value[vLen-1] != '}' {
|
||||
return
|
||||
}
|
||||
|
||||
key := ""
|
||||
defaultV := ""
|
||||
// value start with "${"
|
||||
for i := 2; i < vLen; i++ {
|
||||
if value[i] == '|' && (i+1 < vLen && value[i+1] == '|') {
|
||||
key = value[2:i]
|
||||
defaultV = value[i+2 : vLen-1] // other string is default value.
|
||||
break
|
||||
} else if value[i] == '}' {
|
||||
key = value[2:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
realValue = os.Getenv(key)
|
||||
if realValue == "" {
|
||||
realValue = defaultV
|
||||
}
|
||||
|
||||
return
|
||||
}
|
60
agent/config/config.yaml
Normal file
60
agent/config/config.yaml
Normal file
@ -0,0 +1,60 @@
|
||||
app:
|
||||
app_env: ${APP_ENV||local}
|
||||
debug: ${APP_DEBUG||true}
|
||||
language: ${APP_LANGUAGE||zh_CN}
|
||||
# base_path: ""
|
||||
server:
|
||||
host: ${SERVER_HOST||0.0.0.0}
|
||||
port: ${SERVER_PORT||8898}
|
||||
|
||||
agent_version: ${AGENT_VERSION||v1.0.0}
|
||||
zombie_cleaner: ${POSTGRES_DATA_ENABLE||true}
|
||||
|
||||
schedule:
|
||||
port: ${SCHEDULE_PORT||9090}
|
||||
heart_beat: 30
|
||||
protocol: http
|
||||
auth:
|
||||
type: none
|
||||
|
||||
postgres:
|
||||
data:
|
||||
enable: ${POSTGRES_DATA_ENABLE||false}
|
||||
host: ${POSTGRES_DATA_HOST||10.110.63.138}
|
||||
port: ${POSTGRES_DATA_PORT||5432}
|
||||
database: ${POSTGRES_DATA_DATABASE||postgres}
|
||||
username: ${POSTGRES_DATA_USERNAME||postgres}
|
||||
password: ${POSTGRES_DATA_PASSWORD||Mypostgres!23}
|
||||
log_level: ${LOG_LEVEL||4}
|
||||
auth:
|
||||
enable: ${POSTGRES_AUTH_ENABLE||false}
|
||||
host: ${POSTGRES_AUTH_HOST||10.110.63.138}
|
||||
port: ${POSTGRES_AUTH_PORT||5432}
|
||||
database: ${POSTGRES_AUTH_DATABASE||auth}
|
||||
username: ${POSTGRES_AUTH_USERNAME||postgres}
|
||||
password: ${POSTGRES_AUTH_PASSWORD||Mypostgres!23}
|
||||
log_level: ${LOG_LEVEL||4}
|
||||
redis:
|
||||
enable: ${REDIS_ENABLE||false}
|
||||
host: ${REDIS_HOST||127.0.0.1}
|
||||
port: ${REDIS_POST||6379}
|
||||
password: ${REDIS_PASSWORD||}
|
||||
database: ${REDIS_DATABASE||0}
|
||||
nats_config:
|
||||
# 10.110.63.81:30529 192.168.12.110
|
||||
url: ${NATS_URL||nats://10.110.63.81:30529}
|
||||
user: ${NATS_USER||admin}
|
||||
password: ${NATS_PASSWORD||T0pS3cr3tFGThjjds56}
|
||||
|
||||
|
||||
logger:
|
||||
default_division: ${LOGGER_DEFAULT_DIVISION||time}
|
||||
file_name: ${LOGGER_FILE_NAME||cfn-schedule-agent.sys.log}
|
||||
division_time:
|
||||
max_age: ${LOGGER_DIVISION_TIME_MAX_AGE||15}
|
||||
rotation_time: ${LOGGER_DIVISION_TIME_ROTATION_TIME||24}
|
||||
division_size:
|
||||
max_size: ${LOGGER_DIVISION_SIZE_MAX_SIZE||20}
|
||||
max_backups: ${LOGGER_DIVISION_SIZE_MAX_BACKUPS||15}
|
||||
max_age: ${LOGGER_DIVISION_SIZE_MAX_AGE||15}
|
||||
compress: ${LOGGER_DIVISION_SIZE_COMPRESS||false}
|
35
agent/config/logger.go
Normal file
35
agent/config/logger.go
Normal file
@ -0,0 +1,35 @@
|
||||
package config
|
||||
|
||||
type DivisionTime struct {
|
||||
MaxAge int `ini:"max_age" yaml:"max_age" mapstructure:"max_age"` // 保留旧文件的最大天数,单位天
|
||||
RotationTime int `ini:"rotation_time" yaml:"rotation_time" mapstructure:"rotation_time"` // 多长时间切割一次文件,单位小时
|
||||
}
|
||||
|
||||
type DivisionSize struct {
|
||||
MaxSize int `ini:"max_size" yaml:"max_size" mapstructure:"max_size"` // 在进行切割之前,日志文件的最大大小(以MB为单位)
|
||||
MaxBackups int `ini:"max_backups" yaml:"max_backups" mapstructure:"max_backups"` // 保留旧文件的最大个数
|
||||
MaxAge int `ini:"max_age" yaml:"max_age" mapstructure:"max_age"` // 保留旧文件的最大天数
|
||||
Compress bool `ini:"compress" yaml:"compress"` // 是否压缩/归档旧文件
|
||||
}
|
||||
|
||||
type LoggerConfig struct {
|
||||
DefaultDivision string `ini:"default_division" yaml:"default_division" mapstructure:"default_division"`
|
||||
Filename string `ini:"file_name" yaml:"file_name" mapstructure:"file_name"`
|
||||
DivisionTime DivisionTime `ini:"division_time" yaml:"division_time" mapstructure:"division_time"`
|
||||
DivisionSize DivisionSize `ini:"division_size" yaml:"division_size" mapstructure:"division_size"`
|
||||
}
|
||||
|
||||
var Logger = LoggerConfig{
|
||||
DefaultDivision: "time", // time 按时间切割,默认一天, size 按文件大小切割
|
||||
Filename: "sys.log",
|
||||
DivisionTime: DivisionTime{
|
||||
MaxAge: 15,
|
||||
RotationTime: 24,
|
||||
},
|
||||
DivisionSize: DivisionSize{
|
||||
MaxSize: 2,
|
||||
MaxBackups: 2,
|
||||
MaxAge: 15,
|
||||
Compress: false,
|
||||
},
|
||||
}
|
13
agent/config/minio.go
Normal file
13
agent/config/minio.go
Normal file
@ -0,0 +1,13 @@
|
||||
package config
|
||||
|
||||
type MinioConfig struct {
|
||||
Endpoint string `ini:"endpoint" yaml:"endpoint"`
|
||||
AccessKey string `ini:"access_key" yaml:"access_key" mapstructure:"access_key"`
|
||||
SecretAccessKey string `ini:"secret_access_key" yaml:"secret_access_key" mapstructure:"secret_access_key"`
|
||||
}
|
||||
|
||||
var Minio = MinioConfig{
|
||||
Endpoint: "192.168.12.78:208670",
|
||||
AccessKey: "xxxxxxxx",
|
||||
SecretAccessKey: "yyyyyyyy",
|
||||
}
|
20
agent/config/nats.go
Normal file
20
agent/config/nats.go
Normal file
@ -0,0 +1,20 @@
|
||||
package config
|
||||
|
||||
type NatsConfig struct {
|
||||
Url string `ini:"url" yaml:"url"`
|
||||
User string `ini:"user" yaml:"user"`
|
||||
Password string `ini:"password" yaml:"password"`
|
||||
|
||||
//ToAgentUnicastSubject string `ini:"to_agent_unicast_subject" yaml:"to_agent_unicast_subject"`
|
||||
//ToAgentBroadcastSubject string `ini:"to_agent_broadcast_subject" yaml:"to_agent_broadcast_subject"`
|
||||
//ToScheduleSubject string `ini:"to_schedule_subject" yaml:"to_schedule_subject"`
|
||||
}
|
||||
|
||||
var Nats = NatsConfig{
|
||||
Url: "nats://192.168.12.110:30529",
|
||||
User: "admin",
|
||||
Password: "T0pS3cr3tFGThjjds56",
|
||||
//ToAgentUnicastSubject: "cfn_to_agent_unicast_{rid}",
|
||||
//ToAgentBroadcastSubject: "cfn_to_agent_broadcast",
|
||||
//ToScheduleSubject: "cfn_to_schedulecfn_to_schedule",
|
||||
}
|
40
agent/config/postgres.go
Normal file
40
agent/config/postgres.go
Normal file
@ -0,0 +1,40 @@
|
||||
package config
|
||||
|
||||
type PostgreSqlConfig struct {
|
||||
Enable bool `ini:"enable" yaml:"enable"`
|
||||
Host string `ini:"host" yaml:"host"`
|
||||
Username string `ini:"username" yaml:"username"`
|
||||
Password string `ini:"password" yaml:"password"`
|
||||
Port uint16 `ini:"port" yaml:"port"`
|
||||
Database string `ini:"database" yaml:"database"`
|
||||
TablePrefix string `ini:"table_prefix" yaml:"table_prefix" mapstructure:"table_prefix"`
|
||||
LogLevel int `ini:"log_level" yaml:"log_level" mapstructure:"log_level"`
|
||||
PrintSql bool `ini:"print_sql" yaml:"print_sql" mapstructure:"print_sql"`
|
||||
}
|
||||
|
||||
type PostgreSqlConfigMap map[string]PostgreSqlConfig
|
||||
|
||||
var PostgreSql = PostgreSqlConfigMap{
|
||||
"data": {
|
||||
Enable: false,
|
||||
Host: "127.0.0.1",
|
||||
Username: "root",
|
||||
Password: "root1234",
|
||||
Port: 3306,
|
||||
Database: "test",
|
||||
TablePrefix: "",
|
||||
LogLevel: 4,
|
||||
PrintSql: false,
|
||||
},
|
||||
"auth": {
|
||||
Enable: false,
|
||||
Host: "127.0.0.1",
|
||||
Username: "root",
|
||||
Password: "root1234",
|
||||
Port: 3306,
|
||||
Database: "test",
|
||||
TablePrefix: "",
|
||||
LogLevel: 4,
|
||||
PrintSql: false,
|
||||
},
|
||||
}
|
17
agent/config/redis.go
Normal file
17
agent/config/redis.go
Normal file
@ -0,0 +1,17 @@
|
||||
package config
|
||||
|
||||
type RedisConfig struct {
|
||||
Enable bool `ini:"enable" yaml:"enable"`
|
||||
Host string `ini:"host" yaml:"host"`
|
||||
Port string `ini:"port" yaml:"port"`
|
||||
Password string `ini:"password" yaml:"password"`
|
||||
Database int `ini:"database" yaml:"database"`
|
||||
}
|
||||
|
||||
var Redis = RedisConfig{
|
||||
Enable: false,
|
||||
Host: "127.0.0.1",
|
||||
Password: "root1234",
|
||||
Port: "6379",
|
||||
Database: 0,
|
||||
}
|
42
agent/config/schedule_server.go
Normal file
42
agent/config/schedule_server.go
Normal file
@ -0,0 +1,42 @@
|
||||
package config
|
||||
|
||||
// The valid auth strategies and values for cookie handling
|
||||
const (
|
||||
// These constants are used for external services auth (Prometheus ...) ;
|
||||
AuthTypeBasic = "basic"
|
||||
AuthTypeBearer = "bearer"
|
||||
AuthTypeNone = "none"
|
||||
)
|
||||
|
||||
// Auth provides authentication data for external services
|
||||
type Auth struct {
|
||||
CAFile string `yaml:"ca_file" mapstructure:"ca_file"`
|
||||
InsecureSkipVerify bool `yaml:"insecure_skip_verify" mapstructure:"insecure_skip_verify"`
|
||||
Password string `yaml:"password" mapstructure:"password"`
|
||||
Token string `yaml:"token" mapstructure:"token"`
|
||||
Type string `yaml:"type" mapstructure:"type"`
|
||||
Username string `yaml:"username" mapstructure:"username"`
|
||||
}
|
||||
|
||||
func (a *Auth) Obfuscate() {
|
||||
a.Token = "xxx"
|
||||
a.Password = "xxx"
|
||||
a.Username = "xxx"
|
||||
a.CAFile = "xxx"
|
||||
}
|
||||
|
||||
type ScheduleServer struct {
|
||||
Port int `yaml:"port,omitempty" mapstructure:"port"`
|
||||
Protocol string `yaml:"protocol,omitempty" mapstructure:"protocol"` // http https socket websocket
|
||||
Auth Auth `yaml:"auth,omitempty" mapstructure:"auth"`
|
||||
HeartBeat int64 `ini:"heart_beat" yaml:"heart_beat" mapstructure:"heart_beat"`
|
||||
}
|
||||
|
||||
var Schedule = ScheduleServer{
|
||||
Port: 1234,
|
||||
Protocol: "http",
|
||||
Auth: Auth{
|
||||
Type: AuthTypeNone,
|
||||
},
|
||||
HeartBeat: 30,
|
||||
}
|
12
agent/config/server.go
Normal file
12
agent/config/server.go
Normal file
@ -0,0 +1,12 @@
|
||||
package config
|
||||
|
||||
// ServerConfig 定义项目配置
|
||||
type ServerConfig struct {
|
||||
Host string `ini:"host" yaml:"host" mapstructure:"host"`
|
||||
Port uint16 `ini:"port" yaml:"port" mapstructure:"port"`
|
||||
}
|
||||
|
||||
var Server = ServerConfig{
|
||||
Host: "127.0.0.1",
|
||||
Port: 9999,
|
||||
}
|
19
agent/data/data.go
Normal file
19
agent/data/data.go
Normal file
@ -0,0 +1,19 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
c "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var once sync.Once
|
||||
|
||||
func InitData() {
|
||||
once.Do(func() {
|
||||
initPostgres()
|
||||
|
||||
if c.Config.Redis.Enable {
|
||||
// 初始化 redis
|
||||
initRedis()
|
||||
}
|
||||
})
|
||||
}
|
73
agent/data/postgres.go
Normal file
73
agent/data/postgres.go
Normal file
@ -0,0 +1,73 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
c "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
)
|
||||
|
||||
var PostgreSqlDB = make(map[string]*gorm.DB)
|
||||
|
||||
type Writer interface {
|
||||
Printf(string, ...interface{})
|
||||
}
|
||||
|
||||
type WriterLog struct {
|
||||
}
|
||||
|
||||
func (w WriterLog) Printf(format string, args ...interface{}) {
|
||||
log.Logger.Sugar().Infof(format, args...)
|
||||
}
|
||||
|
||||
func initPostgres() {
|
||||
var err error
|
||||
postgreSqlConfigMap := c.Config.PostgreSql
|
||||
if c.Config.PostgreSql != nil && len(postgreSqlConfigMap) > 0 {
|
||||
for name, postgreSqlConfig := range postgreSqlConfigMap {
|
||||
if !postgreSqlConfig.Enable {
|
||||
continue
|
||||
}
|
||||
|
||||
var writerLog WriterLog
|
||||
if postgreSqlConfig.PrintSql {
|
||||
writerLog = WriterLog{}
|
||||
}
|
||||
logConfig := logger.New(
|
||||
writerLog,
|
||||
logger.Config{
|
||||
SlowThreshold: 0, // 慢 SQL 阈值
|
||||
LogLevel: logger.LogLevel(postgreSqlConfig.LogLevel), // 日志级别
|
||||
IgnoreRecordNotFoundError: false, // 忽略ErrRecordNotFound(记录未找到)错误
|
||||
Colorful: false, // 是否启用彩色打印
|
||||
},
|
||||
)
|
||||
|
||||
configs := &gorm.Config{
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
TablePrefix: postgreSqlConfig.TablePrefix, // 表名前缀
|
||||
// SingularTable: true, // 使用单数表名
|
||||
},
|
||||
Logger: logConfig,
|
||||
}
|
||||
|
||||
dsn := fmt.Sprintf("host=%s port=%d user=%s dbname=%s password=%s",
|
||||
postgreSqlConfig.Host,
|
||||
postgreSqlConfig.Port,
|
||||
postgreSqlConfig.Username,
|
||||
postgreSqlConfig.Database,
|
||||
postgreSqlConfig.Password,
|
||||
)
|
||||
|
||||
PostgreSqlDB[name], err = gorm.Open(postgres.Open(dsn), configs)
|
||||
|
||||
if err != nil {
|
||||
panic("postgres connection failed:" + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
23
agent/data/redis.go
Normal file
23
agent/data/redis.go
Normal file
@ -0,0 +1,23 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
c "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
var Rdb *redis.Client
|
||||
|
||||
func initRedis() {
|
||||
Rdb = redis.NewClient(&redis.Options{
|
||||
Addr: c.Config.Redis.Host + ":" + c.Config.Redis.Port,
|
||||
Password: c.Config.Redis.Password,
|
||||
DB: c.Config.Redis.Database,
|
||||
})
|
||||
var ctx = context.Background()
|
||||
_, err := Rdb.Ping(ctx).Result()
|
||||
|
||||
if err != nil {
|
||||
panic("Redis connection failed:" + err.Error())
|
||||
}
|
||||
}
|
44
agent/deploy/docker/run.sh
Normal file
44
agent/deploy/docker/run.sh
Normal file
@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 从环境变量获取值,来更改配置文件
|
||||
|
||||
NAME=$APP_ENV yq -i '.app.app_env=env(NAME)' config/config.yaml
|
||||
NAME=$APP_DEBUG yq -i '.app.debug=env(NAME)' config/config.yaml
|
||||
NAME=$APP_LANGUAGE yq -i '.app.language=env(NAME)' config/config.yaml
|
||||
NAME=$SERVER_HOST yq -i '.server.host=env(NAME)' config/config.yaml
|
||||
NAME=$SERVER_PORT yq -i '.server.port=env(NAME)' config/config.yaml
|
||||
NAME=$SCHEDULE_PORT yq -i '.schedule.port=env(NAME)' config/config.yaml
|
||||
|
||||
if [ $POSTGRES_DATA_ENABLE = true ] ;then
|
||||
NAME=$POSTGRES_DATA_ENABLE yq -i '.postgres.data.enable=env(NAME)' config/config.yaml
|
||||
NAME=$POSTGRES_DATA_HOST yq -i '.postgres.data.host=env(NAME)' config/config.yaml
|
||||
NAME=$POSTGRES_DATA_PORT yq -i '.postgres.data.port=env(NAME)' config/config.yaml
|
||||
NAME=$POSTGRES_DATA_DATABASE yq -i '.postgres.data.database=env(NAME)' config/config.yaml
|
||||
NAME=$POSTGRES_DATA_USERNAME yq -i '.postgres.data.username=env(NAME)' config/config.yaml
|
||||
NAME=$LOG_LEVEL yq -i '.postgres.data.log_level=env(NAME)' config/config.yaml
|
||||
if [ -n "$POSTGRES_DATA_PASSWORD" ] ;then
|
||||
NAME=$POSTGRES_DATA_PASSWORD yq -i '.postgres.data.password=env(NAME)' config/config.yaml
|
||||
fi
|
||||
fi
|
||||
if [ $POSTGRES_AUTH_ENABLE = true ] ;then
|
||||
NAME=$POSTGRES_AUTH_ENABLE yq -i '.postgres.auth.enable=env(NAME)' config/config.yaml
|
||||
NAME=$POSTGRES_AUTH_HOST yq -i '.postgres.auth.host=env(NAME)' config/config.yaml
|
||||
NAME=$POSTGRES_AUTH_PORT yq -i '.postgres.auth.port=env(NAME)' config/config.yaml
|
||||
NAME=$POSTGRES_AUTH_DATABASE yq -i '.postgres.auth.database=env(NAME)' config/config.yaml
|
||||
NAME=$POSTGRES_AUTH_USERNAME yq -i '.postgres.auth.username=env(NAME)' config/config.yaml
|
||||
NAME=$LOG_LEVEL yq -i '.postgres.auth.log_level=env(NAME)' config/config.yaml
|
||||
if [ -n "$POSTGRES_AUTH_PASSWORD" ] ;then
|
||||
NAME=$POSTGRES_AUTH_PASSWORD yq -i '.postgres.auth.password=env(NAME)' config/config.yaml
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $REDIS_EBABLE = true ] ;then
|
||||
NAME=$REDIS_EBABLE yq -i '.redis.enable=env(NAME)' config/config.yaml
|
||||
NAME=$REDIS_HOST yq -i '.redis.host=env(NAME)' config/config.yaml
|
||||
NAME=$REDIS_PORT yq -i '.redis.port=env(NAME)' config/config.yaml
|
||||
NAME=$REDIS_DATABASE yq -i '.redis.database=env(NAME)' config/config.yaml
|
||||
if [ -n "$REDIS_PASSWORD" ] ;then
|
||||
NAME=$REDIS_PASSWORD yq -i '.redis.password=env(NAME)' config/config.yaml
|
||||
fi
|
||||
fi
|
||||
./cfn-schedule-agent -c config/config.yaml
|
162
agent/go.mod
Normal file
162
agent/go.mod
Normal file
@ -0,0 +1,162 @@
|
||||
module git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/StackExchange/wmi v1.2.1
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/docker/docker v24.0.6+incompatible
|
||||
github.com/elastic/go-windows v1.0.1
|
||||
github.com/gin-contrib/cors v1.3.1
|
||||
github.com/gin-gonic/gin v1.8.1
|
||||
github.com/go-playground/locales v0.14.0
|
||||
github.com/go-playground/universal-translator v0.18.0
|
||||
github.com/go-playground/validator/v10 v10.11.1
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/golang/glog v1.1.0
|
||||
github.com/guoyk93/rg v1.0.1
|
||||
github.com/influxdata/telegraf v1.28.2
|
||||
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||
github.com/nats-io/nats.go v1.30.2
|
||||
github.com/prometheus-community/pro-bing v0.3.0
|
||||
github.com/prometheus/procfs v0.12.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/spf13/viper v1.17.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.14.0
|
||||
golang.org/x/net v0.17.0
|
||||
golang.org/x/sys v0.14.0
|
||||
golang.org/x/text v0.13.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/postgres v1.5.2
|
||||
gorm.io/gorm v1.25.0
|
||||
gorm.io/plugin/soft_delete v1.1.0
|
||||
howett.net/plist v1.0.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
|
||||
github.com/awnumar/memcall v0.1.2 // indirect
|
||||
github.com/awnumar/memguard v0.22.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.21.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.42 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.40 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.14.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.22.0 // indirect
|
||||
github.com/aws/smithy-go v1.14.2 // indirect
|
||||
github.com/benbjohnson/clock v1.3.3 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blues/jsonata-go v1.5.4 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/compose-spec/compose-go v1.16.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/distribution/reference v0.5.0 // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/cel-go v0.14.1-0.20230424164844-d39523c445fc // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/google/uuid v1.4.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/influxdata/toml v0.0.0-20190415235208-270119a8ce65 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.3.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.0 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.16 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/minio/highwayhash v1.0.2 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/naoina/go-stringutil v0.1.0 // indirect
|
||||
github.com/nats-io/jwt/v2 v2.4.1 // indirect
|
||||
github.com/nats-io/nats-server/v2 v2.9.9 // indirect
|
||||
github.com/nats-io/nkeys v0.4.5 // indirect
|
||||
github.com/nats-io/nuid v1.0.1 // indirect
|
||||
github.com/onsi/gomega v1.27.6 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc4 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
|
||||
github.com/prometheus/client_golang v1.16.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/prometheus v0.46.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.3.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.8 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.10.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/oauth2 v0.12.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.13.0 // indirect
|
||||
google.golang.org/api v0.143.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
|
||||
google.golang.org/grpc v1.58.2 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gotest.tools/v3 v3.5.1 // indirect
|
||||
)
|
907
agent/go.sum
Normal file
907
agent/go.sum
Normal file
@ -0,0 +1,907 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
|
||||
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
collectd.org v0.5.0 h1:y4uFSAuOmeVhG3GCRa3/oH+ysePfO/+eGJNfd0Qa3d8=
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||
github.com/antchfx/jsonquery v1.3.3 h1:zjZpbnZhYng3uOAbIfdNq81A9mMEeuDJeYIpeKpZ4es=
|
||||
github.com/antchfx/xmlquery v1.3.17 h1:d0qWjPp/D+vtRw7ivCwT5ApH/3CkQU8JOeo3245PpTk=
|
||||
github.com/antchfx/xpath v1.2.5-0.20230505064641-588960cceeac h1:Et7H7mEPWuivbFEXi3dWa8hobnvF380TS2mq7JmgjEI=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
|
||||
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/awnumar/memcall v0.1.2 h1:7gOfDTL+BJ6nnbtAp9+HQzUFjtP1hEseRQq8eP055QY=
|
||||
github.com/awnumar/memcall v0.1.2/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGaWsWsoJo=
|
||||
github.com/awnumar/memguard v0.22.3 h1:b4sgUXtbUjhrGELPbuC62wU+BsPQy+8lkWed9Z+pj0Y=
|
||||
github.com/awnumar/memguard v0.22.3/go.mod h1:mmGunnffnLHlxE5rRgQc3j+uwPZ27eYb61ccr8Clz2Y=
|
||||
github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.42 h1:28jHROB27xZwU0CB88giDSjz7M1Sba3olb5JBGwina8=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.42/go.mod h1:4AZM3nMMxwlG+eZlxvBKqwVbkDLlnN2a4UGTL6HjaZI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.40 h1:s8yOkDh+5b1jUDhMBtngF6zKWLDs84chUk2Vk0c38Og=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.40/go.mod h1:VtEHVAAqDWASwdOqj/1huyT6uHbs5s8FUHfDQdky/Rs=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 h1:uDZJF1hu0EVT/4bogChk8DyjSF6fof6uL/0Y26Ma7Fg=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11/go.mod h1:TEPP4tENqBGO99KwVpV9MlOX4NSrSLP8u3KRy2CDwA8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43 h1:g+qlObJH4Kn4n21g69DjspU0hKTjWtq7naZ9OLCv0ew=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.43/go.mod h1:rzfdUlfA+jdgLDmPKjd3Chq9V7LVLYo1Nz++Wb91aRo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.14.1 h1:YkNzx1RLS0F5qdf9v1Q8Cuv9NXCL2TkosOxhzlUPV64=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.14.1/go.mod h1:fIAwKQKBFu90pBxx07BFOMJLpRUGu8VOzLJakeY+0K4=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.1 h1:8lKOidPkmSmfUtiTgtdXWgaKItCZ/g75/jEk6Ql6GsA=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.1/go.mod h1:yygr8ACQRY2PrEcy3xsUI357stq2AxnFM6DIsR9lij4=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.22.0 h1:s4bioTgjSFRwOoyEFzAVCmFmoowBgjTR8gkrF/sQ4wk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.22.0/go.mod h1:VC7JDqsqiwXukYEDjoHh9U0fOJtNWh04FPQz4ct4GGU=
|
||||
github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ=
|
||||
github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/benbjohnson/clock v1.3.3 h1:g+rSsSaAzhHJYcIQE78hJ3AhyjjtQvleKDjlhdBnIhc=
|
||||
github.com/benbjohnson/clock v1.3.3/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/blues/jsonata-go v1.5.4 h1:XCsXaVVMrt4lcpKeJw6mNJHqQpWU751cnHdCFUq3xd8=
|
||||
github.com/blues/jsonata-go v1.5.4/go.mod h1:uns2jymDrnI7y+UFYCqsRTEiAH22GyHnNXrkupAVFWI=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudevents/sdk-go/v2 v2.14.0 h1:Nrob4FwVgi5L4tV9lhjzZcjYqFVyJzsA56CwPaPfv6s=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/compose-spec/compose-go v1.16.0 h1:HYk4uYWXgArHh6NG+WE4yGYayOXw+hjqJ+eJxpjWWjk=
|
||||
github.com/compose-spec/compose-go v1.16.0/go.mod h1:3yngGBGfls6FHGQsg4B1z6gz8ej9SOvmAJtxCwgbcnc=
|
||||
github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o=
|
||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE=
|
||||
github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0=
|
||||
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
|
||||
github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/fxamacker/cbor v1.5.1 h1:XjQWBgdmQyqimslUh5r4tUGmoqzHmBFQOImkWGi2awg=
|
||||
github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA=
|
||||
github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
|
||||
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
|
||||
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/cel-go v0.14.1-0.20230424164844-d39523c445fc h1:jd+stC3Fqf9kaqgCLOdm4Da/AN3txPTlmLB6tStXAcU=
|
||||
github.com/google/cel-go v0.14.1-0.20230424164844-d39523c445fc/go.mod h1:YzWEoI07MC/a/wj9in8GeVatqfypkldgBlwXh9bCwqY=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/guoyk93/rg v1.0.1 h1:Rnca+1JYfuGqPRMIQkuxAoZhhmrPpMFyS5XwLz0U0ds=
|
||||
github.com/guoyk93/rg v1.0.1/go.mod h1:tLaoLk8bo/PQld1xGvJvAfCl3K0Nckzh0gsnykFoQYg=
|
||||
github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
||||
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/influxdata/line-protocol/v2 v2.2.1 h1:EAPkqJ9Km4uAxtMRgUubJyqAr6zgWM0dznKMLRauQRE=
|
||||
github.com/influxdata/telegraf v1.28.2 h1:psX+oyjo9Ay9Pb/CEDxW9bWoxIWfL3GnzeFYvFJO1Y0=
|
||||
github.com/influxdata/telegraf v1.28.2/go.mod h1:X3UcHLZQDVu8Y5GO4rOY1pr7TrwPLuW5OBf2RGBFjTE=
|
||||
github.com/influxdata/toml v0.0.0-20190415235208-270119a8ce65 h1:vvyMtD5LTJc1W9sQKjDkAWdcg0478CszSdzlHtiAXCY=
|
||||
github.com/influxdata/toml v0.0.0-20190415235208-270119a8ce65/go.mod h1:zApaNFpP/bTpQItGZNNUMISDMDAnTXu9UqJ4yT3ocz8=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
|
||||
github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
|
||||
github.com/jeremywohl/flatten/v2 v2.0.0-20211013061545-07e4a09fb8e4 h1:eA9wi6ZzpIRobvXkn/S2Lyw1hr2pc71zxzOPl7Xjs4w=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4=
|
||||
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
|
||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
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/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/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
|
||||
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/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=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
|
||||
github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
|
||||
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
|
||||
github.com/linkedin/goavro/v2 v2.12.0 h1:rIQQSj8jdAUlKQh6DttK8wCRv4t4QO09g1C4aBWXslg=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
|
||||
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY=
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
|
||||
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
||||
github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4=
|
||||
github.com/nats-io/jwt/v2 v2.4.1/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
|
||||
github.com/nats-io/nats-server/v2 v2.9.9 h1:bmj0RhvHOc8+z5/RuhI38GqPwtkFAHQuU3e99FVA/TI=
|
||||
github.com/nats-io/nats-server/v2 v2.9.9/go.mod h1:AB6hAnGZDlYfqb7CTAm66ZKMZy9DpfierY1/PbpvI2g=
|
||||
github.com/nats-io/nats.go v1.30.2 h1:aloM0TGpPorZKQhbAkdCzYDj+ZmsJDyeo3Gkbr72NuY=
|
||||
github.com/nats-io/nats.go v1.30.2/go.mod h1:dcfhUgmQNN4GJEfIb2f9R7Fow+gzBF4emzDHrVBd5qM=
|
||||
github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk=
|
||||
github.com/nats-io/nkeys v0.4.5/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
|
||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
||||
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI=
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prometheus-community/pro-bing v0.3.0 h1:SFT6gHqXwbItEDJhTkzPWVqU6CLEtqEfNAPp47RUON4=
|
||||
github.com/prometheus-community/pro-bing v0.3.0/go.mod h1:p9dLb9zdmv+eLxWfCT6jESWuDrS+YzpPkQBgysQF8a0=
|
||||
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
|
||||
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73vCMk/Kw=
|
||||
github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIscDWWt3IJ2UDYrz4=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ=
|
||||
github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE=
|
||||
github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
|
||||
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
|
||||
github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI=
|
||||
github.com/srebhan/cborquery v0.0.0-20230626165538-38be85b82316 h1:HVv8JjpX24FuI59aET1uInn0ItuEiyj8CZMuR9Uw+lE=
|
||||
github.com/srebhan/protobufquery v0.0.0-20230803132024-ae4c0d878e55 h1:ksmbrLbJAm+8yxB7fJ245usD0b1v9JHBJrWF+WqGyjs=
|
||||
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/testcontainers/testcontainers-go v0.22.0 h1:hOK4NzNu82VZcKEB1aP9LO1xYssVFMvlfeuDW9JMmV0=
|
||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/vjeantet/grok v1.0.1 h1:2rhIR7J4gThTgcZ1m2JY4TrJZNgjn985U28kT2wQrJ4=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
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-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
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=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
|
||||
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
|
||||
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=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
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=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.143.0 h1:o8cekTkqhywkbZT6p1UHJPZ9+9uuCAJs/KYomxZB8fA=
|
||||
google.golang.org/api v0.143.0/go.mod h1:FoX9DO9hT7DLNn97OuoZAGSDuNAXdJRuGK98rSUgurk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
|
||||
google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
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=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0=
|
||||
gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8=
|
||||
gorm.io/driver/sqlite v1.1.3 h1:BYfdVuZB5He/u9dt4qDpZqiqDJ6KhPqs5QUqsr/Eeuc=
|
||||
gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c=
|
||||
gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
|
||||
gorm.io/gorm v1.23.0/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU=
|
||||
gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/plugin/soft_delete v1.1.0 h1:LcE4L+GD29RkkMLxMYHpT4wQCJ/9945FsdU/mHGaDuE=
|
||||
gorm.io/plugin/soft_delete v1.1.0/go.mod h1:Zv7vQctOJTGOsJ/bWgrN1n3od0GBAZgnLjEx+cApLGk=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
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=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
|
||||
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||
k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw=
|
||||
k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ=
|
||||
k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
|
||||
k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
30
agent/internal/command/command.go
Normal file
30
agent/internal/command/command.go
Normal file
@ -0,0 +1,30 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/func_make"
|
||||
)
|
||||
|
||||
var (
|
||||
commandMap = map[string]interface{}{
|
||||
"demo": demo,
|
||||
}
|
||||
funcMake = func_make.New()
|
||||
)
|
||||
|
||||
func Register() {
|
||||
err := funcMake.Registers(commandMap)
|
||||
if err != nil {
|
||||
panic("failed to register console command: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func Run(funcName string) {
|
||||
Register()
|
||||
_, err := funcMake.Call(funcName)
|
||||
if err != nil {
|
||||
fmt.Printf("execution failed, error cause: %v \n", err.Error())
|
||||
return
|
||||
}
|
||||
fmt.Printf("complete! \n")
|
||||
}
|
7
agent/internal/command/demo.go
Normal file
7
agent/internal/command/demo.go
Normal file
@ -0,0 +1,7 @@
|
||||
package command
|
||||
|
||||
import "fmt"
|
||||
|
||||
func demo() {
|
||||
fmt.Println("hello console!")
|
||||
}
|
54
agent/internal/controller/base.go
Normal file
54
agent/internal/controller/base.go
Normal file
@ -0,0 +1,54 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/errors"
|
||||
r "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/response"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Success 业务成功响应
|
||||
func Success(c *gin.Context, data ...any) {
|
||||
response := r.Resp()
|
||||
if data != nil {
|
||||
response.WithDataSuccess(c, data[0])
|
||||
return
|
||||
}
|
||||
response.Success(c)
|
||||
}
|
||||
|
||||
// FailCode 业务失败响应
|
||||
func FailCode(c *gin.Context, code int, err error, data ...any) {
|
||||
response := r.Resp()
|
||||
if err != nil {
|
||||
log.Error("异常: %s", err.Error())
|
||||
}
|
||||
if data != nil {
|
||||
response.WithData(data[0]).FailCode(c, code)
|
||||
return
|
||||
}
|
||||
response.FailCode(c, code)
|
||||
}
|
||||
|
||||
// Fail 业务失败响应
|
||||
func Fail(c *gin.Context, code int, message string, data ...any) {
|
||||
response := r.Resp()
|
||||
if data != nil {
|
||||
response.WithData(data[0]).FailCode(c, code, message)
|
||||
return
|
||||
}
|
||||
response.FailCode(c, code, message)
|
||||
}
|
||||
|
||||
// Err 判断错误类型是自定义类型则自动返回错误中携带的code和message,否则返回服务器错误
|
||||
func Err(c *gin.Context, e error) {
|
||||
businessError, err := errors.AsBusinessError(e)
|
||||
if err != nil {
|
||||
log.Logger.Warn("Unknown error:", zap.Any("Error reason:", err))
|
||||
FailCode(c, errors.ServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
Fail(c, businessError.GetCode(), businessError.GetMessage())
|
||||
}
|
69
agent/internal/controller/v1/agentController.go
Normal file
69
agent/internal/controller/v1/agentController.go
Normal file
@ -0,0 +1,69 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/controller"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/errors"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/request"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/component"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/load_resource_info"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io"
|
||||
)
|
||||
|
||||
func AssetInformationEntry(c *gin.Context) {
|
||||
body := request.GetBody(c)
|
||||
var rinfo = agent.AgentConfig{}
|
||||
err := json.Unmarshal(body, &rinfo)
|
||||
if err != nil {
|
||||
controller.FailCode(c, errors.ServerError, err, "更新资产信息失败!")
|
||||
return
|
||||
}
|
||||
|
||||
agent.Agent = &rinfo
|
||||
load_resource_info.LoadAgentInfo(rinfo)
|
||||
|
||||
controller.Success(c, "配置初始化完成")
|
||||
}
|
||||
|
||||
func GetComponentInfo(c *gin.Context) {
|
||||
info, err := component.GetComInfo()
|
||||
if err != nil {
|
||||
controller.FailCode(c, errors.ServerError, err, "获取组件详情失败!")
|
||||
return
|
||||
}
|
||||
controller.Success(c, info)
|
||||
}
|
||||
|
||||
func UpdateTelegrafConfig(c *gin.Context) {
|
||||
|
||||
_, fileHeader, err := c.Request.FormFile("telegraf-config")
|
||||
if err != nil {
|
||||
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数(body)是否符合要求!")
|
||||
return
|
||||
}
|
||||
|
||||
src, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数(body)是否符合要求!")
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
var out []byte
|
||||
out, _ = io.ReadAll(src)
|
||||
|
||||
component.UpdateTelegrafConfig(out)
|
||||
|
||||
if err != nil {
|
||||
controller.FailCode(c, errors.ServerError, err, "请检查参数(body)是否符合要求!")
|
||||
return
|
||||
}
|
||||
controller.Success(c, "完成配置文件更新!")
|
||||
}
|
||||
|
||||
func RecoverConfig(c *gin.Context) {
|
||||
component.RecoverConfig()
|
||||
controller.Success(c, "完成配置文件恢复!")
|
||||
}
|
16
agent/internal/controller/v1/demo.go
Normal file
16
agent/internal/controller/v1/demo.go
Normal file
@ -0,0 +1,16 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/controller"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func HelloWorld(c *gin.Context) {
|
||||
str, ok := c.GetQuery("name")
|
||||
if !ok {
|
||||
str = "gin-layout"
|
||||
}
|
||||
|
||||
controller.Success(c, fmt.Sprintf("hello %s", str))
|
||||
}
|
21
agent/internal/controller/v1/downloadAgent.go
Normal file
21
agent/internal/controller/v1/downloadAgent.go
Normal file
@ -0,0 +1,21 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/definition"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func DownloadAgent(c *gin.Context) {
|
||||
filename := c.Query("filename")
|
||||
|
||||
c.Writer.WriteHeader(http.StatusOK)
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
|
||||
c.Header("Content-Type", "application/octet-stream")
|
||||
|
||||
versionedAgent := filepath.Join(definition.RunDirectory, "../upgrade", filename)
|
||||
|
||||
c.File(versionedAgent)
|
||||
}
|
54
agent/internal/controller/v1/logController.go
Normal file
54
agent/internal/controller/v1/logController.go
Normal file
@ -0,0 +1,54 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/controller"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/errors"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/log_service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func GetAgentLog(c *gin.Context) {
|
||||
lineNum := c.Query("lines")
|
||||
lineUnit, err2 := strconv.ParseUint(lineNum, 10, 64)
|
||||
if err2 != nil {
|
||||
lineUnit = 100
|
||||
}
|
||||
|
||||
info, err := log_service.GetAgentLog(lineUnit)
|
||||
if err != nil {
|
||||
controller.FailCode(c, errors.ServerError, err, "读取日志失败!")
|
||||
return
|
||||
}
|
||||
controller.Success(c, info)
|
||||
}
|
||||
|
||||
func GetAgentUpgradeLog(c *gin.Context) {
|
||||
lineNum := c.Query("lines")
|
||||
lineUnit, err2 := strconv.ParseUint(lineNum, 10, 64)
|
||||
if err2 != nil {
|
||||
lineUnit = 100
|
||||
}
|
||||
|
||||
info, err := log_service.GetAgentUpgradeLog(lineUnit)
|
||||
if err != nil {
|
||||
controller.FailCode(c, errors.ServerError, err, "读取日志失败!")
|
||||
return
|
||||
}
|
||||
controller.Success(c, info)
|
||||
}
|
||||
|
||||
func GetTelegrafLog(c *gin.Context) {
|
||||
lineNum := c.Query("lines")
|
||||
lineUnit, err2 := strconv.ParseUint(lineNum, 10, 64)
|
||||
if err2 != nil {
|
||||
lineUnit = 100
|
||||
}
|
||||
|
||||
info, err := log_service.GetTelegrafLog(lineUnit)
|
||||
if err != nil {
|
||||
controller.FailCode(c, errors.ServerError, err, "读取日志失败!")
|
||||
return
|
||||
}
|
||||
controller.Success(c, info)
|
||||
}
|
13
agent/internal/controller/v1/shutdown.go
Normal file
13
agent/internal/controller/v1/shutdown.go
Normal file
@ -0,0 +1,13 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/controller"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"os"
|
||||
)
|
||||
|
||||
func Shutdown(c *gin.Context) {
|
||||
utils.ChUserSig <- os.Interrupt
|
||||
controller.Success(c, "关闭命令已发送!")
|
||||
}
|
27
agent/internal/middleware/app_context.go
Normal file
27
agent/internal/middleware/app_context.go
Normal file
@ -0,0 +1,27 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
CLUSTERID = "clusterId"
|
||||
NAMESPACE = "namespace"
|
||||
)
|
||||
|
||||
func AppContextHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
ns := c.Request.Header.Get("namespace")
|
||||
if len(ns) != 0 {
|
||||
c.Set(NAMESPACE, ns)
|
||||
}
|
||||
|
||||
clusterId := c.Param("cluster")
|
||||
if len(clusterId) != 0 {
|
||||
c.Set(CLUSTERID, clusterId)
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
||||
}
|
81
agent/internal/middleware/authentication.go
Normal file
81
agent/internal/middleware/authentication.go
Normal file
@ -0,0 +1,81 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/authen"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/errors"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/response"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang/glog"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const (
|
||||
LoginUserKey = "login-user"
|
||||
)
|
||||
|
||||
func AuthenticationHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
match, _ := regexp.MatchString("/healthz", c.Request.RequestURI)
|
||||
if match {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
rawToken := c.Request.Header.Get("Authorization")
|
||||
if rawToken == "" {
|
||||
glog.Warning("unauthorized access, token not specified")
|
||||
response.Resp().FailCode(c, errors.AuthorizationError, "token should be specified in header with 'Authorization' key")
|
||||
return
|
||||
}
|
||||
var username, encrypted string
|
||||
ok, bearerToken := authen.JWTAuthorizer.IsBearerToken(rawToken)
|
||||
if ok {
|
||||
loginInfo, err := authen.JWTAuthorizer.ValidateToken(bearerToken)
|
||||
//marshal, _ := json.Marshal(loginInfo)
|
||||
//fmt.Print(string(marshal))
|
||||
|
||||
if err != nil {
|
||||
if authen.JWTAuthorizer.IsTokenExpired(err) {
|
||||
glog.Warning("unauthorized access, bearer token expired")
|
||||
response.Resp().FailCode(c, errors.AuthorizationError, "bearer token expired")
|
||||
return
|
||||
}
|
||||
glog.Warningf("validate bearer token failed, %s", err)
|
||||
response.Resp().FailCode(c, errors.AuthorizationError, fmt.Sprint("validate bearer token failed, %s", err))
|
||||
return
|
||||
}
|
||||
username = loginInfo.Username
|
||||
encrypted = loginInfo.Encrypted
|
||||
} else {
|
||||
glog.Warningf("validate bearer token failed")
|
||||
response.Resp().FailCode(c, errors.AuthorizationError, "validate bearer token failed")
|
||||
|
||||
return
|
||||
}
|
||||
//u, err := user.FindOneByName(username, model.DBAuth())
|
||||
//if err != nil {
|
||||
// if err == gorm.ErrRecordNotFound {
|
||||
// glog.Errorf("unauthorized access, user not found, %s", username)
|
||||
// response.Resp().FailCode(c, errors.AuthorizationError, "user not found")
|
||||
//
|
||||
// return
|
||||
// }
|
||||
// glog.Errorf("get user from db failed, user %s, %s", username, err)
|
||||
// response.Resp().FailCode(c, errors.ServerError, fmt.Sprintf("get user from db failed, user %s, %s", username, err))
|
||||
//
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//if encrypted != "" && encrypted != u.EncryptedPassword {
|
||||
// glog.Warningf("unauthorized access, password mismatch, user %s", username)
|
||||
// response.Resp().FailCode(c, errors.AuthorizationError, "password mismatch")
|
||||
// return
|
||||
//}
|
||||
|
||||
//c.Set(LoginUserKey, u)
|
||||
|
||||
c.Set(LoginUserKey, username+":"+encrypted)
|
||||
c.Next()
|
||||
}
|
||||
}
|
26
agent/internal/middleware/authorization.go
Normal file
26
agent/internal/middleware/authorization.go
Normal file
@ -0,0 +1,26 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang/glog"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func AuthorizationHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
match, _ := regexp.MatchString("/healthz", c.Request.RequestURI)
|
||||
if match {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
_, exist := c.Get(LoginUserKey)
|
||||
if !exist {
|
||||
glog.Fatal("Authorization middleware should work together with Authentication middleware")
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
10
agent/internal/middleware/cors.go
Normal file
10
agent/internal/middleware/cors.go
Normal file
@ -0,0 +1,10 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func CorsHandler() gin.HandlerFunc {
|
||||
return cors.Default()
|
||||
}
|
53
agent/internal/middleware/logger.go
Normal file
53
agent/internal/middleware/logger.go
Normal file
@ -0,0 +1,53 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
"time"
|
||||
)
|
||||
|
||||
type responseWriter struct {
|
||||
gin.ResponseWriter
|
||||
body *bytes.Buffer
|
||||
}
|
||||
|
||||
func (w responseWriter) Write(b []byte) (int, error) {
|
||||
w.body.Write(b)
|
||||
return w.ResponseWriter.Write(b)
|
||||
}
|
||||
|
||||
func (w responseWriter) WriteString(s string) (int, error) {
|
||||
w.body.WriteString(s)
|
||||
return w.ResponseWriter.WriteString(s)
|
||||
}
|
||||
|
||||
// CustomLogger 接收gin框架默认的日志
|
||||
func CustomLogger() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
blw := &responseWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
|
||||
c.Writer = blw
|
||||
// 读取body数据
|
||||
//body := request.GetBody(c)
|
||||
c.Next()
|
||||
|
||||
cost := time.Since(c.GetTime("requestStartTime"))
|
||||
if config.Config.AppEnv != "production" {
|
||||
path := c.Request.URL.Path
|
||||
log.Logger.Info(path,
|
||||
zap.Int("status", c.Writer.Status()),
|
||||
zap.String("method", c.Request.Method),
|
||||
zap.String("path", path),
|
||||
zap.String("query", c.Request.URL.RawQuery),
|
||||
//zap.Any("body", string(body)),
|
||||
zap.String("ip", c.ClientIP()),
|
||||
zap.String("user-agent", c.Request.UserAgent()),
|
||||
zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()),
|
||||
zap.String("cost", cost.String()),
|
||||
zap.String("response", blw.body.String()),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
40
agent/internal/middleware/recovery.go
Normal file
40
agent/internal/middleware/recovery.go
Normal file
@ -0,0 +1,40 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
e "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/errors"
|
||||
response2 "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/response"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CustomRecovery 自定义错误 (panic) 拦截中间件、对可能发生的错误进行拦截、统一记录
|
||||
func CustomRecovery() gin.HandlerFunc {
|
||||
DefaultErrorWriter := &PanicExceptionRecord{}
|
||||
return gin.RecoveryWithWriter(DefaultErrorWriter, func(c *gin.Context, err interface{}) {
|
||||
// 这里针对发生的panic等异常进行统一响应即
|
||||
// 这里针对发生的panic等异常进行统一响应即
|
||||
errStr := ""
|
||||
if config.Config.Debug == true {
|
||||
errStr = fmt.Sprintf("%v", err)
|
||||
}
|
||||
response2.Resp().SetHttpCode(http.StatusInternalServerError).FailCode(c, e.ServerError, errStr)
|
||||
})
|
||||
}
|
||||
|
||||
// PanicExceptionRecord panic等异常记录
|
||||
type PanicExceptionRecord struct{}
|
||||
|
||||
func (p *PanicExceptionRecord) Write(b []byte) (n int, err error) {
|
||||
s1 := "An error occurred in the server's internal code:"
|
||||
var build strings.Builder
|
||||
build.WriteString(s1)
|
||||
build.Write(b)
|
||||
errStr := build.String()
|
||||
log.Error(errStr)
|
||||
return len(errStr), errors.New(errStr)
|
||||
}
|
13
agent/internal/middleware/requestCost.go
Normal file
13
agent/internal/middleware/requestCost.go
Normal file
@ -0,0 +1,13 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"time"
|
||||
)
|
||||
|
||||
func RequestCostHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Set("requestStartTime", time.Now())
|
||||
c.Next()
|
||||
}
|
||||
}
|
40
agent/internal/model/base.go
Normal file
40
agent/internal/model/base.go
Normal file
@ -0,0 +1,40 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/data"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/plugin/soft_delete"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PageData struct {
|
||||
TotalCount int64
|
||||
PageSize int
|
||||
PageNumber int
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type BaseModel struct {
|
||||
ID string `gorm:"column:id;not null;primarykey" json:"id"`
|
||||
CreateTime time.Time `gorm:"column:create_time;type:timestamp;<-:create" json:"createTime"`
|
||||
UpdateTime time.Time `gorm:"column:update_time;type:timestamp" json:"updateTime"`
|
||||
CreatorID string `gorm:"column:creator_id;type:varchar(64);not null;<-:create" json:"creatorID"`
|
||||
Modifier string `gorm:"column:modifier;type:varchar(64);not null;" json:"modifier"`
|
||||
}
|
||||
|
||||
func (model *BaseModel) DB() *gorm.DB {
|
||||
return DB()
|
||||
}
|
||||
|
||||
type ContainsDeleteBaseModel struct {
|
||||
BaseModel
|
||||
DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at;type:int(11) unsigned;not null;default:0;index" json:"-"`
|
||||
}
|
||||
|
||||
func DB() *gorm.DB {
|
||||
return data.PostgreSqlDB["data"]
|
||||
}
|
||||
|
||||
func DBAuth() *gorm.DB {
|
||||
return data.PostgreSqlDB["auth"]
|
||||
}
|
30
agent/internal/model/component/component.go
Normal file
30
agent/internal/model/component/component.go
Normal file
@ -0,0 +1,30 @@
|
||||
package component
|
||||
|
||||
import "time"
|
||||
|
||||
// 组件详情
|
||||
type Component struct {
|
||||
COMName string `json:"comName"` // 组件名称,枚举:Telegraf、ProcessExporter
|
||||
COMPort int64 `json:"comPort"` // 组件端口
|
||||
COMType string `json:"comType"` // 组件类型,中文描述既可
|
||||
COMVersion string `json:"comVersion"` // 组件版本
|
||||
Config Config `json:"config"` // 组件配置(传json字符串),每个组件的信息不同
|
||||
LastStarttime time.Time `json:"lastStarttime"` // 最近运行时间, 2023-08-16 00:00:00
|
||||
Status string `json:"status"` // 组件状态,0:离线,1:在线,2:故障
|
||||
}
|
||||
|
||||
// Config 组件配置(传json字符串),每个组件的信息不同
|
||||
//
|
||||
// # Telegraf配置
|
||||
//
|
||||
// ProcessExporter配置
|
||||
type Config struct {
|
||||
Metrics []string `json:"metrics,omitempty"`
|
||||
MetricServer []MetricServer `json:"metricServer,omitempty"` // 指标服务器名称
|
||||
Tags map[string]string `json:"tags,omitempty"` // 标签,map[string]string类型
|
||||
}
|
||||
|
||||
type MetricServer struct {
|
||||
Address string `json:"address"` // 指标服务器地址
|
||||
Name string `json:"name"` // 指标服务器名称
|
||||
}
|
28
agent/internal/model/heartbeat/heartbeat.go
Normal file
28
agent/internal/model/heartbeat/heartbeat.go
Normal file
@ -0,0 +1,28 @@
|
||||
package heartbeat
|
||||
|
||||
import "time"
|
||||
|
||||
// 1.返回应用一体机开机后运行时间和开始时间
|
||||
// 2.返回CPU、内存、网卡等配置信息、型号信息、操作系统信息,硬盘信息等
|
||||
|
||||
// HeartBeat 一体机-心跳检测信息
|
||||
type HeartBeat struct {
|
||||
SerialNo string `json:"serialNo"` // 序列号
|
||||
AgentVersion string `json:"agentVersion"` // 小助手版本
|
||||
IPAddress string `json:"ipAddress"` // ip地址,多个逗号分割
|
||||
MACAddress string `json:"macAddress"` // mac地址
|
||||
|
||||
Architecture string `json:"archType"` // architecture
|
||||
KernelVersion string `json:"kernelVersion"` // kernel_version
|
||||
OS string `json:"osInfo"` // os
|
||||
OSType string `json:"osType"` // os
|
||||
|
||||
LastStarttime time.Time `json:"lastStarttime"` // 最近开机时间, 2023-08-16 00:00:00 - 2023-08-16 23:59:59
|
||||
COMInfo []COMInfo `json:"comInfo"` // 组件信息
|
||||
}
|
||||
|
||||
type COMInfo struct {
|
||||
LastStarttime time.Time `json:"lastStarttime"` // 最近运行时间, 2023-08-16 00:00:00
|
||||
Name string `json:"name"` // 组件名称
|
||||
Status string `json:"status"` // 组件状态,0:离线,1:在线,2:故障
|
||||
}
|
7
agent/internal/model/heartbeat/heartbeat_response.go
Normal file
7
agent/internal/model/heartbeat/heartbeat_response.go
Normal file
@ -0,0 +1,7 @@
|
||||
package heartbeat
|
||||
|
||||
type HeartbeatResponse struct {
|
||||
ID int `gorm:"column:user_id"`
|
||||
Name string `gorm:"column:login_name"`
|
||||
EncryptedPassword string `gorm:"column:login_pass"`
|
||||
}
|
29
agent/internal/model/nats_msg_model/local_upgrade_cmd.go
Normal file
29
agent/internal/model/nats_msg_model/local_upgrade_cmd.go
Normal file
@ -0,0 +1,29 @@
|
||||
package nats_msg_model
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func UnmarshalLocalUpgradeCMD(data []byte) (LocalUpgradeCMD, error) {
|
||||
var r LocalUpgradeCMD
|
||||
err := json.Unmarshal(data, &r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (r *LocalUpgradeCMD) Marshal() ([]byte, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
type LocalUpgradeCMD struct {
|
||||
AgentId string `json:"agentId"` // 需要关联升级记录
|
||||
// 备用
|
||||
DownUrl string `json:"downUrl"`
|
||||
Filename string `json:"filename"`
|
||||
Version string `json:"version"`
|
||||
Command string `json:"command"`
|
||||
|
||||
CompressionType string `json:"compressionType"` // tar.gz or zip
|
||||
IP string `json:"ip"`
|
||||
Port uint16 `json:"port"`
|
||||
OsType string `json:"osType"` // 字典:Windows\Ubuntu\CentOS\KylinOS
|
||||
ArchType string `json:"archType"` // 字典: X86\ARM
|
||||
//DeviceType string `json:"deviceType"` // 设备类型;0:为全部,1:应用一体机,2:调度一体机,3:纳管一体机
|
||||
}
|
20
agent/internal/model/nats_msg_model/msg_model.go
Normal file
20
agent/internal/model/nats_msg_model/msg_model.go
Normal file
@ -0,0 +1,20 @@
|
||||
package nats_msg_model
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func UnmarshalMsgModel(data []byte) (MsgModel, error) {
|
||||
var r MsgModel
|
||||
err := json.Unmarshal(data, &r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (r *MsgModel) Marshal() ([]byte, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
type MsgModel struct {
|
||||
Body []byte `json:"body"` // 函数入参,与函数配套。JSON
|
||||
Func string `json:"func"` // 功能名称,一般代表一个函数接口。命名规范为:cfn.{agent or schedule}.{包名}.函数名例如:cfn.agent.component.GetComInfo
|
||||
Rid string `json:"rid"` // 资产ID列表,可选。可用于部分广播
|
||||
Version string `json:"version"` // 函数版本
|
||||
}
|
25
agent/internal/model/nats_msg_model/upgrade_cmd.go
Normal file
25
agent/internal/model/nats_msg_model/upgrade_cmd.go
Normal file
@ -0,0 +1,25 @@
|
||||
package nats_msg_model
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func UnmarshalUpgradeCMD(data []byte) (UpgradeCMD, error) {
|
||||
var r UpgradeCMD
|
||||
err := json.Unmarshal(data, &r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (r *UpgradeCMD) Marshal() ([]byte, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
type UpgradeCMD struct {
|
||||
AgentId string `json:"agentId"`
|
||||
DownUrl string `json:"downUrl"`
|
||||
BucketName string `json:"bucketName"`
|
||||
Filename string `json:"filename"`
|
||||
CompressionType string `json:"compressionType"`
|
||||
Command string `json:"command"`
|
||||
Version string `json:"version"`
|
||||
OsType string `json:"osType"` //字典:Windows\Ubuntu\CentOS\KylinOS
|
||||
ArchType string `json:"archType"` //字典: X86\ARM
|
||||
}
|
25
agent/internal/model/nats_msg_model/upgrade_plan.go
Normal file
25
agent/internal/model/nats_msg_model/upgrade_plan.go
Normal file
@ -0,0 +1,25 @@
|
||||
package nats_msg_model
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func UnmarshalUpgradePlan(data []byte) (UpgradePlan, error) {
|
||||
var r UpgradePlan
|
||||
err := json.Unmarshal(data, &r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (r *UpgradePlan) Marshal() ([]byte, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
type UpgradePlan struct {
|
||||
UpgradeTime string `json:"upgradeTime" yaml:"upgradeTime"` //指定升级时间;指定时间升级时有值
|
||||
UpgradeRule string `json:"upgradeRule" yaml:"upgradeRule"` //升级策略;0:立刻升级,1:指定时间升级
|
||||
DeviceType string `json:"deviceType" yaml:"deviceType"` //设备类型;0:为全部,1:应用一体机,2:调度一体机,3:纳管一体机
|
||||
Status string `json:"status" yaml:"status"` //字典:create:创建此条升级规则,delete:删除升级规则
|
||||
AgentId string `json:"agentId" yaml:"agentId"` // 关联升级记录,反馈升级结果时用
|
||||
Option string `json:"option" yaml:"option"` // reboot|upgrade|rollback # 动作
|
||||
Version string `json:"version" yaml:"version"`
|
||||
CurrentVerson string `json:"currentVerson" yaml:"currentVerson"`
|
||||
RID string `json:"rid" yaml:"rid" mapstructure:"rid"`
|
||||
}
|
74
agent/internal/model/nats_msg_model/upgrade_result.go
Normal file
74
agent/internal/model/nats_msg_model/upgrade_result.go
Normal file
@ -0,0 +1,74 @@
|
||||
package nats_msg_model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/heartbeat_service"
|
||||
"time"
|
||||
)
|
||||
|
||||
func UnmarshalUpgradeResult(data []byte) (UpgradeResult, error) {
|
||||
var r UpgradeResult
|
||||
err := json.Unmarshal(data, &r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (r *UpgradeResult) Marshal() ([]byte, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
// 设备升级记录
|
||||
type UpgradeResult struct {
|
||||
SerialNo string `json:"serialNo"` // 序列号
|
||||
|
||||
AgentID string `json:"agentId"` // 小助手版本ID
|
||||
AgentVersion string `json:"agentVersion"` // 升级版本
|
||||
OldVersion string `json:"oldVersion"` // 旧版本
|
||||
|
||||
UpgradeTime string `json:"upgradeTime"` // 升级时间,2016-06-30T16:09:51.692226358+08:00
|
||||
UpgradeResult string `json:"upgradeResult"` // 升级结果
|
||||
UpgradeStatus string `json:"upgradeStatus"` // 状态,0:失败,1:成功
|
||||
Option string `json:"option"`
|
||||
}
|
||||
|
||||
func NewUpgradeResult(upgradeCMD UpgradeCMD, upgradeResult, UpgradeStatus string) *UpgradeResult {
|
||||
result := UpgradeResult{
|
||||
SerialNo: agent.Agent.RID,
|
||||
AgentID: upgradeCMD.AgentId,
|
||||
AgentVersion: upgradeCMD.Version,
|
||||
OldVersion: heartbeat_service.AgentState.AgentVersion,
|
||||
UpgradeTime: time.Now().String(),
|
||||
UpgradeStatus: UpgradeStatus,
|
||||
UpgradeResult: upgradeResult,
|
||||
Option: "upgrade",
|
||||
}
|
||||
return &result
|
||||
}
|
||||
|
||||
func NewLocalUpgradeResult(upgradeCMD LocalUpgradeCMD, upgradeResult, UpgradeStatus string) *UpgradeResult {
|
||||
result := UpgradeResult{
|
||||
SerialNo: agent.Agent.RID,
|
||||
AgentID: upgradeCMD.AgentId,
|
||||
AgentVersion: upgradeCMD.Version,
|
||||
OldVersion: heartbeat_service.AgentState.AgentVersion,
|
||||
UpgradeTime: time.Now().String(),
|
||||
UpgradeStatus: UpgradeStatus,
|
||||
UpgradeResult: upgradeResult,
|
||||
Option: "upgrade",
|
||||
}
|
||||
return &result
|
||||
}
|
||||
|
||||
func NewUpgradePlanResult(upgradePlan UpgradePlan, upgradeResult, UpgradeStatus string) *UpgradeResult {
|
||||
result := UpgradeResult{
|
||||
SerialNo: agent.Agent.RID,
|
||||
AgentID: upgradePlan.AgentId,
|
||||
AgentVersion: upgradePlan.Version,
|
||||
OldVersion: heartbeat_service.AgentState.AgentVersion,
|
||||
UpgradeTime: time.Now().String(),
|
||||
UpgradeStatus: UpgradeStatus,
|
||||
UpgradeResult: upgradeResult,
|
||||
Option: "upgrade",
|
||||
}
|
||||
return &result
|
||||
}
|
30
agent/internal/model/user/user.go
Normal file
30
agent/internal/model/user/user.go
Normal file
@ -0,0 +1,30 @@
|
||||
package user
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type User struct {
|
||||
ID int `gorm:"column:user_id"`
|
||||
Name string `gorm:"column:login_name"`
|
||||
EncryptedPassword string `gorm:"column:login_pass"`
|
||||
}
|
||||
|
||||
func (User) TableName() string {
|
||||
return "sys_account"
|
||||
}
|
||||
|
||||
func (m User) GetUserID() int {
|
||||
return m.ID
|
||||
}
|
||||
|
||||
func (m User) GetUserName() string {
|
||||
return m.Name
|
||||
}
|
||||
|
||||
func FindOneByName(name string, db *gorm.DB) (user *User, err error) {
|
||||
var u User
|
||||
if err = db.Where("login_name = ?", name).First(&u).Error; err != nil {
|
||||
return
|
||||
}
|
||||
user = &u
|
||||
return
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package cfn_to_agent_broadcast
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/nats_msg_model"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/definition"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/handle"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
natsClient "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/nats-client"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"github.com/nats-io/nats.go"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
Role = agent.Agent.Role
|
||||
)
|
||||
|
||||
// 小助手升级包下载命令接收接口
|
||||
// 升级计划下发
|
||||
|
||||
func Start() {
|
||||
log.Infof("启动nats订阅服务: 升级助手命令广播")
|
||||
|
||||
// Connect Options.
|
||||
opts := []nats.Option{nats.Name("Agent CMD Subscriber")}
|
||||
opts = setupConnOptions(opts)
|
||||
opts = append(opts, nats.UserInfo(natsClient.NatsConfig.User, natsClient.NatsConfig.Password))
|
||||
|
||||
// Connect to NATS
|
||||
nc, err := nats.Connect(natsClient.NatsConfig.Url, opts...)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
nc.Subscribe(definition.ToAgentBroadcastSubject, func(msg *nats.Msg) {
|
||||
model, err := nats_msg_model.UnmarshalMsgModel(msg.Data)
|
||||
if err != nil {
|
||||
log.Errorf("解析消息体失败:%s", err)
|
||||
}
|
||||
|
||||
log.Infof("接收到广播命令消息, Func:%s", model.Func)
|
||||
log.Infof("接收到广播命令消息, Body:%s", model.Body)
|
||||
log.Infof("接收到广播命令消息, Version:%s", model.Version)
|
||||
log.Infof("接收到广播命令消息, Rid:%s", model.Rid)
|
||||
|
||||
go handle.HandleMsg(msg, model)
|
||||
|
||||
})
|
||||
nc.Flush()
|
||||
|
||||
if err := nc.LastError(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
// holdon
|
||||
<-utils.StopNats
|
||||
}
|
||||
|
||||
func setupConnOptions(opts []nats.Option) []nats.Option {
|
||||
totalWait := 10 * time.Minute
|
||||
reconnectDelay := time.Second
|
||||
|
||||
opts = append(opts, nats.ReconnectWait(reconnectDelay))
|
||||
opts = append(opts, nats.MaxReconnects(int(totalWait/reconnectDelay)))
|
||||
opts = append(opts, nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
|
||||
log.Infof("Disconnected due to:%s, will attempt reconnects for %.0fm", err, totalWait.Minutes())
|
||||
}))
|
||||
opts = append(opts, nats.ReconnectHandler(func(nc *nats.Conn) {
|
||||
log.Infof("Reconnected [%s]", nc.ConnectedUrl())
|
||||
}))
|
||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Errorf("Exiting: %v", nc.LastError())
|
||||
}))
|
||||
return opts
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package cfn_to_agent_broadcast_private_enterprise
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/nats_msg_model"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/definition"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/handle"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
natsClient "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/nats-client"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"github.com/nats-io/nats.go"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Start() {
|
||||
log.Infof("启动nats订阅服务: 企业私有广播")
|
||||
// Connect Options.
|
||||
opts := []nats.Option{nats.Name("Enterprise Private Broadcast Subscriber")}
|
||||
opts = setupConnOptions(opts)
|
||||
opts = append(opts, nats.UserInfo(natsClient.NatsConfig.User, natsClient.NatsConfig.Password))
|
||||
|
||||
// Connect to NATS
|
||||
nc, err := nats.Connect(natsClient.NatsConfig.Url, opts...)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
nc.Subscribe(definition.ToAgentBroadcastPrivateEnterpriseSubject, func(msg *nats.Msg) {
|
||||
model, err := nats_msg_model.UnmarshalMsgModel(msg.Data)
|
||||
if err != nil {
|
||||
log.Errorf("解析消息体失败:%s", err)
|
||||
}
|
||||
|
||||
log.Infof("接收到企业内私有广播命令消息, Func:%s", model.Func)
|
||||
log.Infof("接收到企业内私有广播命令消息, Body:%s", model.Body)
|
||||
log.Infof("接收到企业内私有广播命令消息, Version:%s", model.Version)
|
||||
log.Infof("接收到企业内私有广播命令消息, Rid:%s", model.Rid)
|
||||
|
||||
go handle.HandleMsg(msg, model)
|
||||
|
||||
})
|
||||
nc.Flush()
|
||||
|
||||
if err := nc.LastError(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
// holdon
|
||||
<-utils.StopNats
|
||||
}
|
||||
|
||||
func setupConnOptions(opts []nats.Option) []nats.Option {
|
||||
totalWait := 10 * time.Minute
|
||||
reconnectDelay := time.Second
|
||||
|
||||
opts = append(opts, nats.ReconnectWait(reconnectDelay))
|
||||
opts = append(opts, nats.MaxReconnects(int(totalWait/reconnectDelay)))
|
||||
opts = append(opts, nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
|
||||
log.Infof("Disconnected due to:%s, will attempt reconnects for %.0fm", err, totalWait.Minutes())
|
||||
}))
|
||||
opts = append(opts, nats.ReconnectHandler(func(nc *nats.Conn) {
|
||||
log.Infof("Reconnected [%s]", nc.ConnectedUrl())
|
||||
}))
|
||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Errorf("Exiting: %v", nc.LastError())
|
||||
}))
|
||||
return opts
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package cfn_to_agent_broadcast_public_enterprice
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/nats_msg_model"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/definition"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/handle"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
natsClient "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/nats-client"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"github.com/nats-io/nats.go"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Start() {
|
||||
log.Infof("启动nats订阅服务: 企业公共广播")
|
||||
// Connect Options.
|
||||
opts := []nats.Option{nats.Name("Enterprise Public Broadcast Subscriber")}
|
||||
opts = setupConnOptions(opts)
|
||||
opts = append(opts, nats.UserInfo(natsClient.NatsConfig.User, natsClient.NatsConfig.Password))
|
||||
|
||||
// Connect to NATS
|
||||
nc, err := nats.Connect(natsClient.NatsConfig.Url, opts...)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
nc.Subscribe(definition.ToAgentBroadcastPublicEnterpriseSubject, func(msg *nats.Msg) {
|
||||
model, err := nats_msg_model.UnmarshalMsgModel(msg.Data)
|
||||
if err != nil {
|
||||
log.Errorf("解析消息体失败:%s", err)
|
||||
}
|
||||
|
||||
log.Infof("接收到企业公共广播命令消息, Func:%s", model.Func)
|
||||
log.Infof("接收到企业公共广播命令消息, Body:%s", model.Body)
|
||||
log.Infof("接收到企业公共广播命令消息, Version:%s", model.Version)
|
||||
log.Infof("接收到企业公共广播命令消息, Rid:%s", model.Rid)
|
||||
|
||||
go handle.HandleMsg(msg, model)
|
||||
|
||||
})
|
||||
nc.Flush()
|
||||
|
||||
if err := nc.LastError(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
// holdon
|
||||
<-utils.StopNats
|
||||
}
|
||||
|
||||
func setupConnOptions(opts []nats.Option) []nats.Option {
|
||||
totalWait := 10 * time.Minute
|
||||
reconnectDelay := time.Second
|
||||
|
||||
opts = append(opts, nats.ReconnectWait(reconnectDelay))
|
||||
opts = append(opts, nats.MaxReconnects(int(totalWait/reconnectDelay)))
|
||||
opts = append(opts, nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
|
||||
log.Infof("Disconnected due to:%s, will attempt reconnects for %.0fm", err, totalWait.Minutes())
|
||||
}))
|
||||
opts = append(opts, nats.ReconnectHandler(func(nc *nats.Conn) {
|
||||
log.Infof("Reconnected [%s]", nc.ConnectedUrl())
|
||||
}))
|
||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Errorf("Exiting: %v", nc.LastError())
|
||||
}))
|
||||
return opts
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package cfn_to_agent_unicast
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/nats_msg_model"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/definition"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/handle"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
natsClient "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/nats-client"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"github.com/nats-io/nats.go"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 系统(小助手)日志查询服务
|
||||
// 组件详情服务(包含配置内容)
|
||||
// 更新telegraf配置文件
|
||||
// 单个升级(包含升级包地址、升级配置)
|
||||
|
||||
func Start() {
|
||||
log.Infof("启动nats订阅服务: 单播命令")
|
||||
|
||||
// Connect Options.
|
||||
opts := []nats.Option{nats.Name("Agent Unicast Subscriber")}
|
||||
opts = setupConnOptions(opts)
|
||||
opts = append(opts, nats.UserInfo(natsClient.NatsConfig.User, natsClient.NatsConfig.Password))
|
||||
|
||||
// Connect to NATS
|
||||
nc, err := nats.Connect(natsClient.NatsConfig.Url, opts...)
|
||||
if err != nil {
|
||||
log.Errorf("连接nats失败:%s", err)
|
||||
}
|
||||
|
||||
nc.Subscribe(definition.ToAgentUnicastSubject, func(msg *nats.Msg) {
|
||||
model, err := nats_msg_model.UnmarshalMsgModel(msg.Data)
|
||||
if err != nil {
|
||||
log.Errorf("解析消息体失败:%s", err)
|
||||
}
|
||||
|
||||
log.Infof("接收到单播命令消息, Func:%s", model.Func)
|
||||
log.Infof("接收到单播命令消息, Body:%s", model.Body)
|
||||
log.Infof("接收到单播命令消息, Version:%s", model.Version)
|
||||
log.Infof("接收到单播命令消息, Rid:%s", model.Rid)
|
||||
|
||||
go handle.HandleMsg(msg, model)
|
||||
|
||||
})
|
||||
nc.Flush()
|
||||
|
||||
if err := nc.LastError(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
// holdon
|
||||
<-utils.StopNats
|
||||
}
|
||||
|
||||
func setupConnOptions(opts []nats.Option) []nats.Option {
|
||||
totalWait := 10 * time.Minute
|
||||
reconnectDelay := time.Second
|
||||
|
||||
opts = append(opts, nats.ReconnectWait(reconnectDelay))
|
||||
opts = append(opts, nats.MaxReconnects(int(totalWait/reconnectDelay)))
|
||||
opts = append(opts, nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
|
||||
log.Infof("Disconnected due to:%s, will attempt reconnects for %.0fm", err, totalWait.Minutes())
|
||||
}))
|
||||
opts = append(opts, nats.ReconnectHandler(func(nc *nats.Conn) {
|
||||
log.Infof("Reconnected [%s]", nc.ConnectedUrl())
|
||||
}))
|
||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||
log.Errorf("Exiting: %v", nc.LastError())
|
||||
}))
|
||||
return opts
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package asset_info
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/nats_msg_model"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/definition"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/heartbeat_service"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/load_resource_info"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
nats_client "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/nats-client"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils/randomutils"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Strat() {
|
||||
InitAssertInfoScheduler()
|
||||
}
|
||||
|
||||
func InitAssertInfoScheduler() {
|
||||
log.Infof("启动资产上报服务")
|
||||
|
||||
randomNumber := randomutils.GetRandomNumber(-3600, 3600)
|
||||
|
||||
// 每天执行一次
|
||||
ticker := time.NewTicker((60*60*24 + time.Duration(randomNumber)) * time.Second) // 创建一个定时器
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
updataAssertInfoMq()
|
||||
doAssertInfoMQ()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
updataAssertInfoMq()
|
||||
// 开机后先上传一次(复用心跳)
|
||||
doAssertInfoMQ()
|
||||
}()
|
||||
}
|
||||
|
||||
func updataAssertInfoMq() {
|
||||
rid := nats_msg_model.MsgModel{
|
||||
Func: definition.GETCOMPANY,
|
||||
Body: []byte(agent.Agent.RID),
|
||||
Version: "v1",
|
||||
Rid: agent.Agent.RID,
|
||||
}
|
||||
marshal, _ := rid.Marshal()
|
||||
msg, err := nats_client.Request(definition.ToScheduleQueueSubject, marshal)
|
||||
if err != nil {
|
||||
log.Errorf("获取资产信息失败(企业、资产类型):%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if msg == nil || msg.Data == nil {
|
||||
log.Errorf("获取资产信息为空!")
|
||||
return
|
||||
}
|
||||
|
||||
var resp = definition.Response{}
|
||||
err = json.Unmarshal(msg.Data, &resp)
|
||||
|
||||
if resp.Code == 200 {
|
||||
var rinfo = agent.AgentConfig{}
|
||||
err = json.Unmarshal(resp.Data, &rinfo)
|
||||
agent.Agent.Enterprise = rinfo.Enterprise
|
||||
agent.Agent.Type = rinfo.Type
|
||||
load_resource_info.LoadAgentInfo(*agent.Agent)
|
||||
} else {
|
||||
log.Infof("资产信息获取失败:%s", resp.Msg)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 1.返回应用一体机开机后运行时间和开始时间
|
||||
// 2.返回CPU、内存、网卡等配置信息、型号信息、操作系统信息,硬盘信息等
|
||||
func doAssertInfoMQ() {
|
||||
bytes, err := json.Marshal(heartbeat_service.AgentState)
|
||||
if err != nil {
|
||||
log.Infof("上报心跳信息序列化失败:%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := nats_msg_model.MsgModel{
|
||||
Func: definition.ASSETINFO,
|
||||
Body: bytes,
|
||||
Version: "v1",
|
||||
Rid: agent.Agent.RID,
|
||||
}
|
||||
|
||||
marshal, _ := msg.Marshal()
|
||||
log.Infof("上报资产信息")
|
||||
nats_client.Publish(definition.ToScheduleSubject, marshal)
|
||||
}
|
@ -0,0 +1,237 @@
|
||||
package asset_info
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
)
|
||||
|
||||
var (
|
||||
advapi = syscall.NewLazyDLL("Advapi32.dll")
|
||||
kernel = syscall.NewLazyDLL("Kernel32.dll")
|
||||
)
|
||||
|
||||
// 开机时间
|
||||
func GetStartTime() string {
|
||||
GetTickCount := kernel.NewProc("GetTickCount")
|
||||
r, _, _ := GetTickCount.Call()
|
||||
if r == 0 {
|
||||
return ""
|
||||
}
|
||||
ms := time.Duration(r * 1000 * 1000)
|
||||
return ms.String()
|
||||
}
|
||||
|
||||
// 当前用户名
|
||||
func GetUserName() string {
|
||||
var size uint32 = 128
|
||||
var buffer = make([]uint16, size)
|
||||
user := syscall.StringToUTF16Ptr("USERNAME")
|
||||
domain := syscall.StringToUTF16Ptr("USERDOMAIN")
|
||||
r, err := syscall.GetEnvironmentVariable(user, &buffer[0], size)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
buffer[r] = '@'
|
||||
old := r + 1
|
||||
if old >= size {
|
||||
return syscall.UTF16ToString(buffer[:r])
|
||||
}
|
||||
r, err = syscall.GetEnvironmentVariable(domain, &buffer[old], size-old)
|
||||
return syscall.UTF16ToString(buffer[:old+r])
|
||||
}
|
||||
|
||||
// 系统版本
|
||||
func GetSystemVersion() string {
|
||||
version, err := syscall.GetVersion()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%d.%d (%d)", byte(version), uint8(version>>8), version>>16)
|
||||
}
|
||||
|
||||
type diskusage struct {
|
||||
Path string `json:"path"`
|
||||
Total uint64 `json:"total"`
|
||||
Free uint64 `json:"free"`
|
||||
}
|
||||
|
||||
func usage(getDiskFreeSpaceExW *syscall.LazyProc, path string) (diskusage, error) {
|
||||
lpFreeBytesAvailable := int64(0)
|
||||
var info = diskusage{Path: path}
|
||||
diskret, _, err := getDiskFreeSpaceExW.Call(
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(info.Path))),
|
||||
uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
|
||||
uintptr(unsafe.Pointer(&(info.Total))),
|
||||
uintptr(unsafe.Pointer(&(info.Free))))
|
||||
if diskret != 0 {
|
||||
err = nil
|
||||
}
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 硬盘信息
|
||||
func GetDiskInfo() (infos []diskusage) {
|
||||
GetLogicalDriveStringsW := kernel.NewProc("GetLogicalDriveStringsW")
|
||||
GetDiskFreeSpaceExW := kernel.NewProc("GetDiskFreeSpaceExW")
|
||||
lpBuffer := make([]byte, 254)
|
||||
diskret, _, _ := GetLogicalDriveStringsW.Call(
|
||||
uintptr(len(lpBuffer)),
|
||||
uintptr(unsafe.Pointer(&lpBuffer[0])))
|
||||
if diskret == 0 {
|
||||
return
|
||||
}
|
||||
for _, v := range lpBuffer {
|
||||
if v >= 65 && v <= 90 {
|
||||
path := string(v) + ":"
|
||||
if path == "A:" || path == "B:" {
|
||||
continue
|
||||
}
|
||||
info, err := usage(GetDiskFreeSpaceExW, string(v)+":")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
infos = append(infos, info)
|
||||
}
|
||||
}
|
||||
return infos
|
||||
}
|
||||
|
||||
// CPU信息
|
||||
// 简单的获取方法fmt.Sprintf("Num:%d Arch:%s\n", runtime.NumCPU(), runtime.GOARCH)
|
||||
func GetCpuInfo() string {
|
||||
var size uint32 = 128
|
||||
var buffer = make([]uint16, size)
|
||||
var index = uint32(copy(buffer, syscall.StringToUTF16("Num:")) - 1)
|
||||
nums := syscall.StringToUTF16Ptr("NUMBER_OF_PROCESSORS")
|
||||
arch := syscall.StringToUTF16Ptr("PROCESSOR_ARCHITECTURE")
|
||||
r, err := syscall.GetEnvironmentVariable(nums, &buffer[index], size-index)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
index += r
|
||||
index += uint32(copy(buffer[index:], syscall.StringToUTF16(" Arch:")) - 1)
|
||||
r, err = syscall.GetEnvironmentVariable(arch, &buffer[index], size-index)
|
||||
if err != nil {
|
||||
return syscall.UTF16ToString(buffer[:index])
|
||||
}
|
||||
index += r
|
||||
return syscall.UTF16ToString(buffer[:index+r])
|
||||
}
|
||||
|
||||
type memoryStatusEx struct {
|
||||
cbSize uint32
|
||||
dwMemoryLoad uint32
|
||||
ullTotalPhys uint64 // in bytes
|
||||
ullAvailPhys uint64
|
||||
ullTotalPageFile uint64
|
||||
ullAvailPageFile uint64
|
||||
ullTotalVirtual uint64
|
||||
ullAvailVirtual uint64
|
||||
ullAvailExtendedVirtual uint64
|
||||
}
|
||||
|
||||
// 内存信息
|
||||
func GetMemory() string {
|
||||
GlobalMemoryStatusEx := kernel.NewProc("GlobalMemoryStatusEx")
|
||||
var memInfo memoryStatusEx
|
||||
memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
|
||||
mem, _, _ := GlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo)))
|
||||
if mem == 0 {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprint(memInfo.ullTotalPhys/(1024*1024)) + "MB"
|
||||
}
|
||||
|
||||
type intfInfo struct {
|
||||
Name string
|
||||
Ipv4 []string
|
||||
Ipv6 []string
|
||||
}
|
||||
|
||||
// 网卡信息
|
||||
func GetIntfs() []intfInfo {
|
||||
intf, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return []intfInfo{}
|
||||
}
|
||||
|
||||
//fmt.Println(intf)
|
||||
var is = make([]intfInfo, len(intf))
|
||||
for i, v := range intf {
|
||||
|
||||
if (v.Flags & net.FlagBroadcast) > 0 {
|
||||
|
||||
ips, err := v.Addrs()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
is[i].Name = v.Name
|
||||
for _, ip := range ips {
|
||||
if strings.Contains(ip.String(), ":") {
|
||||
is[i].Ipv6 = append(is[i].Ipv6, ip.String())
|
||||
} else {
|
||||
is[i].Ipv4 = append(is[i].Ipv4, ip.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return is
|
||||
}
|
||||
|
||||
// 主板信息
|
||||
func GetMoreCpuInfo() string {
|
||||
var s = []struct {
|
||||
Name string
|
||||
}{}
|
||||
err := wmi.Query("SELECT * FROM Win32_Processor", &s)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return s[0].Name
|
||||
}
|
||||
|
||||
// 主板信息
|
||||
func GetMotherboardInfo() string {
|
||||
var s = []struct {
|
||||
Product string
|
||||
}{}
|
||||
err := wmi.Query("SELECT Product FROM Win32_BaseBoard WHERE (Product IS NOT NULL)", &s)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return s[0].Product
|
||||
}
|
||||
|
||||
// SerialNumber信息
|
||||
func GetSerialNumber() string {
|
||||
var s = []struct {
|
||||
SerialNumber string
|
||||
}{}
|
||||
err := wmi.Query("SELECT SerialNumber FROM Win32_DiskDrive WHERE (SerialNumber IS NOT NULL) ", &s) //AND (MediaType LIKE 'Fixed hard disk%')
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
fmt.Println(s)
|
||||
fmt.Println("====SerialNumber===")
|
||||
return s[0].SerialNumber
|
||||
|
||||
}
|
||||
|
||||
// BIOS信息
|
||||
func GetBiosInfo() string {
|
||||
var s = []struct {
|
||||
Name string
|
||||
}{}
|
||||
err := wmi.Query("SELECT Name FROM Win32_BIOS WHERE (Name IS NOT NULL)", &s) // WHERE (BIOSVersion IS NOT NULL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return s[0].Name
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package asset_info
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetBiosInfo(t *testing.T) {
|
||||
fmt.Printf("开机时长:%s\n", GetStartTime())
|
||||
fmt.Printf("当前用户:%s\n", GetUserName())
|
||||
fmt.Printf("当前系统:%s\n", runtime.GOOS)
|
||||
fmt.Printf("系统版本:%s\n", GetSystemVersion())
|
||||
fmt.Printf("Bios:%s\n", GetBiosInfo())
|
||||
fmt.Printf("Motherboard:\t%s\n", GetMotherboardInfo())
|
||||
|
||||
fmt.Printf("CPU:\t%s\n", GetCpuInfo())
|
||||
fmt.Printf("CPU:\t%s\n", GetMoreCpuInfo())
|
||||
|
||||
fmt.Printf("Memory:\t%s\n", GetMemory())
|
||||
fmt.Printf("Disk:\t%v\n", GetDiskInfo())
|
||||
|
||||
intfs := GetIntfs()
|
||||
for _, i := range intfs {
|
||||
fmt.Printf("Interfaces:\t%v\n", i)
|
||||
}
|
||||
|
||||
number := GetSerialNumber()
|
||||
|
||||
fmt.Printf("number:\t%v\n", number)
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package heartbeat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/nats_msg_model"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/definition"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/heartbeat_service"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
natsClient "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/nats-client"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils/randomutils"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
commonConfig = config.Config
|
||||
)
|
||||
|
||||
func Strat() {
|
||||
InitHeartBeatScheduler()
|
||||
}
|
||||
|
||||
// InitHeartBeatScheduler
|
||||
// 初始化 heartbeat 定时器
|
||||
func InitHeartBeatScheduler() {
|
||||
log.Infof("启动心跳服务")
|
||||
// 每 30 秒钟时执行一次
|
||||
randomNumber := randomutils.GetRandomNumber(-10, 10)
|
||||
ticker := time.NewTicker(time.Duration(commonConfig.Schedule.HeartBeat+int64(randomNumber)) * time.Second) // 创建一个定时器
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
doHeartBeatMQ()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func doHeartBeatMQ() {
|
||||
bytes, err := json.Marshal(heartbeat_service.AgentState)
|
||||
if err != nil {
|
||||
log.Infof("上报心跳信息序列化失败:%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := nats_msg_model.MsgModel{
|
||||
Func: definition.HEALTHCHECK,
|
||||
Body: bytes,
|
||||
Version: "v1",
|
||||
Rid: agent.Agent.RID,
|
||||
}
|
||||
|
||||
marshal, _ := msg.Marshal()
|
||||
log.Infof("上报心跳")
|
||||
natsClient.Publish(definition.ToScheduleSubject, marshal)
|
||||
}
|
11
agent/internal/nats_service/definition/const.go
Normal file
11
agent/internal/nats_service/definition/const.go
Normal file
@ -0,0 +1,11 @@
|
||||
package definition
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
RunDirectory, _ = utils.GetCurrentPath()
|
||||
CompressedAgentPath = filepath.Join(RunDirectory, "../upgrade")
|
||||
)
|
18
agent/internal/nats_service/definition/func_definition.go
Normal file
18
agent/internal/nats_service/definition/func_definition.go
Normal file
@ -0,0 +1,18 @@
|
||||
package definition
|
||||
|
||||
const (
|
||||
HEALTHCHECK = "cfn.schedule.health.probe"
|
||||
ASSETINFO = "cfn.schedule.asset.base_info"
|
||||
GETCOMPANY = "cfn.schedule.asset.company"
|
||||
// AGENTUPGRADERESULT = "cfn.schedule.deamon.agent_upgrade_result"
|
||||
AGENTLOG = "cfn.agent.log.agent"
|
||||
TELEGRAFLOG = "cfn.agent.log.telegraf"
|
||||
COMPONENTINFO = "cfn.agent.component.detail_info"
|
||||
TELEGRAFCONF = "cfn.agent.component.telegraf_conf" // 更新telegraf配置文件
|
||||
|
||||
AGENTDOWNLOAD = "cfn.agent.agent.download"
|
||||
UPGRADEPLAN = "cfn.agent.agent.upgrade_plan"
|
||||
UPGRADEIMMEDIATELY = "cfn.agent.agent.upgrade_immediately"
|
||||
|
||||
AGENTDOWNLOADLOCAL = "cfn.agent.agent.download_local"
|
||||
)
|
62
agent/internal/nats_service/definition/response.go
Normal file
62
agent/internal/nats_service/definition/response.go
Normal file
@ -0,0 +1,62 @@
|
||||
package definition
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func UnmarshalMsgModel(data []byte) (Response, error) {
|
||||
var r Response
|
||||
err := json.Unmarshal(data, &r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (r *Response) Marshal() ([]byte, error) {
|
||||
return json.Marshal(r)
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data []byte `json:"data"`
|
||||
}
|
||||
|
||||
func Resp() *Response {
|
||||
// 初始化response
|
||||
return &Response{
|
||||
Code: 0,
|
||||
Msg: "",
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// FailCode 自定义错误码返回
|
||||
func (r *Response) Fail(msg ...string) *Response {
|
||||
r.Code = http.StatusInternalServerError
|
||||
if msg != nil {
|
||||
r.Msg = msg[0]
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// FailCode 自定义错误码返回
|
||||
func (r *Response) FailWithData(data []byte, msg ...string) *Response {
|
||||
r.Code = http.StatusInternalServerError
|
||||
if msg != nil {
|
||||
r.Msg = msg[0]
|
||||
}
|
||||
r.Data = data
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// Success 正确返回
|
||||
func (r *Response) Success(data []byte, msg ...string) *Response {
|
||||
r.Code = http.StatusOK
|
||||
if msg != nil {
|
||||
r.Msg = msg[0]
|
||||
}
|
||||
r.Data = data
|
||||
|
||||
return r
|
||||
}
|
16
agent/internal/nats_service/definition/subject.go
Normal file
16
agent/internal/nats_service/definition/subject.go
Normal file
@ -0,0 +1,16 @@
|
||||
package definition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
)
|
||||
|
||||
var (
|
||||
ToAgentUnicastSubject = fmt.Sprintf("cfn_to_agent_unicast_%s", agent.Agent.RID)
|
||||
ToAgentBroadcastSubject = "cfn_to_agent_broadcast"
|
||||
ToAgentBroadcastPublicEnterpriseSubject = fmt.Sprintf("cfn_to_agent_broadcast_public_%s", agent.Agent.Enterprise)
|
||||
|
||||
ToScheduleSubject = "cfn_to_schedule"
|
||||
ToAgentBroadcastPrivateEnterpriseSubject = fmt.Sprintf("cfn_to_agent_broadcast_private_%s", agent.Agent.Enterprise)
|
||||
ToScheduleQueueSubject = "cfn_to_schedule_queue"
|
||||
)
|
482
agent/internal/nats_service/handle/handle_msg.go
Normal file
482
agent/internal/nats_service/handle/handle_msg.go
Normal file
@ -0,0 +1,482 @@
|
||||
package handle
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/bin_path"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/nats_msg_model"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/definition"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/component"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/heartbeat_service"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/log_service"
|
||||
minioClient "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/file-download-client"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/go-sysinfo/providers/shared"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
natsClient "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/nats-client"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils/compression"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils/randomutils"
|
||||
"github.com/nats-io/nats.go"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
UpgradePlan = &nats_msg_model.UpgradePlan{}
|
||||
)
|
||||
|
||||
func HandleMsg(msg *nats.Msg, model nats_msg_model.MsgModel) {
|
||||
var err error
|
||||
|
||||
switch model.Func {
|
||||
case definition.AGENTLOG:
|
||||
lineNum := string(model.Body)
|
||||
lineUnit, err2 := strconv.ParseUint(lineNum, 10, 64)
|
||||
if err2 != nil {
|
||||
lineUnit = 100
|
||||
}
|
||||
|
||||
info, err := log_service.GetAgentLog(lineUnit)
|
||||
if err != nil {
|
||||
log.Errorf("获取Agent日志报错: %s", err)
|
||||
ret, _ := definition.Resp().Fail(err.Error()).Marshal()
|
||||
msg.Respond(ret)
|
||||
} else {
|
||||
marshal, _ := json.Marshal(info)
|
||||
ret, _ := definition.Resp().Success(marshal, "OK!").Marshal()
|
||||
msg.Respond(ret)
|
||||
}
|
||||
break
|
||||
|
||||
case definition.TELEGRAFLOG:
|
||||
lineNum := string(model.Body)
|
||||
lineUnit, err2 := strconv.ParseUint(lineNum, 10, 64)
|
||||
if err2 != nil {
|
||||
lineUnit = 100
|
||||
}
|
||||
|
||||
info, err := log_service.GetAgentUpgradeLog(lineUnit)
|
||||
if err != nil {
|
||||
log.Errorf("获取Telegraf日志报错: %s", err)
|
||||
ret, _ := definition.Resp().Fail(err.Error()).Marshal()
|
||||
msg.Respond(ret)
|
||||
} else {
|
||||
marshal, _ := json.Marshal(info)
|
||||
ret, _ := definition.Resp().Success(marshal, "OK!").Marshal()
|
||||
msg.Respond(ret)
|
||||
}
|
||||
break
|
||||
|
||||
case definition.COMPONENTINFO:
|
||||
info, err := component.GetComInfo()
|
||||
if err != nil {
|
||||
log.Errorf("获取组件详情报错: %s", err)
|
||||
ret, _ := definition.Resp().Fail(err.Error()).Marshal()
|
||||
msg.Respond(ret)
|
||||
} else {
|
||||
marshal, _ := json.Marshal(info)
|
||||
ret, _ := definition.Resp().Success(marshal, "OK!").Marshal()
|
||||
msg.Respond(ret)
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
case definition.TELEGRAFCONF: // 更新telegraf配置文件
|
||||
component.UpdateTelegrafConfig(model.Body)
|
||||
if err != nil {
|
||||
log.Errorf("更新Telegraf配置报错: %s", err)
|
||||
ret, _ := definition.Resp().Fail(err.Error()).Marshal()
|
||||
msg.Respond(ret)
|
||||
} else {
|
||||
ret, _ := definition.Resp().Success([]byte("完成配置文件更新!"), "OK!").Marshal()
|
||||
msg.Respond(ret)
|
||||
}
|
||||
break
|
||||
|
||||
case definition.UPGRADEIMMEDIATELY: // 单个升级(包含升级包地址、升级配置),并解压至指定目录,对于失败的情况给与结果反馈(仅报告失败结果,成功与否由升级程序判断)
|
||||
upgradeCMD, err := nats_msg_model.UnmarshalUpgradeCMD(model.Body) // 解析命令
|
||||
if err != nil {
|
||||
log.Errorf("消息body格式有误: %s", err)
|
||||
result := nats_msg_model.NewUpgradeResult(upgradeCMD, "消息body格式有误", "0")
|
||||
marshal, err := json.Marshal(result)
|
||||
ret, _ := definition.Resp().FailWithData(marshal, err.Error()).Marshal()
|
||||
msg.Respond(ret)
|
||||
return
|
||||
}
|
||||
|
||||
if heartbeat_service.AgentState.AgentVersion == upgradeCMD.Version {
|
||||
log.Info(definition.UPGRADEIMMEDIATELY + "当前运行版本无需升级!")
|
||||
result := nats_msg_model.NewUpgradeResult(upgradeCMD, "当前运行版本无需升级!", "0")
|
||||
marshal, _ := json.Marshal(result)
|
||||
ret, _ := definition.Resp().FailWithData(marshal, "当前运行版本无需升级!").Marshal()
|
||||
msg.Respond(ret)
|
||||
return
|
||||
}
|
||||
|
||||
if !(heartbeat_service.AgentState.OSType == upgradeCMD.OsType && heartbeat_service.AgentState.Architecture == upgradeCMD.ArchType) {
|
||||
log.Info(definition.UPGRADEIMMEDIATELY + "操作系统或服务器架构与本机不符!")
|
||||
result := nats_msg_model.NewUpgradeResult(upgradeCMD, "操作系统或服务器架构与本机不符!", "0")
|
||||
marshal, _ := json.Marshal(result)
|
||||
ret, _ := definition.Resp().FailWithData(marshal, definition.UPGRADEIMMEDIATELY+"操作系统或服务器架构与本机不符!").Marshal()
|
||||
msg.Respond(ret)
|
||||
return
|
||||
}
|
||||
|
||||
// 下载升级包至本地 upgrade 目录
|
||||
localUpgradeCompressedFile := filepath.Join(definition.CompressedAgentPath, upgradeCMD.Filename)
|
||||
err = minioClient.DownloadToLocal(upgradeCMD.DownUrl, upgradeCMD.Filename, localUpgradeCompressedFile, 3)
|
||||
if err != nil {
|
||||
log.Errorf("下载安装包至本地失败: %s", err)
|
||||
result := nats_msg_model.NewUpgradeResult(upgradeCMD, "下载安装包至本地失败!", "0")
|
||||
marshal, _ := json.Marshal(result)
|
||||
ret, _ := definition.Resp().FailWithData(marshal, fmt.Sprintf(definition.UPGRADEIMMEDIATELY+"下载安装包至本地失败: %s", err)).Marshal()
|
||||
msg.Respond(ret)
|
||||
return
|
||||
}
|
||||
|
||||
// response请求端
|
||||
log.Infof(definition.UPGRADEIMMEDIATELY+"下载成功,%s,%s", upgradeCMD.Filename, upgradeCMD.Version)
|
||||
ret, _ := definition.Resp().Success([]byte(definition.UPGRADEIMMEDIATELY + "下载成功!")).Marshal()
|
||||
msg.Respond(ret)
|
||||
|
||||
// 将安装包文件解压到以版本命名的目录
|
||||
unCompression(upgradeCMD.Filename, upgradeCMD.CompressionType, upgradeCMD.Version)
|
||||
|
||||
// 更新升级计划信息
|
||||
updateUpgradeVersionInfo(upgradeCMD, true)
|
||||
break
|
||||
|
||||
case definition.AGENTDOWNLOAD: // 小助手升级包下载命令接收接口,并解压至指定目录 【下载所有版本、所有架构的升级包,仅解压符合自己版本、架构的升级包,已供后续升级】。对于失败的情况给与结果反馈
|
||||
if agent.Agent.Role == "Cache" {
|
||||
// 解析命令
|
||||
upgradeCMD, err := nats_msg_model.UnmarshalUpgradeCMD(model.Body)
|
||||
if err != nil {
|
||||
log.Errorf(definition.AGENTDOWNLOAD+"消息body格式有误: %s", err)
|
||||
reportUpgradeRrrors(upgradeCMD, "消息body格式有误!")
|
||||
return
|
||||
}
|
||||
|
||||
// 下载升级包至本地 upgrade 目录
|
||||
localUpgradeCompressedFile := filepath.Join(definition.CompressedAgentPath, upgradeCMD.Filename)
|
||||
err = minioClient.DownloadToLocal(upgradeCMD.DownUrl, upgradeCMD.Filename, localUpgradeCompressedFile, 3)
|
||||
if err != nil {
|
||||
log.Errorf(definition.AGENTDOWNLOAD+"下载安装包至本地失败: %s", err)
|
||||
reportUpgradeRrrors(upgradeCMD,
|
||||
fmt.Sprintf("下载安装包至本地失败!升级包:%s, 下载缓存机:%s, 企业:%s", upgradeCMD.Filename, agent.Agent.RID, agent.Agent.Enterprise),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof(definition.AGENTDOWNLOAD+"下载成功,%s,%s", upgradeCMD.Filename, upgradeCMD.Version)
|
||||
|
||||
// 通知企业内其他一体机来下载
|
||||
// todo 内网IP
|
||||
ip, _, _ := shared.NamedNetwork(agent.Agent.NetInterface)
|
||||
LocalUpgradeCMD := nats_msg_model.LocalUpgradeCMD{
|
||||
AgentId: upgradeCMD.AgentId,
|
||||
|
||||
CompressionType: upgradeCMD.CompressionType,
|
||||
Filename: upgradeCMD.Filename,
|
||||
Version: upgradeCMD.Version,
|
||||
IP: ip,
|
||||
Port: config.Config.Server.Port,
|
||||
OsType: upgradeCMD.OsType,
|
||||
ArchType: upgradeCMD.ArchType,
|
||||
|
||||
// 备用
|
||||
DownUrl: upgradeCMD.DownUrl,
|
||||
}
|
||||
|
||||
bytes, _ := LocalUpgradeCMD.Marshal()
|
||||
|
||||
msg := nats_msg_model.MsgModel{
|
||||
Func: definition.AGENTDOWNLOADLOCAL,
|
||||
Body: bytes,
|
||||
Version: "v1",
|
||||
Rid: agent.Agent.RID,
|
||||
}
|
||||
|
||||
marshal, _ := msg.Marshal()
|
||||
err = natsClient.Publish(definition.ToAgentBroadcastPrivateEnterpriseSubject, marshal)
|
||||
if err != nil {
|
||||
log.Errorf(definition.AGENTDOWNLOAD+"安装包本地广播失败: %s", err)
|
||||
reportUpgradeRrrors(upgradeCMD,
|
||||
fmt.Sprintf("安装包本地广播失败:%s,下载缓存机:%s,频道:%s", upgradeCMD.Filename, agent.Agent.RID, agent.Agent.Enterprise),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// 将安装包文件解压到以版本命名的目录,仅解压符合自己版本、架构的升级包,已供后续升级
|
||||
// 如果缓存机下载升级包失败,则通过手工升级
|
||||
if heartbeat_service.AgentState.AgentVersion == upgradeCMD.Version {
|
||||
log.Infof(definition.AGENTDOWNLOAD+"版本与本机运行版本一至: %s", upgradeCMD.Version)
|
||||
return
|
||||
}
|
||||
|
||||
if !checkOsTypeAndArchSame(upgradeCMD) {
|
||||
return
|
||||
}
|
||||
|
||||
unCompression(upgradeCMD.Filename, upgradeCMD.CompressionType, upgradeCMD.Version)
|
||||
// 更新升级计划信息
|
||||
updateUpgradeVersionInfo(upgradeCMD, false)
|
||||
}
|
||||
break
|
||||
|
||||
case definition.UPGRADEPLAN: // 升级计划下发,更新upgradelock文件
|
||||
plan, err := nats_msg_model.UnmarshalUpgradePlan(model.Body)
|
||||
if err != nil {
|
||||
log.Errorf(definition.UPGRADEPLAN+"消息body格式有误: %s", err)
|
||||
reportUpgradePlanRrrors(plan, "消息body格式有误!")
|
||||
return
|
||||
}
|
||||
|
||||
if plan.DeviceType != "0" && agent.Agent.Type != plan.DeviceType {
|
||||
log.Info(definition.UPGRADEPLAN + "设备不匹配!")
|
||||
//reportUpgradePlanRrrors(plan, fmt.Sprintf("设备不匹配:%s", agent.Agent.RID), "0")
|
||||
return
|
||||
}
|
||||
|
||||
updateUpgradeTimePlan(plan)
|
||||
break
|
||||
|
||||
case definition.AGENTDOWNLOADLOCAL: // 从企业内缓存机下载,并解压至指定目录,对于失败的情况给与结果反馈
|
||||
if agent.Agent.Role != "Cache" {
|
||||
// 先收集缓存机IP列表,
|
||||
localUpgradeCMD, err := nats_msg_model.UnmarshalLocalUpgradeCMD(model.Body)
|
||||
if err != nil {
|
||||
log.Errorf(definition.AGENTDOWNLOADLOCAL+"消息body格式有误: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if agent.Agent.Type != UpgradePlan.DeviceType {
|
||||
log.Info(definition.AGENTDOWNLOADLOCAL + "设备不匹配!")
|
||||
return
|
||||
}
|
||||
|
||||
if heartbeat_service.AgentState.AgentVersion == localUpgradeCMD.Version {
|
||||
log.Info(definition.AGENTDOWNLOADLOCAL + "当前运行版本为最新版本!")
|
||||
return
|
||||
}
|
||||
|
||||
if !checkOsTypeAndArchSameLocal(localUpgradeCMD) {
|
||||
return
|
||||
}
|
||||
|
||||
// 新的版本到来了,清空CacheIPs列表,开启一个新的doLocalDownload
|
||||
// todo: 支持处理连续两次紧急升级情况处理, 需要支持取消上一次未执行完的doLocalDownload方法
|
||||
if len(CacheIPs) > 0 {
|
||||
if CacheIPs[0].Version != localUpgradeCMD.Version {
|
||||
CacheIPs = []nats_msg_model.LocalUpgradeCMD{}
|
||||
}
|
||||
}
|
||||
|
||||
if len(CacheIPs) == 0 {
|
||||
go doLocalDownloadAndUnComporess(localUpgradeCMD)
|
||||
}
|
||||
|
||||
CacheIPs = append(CacheIPs, localUpgradeCMD)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func checkOsTypeAndArchSameLocal(upgradeCMD nats_msg_model.LocalUpgradeCMD) bool {
|
||||
localArch := strings.ToLower(heartbeat_service.AgentState.Architecture)
|
||||
cmdArch := strings.ToLower(upgradeCMD.ArchType)
|
||||
if strings.Index(localArch, cmdArch) >= 0 || strings.Index(cmdArch, localArch) >= 0 {
|
||||
|
||||
} else {
|
||||
log.Infof(definition.AGENTDOWNLOAD+"Architecture(%s)与本机(%s)不一致", upgradeCMD.ArchType, heartbeat_service.AgentState.Architecture)
|
||||
return false
|
||||
}
|
||||
|
||||
localOS := strings.ToLower(heartbeat_service.AgentState.OSType)
|
||||
cmdOS := strings.ToLower(upgradeCMD.OsType)
|
||||
if strings.Index(localOS, cmdOS) >= 0 || strings.Index(cmdOS, localOS) >= 0 {
|
||||
|
||||
} else {
|
||||
log.Infof(definition.AGENTDOWNLOAD+"OSType(%s)与本机(%s)不一致", upgradeCMD.OsType, heartbeat_service.AgentState.OSType)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func checkOsTypeAndArchSame(upgradeCMD nats_msg_model.UpgradeCMD) bool {
|
||||
localArch := strings.ToLower(heartbeat_service.AgentState.Architecture)
|
||||
cmdArch := strings.ToLower(upgradeCMD.ArchType)
|
||||
if strings.Index(localArch, cmdArch) >= 0 || strings.Index(cmdArch, localArch) >= 0 {
|
||||
|
||||
} else {
|
||||
log.Infof(definition.AGENTDOWNLOAD+"Architecture(%s)与本机(%s)不一致", upgradeCMD.ArchType, heartbeat_service.AgentState.Architecture)
|
||||
return false
|
||||
}
|
||||
|
||||
localOS := strings.ToLower(heartbeat_service.AgentState.OSType)
|
||||
cmdOS := strings.ToLower(upgradeCMD.OsType)
|
||||
if strings.Index(localOS, cmdOS) >= 0 || strings.Index(cmdOS, localOS) >= 0 {
|
||||
|
||||
} else {
|
||||
log.Infof(definition.AGENTDOWNLOAD+"OSType(%s)与本机(%s)不一致", upgradeCMD.OsType, heartbeat_service.AgentState.OSType)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func reportUpgradeRrrors(upgradeCMD nats_msg_model.UpgradeCMD, upgradeResult string) {
|
||||
result := nats_msg_model.NewUpgradeResult(upgradeCMD, upgradeResult, "0")
|
||||
marshal, _ := json.Marshal(result)
|
||||
natsClient.Publish(definition.ToScheduleSubject, marshal)
|
||||
}
|
||||
|
||||
func reportLocalUpgradeRrrors(upgradeCMD nats_msg_model.LocalUpgradeCMD, upgradeResult string) {
|
||||
result := nats_msg_model.NewLocalUpgradeResult(upgradeCMD, upgradeResult, "0")
|
||||
marshal, _ := json.Marshal(result)
|
||||
natsClient.Publish(definition.ToScheduleSubject, marshal)
|
||||
}
|
||||
|
||||
func reportUpgradePlanRrrors(upgradePlan nats_msg_model.UpgradePlan, upgradeResult string) {
|
||||
result := nats_msg_model.NewUpgradePlanResult(upgradePlan, upgradeResult, "0")
|
||||
marshal, _ := json.Marshal(result)
|
||||
natsClient.Publish(definition.ToScheduleSubject, marshal)
|
||||
}
|
||||
|
||||
func readUpgradePlan() error {
|
||||
if UpgradePlan.UpgradeRule == "" || UpgradePlan.Version == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
upgradeByte, err := os.ReadFile(bin_path.UPGRADEPLAN)
|
||||
if err != nil {
|
||||
log.Error(definition.UPGRADEIMMEDIATELY + "读取配置文件失败:" + err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
yaml.Unmarshal(upgradeByte, UpgradePlan)
|
||||
return err
|
||||
}
|
||||
|
||||
func updateUpgradeTimePlan(plan nats_msg_model.UpgradePlan) {
|
||||
log.Info(definition.UPGRADEPLAN + "开始升级计划文本")
|
||||
|
||||
err := readUpgradePlan()
|
||||
if err != nil {
|
||||
reportUpgradePlanRrrors(plan, fmt.Sprintf("读取配置文件失败:%s", agent.Agent.RID))
|
||||
return
|
||||
}
|
||||
|
||||
UpgradePlan.UpgradeRule = plan.UpgradeRule
|
||||
UpgradePlan.UpgradeTime = plan.UpgradeTime
|
||||
UpgradePlan.DeviceType = plan.DeviceType
|
||||
UpgradePlan.Status = plan.Status
|
||||
UpgradePlan.RID = agent.Agent.RID
|
||||
|
||||
out, _ := yaml.Marshal(UpgradePlan)
|
||||
err = os.WriteFile(bin_path.UPGRADEPLAN, out, fs.ModePerm)
|
||||
if err != nil {
|
||||
log.Error(definition.UPGRADEPLAN + "写升级计划文本失败:" + err.Error())
|
||||
reportUpgradePlanRrrors(plan, fmt.Sprintf("写升级计划文本失败:%s", agent.Agent.RID))
|
||||
}
|
||||
log.Info(definition.UPGRADEPLAN + "完成升级计划文本")
|
||||
}
|
||||
|
||||
// updateUpgradeInfo 更新版本
|
||||
func updateUpgradeVersionInfo(upgradeCMD nats_msg_model.UpgradeCMD, immediately bool) {
|
||||
log.Info(definition.UPGRADEPLAN + "开始升级计划文本")
|
||||
|
||||
err := readUpgradePlan()
|
||||
if err != nil {
|
||||
reportUpgradeRrrors(upgradeCMD, fmt.Sprintf("读取配置文件失败:%s", agent.Agent.RID))
|
||||
return
|
||||
}
|
||||
|
||||
UpgradePlan.CurrentVerson = heartbeat_service.AgentState.AgentVersion
|
||||
UpgradePlan.Version = upgradeCMD.Version
|
||||
UpgradePlan.AgentId = upgradeCMD.AgentId
|
||||
UpgradePlan.Option = "upgrade"
|
||||
if immediately {
|
||||
UpgradePlan.UpgradeRule = "0" // 0:立即升级 1:按计划升级
|
||||
}
|
||||
UpgradePlan.RID = agent.Agent.RID
|
||||
|
||||
out, _ := yaml.Marshal(UpgradePlan)
|
||||
err = os.WriteFile(bin_path.UPGRADEPLAN, out, fs.ModePerm)
|
||||
if err != nil {
|
||||
log.Info(definition.UPGRADEPLAN + "写升级计划文本失败:" + err.Error())
|
||||
reportUpgradeRrrors(upgradeCMD, fmt.Sprintf("写升级计划文本失败:%s", agent.Agent.RID))
|
||||
}
|
||||
|
||||
log.Info(definition.UPGRADEPLAN + "完成升级计划文本")
|
||||
}
|
||||
|
||||
func doLocalDownloadAndUnComporess(localUpgradeCMD nats_msg_model.LocalUpgradeCMD) {
|
||||
// 5分钟后开始下载
|
||||
randomNumber := 60*5 + randomutils.GetRandomNumber(-100, 200)
|
||||
ticker := time.NewTicker(time.Duration(randomNumber) * time.Second)
|
||||
|
||||
log.Infof(definition.UPGRADEPLAN+"%d秒后开始下载", randomNumber)
|
||||
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Infof(definition.UPGRADEPLAN + "开始下载......")
|
||||
|
||||
// 从缓存机中随机选一个,随机等1~10分钟下载
|
||||
// 下载安装包至 localUpgradeCompressedFile
|
||||
localUpgradeCompressedFile := filepath.Join(definition.CompressedAgentPath, localUpgradeCMD.Filename)
|
||||
url := fmt.Sprintf("http://%s:%d?filename=%s", localUpgradeCMD.IP, localUpgradeCMD.Port, localUpgradeCMD.Filename)
|
||||
|
||||
err := minioClient.DownloadToLocal(url, localUpgradeCMD.Filename, localUpgradeCompressedFile, 3)
|
||||
if err != nil {
|
||||
log.Errorf(definition.AGENTDOWNLOADLOCAL+"下载安装包至本地失败: %s", err)
|
||||
|
||||
log.Errorf("使用备用下载地址下载安装包至本地......")
|
||||
|
||||
// 直接去minio下载
|
||||
err = minioClient.DownloadToLocal(localUpgradeCMD.DownUrl, localUpgradeCMD.Filename, localUpgradeCompressedFile, 1)
|
||||
if err != nil {
|
||||
log.Errorf("使用备用下载地址下载安装包至本地失败: %s", err)
|
||||
reportLocalUpgradeRrrors(localUpgradeCMD,
|
||||
fmt.Sprintf("下载安装包至本地失败:%s,企业频道:%s", localUpgradeCMD.Filename, definition.AGENTDOWNLOADLOCAL))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof(definition.UPGRADEPLAN + "下载完成")
|
||||
|
||||
// 将安装包文件解压到以版本命名的目录
|
||||
unCompression(localUpgradeCMD.Filename, localUpgradeCMD.CompressionType, localUpgradeCMD.Version)
|
||||
|
||||
heartbeat_service.AgentState.AgentVersion = localUpgradeCMD.Version
|
||||
// 清空
|
||||
CacheIPs = make([]nats_msg_model.LocalUpgradeCMD, 5)
|
||||
}
|
||||
}
|
||||
|
||||
// unCompression 将安装包文件解压到以版本命名的目录
|
||||
func unCompression(filename, compressionType, version string) {
|
||||
log.Infof("开始解压%s版本小助手至本地......", version)
|
||||
|
||||
versionedAgentPath := filepath.Join(definition.RunDirectory, "../upgrade", version)
|
||||
|
||||
// 如果 path 路径不存在,会有 err,然后通过 IsNotExist 判定文件路径是否存在,如果 true 则不存在,注意用 os.ModePerm 这样文件是可以写入的
|
||||
if _, err := os.Stat(versionedAgentPath); os.IsNotExist(err) {
|
||||
// mkdir 创建目录,mkdirAll 可创建多层级目录
|
||||
os.MkdirAll(versionedAgentPath, os.ModePerm)
|
||||
}
|
||||
|
||||
if compressionType == compression.ZIP {
|
||||
compression.NewZipHandler().UnZip(filepath.Join(definition.CompressedAgentPath, filename), versionedAgentPath)
|
||||
} else {
|
||||
compression.NewTGZHandler().UNTarGZ(filepath.Join(definition.CompressedAgentPath, filename), versionedAgentPath)
|
||||
}
|
||||
|
||||
log.Infof("已完成解压小助手%s至%s", filepath.Join(definition.CompressedAgentPath, filename), versionedAgentPath)
|
||||
}
|
5
agent/internal/nats_service/handle/variable.go
Normal file
5
agent/internal/nats_service/handle/variable.go
Normal file
@ -0,0 +1,5 @@
|
||||
package handle
|
||||
|
||||
import "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/nats_msg_model"
|
||||
|
||||
var CacheIPs = make([]nats_msg_model.LocalUpgradeCMD, 50)
|
23
agent/internal/nats_service/start.go
Normal file
23
agent/internal/nats_service/start.go
Normal file
@ -0,0 +1,23 @@
|
||||
package nats_service
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/cfn_to_agent_broadcast"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/cfn_to_agent_broadcast_private_enterprise"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/cfn_to_agent_broadcast_public_enterprice"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/cfn_to_agent_unicast"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/cfn_to_schdule/asset_info"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/nats_service/cfn_to_schdule/heartbeat"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
)
|
||||
|
||||
func init() {
|
||||
log.Infof("启动nats订阅服务")
|
||||
|
||||
go cfn_to_agent_unicast.Start()
|
||||
go cfn_to_agent_broadcast.Start()
|
||||
go cfn_to_agent_broadcast_private_enterprise.Start()
|
||||
go cfn_to_agent_broadcast_public_enterprice.Start()
|
||||
|
||||
asset_info.Strat()
|
||||
heartbeat.Strat()
|
||||
}
|
BIN
agent/internal/nats_service/upgrade/agentv1.1.0.tar.gz
Normal file
BIN
agent/internal/nats_service/upgrade/agentv1.1.0.tar.gz
Normal file
Binary file not shown.
8
agent/internal/pkg/authen/contract/configuration.go
Normal file
8
agent/internal/pkg/authen/contract/configuration.go
Normal file
@ -0,0 +1,8 @@
|
||||
package contract
|
||||
|
||||
type Configuration interface {
|
||||
Secret() []byte
|
||||
JWTCert() []byte
|
||||
JWTTokenLife() int
|
||||
JWTIssuer() string
|
||||
}
|
6
agent/internal/pkg/authen/contract/jwt.go
Normal file
6
agent/internal/pkg/authen/contract/jwt.go
Normal file
@ -0,0 +1,6 @@
|
||||
package contract
|
||||
|
||||
type LoginInfo interface {
|
||||
GetUserID() int
|
||||
GetUserName() string
|
||||
}
|
6
agent/internal/pkg/authen/contract/user.go
Normal file
6
agent/internal/pkg/authen/contract/user.go
Normal file
@ -0,0 +1,6 @@
|
||||
package contract
|
||||
|
||||
type User interface {
|
||||
GetUserID() int
|
||||
GetUserName() string
|
||||
}
|
14
agent/internal/pkg/authen/root.go
Normal file
14
agent/internal/pkg/authen/root.go
Normal file
@ -0,0 +1,14 @@
|
||||
package authen
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/authen/contract"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/authen/utility"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/authen/utility/crypto"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/authen/utility/jwt"
|
||||
)
|
||||
|
||||
var (
|
||||
Configuration contract.Configuration = utility.NewBaseConfig()
|
||||
LoginInfoCryptor = crypto.NewAEADCryptor(Configuration)
|
||||
JWTAuthorizer = jwt.NewJWTAuthorizer(Configuration, LoginInfoCryptor)
|
||||
)
|
189
agent/internal/pkg/authen/utility/configuration.go
Normal file
189
agent/internal/pkg/authen/utility/configuration.go
Normal file
@ -0,0 +1,189 @@
|
||||
package utility
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"github.com/golang/glog"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func NewBaseConfig() *cfg {
|
||||
return &cfg{
|
||||
secret: secret(),
|
||||
jwtCert: jwtCert(),
|
||||
jwtTokenLife: jwtTokenLife(),
|
||||
jwtIssuer: jwtIssuer(),
|
||||
}
|
||||
}
|
||||
|
||||
type cfg struct {
|
||||
secret Lazy
|
||||
jwtCert Lazy
|
||||
jwtTokenLife Lazy
|
||||
jwtIssuer Lazy
|
||||
}
|
||||
|
||||
func (s cfg) Secret() (secret []byte) {
|
||||
Must(s.secret.Value(&secret))
|
||||
return
|
||||
}
|
||||
|
||||
func (s cfg) JWTCert() (jwtCert []byte) {
|
||||
Must(s.jwtCert.Value(&jwtCert))
|
||||
return
|
||||
}
|
||||
|
||||
func (s cfg) JWTTokenLife() (tokenLife int) {
|
||||
Must(s.jwtTokenLife.Value(&tokenLife))
|
||||
return
|
||||
}
|
||||
|
||||
func (s cfg) JWTIssuer() (issuer string) {
|
||||
Must(s.jwtIssuer.Value(&issuer))
|
||||
return
|
||||
}
|
||||
|
||||
func (s cfg) Data() interface{} {
|
||||
return &struct {
|
||||
Secret string `json:"secret"`
|
||||
JWTCert string `json:"jwtCert"`
|
||||
JWTTokenLife int `json:"jwtTokenLife"`
|
||||
JWTIssuer string `json:"jwtIssuer"`
|
||||
}{
|
||||
Secret: "********",
|
||||
JWTCert: "********",
|
||||
JWTTokenLife: s.JWTTokenLife(),
|
||||
JWTIssuer: s.JWTIssuer(),
|
||||
}
|
||||
}
|
||||
|
||||
func GetEnv(key, defaultValue string) (value string) {
|
||||
if value = os.Getenv(key); value == "" {
|
||||
value = defaultValue
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func secret() Lazy {
|
||||
return NewLazy(func() (value interface{}, err error) {
|
||||
if s := GetEnv("AEAD_SECRET", "internal"); s == "" || s == "internal" {
|
||||
value = []byte("dazyunsecretkeysforuserstenx20141019generatedKey")
|
||||
return
|
||||
} else {
|
||||
value = []byte(s)
|
||||
}
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func jwtCert() Lazy {
|
||||
return NewLazy(func() (value interface{}, err error) {
|
||||
if c := GetEnv("JWT_CERT", "internal"); c == "" || c == "internal" {
|
||||
value = loadSecret()
|
||||
return
|
||||
} else if _, err = os.Stat(c); err == nil {
|
||||
var content []byte
|
||||
if content, err = ioutil.ReadFile(c); err != nil {
|
||||
return
|
||||
}
|
||||
block, _ := pem.Decode(content)
|
||||
value = block.Bytes
|
||||
return
|
||||
}
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func jwtTokenLife() Lazy {
|
||||
return NewLazy(func() (value interface{}, err error) {
|
||||
hourStr := GetEnv("BEARER_TOKEN_LIFE", "2")
|
||||
var hour int
|
||||
if hour, err = strconv.Atoi(hourStr); err != nil {
|
||||
glog.Fatalf("parse jwt token life failed, should be specified by number in hour, %s", err)
|
||||
}
|
||||
value = hour
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func jwtIssuer() Lazy {
|
||||
return NewLazy(func() (value interface{}, err error) {
|
||||
value = GetEnv("TOKEN_ISSUER", "api-server")
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func corsAllowHeaders() Lazy {
|
||||
return NewLazy(func() (value interface{}, err error) {
|
||||
headers := GetEnv(
|
||||
"ALLOW_HEADERS",
|
||||
"Content-Type,username,authorization,teamspace,project,onbehalfuser")
|
||||
value = strings.Split(headers, ",")
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func corsAllowMethods() Lazy {
|
||||
return NewLazy(func() (value interface{}, err error) {
|
||||
methods := GetEnv("ALLOW_METHODS", "GET,POST,PUT,DELETE,PATCH")
|
||||
value = strings.Split(methods, ",")
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func loadSecret() []byte {
|
||||
block, _ := pem.Decode([]byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIJKQIBAAKCAgEA2XUrxPC2ZzfLXiGz3J+BJmfpzNWyRNhUEdljCb9QfMz/54t1
|
||||
Eri+R3XEvPE+h7n7izBYohv/qXstwM55SBrLqhHVx8qD9SB5FfvkFjU1Q8K+d/1C
|
||||
KPQpGZnckCtr9c+LjXVB6h1yXP5lBcmbR2SNBAhN+zRdOAoxyw2CgycCo0kyAotT
|
||||
a9EiKYVLoP4TyDJJIebRp2rRVENBl647jC2Lp13YEXeZhxe6gHw2yEJcg0e8qn3A
|
||||
hw/842CNbhCVO5kvEhFnCrfJ7w/K7FpS4sQQzI4BocwrvDJxbwBH7RS9Q4+bax5k
|
||||
RQqB5C6bGWS59ePmqSJ/HjPBPaWcXT/FaFCqZX6umCiAkVWi2F6PK/Un3mkbCa3u
|
||||
AnqjPO0urgjel3W7kGbHZc1qnSPypUPhmuoLcLCZvzfpY6sl6rUyn8Pbbx3AaEbn
|
||||
Taxn2wvWVYAik9eeSO3mXOqdZOyFxL1oQe+dv5BjfC/KaeTA5LDPQZ+GpqUq/1ya
|
||||
lkeEUU8UsrOuSnmekxYQkHEOJ+LAK/aiCsVkbe05Ues4lAFB8g8FZ9Fo/yoCSAzs
|
||||
AMC4MPFqtNE+GeZPNAsGaNh3GUDWET7IRmu/scZI5L/eBkAyPwsKohkZOpAzfLEx
|
||||
5OiewUQ9J5zUBXZuKaZL/5HYyqf6/stItzU7UtP62X8cLi8NnC1Vq+4c9mMCAwEA
|
||||
AQKCAgEAkgCrrIT50v+RGdiDDKRDcGfggFkSYkrk1z8f0dGT1tdFEk9+AV3s08ns
|
||||
l/dZxoNGssN5Hw6xbzd3FrcKkzD6gWuMH6KHSrPM2MfQ8mAzLRW6EJIIM7sLRVca
|
||||
0el1iQsaZZXO9cNjn7BmX6ZnDV4jmAuDYCBeXlvp5q1hbXFpwfxJCZBGKGO4Diyj
|
||||
BKrS2V154Ls7FK8RcQPfLFodPRbvZyYJBmFIwX1bCR1dIsP7nWEy+T2JYKWJY5jW
|
||||
HIohyGwnQHhSuM2BVXNDCcHzWLHPnafSzLFqw+cSZjbIFBQSpyPqc9dp9zkA0RXB
|
||||
qSEKAmBL5E93De4t1pg1Dh7dChbu8A0BjeT9YOX3eLdSnu5A9tJXu8lubyzRBjNE
|
||||
360tFwC8c4IAs0KuEq3W1tzv4AEPqyx/k0V/o1d8do9WL7NqtiEk/EuMr5pkPOmb
|
||||
yUQOT9qY/B1bMk8jHllRE6E68BdhFa6pbgVrpsFehXslukN/QsgCK4yEsS22aE0R
|
||||
K4TLmRaYT8JU9hlbY86dRhqNKM+m5aH4Aa1owUj6nZQq3zYgY+0SoCdlJdGSD0gG
|
||||
LN5E4i2tlPvxBo/z7ObV9Cc+zI1OwcH5WvcBYINYDPLN9Fr9iZzLC0zI1H7eL0ut
|
||||
0eI+4BfytTk8Ff8EA2mLrfYy1fyNZqBol7lyzIg6iTBDaLzUCTECggEBAPjFmarO
|
||||
dsj2KDWr1VOobwaoY54Q/AavRARnGi24QcprHLQAJsKIUbSmMoIV/qRBUhyw88VB
|
||||
LCRW92kK4GJJIOwkr8l/zNIJRGRg/CK4E0S3vu4GA1x300VAole/nk/jUKQGCUL9
|
||||
27XJrrOKNz1Equn98OSeRB9j7AJ0aPy5BafI2PWoUoMPfpWfULeK8eBAxiYMewwk
|
||||
VpBzJr/FoZD4QgFKXhk6PoxdqdEaRQxySRWNCwgjVsSxYKVxO47bd3lJjGgXF2sd
|
||||
hfGnurBZt0jL7CmmdcI4t8+05svZrw02L+GPmp6dnpmVudlKdTbJPjRdW/SVAFuc
|
||||
vwtXrbD3glY5pccCggEBAN/GpsnePTRwGKsM43RLDlKM0SGMbpAoORFNC/X6PtQ9
|
||||
nLNM+y+ZUYVT+/TZXsKY7vOKOFFxcS/vt3Sez6CH1fkiEj7eHMFadjnYQp4mDJUh
|
||||
NuT3eOCCLnqImuVhyuGjb0kVo+Uw7NLKcWFshj16ybCO/3dSLAAf/QWjk9XMVarP
|
||||
0GHXysqOE+6aqvVwjqgZcXrteP8z/Xrij2pVsDUn6+o7E9c/snUAxpNxO5pKuaI0
|
||||
cYpLC6YILhbwLgICo22wY4W3Cd7GNJ+F8UK9QZChnbJmrMG7gqtD2wqNKiiKue4T
|
||||
n3jGG9W6DRwYsVExDsWTC8WPJ5ZULBZ8dDY5OXmPeoUCggEAXHIB0sl6tt9Sve8n
|
||||
DTmQWKcGrdyd61YCLqipv8ezGyeGuRU9UhkaU8lXB6Roxl1HyEWxsOGxJ6fxtOVH
|
||||
0P5f76EKehS15m9vLOYljDlfX6/wkb9GTHxy1E9ahMU+bW2JsApWMsDnfrx94VZB
|
||||
hNEZum6VsD9oDUoykA72XMPc6CbpCREN6Io/fhaABlTp4W3wtH760t5GFNPV2Hn2
|
||||
ukqnLJeYNEPCrqK30m6yrhdiNVH+gX2wZtOLmK9ldIb19Opx9NRv7WxBNDYiWBpe
|
||||
0/yDvE6RgCVXmSYehi5UsNIsJOQaj0r/fw92ytqyiDNsnET9QPyF74VmMS7Z6uNv
|
||||
Wd9+TQKCAQBVFD0ToShaCIiIeCT+cQ7n+dwFSlQ7AN/5oPZ8NgGvRiGO1iTmSv+A
|
||||
lpbD1+U8TVMESzfwVxY2qIhykXLVUO/cgcS4HFCIfvFWOs/ROxwrku5BDYnqqfQr
|
||||
6EYkEhNFyJKmEdE3cWuJFSkYZl9/fnCybRvZ7OcHwSG9BB1P+xlTESHkIVxbuLsB
|
||||
S9LV8E58wPexShpnxQeJshvezOdqvlvmuUFo5DHgZEQbiMClf+WmMxQ8BR5PqOqF
|
||||
FBoZ75DdQmQEUbwx89/MCuvYeQY1jAzd6EWkfrtGjEz6bQNrWJsqVlGaZI/uqYcU
|
||||
eJrqCKHaIncmTLA7apM8lWLFvuoIOrHVAoIBAQDzs6q8kcDRwJhvGCbCf2wGpRTZ
|
||||
Jza0O/toOSgI7fqrOopub/XZ/mNCsa/fFskbkJJwBj34Mt3wb59P9zFVIRyX+amh
|
||||
YREfbwk/PF8fEW6OH0FFtP6Y5D0K8MV/0qls7lVTPXeKT7UXA1nQHbBG0Bb1G2Kq
|
||||
hhovPyYZzh0xOmiXC0z8pBn1BLMnbC7/PUkDiVBmxJYAilD11xJDx+LLEuCzC8vL
|
||||
J2FMsw2T/L4egMn2Ae17AuVXOxgTkkfIf1NI4AtoznnFmhtG4+ztFyoOAOUUDE2L
|
||||
8kjUZ1BV35VkZFSz5NPbdelAp4HzkhdbUvfA9MotTtYtN8mgTPJ2neq8Lx4Z
|
||||
-----END RSA PRIVATE KEY-----`))
|
||||
return block.Bytes
|
||||
}
|
83
agent/internal/pkg/authen/utility/crypto/aead.go
Normal file
83
agent/internal/pkg/authen/utility/crypto/aead.go
Normal file
@ -0,0 +1,83 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"crypto/sha512"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
"io"
|
||||
)
|
||||
|
||||
func NewAEADCryptor(c config) *aead {
|
||||
return &aead{
|
||||
secret: c.Secret(),
|
||||
}
|
||||
}
|
||||
|
||||
type aead struct {
|
||||
secret []byte
|
||||
}
|
||||
|
||||
func (a aead) Encrypt(content []byte) (encrypted []byte, err error) {
|
||||
var salt []byte
|
||||
if salt, err = randBytes(64); err != nil {
|
||||
return
|
||||
}
|
||||
var block cipher.Block
|
||||
if block, err = aes.NewCipher(a.key(salt)); err != nil {
|
||||
return
|
||||
}
|
||||
var iv []byte
|
||||
if iv, err = randBytes(12); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return
|
||||
}
|
||||
var aes256gcm cipher.AEAD
|
||||
if aes256gcm, err = cipher.NewGCM(block); err != nil {
|
||||
return
|
||||
}
|
||||
withTag := aes256gcm.Seal(nil, iv, content, nil)
|
||||
encryptedLen := len(withTag) - 16
|
||||
withoutTag := withTag[:encryptedLen]
|
||||
tag := withTag[encryptedLen:]
|
||||
encrypted = bytes.Join([][]byte{salt, iv, tag, withoutTag}, []byte{})
|
||||
return
|
||||
}
|
||||
|
||||
func (a aead) Decrypt(encrypted []byte) (content []byte, err error) {
|
||||
if len(encrypted) <= 92 {
|
||||
err = Undecryptable
|
||||
return
|
||||
}
|
||||
salt := encrypted[:64]
|
||||
iv := encrypted[64:76]
|
||||
tag := encrypted[76:92]
|
||||
withoutTag := encrypted[92:]
|
||||
withTag := bytes.Join([][]byte{withoutTag, tag}, []byte{})
|
||||
var block cipher.Block
|
||||
if block, err = aes.NewCipher(a.key(salt)); err != nil {
|
||||
return
|
||||
}
|
||||
var aes256gcm cipher.AEAD
|
||||
if aes256gcm, err = cipher.NewGCM(block); err != nil {
|
||||
return
|
||||
}
|
||||
content, err = aes256gcm.Open(nil, iv, withTag, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (a aead) key(salt []byte) []byte {
|
||||
return pbkdf2.Key(a.secret, salt, 2145, 32, sha512.New)
|
||||
}
|
||||
|
||||
func randBytes(length int) (bytes []byte, err error) {
|
||||
bytes = make([]byte, length)
|
||||
if _, err = io.ReadFull(rand.Reader, bytes); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
69
agent/internal/pkg/authen/utility/crypto/cipher.go
Normal file
69
agent/internal/pkg/authen/utility/crypto/cipher.go
Normal file
@ -0,0 +1,69 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
var (
|
||||
seckey = []byte("Q1A2Z3X!D^R$T&G*B(N)U088") //24Byte
|
||||
base64Tables = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
iv = []byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
|
||||
)
|
||||
|
||||
func base64Decode(src string) ([]byte, error) {
|
||||
coder := base64.NewEncoding(base64Tables)
|
||||
return coder.DecodeString(src)
|
||||
}
|
||||
|
||||
func aesPadding(src []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(src)%blockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
return append(src, padtext...)
|
||||
}
|
||||
|
||||
func aesUnPadding(src []byte) []byte {
|
||||
length := len(src)
|
||||
unpadding := int(src[length-1])
|
||||
return src[:(length - unpadding)]
|
||||
}
|
||||
func Encrypt(src string) (string, error) {
|
||||
block, err := aes.NewCipher(seckey)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
arr := aesPadding([]byte(src), aes.BlockSize)
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(arr, arr)
|
||||
return string(arr), nil
|
||||
}
|
||||
func Decrypt(src string) (string, error) {
|
||||
block, err := aes.NewCipher(seckey)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
arr := []byte(src)
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(arr, arr)
|
||||
arr = aesUnPadding(arr)
|
||||
return string(arr), nil
|
||||
|
||||
}
|
||||
|
||||
func Base64AndDecrypt(src string) (string, error) {
|
||||
block, err := aes.NewCipher(seckey)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
arr, err := base64Decode(src)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(arr, arr)
|
||||
arr = aesUnPadding(arr)
|
||||
return string(arr), nil
|
||||
}
|
35
agent/internal/pkg/authen/utility/crypto/common.go
Normal file
35
agent/internal/pkg/authen/utility/crypto/common.go
Normal file
@ -0,0 +1,35 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"hash"
|
||||
)
|
||||
|
||||
var Undecryptable = errors.New("undecryptable input")
|
||||
|
||||
type config interface {
|
||||
Secret() []byte
|
||||
}
|
||||
|
||||
// https://nodejs.org/api/crypto.html#crypto_crypto_createdecipher_algorithm_password_options
|
||||
// openssl/evp.h - EVP_BytesToKey
|
||||
func bytesToKey(hashAlgorithm func() hash.Hash, secret, salt []byte, iteration int, keySize, ivSize int) (key, iv []byte) {
|
||||
h := hashAlgorithm()
|
||||
var d, result []byte
|
||||
sum := make([]byte, 0, h.Size())
|
||||
for len(result) < keySize+ivSize {
|
||||
h.Reset()
|
||||
h.Write(d)
|
||||
h.Write(secret)
|
||||
h.Write(salt)
|
||||
sum = h.Sum(sum[:0])
|
||||
for j := 1; j < iteration; j++ {
|
||||
h.Reset()
|
||||
h.Write(sum)
|
||||
sum = h.Sum(sum[:0])
|
||||
}
|
||||
d = append(d[:0], sum...)
|
||||
result = append(result, d...)
|
||||
}
|
||||
return result[:keySize], result[keySize : keySize+ivSize]
|
||||
}
|
87
agent/internal/pkg/authen/utility/crypto/des.go
Normal file
87
agent/internal/pkg/authen/utility/crypto/des.go
Normal file
@ -0,0 +1,87 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"crypto/des"
|
||||
"crypto/md5"
|
||||
)
|
||||
|
||||
func NewDESCryptor(c config) *desEDE3CBC {
|
||||
k, iv := bytesToKey(md5.New, c.Secret(), []byte{}, 1, 24, 8)
|
||||
return &desEDE3CBC{
|
||||
key: k,
|
||||
iv: iv,
|
||||
}
|
||||
}
|
||||
|
||||
type desEDE3CBC struct {
|
||||
key []byte
|
||||
iv []byte
|
||||
}
|
||||
|
||||
func (d desEDE3CBC) Encrypt(content []byte) (encrypted []byte, err error) {
|
||||
var block cipher.Block
|
||||
if block, err = des.NewTripleDESCipher(d.key); err != nil {
|
||||
return
|
||||
}
|
||||
cbc := cipher.NewCBCEncrypter(block, d.iv)
|
||||
encrypted, err = d.crypt(content, cbc)
|
||||
return
|
||||
}
|
||||
|
||||
func (d desEDE3CBC) Decrypt(encrypted []byte) (content []byte, err error) {
|
||||
var block cipher.Block
|
||||
if block, err = des.NewTripleDESCipher(d.key); err != nil {
|
||||
return
|
||||
}
|
||||
cbc := cipher.NewCBCDecrypter(block, d.iv)
|
||||
content, err = d.crypt(encrypted, cbc)
|
||||
return
|
||||
}
|
||||
|
||||
func (d desEDE3CBC) crypt(in []byte, cbc cipher.BlockMode) (out []byte, err error) {
|
||||
blockSize := cbc.BlockSize()
|
||||
padded := padding(in, blockSize)
|
||||
entriesCount := len(padded)
|
||||
crypted := make([][]byte, entriesCount)
|
||||
for i := 0; i < entriesCount; i++ {
|
||||
crypted[i] = make([]byte, blockSize)
|
||||
cbc.CryptBlocks(crypted[i], padded[i])
|
||||
}
|
||||
contentSize := len(in)
|
||||
out = make([]byte, contentSize)
|
||||
for i := 0; i < entriesCount; i++ {
|
||||
for j := 0; j < blockSize; j++ {
|
||||
index := i*blockSize + j
|
||||
if index >= contentSize {
|
||||
break
|
||||
}
|
||||
out[index] = crypted[i][j]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func padding(content []byte, blockSize int) (padded [][]byte) {
|
||||
contentLength := len(content)
|
||||
size := contentLength / blockSize
|
||||
if contentLength%blockSize != 0 {
|
||||
size++
|
||||
}
|
||||
padded = make([][]byte, size)
|
||||
for i := 0; i < size; i++ {
|
||||
padded[i] = make([]byte, blockSize)
|
||||
entry := padded[i]
|
||||
for j := 0; j < blockSize; j++ {
|
||||
index := i*blockSize + j
|
||||
if index >= contentLength {
|
||||
for k := j; k < blockSize; k++ {
|
||||
entry[k] = 0
|
||||
}
|
||||
break
|
||||
}
|
||||
entry[j] = content[index]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
181
agent/internal/pkg/authen/utility/jwt/jwt.go
Normal file
181
agent/internal/pkg/authen/utility/jwt/jwt.go
Normal file
@ -0,0 +1,181 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
UnexpectedSingingMethod = errors.New("unexpected signing method")
|
||||
UnknownEntity = errors.New("unknown entity")
|
||||
)
|
||||
|
||||
func NewJWTAuthorizer(c config, cryptor cryptor) *authorizer {
|
||||
tl := time.Duration(c.JWTTokenLife())
|
||||
return &authorizer{
|
||||
tokenLifeInHour: tl,
|
||||
tokenLifeInSecond: int(time.Hour * tl / time.Second),
|
||||
issuer: c.JWTIssuer(),
|
||||
cert: c.JWTCert(),
|
||||
cryptor: cryptor,
|
||||
}
|
||||
}
|
||||
|
||||
type config interface {
|
||||
JWTCert() []byte
|
||||
JWTTokenLife() int
|
||||
JWTIssuer() string
|
||||
}
|
||||
|
||||
type loginInfo interface {
|
||||
GetUserID() int
|
||||
GetUserName() string
|
||||
GetUserToken() string
|
||||
}
|
||||
|
||||
type authorizer struct {
|
||||
tokenLifeInHour time.Duration
|
||||
tokenLifeInSecond int
|
||||
issuer string
|
||||
cert []byte
|
||||
cryptor cryptor
|
||||
}
|
||||
|
||||
type entity struct {
|
||||
Encrypted string `json:"encrypted"`
|
||||
jwt.StandardClaims `json:",inline"`
|
||||
}
|
||||
|
||||
func (a authorizer) Authorize(li loginInfo) (token string, err error) {
|
||||
i := &info{
|
||||
Username: li.GetUserName(),
|
||||
Token: li.GetUserToken(),
|
||||
UserID: li.GetUserID(),
|
||||
}
|
||||
now := time.Now()
|
||||
var encrypted string
|
||||
if encrypted, err = encryptLoginInfo(i, a.cryptor); err != nil {
|
||||
return
|
||||
}
|
||||
claims := jwt.NewWithClaims(jwt.SigningMethodHS512, &entity{
|
||||
Encrypted: encrypted,
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
ExpiresAt: now.Add(a.tokenLifeInHour * time.Hour).Unix(),
|
||||
Issuer: a.issuer,
|
||||
},
|
||||
})
|
||||
var rawToken string
|
||||
if rawToken, err = claims.SignedString(a.cert); err != nil {
|
||||
return
|
||||
}
|
||||
token = (&dto{
|
||||
Token: rawToken,
|
||||
ExpiresIn: a.tokenLifeInSecond,
|
||||
IssuedAt: now,
|
||||
UserID: i.UserID,
|
||||
}).String()
|
||||
return
|
||||
}
|
||||
|
||||
func (a authorizer) Validate(token string) (l loginInfo, err error) {
|
||||
var t *jwt.Token
|
||||
if t, err = jwt.ParseWithClaims(token, &entity{}, a.validateCert); err != nil {
|
||||
return
|
||||
}
|
||||
obj, ok := t.Claims.(*entity)
|
||||
if !ok {
|
||||
err = UnknownEntity
|
||||
return
|
||||
}
|
||||
var li *info
|
||||
if li, err = decryptLoginInfo(obj.Encrypted, a.cryptor); err != nil {
|
||||
return
|
||||
}
|
||||
l = li
|
||||
return
|
||||
}
|
||||
|
||||
const (
|
||||
bearerKeyword = "Bearer"
|
||||
bearerKeywordLength = len(bearerKeyword)
|
||||
)
|
||||
|
||||
func (authorizer) IsBearerToken(rawToken string) (ok bool, token string) {
|
||||
ok = len(rawToken) > bearerKeywordLength &&
|
||||
strings.EqualFold(bearerKeyword, rawToken[:bearerKeywordLength])
|
||||
if ok {
|
||||
token = strings.TrimSpace(rawToken[bearerKeywordLength:])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (authorizer) IsTokenExpired(err error) bool {
|
||||
if jve, ok := err.(*jwt.ValidationError); ok && jve.Inner != nil {
|
||||
return jve.Errors&jwt.ValidationErrorExpired == jwt.ValidationErrorExpired
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a authorizer) validateCert(token *jwt.Token) (obj interface{}, err error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
err = UnexpectedSingingMethod
|
||||
return
|
||||
}
|
||||
return a.cert, nil
|
||||
}
|
||||
|
||||
var (
|
||||
secret = loadSecret()
|
||||
)
|
||||
|
||||
func loadSecret() []byte {
|
||||
block, _ := base64.StdEncoding.DecodeString(`IUkVLcM72OGEOJgQX3BXjLP4dsLs084joI2aQWcmB8rLxPyEX2cxLdVllRrx/v/Tzh2iSPsftmcABQ+q5kVYdQ==`)
|
||||
return block
|
||||
}
|
||||
|
||||
type LoginInfo struct {
|
||||
Username string `json:"username"`
|
||||
Encrypted string `json:"encrypted"`
|
||||
}
|
||||
|
||||
type tokenEntity struct {
|
||||
Encrypted string `json:"encrypted"`
|
||||
Username string `json:"login_loginname"`
|
||||
Role int32 `json:"role"`
|
||||
ApiToken string `json:"api_token"`
|
||||
LoginAppId string `json:"login_app_id"`
|
||||
LoginUid string `json:"login_uid"`
|
||||
LoginAccountId string `json:"login_account_id"`
|
||||
ClientIp string `json:"client_ip"`
|
||||
LoginAccountName string `json:"login_account_name"`
|
||||
UsersAppId string `json:"users_app_id"`
|
||||
LoginUname string `json:"login_uname"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
func (authorizer) ValidateToken(rawToken string) (loginInfo *LoginInfo, err error) {
|
||||
var token *jwt.Token
|
||||
if token, err = jwt.ParseWithClaims(rawToken, &tokenEntity{}, validateSecret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj, ok := token.Claims.(*tokenEntity)
|
||||
if !ok {
|
||||
return nil, UnknownEntity
|
||||
}
|
||||
loginInfo = &LoginInfo{
|
||||
Username: obj.Username,
|
||||
Encrypted: obj.Encrypted,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func validateSecret(token *jwt.Token) (obj interface{}, err error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
err = UnexpectedSingingMethod
|
||||
return
|
||||
}
|
||||
return secret, nil
|
||||
}
|
71
agent/internal/pkg/authen/utility/jwt/login_info.go
Normal file
71
agent/internal/pkg/authen/utility/jwt/login_info.go
Normal file
@ -0,0 +1,71 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type dto struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresIn int `json:"expiresIn"`
|
||||
IssuedAt time.Time `json:"issuedAt"`
|
||||
UserID int `json:"userID"`
|
||||
}
|
||||
|
||||
func (t dto) String() string {
|
||||
c, _ := json.Marshal(t)
|
||||
return string(c)
|
||||
}
|
||||
|
||||
type cryptor interface {
|
||||
Encrypt(content []byte) (encrypted []byte, err error)
|
||||
Decrypt(encrypted []byte) (content []byte, err error)
|
||||
}
|
||||
|
||||
type info struct {
|
||||
Username string `json:"username"`
|
||||
Token string `json:"token"`
|
||||
UserID int `json:"userId"`
|
||||
}
|
||||
|
||||
func (i info) GetUserID() int {
|
||||
return i.UserID
|
||||
}
|
||||
|
||||
func (i info) GetUserName() string {
|
||||
return i.Username
|
||||
}
|
||||
|
||||
func (i info) GetUserToken() string {
|
||||
return i.Token
|
||||
}
|
||||
|
||||
func encryptLoginInfo(i *info, cryptor cryptor) (encrypted string, err error) {
|
||||
var buffer []byte
|
||||
if buffer, err = json.Marshal(i); err != nil {
|
||||
return
|
||||
}
|
||||
if buffer, err = cryptor.Encrypt(buffer); err != nil {
|
||||
return
|
||||
}
|
||||
encrypted = base64.StdEncoding.EncodeToString(buffer)
|
||||
return
|
||||
}
|
||||
|
||||
func decryptLoginInfo(encrypted string, cryptor cryptor) (decrypted *info, err error) {
|
||||
var buffer []byte
|
||||
buffer, err = base64.StdEncoding.DecodeString(encrypted)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if buffer, err = cryptor.Decrypt(buffer); err != nil {
|
||||
return
|
||||
}
|
||||
var t info
|
||||
if err = json.Unmarshal(buffer, &t); err != nil {
|
||||
return
|
||||
}
|
||||
decrypted = &t
|
||||
return
|
||||
}
|
55
agent/internal/pkg/authen/utility/lazy.go
Normal file
55
agent/internal/pkg/authen/utility/lazy.go
Normal file
@ -0,0 +1,55 @@
|
||||
package utility
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Lazy interface {
|
||||
Value(value interface{}) (err error)
|
||||
}
|
||||
|
||||
var (
|
||||
TypeMismatched = errors.New("type mismatched")
|
||||
)
|
||||
|
||||
type lazy struct {
|
||||
lock *sync.Once
|
||||
fetch func() (value interface{}, err error)
|
||||
value interface{}
|
||||
done bool
|
||||
}
|
||||
|
||||
func (l *lazy) Value(value interface{}) (err error) {
|
||||
if l.done {
|
||||
l.setValueTo(value)
|
||||
return
|
||||
}
|
||||
l.lock.Do(func() {
|
||||
if l.value, err = l.fetch(); err != nil {
|
||||
l.lock = new(sync.Once)
|
||||
return
|
||||
} else {
|
||||
l.setValueTo(value)
|
||||
l.done = true
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (l lazy) setValueTo(receiver interface{}) (err error) {
|
||||
rv := reflect.Indirect(reflect.ValueOf(receiver))
|
||||
vv := reflect.ValueOf(l.value)
|
||||
if vv.Type().AssignableTo(rv.Type()) && rv.CanSet() {
|
||||
rv.Set(reflect.ValueOf(l.value))
|
||||
}
|
||||
return TypeMismatched
|
||||
}
|
||||
|
||||
func NewLazy(fetch func() (value interface{}, err error)) Lazy {
|
||||
return &lazy{
|
||||
lock: new(sync.Once),
|
||||
fetch: fetch,
|
||||
}
|
||||
}
|
23
agent/internal/pkg/authen/utility/lazy_test.go
Normal file
23
agent/internal/pkg/authen/utility/lazy_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
package utility
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestLazy_Value(t *testing.T) {
|
||||
i := 0
|
||||
someLazyValue := NewLazy(func() (value interface{}, err error) {
|
||||
value = "some lazy value"
|
||||
i++
|
||||
return
|
||||
})
|
||||
var theValueOfSomeLazyValue string
|
||||
if err := someLazyValue.Value(&theValueOfSomeLazyValue); err != nil {
|
||||
t.Fatalf("get value failed, %s", err)
|
||||
}
|
||||
t.Logf("value of lazy: %s", theValueOfSomeLazyValue)
|
||||
if err := someLazyValue.Value(&theValueOfSomeLazyValue); err != nil {
|
||||
t.Fatalf("get value failed, %s", err)
|
||||
}
|
||||
if i > 1 {
|
||||
t.Fatalf("lazy should only evaluate once, but %d times", i)
|
||||
}
|
||||
}
|
38
agent/internal/pkg/authen/utility/must.go
Normal file
38
agent/internal/pkg/authen/utility/must.go
Normal file
@ -0,0 +1,38 @@
|
||||
package utility
|
||||
|
||||
import "reflect"
|
||||
|
||||
func Must(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type receiver interface {
|
||||
Value(interface{})
|
||||
}
|
||||
|
||||
type holder struct {
|
||||
value interface{}
|
||||
}
|
||||
|
||||
func (h holder) Value(receiver interface{}) {
|
||||
reflect.Indirect(reflect.ValueOf(receiver)).Set(reflect.ValueOf(h.value))
|
||||
}
|
||||
|
||||
// So everyone who may use this, must be familiar with golang.
|
||||
// Then they should take care with the 'receiver'.
|
||||
// func someMethod(someArg string, otherArg int) (returnValue int, err error)
|
||||
// for instance a method like above, then MustGet can used like below
|
||||
// var returnValue int
|
||||
// MustGet(someMethod("someArg", /* otherArg */ 888)).Value(&returnValue)
|
||||
// and if someMethod's second return value (the err) was not nil
|
||||
// the expression panic, other way the 'returnValue' should be the first
|
||||
// return value of someMethod.
|
||||
// YOU SHOULD take care of the receiver type yourself, if the 'var returnValue int'
|
||||
// line goes to 'var returnValue string', then it also panic, since the first
|
||||
// return value of someMethod is int not string.
|
||||
func MustGet(anything interface{}, err error) receiver {
|
||||
Must(err)
|
||||
return &holder{value: anything}
|
||||
}
|
57
agent/internal/pkg/authen/utility/must_test.go
Normal file
57
agent/internal/pkg/authen/utility/must_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package utility
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func chaosMonkeyA(t *testing.T) error {
|
||||
t.Logf("chaosMonkeyA")
|
||||
return errors.New("chaosMonkeyA")
|
||||
}
|
||||
|
||||
func chaosMonkeyB(t *testing.T) (string, error) {
|
||||
t.Logf("chaosMonkeyB")
|
||||
return "chaosMonkeyB", errors.New("chaosMonkeyB")
|
||||
}
|
||||
|
||||
func iAmWalkingInLine(t *testing.T) (float64, error) {
|
||||
t.Logf("iAmWalkingInLine")
|
||||
return 88888888.88888888, nil
|
||||
}
|
||||
|
||||
func TestMust(t *testing.T) {
|
||||
func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
t.Logf("caseA: should panic, %s", err)
|
||||
} else {
|
||||
t.Fatalf("caseA: should panic, but didn't")
|
||||
}
|
||||
}()
|
||||
Must(chaosMonkeyA(t))
|
||||
}()
|
||||
func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
t.Logf("caseB: should panic, %s", err)
|
||||
} else {
|
||||
t.Fatalf("caseB: should panic, but didn't")
|
||||
}
|
||||
}()
|
||||
var value string
|
||||
MustGet(chaosMonkeyB(t)).Value(&value)
|
||||
}()
|
||||
func() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
t.Fatalf("caseC: should not panic, but paniced %s", err)
|
||||
} else {
|
||||
t.Logf("caseC: everything went fine")
|
||||
}
|
||||
}()
|
||||
var value float64
|
||||
MustGet(iAmWalkingInLine(t)).Value(&value)
|
||||
t.Logf("caseC: value, %f", value)
|
||||
}()
|
||||
}
|
38
agent/internal/pkg/errors/code.go
Normal file
38
agent/internal/pkg/errors/code.go
Normal file
@ -0,0 +1,38 @@
|
||||
package errors
|
||||
|
||||
const (
|
||||
SUCCESS = 200
|
||||
FAILURE = 600
|
||||
NotFound = 404
|
||||
InvalidParameter = 400
|
||||
ServerError = 500
|
||||
TooManyRequests = 429
|
||||
AuthorizationError = 401
|
||||
RBACError = 403
|
||||
)
|
||||
|
||||
type ErrorText struct {
|
||||
Language string
|
||||
}
|
||||
|
||||
func NewErrorText(language string) *ErrorText {
|
||||
return &ErrorText{
|
||||
Language: language,
|
||||
}
|
||||
}
|
||||
|
||||
func (et *ErrorText) Text(code int) (str string) {
|
||||
var ok bool
|
||||
switch et.Language {
|
||||
case "zh_CN":
|
||||
str, ok = zhCNText[code]
|
||||
case "en":
|
||||
str, ok = enUSText[code]
|
||||
default:
|
||||
str, ok = zhCNText[code]
|
||||
}
|
||||
if !ok {
|
||||
return "unknown error"
|
||||
}
|
||||
return
|
||||
}
|
16
agent/internal/pkg/errors/code_test.go
Normal file
16
agent/internal/pkg/errors/code_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestText(t *testing.T) {
|
||||
var errorText = NewErrorText("zh_CN")
|
||||
if "OK" != errorText.Text(0) {
|
||||
t.Error("text 返回 msg 不是预期的")
|
||||
}
|
||||
|
||||
if "unknown error" != errorText.Text(1202389) {
|
||||
t.Error("text 返回 msg 不是预期的")
|
||||
}
|
||||
}
|
12
agent/internal/pkg/errors/en-us.go
Normal file
12
agent/internal/pkg/errors/en-us.go
Normal file
@ -0,0 +1,12 @@
|
||||
package errors
|
||||
|
||||
var enUSText = map[int]string{
|
||||
SUCCESS: "OK",
|
||||
FAILURE: "FAIL",
|
||||
NotFound: "resources not found",
|
||||
ServerError: "Internal server error",
|
||||
TooManyRequests: "Too many requests",
|
||||
InvalidParameter: "Parameter error",
|
||||
AuthorizationError: "Authorization error",
|
||||
RBACError: "No access",
|
||||
}
|
63
agent/internal/pkg/errors/error.go
Normal file
63
agent/internal/pkg/errors/error.go
Normal file
@ -0,0 +1,63 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
c "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
)
|
||||
|
||||
type BusinessError struct {
|
||||
code int
|
||||
message string
|
||||
contextErr []error
|
||||
}
|
||||
|
||||
func (e *BusinessError) Error() string {
|
||||
return fmt.Sprintf("[Code]:%d [Msg]:%s, [context error] %s", e.code, e.message, e.contextErr)
|
||||
}
|
||||
|
||||
func (e *BusinessError) GetCode() int {
|
||||
return e.code
|
||||
}
|
||||
|
||||
func (e *BusinessError) GetMessage() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func (e *BusinessError) SetCode(code int) {
|
||||
e.code = code
|
||||
}
|
||||
|
||||
func (e *BusinessError) SetMessage(message string) {
|
||||
e.message = message
|
||||
}
|
||||
|
||||
func (e *BusinessError) SetContextErr(err error) {
|
||||
e.contextErr = append(e.contextErr, err)
|
||||
}
|
||||
|
||||
func (e *BusinessError) GetContextErr() []error {
|
||||
return e.contextErr
|
||||
}
|
||||
|
||||
// NewBusinessError Create a business error
|
||||
func NewBusinessError(code int, message ...string) *BusinessError {
|
||||
var msg string
|
||||
if message != nil {
|
||||
msg = message[0]
|
||||
} else {
|
||||
msg = NewErrorText(c.Config.Language).Text(code)
|
||||
}
|
||||
err := new(BusinessError)
|
||||
err.SetCode(code)
|
||||
err.SetMessage(msg)
|
||||
return err
|
||||
}
|
||||
|
||||
func AsBusinessError(err error) (*BusinessError, error) {
|
||||
var BusinessError = new(BusinessError)
|
||||
if errors.As(err, &BusinessError) {
|
||||
return BusinessError, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
12
agent/internal/pkg/errors/zh-cn.go
Normal file
12
agent/internal/pkg/errors/zh-cn.go
Normal file
@ -0,0 +1,12 @@
|
||||
package errors
|
||||
|
||||
var zhCNText = map[int]string{
|
||||
SUCCESS: "OK",
|
||||
FAILURE: "FAIL",
|
||||
NotFound: "资源不存在",
|
||||
ServerError: "服务器内部错误",
|
||||
TooManyRequests: "请求过多",
|
||||
InvalidParameter: "参数错误",
|
||||
AuthorizationError: "权限错误",
|
||||
RBACError: "暂无访问权限",
|
||||
}
|
51
agent/internal/pkg/func_make/func_make.go
Normal file
51
agent/internal/pkg/func_make/func_make.go
Normal file
@ -0,0 +1,51 @@
|
||||
package func_make
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type FuncMap map[string]reflect.Value
|
||||
|
||||
func New() FuncMap {
|
||||
return make(FuncMap, 2)
|
||||
}
|
||||
|
||||
func (f FuncMap) Register(name string, fn any) error {
|
||||
v := reflect.ValueOf(fn)
|
||||
if v.Kind() != reflect.Func {
|
||||
return errors.New(name + " is not a function type.")
|
||||
}
|
||||
f[name] = v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f FuncMap) Registers(funcMap map[string]any) (err error) {
|
||||
for k, v := range funcMap {
|
||||
err = f.Register(k, v)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f FuncMap) Call(name string, params ...any) (result []reflect.Value, err error) {
|
||||
if _, ok := f[name]; !ok {
|
||||
err = errors.New(name + " method does not exist.")
|
||||
return
|
||||
}
|
||||
in := make([]reflect.Value, len(params))
|
||||
for k, param := range params {
|
||||
in[k] = reflect.ValueOf(param)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = errors.New("call " + name + " method fail. " + e.(string))
|
||||
}
|
||||
}()
|
||||
|
||||
result = f[name].Call(in)
|
||||
return
|
||||
}
|
45
agent/internal/pkg/func_make/func_make_test.go
Normal file
45
agent/internal/pkg/func_make/func_make_test.go
Normal file
@ -0,0 +1,45 @@
|
||||
package func_make
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
funcMap = map[string]interface{}{
|
||||
"test": func(str string) string {
|
||||
return str
|
||||
},
|
||||
}
|
||||
funcMake = New()
|
||||
)
|
||||
|
||||
func TestRegisters(t *testing.T) {
|
||||
err := funcMake.Registers(funcMap)
|
||||
if err != nil {
|
||||
t.Errorf("绑定失败")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
err := funcMake.Register("test1", func(str ...string) string {
|
||||
var res string
|
||||
for _, v := range str {
|
||||
res += v
|
||||
}
|
||||
return res
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("绑定失败")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCall(t *testing.T) {
|
||||
TestRegisters(t)
|
||||
TestRegister(t)
|
||||
if _, err := funcMake.Call("test", "1"); err != nil {
|
||||
t.Errorf("请求test方法失败:%s", err)
|
||||
}
|
||||
if _, err := funcMake.Call("test1", "2323", "ddd"); err != nil {
|
||||
t.Errorf("请求test1方法失败:%s", err)
|
||||
}
|
||||
}
|
47
agent/internal/pkg/request/request.go
Normal file
47
agent/internal/pkg/request/request.go
Normal file
@ -0,0 +1,47 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetQueryParams(c *gin.Context) map[string]any {
|
||||
query := c.Request.URL.Query()
|
||||
var queryMap = make(map[string]any, len(query))
|
||||
for k := range query {
|
||||
queryMap[k] = c.Query(k)
|
||||
}
|
||||
return queryMap
|
||||
}
|
||||
|
||||
func GetPostFormParams(c *gin.Context) (map[string]any, error) {
|
||||
if err := c.Request.ParseMultipartForm(32 << 20); err != nil {
|
||||
if !errors.Is(err, http.ErrNotMultipart) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var postMap = make(map[string]any, len(c.Request.PostForm))
|
||||
for k, v := range c.Request.PostForm {
|
||||
if len(v) > 1 {
|
||||
postMap[k] = v
|
||||
} else if len(v) == 1 {
|
||||
postMap[k] = v[0]
|
||||
}
|
||||
}
|
||||
|
||||
return postMap, nil
|
||||
}
|
||||
|
||||
func GetBody(c *gin.Context) []byte {
|
||||
// 读取body数据
|
||||
body, err := c.GetRawData()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
//把读过的字节流重新放到body
|
||||
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
|
||||
return body
|
||||
}
|
142
agent/internal/pkg/response/response.go
Normal file
142
agent/internal/pkg/response/response.go
Normal file
@ -0,0 +1,142 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type result struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
Cost string `json:"cost"`
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
httpCode int
|
||||
result *result
|
||||
}
|
||||
|
||||
func Resp() *Response {
|
||||
// 初始化response
|
||||
return &Response{
|
||||
httpCode: http.StatusOK,
|
||||
result: &result{
|
||||
Code: 0,
|
||||
Msg: "",
|
||||
Data: nil,
|
||||
Cost: "",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Fail 错误返回
|
||||
func (r *Response) Fail(c *gin.Context, code int, msg string, data ...any) {
|
||||
r.SetCode(code)
|
||||
r.SetMessage(msg)
|
||||
if data != nil {
|
||||
r.WithData(data[0])
|
||||
}
|
||||
r.json(c)
|
||||
}
|
||||
|
||||
// FailCode 自定义错误码返回
|
||||
func (r *Response) FailCode(c *gin.Context, code int, msg ...string) {
|
||||
r.SetCode(code)
|
||||
if msg != nil {
|
||||
r.SetMessage(msg[0])
|
||||
}
|
||||
r.json(c)
|
||||
}
|
||||
|
||||
// Success 正确返回
|
||||
func (r *Response) Success(c *gin.Context) {
|
||||
r.SetCode(errors.SUCCESS)
|
||||
r.json(c)
|
||||
}
|
||||
|
||||
// WithDataSuccess 成功后需要返回值
|
||||
func (r *Response) WithDataSuccess(c *gin.Context, data interface{}) {
|
||||
r.SetCode(errors.SUCCESS)
|
||||
r.WithData(data)
|
||||
r.json(c)
|
||||
}
|
||||
|
||||
// SetCode 设置返回code码
|
||||
func (r *Response) SetCode(code int) *Response {
|
||||
r.result.Code = code
|
||||
return r
|
||||
}
|
||||
|
||||
// SetHttpCode 设置http状态码
|
||||
func (r *Response) SetHttpCode(code int) *Response {
|
||||
r.httpCode = code
|
||||
return r
|
||||
}
|
||||
|
||||
type defaultRes struct {
|
||||
Result any `json:"result"`
|
||||
}
|
||||
|
||||
// WithData 设置返回data数据
|
||||
func (r *Response) WithData(data any) *Response {
|
||||
switch data.(type) {
|
||||
case string, int, bool:
|
||||
r.result.Data = &defaultRes{Result: data}
|
||||
default:
|
||||
r.result.Data = data
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// SetMessage 设置返回自定义错误消息
|
||||
func (r *Response) SetMessage(message string) *Response {
|
||||
r.result.Msg = message
|
||||
return r
|
||||
}
|
||||
|
||||
var ErrorText = errors.NewErrorText(config.Config.Language)
|
||||
|
||||
// json 返回 gin 框架的 HandlerFunc
|
||||
func (r *Response) json(c *gin.Context) {
|
||||
if r.result.Msg == "" {
|
||||
r.result.Msg = ErrorText.Text(r.result.Code)
|
||||
}
|
||||
|
||||
// if r.Data == nil {
|
||||
// r.Data = struct{}{}
|
||||
// }
|
||||
|
||||
r.result.Cost = time.Since(c.GetTime("requestStartTime")).String()
|
||||
c.AbortWithStatusJSON(r.httpCode, r.result)
|
||||
}
|
||||
|
||||
// Success 业务成功响应
|
||||
func Success(c *gin.Context, data ...any) {
|
||||
if data != nil {
|
||||
Resp().WithDataSuccess(c, data[0])
|
||||
return
|
||||
}
|
||||
Resp().Success(c)
|
||||
}
|
||||
|
||||
// FailCode 业务失败响应
|
||||
func FailCode(c *gin.Context, code int, data ...any) {
|
||||
if data != nil {
|
||||
Resp().WithData(data[0]).FailCode(c, code)
|
||||
return
|
||||
}
|
||||
Resp().FailCode(c, code)
|
||||
}
|
||||
|
||||
// Fail 业务失败响应
|
||||
func Fail(c *gin.Context, code int, message string, data ...any) {
|
||||
if data != nil {
|
||||
Resp().WithData(data[0]).FailCode(c, code, message)
|
||||
return
|
||||
}
|
||||
Resp().FailCode(c, code, message)
|
||||
}
|
56
agent/internal/pkg/utils/utils.go
Normal file
56
agent/internal/pkg/utils/utils.go
Normal file
@ -0,0 +1,56 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FormatDate struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
const (
|
||||
timeFormat = "2006-01-02 15:04:05"
|
||||
)
|
||||
|
||||
func (t FormatDate) MarshalJSON() ([]byte, error) {
|
||||
if &t == nil || t.IsZero() {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return []byte(fmt.Sprintf("\"%s\"", t.Format(timeFormat))), nil
|
||||
}
|
||||
|
||||
func (t FormatDate) Value() (driver.Value, error) {
|
||||
var zeroTime time.Time
|
||||
if t.Time.UnixNano() == zeroTime.UnixNano() {
|
||||
return nil, nil
|
||||
}
|
||||
return t.Time, nil
|
||||
}
|
||||
|
||||
func (t *FormatDate) Scan(v interface{}) error {
|
||||
if value, ok := v.(time.Time); ok {
|
||||
*t = FormatDate{value}
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("can not convert %v to timestamp", v)
|
||||
}
|
||||
|
||||
func (t *FormatDate) String() string {
|
||||
if t == nil || t.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s", t.Time.Format(timeFormat))
|
||||
}
|
||||
|
||||
func (t *FormatDate) UnmarshalJSON(data []byte) error {
|
||||
str := string(data)
|
||||
if str == "null" {
|
||||
return nil
|
||||
}
|
||||
t1, err := time.ParseInLocation(timeFormat, strings.Trim(str, "\""), time.Local)
|
||||
*t = FormatDate{t1}
|
||||
return err
|
||||
}
|
30
agent/internal/routers/api_router.go
Normal file
30
agent/internal/routers/api_router.go
Normal file
@ -0,0 +1,30 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
controllerV1 "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/controller/v1"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func setApiRoute(r *gin.Engine) {
|
||||
// version 1
|
||||
v1 := r.Group("/api/v1")
|
||||
{
|
||||
//v1.POST("/login", controllerV1.Login)
|
||||
//v1.GET("/host/info", controllerV1.GetAssertInfo)
|
||||
|
||||
v1.POST("/asset", controllerV1.AssetInformationEntry)
|
||||
v1.POST("/shutdown", controllerV1.Shutdown)
|
||||
|
||||
v1.GET("/host/compose", controllerV1.GetComponentInfo)
|
||||
|
||||
v1.GET("/log/agent", controllerV1.GetAgentLog)
|
||||
v1.GET("/log/agent/upgrade", controllerV1.GetAgentUpgradeLog)
|
||||
v1.GET("/log/telegraf", controllerV1.GetTelegrafLog)
|
||||
|
||||
v1.POST("/telegraf/config", controllerV1.UpdateTelegrafConfig)
|
||||
v1.POST("/telegraf/config/recover", controllerV1.RecoverConfig)
|
||||
|
||||
v1.GET("/agent/download", controllerV1.DownloadAgent)
|
||||
|
||||
}
|
||||
}
|
75
agent/internal/routers/router.go
Normal file
75
agent/internal/routers/router.go
Normal file
@ -0,0 +1,75 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/middleware"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/errors"
|
||||
response2 "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/pkg/response"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func SetRouters() *gin.Engine {
|
||||
var r *gin.Engine
|
||||
|
||||
if config.Config.Debug == false {
|
||||
// 生产模式
|
||||
r = ReleaseRouter()
|
||||
r.Use(
|
||||
middleware.AuthenticationHandler(),
|
||||
middleware.RequestCostHandler(),
|
||||
middleware.CustomLogger(),
|
||||
middleware.CustomRecovery(),
|
||||
middleware.CorsHandler(),
|
||||
middleware.AppContextHandler(),
|
||||
middleware.AuthorizationHandler(),
|
||||
)
|
||||
} else {
|
||||
// 开发调试模式
|
||||
r = gin.New()
|
||||
r.Use(
|
||||
//gin.Logger(),
|
||||
middleware.AuthenticationHandler(),
|
||||
middleware.RequestCostHandler(),
|
||||
middleware.CustomLogger(),
|
||||
middleware.CustomRecovery(),
|
||||
middleware.CorsHandler(),
|
||||
middleware.AppContextHandler(),
|
||||
middleware.AuthorizationHandler(),
|
||||
)
|
||||
}
|
||||
//// set up trusted agents
|
||||
//err := r.SetTrustedProxies([]string{"127.0.0.1"})
|
||||
//if err != nil {
|
||||
// panic(err)
|
||||
//}
|
||||
|
||||
// ping
|
||||
//r.Any("/ping", func(c *gin.Context) {
|
||||
// c.AbortWithStatusJSON(http.StatusOK, gin.H{
|
||||
// "message": "pong!",
|
||||
// })
|
||||
//})
|
||||
|
||||
// 设置 API 路由
|
||||
setApiRoute(r)
|
||||
|
||||
r.NoRoute(func(c *gin.Context) {
|
||||
response2.Resp().SetHttpCode(http.StatusNotFound).FailCode(c, errors.NotFound)
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// ReleaseRouter 生产模式使用官方建议设置为 release 模式
|
||||
func ReleaseRouter() *gin.Engine {
|
||||
// 切换到生产模式
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
// 禁用 gin 输出接口访问日志
|
||||
gin.DefaultWriter = ioutil.Discard
|
||||
|
||||
engine := gin.New()
|
||||
|
||||
return engine
|
||||
}
|
152
agent/internal/service/component/component.go
Normal file
152
agent/internal/service/component/component.go
Normal file
@ -0,0 +1,152 @@
|
||||
package component
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"strings"
|
||||
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/component"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/go-sysinfo"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/go-sysinfo/types"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
|
||||
telegrafConfig "github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/outputs/http"
|
||||
"github.com/influxdata/telegraf/plugins/outputs/prometheus_client"
|
||||
|
||||
_ "github.com/influxdata/telegraf/plugins/parsers/prometheus"
|
||||
_ "github.com/influxdata/telegraf/plugins/serializers/json"
|
||||
_ "github.com/influxdata/telegraf/plugins/serializers/prometheus"
|
||||
_ "github.com/influxdata/telegraf/plugins/serializers/prometheusremotewrite"
|
||||
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/cpu" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/disk" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/diskio" // register plugin
|
||||
//_ "github.com/influxdata/telegraf/plugins/inputs/all"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/http" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/kernel" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/linux_cpu" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/mem" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/nats" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/net" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/netstat" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/nstat" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/processes" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/swap" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/sysstat" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/system" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/systemd_units" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/win_eventlog" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/win_services" // register plugin
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/wireless" // register plugin
|
||||
)
|
||||
|
||||
func GetComInfo() ([]component.Component, error) {
|
||||
|
||||
var telegrafCom component.Component
|
||||
info, err := GetTelegrafProcessInfo()
|
||||
if err != nil {
|
||||
telegrafCom.COMName = "telegraf"
|
||||
telegrafCom.COMPort = 0
|
||||
telegrafCom.COMType = "telegraf"
|
||||
telegrafCom.COMVersion = "1.28.2"
|
||||
telegrafCom.Status = "0"
|
||||
} else {
|
||||
telegrafCom.COMName = "telegraf"
|
||||
telegrafCom.COMPort = 0
|
||||
telegrafCom.COMType = "telegraf"
|
||||
telegrafCom.COMVersion = "1.28.2"
|
||||
telegrafCom.LastStarttime = info.StartTime
|
||||
telegrafCom.Status = "1"
|
||||
}
|
||||
|
||||
runDirectory, _ := utils.GetCurrentPath()
|
||||
conf := runDirectory + "/data-collector/telegraf/conf/telegraf.conf"
|
||||
|
||||
c := telegrafConfig.NewConfig()
|
||||
err = c.LoadConfig(conf)
|
||||
if err != nil {
|
||||
log.Errorf("读取Telegraf配置失败:%s", err)
|
||||
log.Errorf("读取Telegraf配置失败:%s", conf)
|
||||
|
||||
} else {
|
||||
inputs := c.Inputs
|
||||
for _, input := range inputs {
|
||||
telegrafCom.Config.Metrics = append(telegrafCom.Config.Metrics, input.Config.Name)
|
||||
}
|
||||
|
||||
outputs := c.Outputs
|
||||
for _, output := range outputs {
|
||||
|
||||
prometheusClient, ok := output.Output.(*prometheus_client.PrometheusClient)
|
||||
|
||||
if ok {
|
||||
ms1 := component.MetricServer{
|
||||
Name: output.Config.Name,
|
||||
Address: prometheusClient.Listen + prometheusClient.Path,
|
||||
}
|
||||
telegrafCom.Config.MetricServer = append(telegrafCom.Config.MetricServer, ms1)
|
||||
} else {
|
||||
httpClient, ok := output.Output.(*http.HTTP)
|
||||
if ok {
|
||||
ms2 := component.MetricServer{
|
||||
Name: output.Config.Name,
|
||||
Address: httpClient.URL,
|
||||
}
|
||||
telegrafCom.Config.MetricServer = append(telegrafCom.Config.MetricServer, ms2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
telegrafCom.Config.Tags = c.Tags
|
||||
}
|
||||
|
||||
data := make([]component.Component, 1)
|
||||
data[0] = telegrafCom
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func GetTelegrafProcessInfo() (*types.ProcessInfo, error) {
|
||||
processes, err := sysinfo.Processes()
|
||||
if err != nil {
|
||||
log.Errorf("心跳检测服务调用失败!")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range processes {
|
||||
info, err := process.Info()
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Contains(info.Name, "telegraf") || strings.Contains(info.Name, "Telegraf") {
|
||||
return &info, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("telegraf采集器进程未运行!")
|
||||
}
|
||||
|
||||
func GetProcessExporterProcessInfo() (*types.ProcessInfo, error) {
|
||||
processes, err := sysinfo.Processes()
|
||||
if err != nil {
|
||||
log.Errorf("心跳检测服务调用失败!")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, process := range processes {
|
||||
info, err := process.Info()
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Contains(info.Name, "process-exporter") || strings.Contains(info.Name, "process-exporter") {
|
||||
return &info, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("process-exporte采集器进程未运行!")
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
68
agent/internal/service/component/telegraf.go
Normal file
68
agent/internal/service/component/telegraf.go
Normal file
@ -0,0 +1,68 @@
|
||||
package component
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/boot"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/bin_path"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/log"
|
||||
process_manager "git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/process-manager"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/utils"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
telegrafConfFile = filepath.Join(bin_path.BINDIR, "/data-collector/telegraf/conf/", "telegraf.conf")
|
||||
bakFile = filepath.Join(bin_path.BINDIR, "/data-collector/telegraf/conf/", "telegraf.conf.bak")
|
||||
)
|
||||
|
||||
func UpdateTelegrafConfig(configText []byte) error {
|
||||
// 1.先备份
|
||||
oldConfig, err := os.ReadFile(telegrafConfFile)
|
||||
err = os.WriteFile(bakFile, oldConfig, fs.ModePerm)
|
||||
if err != nil {
|
||||
panic("备份文件失败:" + err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// 2.后替换
|
||||
err = os.WriteFile(telegrafConfFile, configText, fs.ModePerm)
|
||||
|
||||
if err != nil {
|
||||
panic("替换文件失败:" + err.Error())
|
||||
go rollback(false, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 3.再启动,让minit重启
|
||||
utils.StopCh <- os.Interrupt
|
||||
time.Sleep(time.Second * 5)
|
||||
go process_manager.Start(boot.ProcessUnitDir)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RecoverConfig() {
|
||||
config, _ := os.ReadFile(bakFile)
|
||||
os.WriteFile(telegrafConfFile, config, fs.ModePerm)
|
||||
|
||||
utils.StopCh <- os.Interrupt
|
||||
time.Sleep(time.Second * 5)
|
||||
|
||||
go process_manager.Start(boot.ProcessUnitDir)
|
||||
}
|
||||
|
||||
func rollback(needRestart bool, err error) {
|
||||
|
||||
log.Infof("Telegraf配置更新失败: %s", err)
|
||||
config, _ := os.ReadFile(bakFile)
|
||||
os.WriteFile(telegrafConfFile, config, fs.ModePerm)
|
||||
if needRestart {
|
||||
utils.StopCh <- os.Interrupt
|
||||
time.Sleep(time.Second * 5)
|
||||
|
||||
go process_manager.Start(boot.ProcessUnitDir)
|
||||
}
|
||||
|
||||
}
|
102
agent/internal/service/heartbeat_service/heartbeat.go
Normal file
102
agent/internal/service/heartbeat_service/heartbeat.go
Normal file
@ -0,0 +1,102 @@
|
||||
package heartbeat_service
|
||||
|
||||
import (
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/config/agent"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/model/heartbeat"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/internal/service/component"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/go-sysinfo"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/go-sysinfo/providers/shared"
|
||||
"git.inspur.com/sbg-jszt/cfn/cfn-schedule-agent/pkg/go-sysinfo/types"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
agentConfig = agent.Agent
|
||||
commonConfig = config.Config
|
||||
|
||||
AgentState = heartbeat.HeartBeat{
|
||||
AgentVersion: "xxx",
|
||||
IPAddress: "xxx",
|
||||
LastStarttime: time.Now(),
|
||||
MACAddress: "xxx",
|
||||
SerialNo: "xxx",
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
host types.Host
|
||||
ip, mac string
|
||||
)
|
||||
|
||||
func init() {
|
||||
host, _ = sysinfo.Host()
|
||||
ip, mac, _ = shared.NamedNetwork(agentConfig.NetInterface)
|
||||
|
||||
RefreshHeartBeatInfo()
|
||||
}
|
||||
|
||||
// RefreshHeartBeatInfo
|
||||
// 更新心跳信息中的组件信息, 检查Telegraf状态
|
||||
func RefreshHeartBeatInfo() {
|
||||
// 每 15 秒钟时执行一次
|
||||
ticker := time.NewTicker(15 * time.Second)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
// 读取状态 更新状态
|
||||
//0:离线,1:在线,2:故障
|
||||
AgentState.IPAddress = ip
|
||||
AgentState.MACAddress = mac
|
||||
AgentState.SerialNo = agentConfig.RID
|
||||
AgentState.AgentVersion = commonConfig.AgentVersion
|
||||
AgentState.LastStarttime = host.Info().BootTime
|
||||
|
||||
AgentState.Architecture = host.Info().Architecture
|
||||
AgentState.KernelVersion = host.Info().KernelVersion
|
||||
AgentState.OS = host.Info().OS.Type + " " + host.Info().OS.Platform + " " + host.Info().OS.Version
|
||||
AgentState.OSType = strings.ToLower(host.Info().OS.Type)
|
||||
|
||||
telegraf, err := component.GetTelegrafProcessInfo()
|
||||
if err != nil {
|
||||
AgentState.COMInfo = []heartbeat.COMInfo{
|
||||
{
|
||||
Name: "telegraf",
|
||||
LastStarttime: time.Now(),
|
||||
Status: "2",
|
||||
},
|
||||
}
|
||||
} else {
|
||||
AgentState.COMInfo = []heartbeat.COMInfo{
|
||||
{
|
||||
Name: "telegraf",
|
||||
LastStarttime: telegraf.StartTime,
|
||||
Status: "1",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
processExporter, err := component.GetProcessExporterProcessInfo()
|
||||
if err != nil {
|
||||
AgentState.COMInfo = []heartbeat.COMInfo{
|
||||
{
|
||||
Name: "process-exporter",
|
||||
LastStarttime: time.Now(),
|
||||
Status: "2",
|
||||
},
|
||||
}
|
||||
} else {
|
||||
AgentState.COMInfo = []heartbeat.COMInfo{
|
||||
{
|
||||
Name: "process-exporter",
|
||||
LastStarttime: processExporter.StartTime,
|
||||
Status: "1",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user