소스 검색

踢出gin

qdy 2 달 전
부모
커밋
2d72042d54
6개의 변경된 파일601개의 추가작업 그리고 75개의 파일을 삭제
  1. 120
    59
      config/config.go
  2. 15
    15
      gct.sh
  3. 61
    1
      go.mod
  4. 228
    0
      go.sum
  5. 89
    0
      micro/service.go
  6. 88
    0
      myMiddleware/authMiddleware.go

+ 120
- 59
config/config.go 파일 보기

@@ -9,58 +9,48 @@ import (
9 9
 	"gopkg.in/yaml.v2"
10 10
 )
11 11
 
12
+// ==================== 配置结构体定义 ====================
13
+
12 14
 // Config 应用配置
13 15
 type Config struct {
14 16
 	Database DBConfig       `yaml:"database"`
15 17
 	Redis    RedisConfig    `yaml:"redis"`
16 18
 	Doris    DorisConfig    `yaml:"doris"`
17
-	RabbitMQ RabbitMQConfig `yaml:"rabbitmq"` // 新增 RabbitMQ 配置
19
+	RabbitMQ RabbitMQConfig `yaml:"rabbitmq"`
18 20
 	Auth     Auth           `yaml:"auth"`
19 21
 	Service  Service        `yaml:"service"`
20 22
 	HTTP     HTTPConfig     `yaml:"http"`
23
+	Micro    MicroConfig    `yaml:"micro"` // Go Micro配置
21 24
 }
22 25
 
26
+// ==================== 各个组件的配置结构 ====================
27
+
23 28
 // RabbitMQConfig RabbitMQ配置
24 29
 type RabbitMQConfig struct {
25
-	// 连接配置
26
-	Host     string `yaml:"host"`
27
-	Port     int    `yaml:"port"`
28
-	Username string `yaml:"username"`
29
-	Password string `yaml:"password"`
30
-	Vhost    string `yaml:"vhost"`
31
-
32
-	// TLS配置
33
-	UseTLS   bool   `yaml:"use_tls"`
34
-	CACert   string `yaml:"ca_cert"`
35
-	CertFile string `yaml:"cert_file"`
36
-	KeyFile  string `yaml:"key_file"`
37
-
38
-	// 连接池和超时配置
39
-	MaxOpenChannels      int `yaml:"max_open_channels"`      // 最大通道数
40
-	ReconnectDelay       int `yaml:"reconnect_delay"`        // 重连延迟(毫秒)
41
-	MaxReconnectAttempts int `yaml:"max_reconnect_attempts"` // 最大重试次数
42
-
43
-	// 心跳和超时
44
-	Heartbeat   int `yaml:"heartbeat"`    // 心跳间隔(秒)
45
-	ChannelSize int `yaml:"channel_size"` // 通道缓冲区大小
46
-
47
-	// 队列和交换机默认配置
48
-	DefaultExchange string `yaml:"default_exchange"`
49
-	DefaultQueue    string `yaml:"default_queue"`
50
-
51
-	// 消息确认模式
52
-	AutoAck   bool `yaml:"auto_ack"`
53
-	Mandatory bool `yaml:"mandatory"`
54
-	Immediate bool `yaml:"immediate"`
55
-
56
-	// QoS配置
57
-	PrefetchCount int  `yaml:"prefetch_count"` // 预取数量
58
-	PrefetchSize  int  `yaml:"prefetch_size"`  // 预取大小(字节)
59
-	Global        bool `yaml:"global"`         // 是否是全局QoS
60
-
61
-	// 发布确认
62
-	PublisherConfirms bool `yaml:"publisher_confirms"` // 是否启用发布者确认
63
-	ConfirmTimeout    int  `yaml:"confirm_timeout"`    // 确认超时(秒)
30
+	Host                 string `yaml:"host"`
31
+	Port                 int    `yaml:"port"`
32
+	Username             string `yaml:"username"`
33
+	Password             string `yaml:"password"`
34
+	Vhost                string `yaml:"vhost"`
35
+	UseTLS               bool   `yaml:"use_tls"`
36
+	CACert               string `yaml:"ca_cert"`
37
+	CertFile             string `yaml:"cert_file"`
38
+	KeyFile              string `yaml:"key_file"`
39
+	MaxOpenChannels      int    `yaml:"max_open_channels"`
40
+	ReconnectDelay       int    `yaml:"reconnect_delay"`
41
+	MaxReconnectAttempts int    `yaml:"max_reconnect_attempts"`
42
+	Heartbeat            int    `yaml:"heartbeat"`
43
+	ChannelSize          int    `yaml:"channel_size"`
44
+	DefaultExchange      string `yaml:"default_exchange"`
45
+	DefaultQueue         string `yaml:"default_queue"`
46
+	AutoAck              bool   `yaml:"auto_ack"`
47
+	Mandatory            bool   `yaml:"mandatory"`
48
+	Immediate            bool   `yaml:"immediate"`
49
+	PrefetchCount        int    `yaml:"prefetch_count"`
50
+	PrefetchSize         int    `yaml:"prefetch_size"`
51
+	Global               bool   `yaml:"global"`
52
+	PublisherConfirms    bool   `yaml:"publisher_confirms"`
53
+	ConfirmTimeout       int    `yaml:"confirm_timeout"`
64 54
 }
65 55
 
66 56
 // HTTPConfig HTTP客户端配置
@@ -124,6 +114,8 @@ type Auth struct {
124 114
 // Service 微服务配置
125 115
 type Service struct {
126 116
 	ServiceName    string `yaml:"service_name"`
117
+	ServiceVersion string `yaml:"service_version"`
118
+	ServiceTag     string `yaml:"service_tags"`
127 119
 	Port           int    `yaml:"port"`
128 120
 	ReadTimeout    int    `yaml:"read_timeout"`
129 121
 	WriteTimeout   int    `yaml:"write_timeout"`
@@ -131,28 +123,61 @@ type Service struct {
131 123
 	TrustedProxies string `yaml:"trusted_proxies"`
132 124
 }
133 125
 
134
-// 导出接口,防止外部修改
126
+// MicroConfig Go Micro微服务配置
127
+type MicroConfig struct {
128
+	RegistryAddress string `yaml:"registry_address"`
129
+	RegistryType    string `yaml:"registry_type"`
130
+	RegistryTimeout int    `yaml:"registry_timeout"`
131
+	LBStrategy      string `yaml:"lb_strategy"`
132
+	LBCacheTTL      int    `yaml:"lb_cache_ttl"`
133
+	LBRetries       int    `yaml:"lb_retries"`
134
+	ClientTimeout   int    `yaml:"client_timeout"`
135
+	ClientPoolSize  int    `yaml:"client_pool_size"`
136
+	MaxRetries      int    `yaml:"max_retries"`
137
+	CircuitEnabled  bool   `yaml:"circuit_enabled"`
138
+	CircuitTimeout  int    `yaml:"circuit_timeout"`
139
+	ErrorThreshold  int    `yaml:"error_threshold"`
140
+	SleepWindow     int    `yaml:"sleep_window"`
141
+	HealthPath      string `yaml:"health_path"`
142
+	HealthInterval  int    `yaml:"health_interval"`
143
+	HealthTimeout   int    `yaml:"health_timeout"`
144
+	LogLevel        string `yaml:"log_level"`
145
+	EnableDebug     bool   `yaml:"enable_debug"`
146
+	MetricsEnabled  bool   `yaml:"metrics_enabled"`
147
+	MetricsAddress  string `yaml:"metrics_address"`
148
+	TracerEnabled   bool   `yaml:"tracer_enabled"`
149
+	TracerAddress   string `yaml:"tracer_address"`
150
+}
151
+
152
+// ==================== 配置接口定义 ====================
153
+
154
+// IConfig 配置接口
135 155
 type IConfig interface {
136 156
 	GetDatabase() DBConfig
137 157
 	GetRedis() RedisConfig
138 158
 	GetDoris() DorisConfig
139
-	GetRabbitMQ() RabbitMQConfig // 新增获取RabbitMQ配置方法
159
+	GetRabbitMQ() RabbitMQConfig
140 160
 	GetAuth() Auth
141 161
 	GetService() Service
142 162
 	GetHTTP() HTTPConfig
163
+	GetMicro() MicroConfig
164
+
143 165
 	IsDatabaseConfigured() bool
144 166
 	IsRedisConfigured() bool
145 167
 	IsDorisConfigured() bool
146
-	IsRabbitMQConfigured() bool // 新增检查RabbitMQ配置方法
168
+	IsRabbitMQConfigured() bool
147 169
 	IsHTTPConfigured() bool
148 170
 	IsAuthConfigured() bool
171
+	IsMicroConfigured() bool
149 172
 }
150 173
 
151
-// 实现接口的具体类型
174
+// configWrapper 配置包装器
152 175
 type configWrapper struct {
153 176
 	config *Config
154 177
 }
155 178
 
179
+// ==================== 接口实现 ====================
180
+
156 181
 func (cw *configWrapper) GetDatabase() DBConfig {
157 182
 	return cw.config.Database
158 183
 }
@@ -181,6 +206,10 @@ func (cw *configWrapper) GetHTTP() HTTPConfig {
181 206
 	return cw.config.HTTP
182 207
 }
183 208
 
209
+func (cw *configWrapper) GetMicro() MicroConfig {
210
+	return cw.config.Micro
211
+}
212
+
184 213
 func (cw *configWrapper) IsDatabaseConfigured() bool {
185 214
 	db := cw.config.Database
186 215
 	return db.Type != "" &&
@@ -202,7 +231,6 @@ func (cw *configWrapper) IsDorisConfigured() bool {
202 231
 
203 232
 func (cw *configWrapper) IsRabbitMQConfigured() bool {
204 233
 	rabbit := cw.config.RabbitMQ
205
-	// 基础连接配置检查
206 234
 	return rabbit.Host != "" && rabbit.Port > 0
207 235
 }
208 236
 
@@ -215,6 +243,13 @@ func (cw *configWrapper) IsAuthConfigured() bool {
215 243
 	return cw.config.Auth.Token != ""
216 244
 }
217 245
 
246
+func (cw *configWrapper) IsMicroConfigured() bool {
247
+	micro := cw.config.Micro
248
+	return micro.RegistryAddress != ""
249
+}
250
+
251
+// ==================== 单例和全局变量 ====================
252
+
218 253
 var (
219 254
 	instance IConfig
220 255
 	once     sync.Once
@@ -240,7 +275,9 @@ func GetInitError() error {
240 275
 	return initErr
241 276
 }
242 277
 
243
-// loadConfig 加载配置文件
278
+// ==================== 配置文件加载 ====================
279
+
280
+// loadConfig 加载配置文件(整合所有默认值)
244 281
 func loadConfig() (*Config, error) {
245 282
 	configFile, err := findConfigFile()
246 283
 	if err != nil {
@@ -249,7 +286,7 @@ func loadConfig() (*Config, error) {
249 286
 
250 287
 	fmt.Printf("✅ Using config file: %s\n", configFile)
251 288
 
252
-	// 创建带默认值的配置
289
+	// 创建带默认值的配置
253 290
 	config := &Config{
254 291
 		Service: Service{
255 292
 			ServiceName:    "myService",
@@ -294,24 +331,48 @@ func loadConfig() (*Config, error) {
294 331
 			Vhost:                "/",
295 332
 			UseTLS:               false,
296 333
 			MaxOpenChannels:      10,
297
-			ReconnectDelay:       5000, // 5秒
298
-			MaxReconnectAttempts: 10,   // 最多重试10次
299
-			Heartbeat:            30,   // 30秒心跳
334
+			ReconnectDelay:       5000,
335
+			MaxReconnectAttempts: 10,
336
+			Heartbeat:            30,
300 337
 			ChannelSize:          100,
301 338
 			DefaultExchange:      "amq.direct",
302 339
 			DefaultQueue:         "",
303
-			AutoAck:              false, // 默认手动确认
340
+			AutoAck:              false,
304 341
 			Mandatory:            false,
305 342
 			Immediate:            false,
306
-			PrefetchCount:        1, // 一次预取1条消息
343
+			PrefetchCount:        1,
307 344
 			PrefetchSize:         0,
308 345
 			Global:               false,
309
-			PublisherConfirms:    false, // 默认不启用发布确认
310
-			ConfirmTimeout:       30,    // 5秒确认超时
346
+			PublisherConfirms:    false,
347
+			ConfirmTimeout:       30,
348
+		},
349
+		Micro: MicroConfig{
350
+			RegistryAddress: "localhost:8500",
351
+			RegistryType:    "consul",
352
+			RegistryTimeout: 10,
353
+			LBStrategy:      "roundrobin",
354
+			LBCacheTTL:      30,
355
+			LBRetries:       3,
356
+			ClientTimeout:   30,
357
+			ClientPoolSize:  100,
358
+			MaxRetries:      3,
359
+			CircuitEnabled:  true,
360
+			CircuitTimeout:  60,
361
+			ErrorThreshold:  5,
362
+			SleepWindow:     5000,
363
+			HealthPath:      "/health",
364
+			HealthInterval:  10,
365
+			HealthTimeout:   5,
366
+			LogLevel:        "info",
367
+			EnableDebug:     false,
368
+			MetricsEnabled:  true,
369
+			MetricsAddress:  ":9090",
370
+			TracerEnabled:   false,
371
+			TracerAddress:   "localhost:6831",
311 372
 		},
312 373
 	}
313 374
 
314
-	// 读取配置文件
375
+	// 读取并解析配置文件
315 376
 	data, err := os.ReadFile(configFile)
316 377
 	if err != nil {
317 378
 		return nil, fmt.Errorf("failed to read config file %s: %v", configFile, err)
@@ -325,9 +386,9 @@ func loadConfig() (*Config, error) {
325 386
 	return config, nil
326 387
 }
327 388
 
328
-// findConfigFile 查找配置文件
389
+// findConfigFile 查找配置文件路径
329 390
 func findConfigFile() (string, error) {
330
-	// 1. 首先尝试可执行文件同目录
391
+	// 1. 可执行文件同目录
331 392
 	exePath, err := os.Executable()
332 393
 	if err == nil {
333 394
 		exeDir := filepath.Dir(exePath)
@@ -337,7 +398,7 @@ func findConfigFile() (string, error) {
337 398
 		}
338 399
 	}
339 400
 
340
-	// 2. 尝试环境变量指定路径
401
+	// 2. 环境变量指定路径
341 402
 	envConfigPath := os.Getenv("DB_CONFIG_PATH")
342 403
 	if envConfigPath != "" {
343 404
 		if _, err := os.Stat(envConfigPath); err == nil {
@@ -346,7 +407,7 @@ func findConfigFile() (string, error) {
346 407
 		return "", fmt.Errorf("DB_CONFIG_PATH file not found: %s", envConfigPath)
347 408
 	}
348 409
 
349
-	// 3. 如果都没有找到,返回错误
410
+	// 3. 未找到配置文件
350 411
 	exeDir := "unknown"
351 412
 	if exePath, err := os.Executable(); err == nil {
352 413
 		exeDir = filepath.Dir(exePath)

+ 15
- 15
gct.sh 파일 보기

@@ -52,18 +52,18 @@ else
52 52
 fi
53 53
 
54 54
 # 检查标签是否已存在
55
-if git rev-parse "$VERSION_TAG" >/dev/null 2>&1; then
56
-    echo "错误: 标签 '$VERSION_TAG' 已经存在。"
57
-    exit 1
58
-fi
55
+#if git rev-parse "$VERSION_TAG" >/dev/null 2>&1; then
56
+ #   echo "错误: 标签 '$VERSION_TAG' 已经存在。"
57
+  #  exit 1
58
+#fi
59 59
 
60 60
 # 创建标签
61
-git tag "$VERSION_TAG"
62
-if [ $? -ne 0 ]; then
63
-    echo "错误: 创建标签失败。"
64
-    exit 1
65
-fi
66
-echo "✅ 标签 '$VERSION_TAG' 已创建"
61
+#git tag "$VERSION_TAG"
62
+#if [ $? -ne 0 ]; then
63
+#    echo "错误: 创建标签失败。"
64
+#    exit 1
65
+#fi
66
+#echo "✅ 标签 '$VERSION_TAG' 已创建"
67 67
 
68 68
 # 推送到远程仓库并推送标签
69 69
 echo "正在推送到远程仓库..."
@@ -73,10 +73,10 @@ if [ $? -ne 0 ]; then
73 73
     exit 1
74 74
 fi
75 75
 
76
-git push origin "$VERSION_TAG"
77
-if [ $? -ne 0 ]; then
78
-    echo "错误: 推送标签失败。"
79
-    exit 1
80
-fi
76
+#git push origin "$VERSION_TAG"
77
+#if [ $? -ne 0 ]; then
78
+#    echo "错误: 推送标签失败。"
79
+#    exit 1
80
+#fi
81 81
 
82 82
 echo "✅ 完成!提交已推送,版本标签 $VERSION_TAG 已创建并推送。"

+ 61
- 1
go.mod 파일 보기

@@ -2,4 +2,64 @@ module git.x2erp.com/qdy/go-base
2 2
 
3 3
 go 1.25.4
4 4
 
5
-require gopkg.in/yaml.v2 v2.4.0
5
+require (
6
+	go-micro.dev/v4 v4.11.0
7
+	gopkg.in/yaml.v2 v2.4.0
8
+    github.com/go-micro/plugins/v4/registry/consul v1.0.0
9
+)
10
+
11
+require (
12
+	github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
13
+	github.com/fatih/color v1.9.0 // indirect
14
+	github.com/hashicorp/consul/api v1.9.0 // indirect
15
+	github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
16
+	github.com/hashicorp/go-hclog v0.12.0 // indirect
17
+	github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
18
+	github.com/hashicorp/go-rootcerts v1.0.2 // indirect
19
+	github.com/hashicorp/golang-lru v0.5.1 // indirect
20
+	github.com/hashicorp/serf v0.9.5 // indirect
21
+	github.com/mattn/go-colorable v0.1.8 // indirect
22
+	github.com/mattn/go-isatty v0.0.12 // indirect
23
+	github.com/mitchellh/hashstructure v1.1.0 // indirect
24
+	github.com/mitchellh/mapstructure v1.3.3 // indirect
25
+)
26
+
27
+require (
28
+	github.com/Microsoft/go-winio v0.6.0 // indirect
29
+	github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
30
+	github.com/acomagu/bufpipe v1.0.3 // indirect
31
+	github.com/bitly/go-simplejson v0.5.0 // indirect
32
+	github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
33
+	github.com/emirpasic/gods v1.12.0 // indirect
34
+	github.com/fsnotify/fsnotify v1.6.0 // indirect
35
+	github.com/go-git/gcfg v1.5.0 // indirect
36
+	github.com/go-git/go-billy/v5 v5.3.1 // indirect
37
+	github.com/go-git/go-git/v5 v5.4.2 // indirect
38
+	github.com/go-micro/plugins/v4/registry/consul v1.2.1
39
+	github.com/golang/protobuf v1.5.2 // indirect
40
+	github.com/google/uuid v1.3.0 // indirect
41
+	github.com/imdario/mergo v0.3.12 // indirect
42
+	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
43
+	github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
44
+	github.com/miekg/dns v1.1.43 // indirect
45
+	github.com/mitchellh/go-homedir v1.1.0 // indirect
46
+	github.com/nxadm/tail v1.4.8 // indirect
47
+	github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
48
+	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
49
+	github.com/pkg/errors v0.9.1 // indirect
50
+	github.com/russross/blackfriday/v2 v2.1.0 // indirect
51
+	github.com/sergi/go-diff v1.1.0 // indirect
52
+	github.com/urfave/cli/v2 v2.25.7 // indirect
53
+	github.com/xanzy/ssh-agent v0.3.0 // indirect
54
+	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
55
+	golang.org/x/crypto v0.21.0 // indirect
56
+	golang.org/x/mod v0.9.0 // indirect
57
+	golang.org/x/net v0.23.0 // indirect
58
+	golang.org/x/sync v0.1.0 // indirect
59
+	golang.org/x/sys v0.18.0 // indirect
60
+	golang.org/x/text v0.14.0 // indirect
61
+	golang.org/x/tools v0.7.0 // indirect
62
+	google.golang.org/protobuf v1.28.1 // indirect
63
+	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
64
+	gopkg.in/warnings.v0 v0.1.2 // indirect
65
+)

+ 228
- 0
go.sum 파일 보기

@@ -1,4 +1,232 @@
1
+github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
2
+github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
3
+github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
4
+github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
5
+github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
6
+github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
7
+github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
8
+github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
9
+github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
10
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
11
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
12
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
13
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
14
+github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
15
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
16
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
17
+github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
18
+github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
19
+github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
20
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
21
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
22
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
23
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
24
+github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
25
+github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
26
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
27
+github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
28
+github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
29
+github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
30
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
31
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
32
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
33
+github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
34
+github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
35
+github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
36
+github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
37
+github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
38
+github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
39
+github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
40
+github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
41
+github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
42
+github.com/go-micro/plugins/v4/registry/consul v1.2.1 h1:3wctYMtstwQLCjoJ1HA6mKGGFF1hcdKDv5MzHakB1jE=
43
+github.com/go-micro/plugins/v4/registry/consul v1.2.1/go.mod h1:wTat7/K9XQ+i64VbbcMYFcEwipYfSgJM51HcA/sgsM4=
44
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
45
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
46
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
47
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
48
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
49
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
50
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
51
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
52
+github.com/hashicorp/consul/api v1.9.0 h1:T6dKIWcaihG2c21YUi0BMAHbJanVXiYuz+mPgqxY3N4=
53
+github.com/hashicorp/consul/api v1.9.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
54
+github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
55
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
56
+github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
57
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
58
+github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM=
59
+github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
60
+github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
61
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
62
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
63
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
64
+github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
65
+github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
66
+github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
67
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
68
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
69
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
70
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
71
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
72
+github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
73
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
74
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
75
+github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
76
+github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
77
+github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM=
78
+github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
79
+github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
80
+github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
81
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
82
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
83
+github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
84
+github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
85
+github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
86
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
87
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
88
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
89
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
90
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
91
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
92
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
93
+github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
94
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
95
+github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
96
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
97
+github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
98
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
99
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
100
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
101
+github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
102
+github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
103
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
104
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
105
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
106
+github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
107
+github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
108
+github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
109
+github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
110
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
111
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
112
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
113
+github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0=
114
+github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA=
115
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
116
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
117
+github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
118
+github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
119
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
120
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
121
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
122
+github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
123
+github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
124
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
125
+github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
126
+github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
127
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
128
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
129
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
130
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
131
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
132
+github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
133
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
134
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
135
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
136
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
137
+github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
138
+github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
139
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
140
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
141
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
142
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
143
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
144
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
145
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
146
+github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
147
+github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
148
+github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
149
+github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
150
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
151
+github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
152
+go-micro.dev/v4 v4.11.0 h1:DZ2xcr0pnZJDlp6MJiCLhw4tXRxLw9xrJlPT91kubr0=
153
+go-micro.dev/v4 v4.11.0/go.mod h1:eE/tD53n3KbVrzrWxKLxdkGw45Fg1qaNLWjpJMvIUF4=
154
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
155
+golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
156
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
157
+golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
158
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
159
+golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
160
+golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
161
+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
162
+golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
163
+golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
164
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
165
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
166
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
167
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
168
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
169
+golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
170
+golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
171
+golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
172
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
173
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
174
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
175
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
176
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
177
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
178
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
179
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
180
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
181
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
182
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
183
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
184
+golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
185
+golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
186
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
187
+golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
188
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
189
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
190
+golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
191
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
192
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
193
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
194
+golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
195
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
196
+golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
197
+golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
198
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
199
+golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
200
+golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
201
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
202
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
203
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
204
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
205
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
206
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
207
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
208
+golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
209
+golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
210
+golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
211
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
212
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
213
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
214
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
215
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
216
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
1 217
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
2 218
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
219
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
220
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
221
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
222
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
223
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
224
+gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
225
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
226
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
227
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
228
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
229
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
3 230
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
4 231
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
232
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 89
- 0
micro/service.go 파일 보기

@@ -0,0 +1,89 @@
1
+package micro
2
+
3
+import (
4
+	"fmt"
5
+	"log"
6
+	"time"
7
+
8
+	"git.x2erp.com/qdy/go-base/config"
9
+	"github.com/go-micro/plugins/v4/registry/consul"
10
+	"go-micro.dev/v4/registry"
11
+	"go-micro.dev/v4/web"
12
+)
13
+
14
+// StartWithRegistry starts microservice with registry (e.g., Consul)
15
+func StartWithRegistry(cfg config.IConfig) web.Service {
16
+	// Get service information from config
17
+	serviceConfig := cfg.GetService()
18
+	microConfig := cfg.GetMicro()
19
+
20
+	// 1. Create Consul registry
21
+	consulRegistry := consul.NewRegistry(
22
+		registry.Addrs(microConfig.RegistryAddress),
23
+	)
24
+
25
+	// 2. Create HTTP web service (for external HTTP access)
26
+	service := web.NewService(
27
+		web.Name(serviceConfig.ServiceName),
28
+		web.Version(serviceConfig.ServiceVersion),
29
+		web.Address(fmt.Sprintf(":%d", serviceConfig.Port)),
30
+		web.Registry(consulRegistry),
31
+		web.RegisterTTL(30*time.Second),      // Health check interval
32
+		web.RegisterInterval(20*time.Second), // Registration interval
33
+	)
34
+
35
+	// 3. Initialize service
36
+	service.Init()
37
+
38
+	log.Printf("Microservice started (with registry)")
39
+	log.Printf("   • Service name: %s", serviceConfig.ServiceName)
40
+	log.Printf("   • Version: %s", serviceConfig.ServiceVersion)
41
+	log.Printf("   • Port: %d", serviceConfig.Port)
42
+	log.Printf("   • Registry: %s", microConfig.RegistryAddress)
43
+
44
+	// Run in background
45
+	go func() {
46
+		if err := service.Run(); err != nil {
47
+			log.Printf("Microservice stopped: %v", err)
48
+		}
49
+	}()
50
+
51
+	return service
52
+}
53
+
54
+// StartStandalone starts standalone microservice (not registered to registry)
55
+func StartStandalone(cfg config.IConfig) web.Service {
56
+	// Get service information from config
57
+	serviceConfig := cfg.GetService()
58
+
59
+	// Create HTTP web service (standalone operation)
60
+	service := web.NewService(
61
+		web.Name(serviceConfig.ServiceName),
62
+		web.Version(serviceConfig.ServiceVersion),
63
+		web.Address(fmt.Sprintf(":%d", serviceConfig.Port)),
64
+		// No Registry specified = standalone service
65
+	)
66
+
67
+	// Initialize service
68
+	service.Init()
69
+
70
+	log.Printf("Standalone microservice started")
71
+	log.Printf("	• Service name: %s", serviceConfig.ServiceName)
72
+	log.Printf("	• Version: %s", serviceConfig.ServiceVersion)
73
+	log.Printf("	• Port: %d", serviceConfig.Port)
74
+	log.Printf("	• Mode: Standalone (no service discovery)")
75
+
76
+	// Run in background
77
+	go func() {
78
+		if err := service.Run(); err != nil {
79
+			log.Printf("Microservice stopped: %v", err)
80
+		}
81
+	}()
82
+
83
+	return service
84
+}
85
+
86
+// Start maintains compatibility with original interface, uses registry version by default
87
+func Start(cfg config.IConfig) web.Service {
88
+	return StartWithRegistry(cfg)
89
+}

+ 88
- 0
myMiddleware/authMiddleware.go 파일 보기

@@ -0,0 +1,88 @@
1
+package mymiddleware
2
+
3
+import (
4
+	"encoding/json"
5
+	"net/http"
6
+	"strings"
7
+	"time"
8
+
9
+	"git.x2erp.com/qdy/go-base/types"
10
+)
11
+
12
+// ResponseFormat 响应格式
13
+type ResponseFormat int
14
+
15
+const (
16
+	FormatJSON ResponseFormat = iota
17
+	FormatCSV
18
+)
19
+
20
+// JWT认证中间件(支持指定响应格式)
21
+func JWTAuthMiddleware(next http.Handler) http.Handler {
22
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
23
+		// 从Header获取Authorization
24
+		authHeader := r.Header.Get("Authorization")
25
+
26
+		// 检查Authorization头是否存在
27
+		if authHeader == "" {
28
+			sendAuthError(w, "Authorization header is required", getResponseFormat(r))
29
+			return
30
+		}
31
+
32
+		// 检查Bearer格式
33
+		if !strings.HasPrefix(authHeader, "Bearer ") {
34
+			sendAuthError(w, "Authorization header must start with 'Bearer '", getResponseFormat(r))
35
+			return
36
+		}
37
+
38
+		token := strings.TrimPrefix(authHeader, "Bearer ")
39
+
40
+		// 验证JWT令牌
41
+		if !isValidToken(token) {
42
+			sendAuthError(w, "Invalid token", getResponseFormat(r))
43
+			return
44
+		}
45
+
46
+		// 继续处理请求
47
+		next.ServeHTTP(w, r)
48
+	})
49
+}
50
+
51
+// 根据请求路径判断响应格式
52
+func getResponseFormat(r *http.Request) ResponseFormat {
53
+	path := r.URL.Path
54
+
55
+	// 判断是否为CSV接口(根据你的路由规则)
56
+	if strings.Contains(path, "/csv") || strings.Contains(path, "/export") {
57
+		return FormatCSV
58
+	}
59
+
60
+	// 默认返回JSON格式
61
+	return FormatJSON
62
+}
63
+
64
+// 发送认证错误响应(根据格式)
65
+func sendAuthError(w http.ResponseWriter, message string, format ResponseFormat) {
66
+	w.WriteHeader(http.StatusUnauthorized)
67
+
68
+	switch format {
69
+	case FormatCSV:
70
+		w.Header().Set("Content-Type", "text/csv")
71
+		w.Write([]byte("error,message\n"))
72
+		w.Write([]byte("unauthorized," + message + "\n"))
73
+	default:
74
+		w.Header().Set("Content-Type", "application/json")
75
+		json.NewEncoder(w).Encode(&types.QueryResult{
76
+			Success: false,
77
+			Error:   message,
78
+			Time:    time.Now().Format(time.RFC3339),
79
+		})
80
+	}
81
+}
82
+
83
+// 验证令牌(需要根据实际项目实现)
84
+func isValidToken(token string) bool {
85
+	// TODO: 实现真正的JWT验证逻辑
86
+	// 暂时简化处理
87
+	return token != ""
88
+}

Loading…
취소
저장