- New CLI commands: key, user - New internal modules: auth (middleware, password, user), db (db, logs, products), email, gateway (gateway, hooks, middlewares), handler (admin, auth, dev, log, product, settings), middleware/geoblock, ratelimit - New demo frontend page - Updated config, server, analytics, stats, and existing frontend pages
95 lines
3.4 KiB
Go
95 lines
3.4 KiB
Go
package cmd
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
|
||
"github.com/spf13/cobra"
|
||
"github.com/spf13/viper"
|
||
)
|
||
|
||
var cfgFile string
|
||
|
||
// rootCmd 根命令
|
||
var rootCmd = &cobra.Command{
|
||
Use: "api-server",
|
||
Short: "高性能 API 服务,内置统计分析与运维监控",
|
||
Long: `api-server 是一个基于 Gin 框架的高性能 API 服务程序。
|
||
它内置了请求统计、IP 地理位置分析、并发监控等功能,
|
||
并通过嵌入式前端提供可视化仪表盘。
|
||
|
||
参考设计:sol148-extractor(模块化、CLI 驱动、Session 管理)`,
|
||
Run: func(cmd *cobra.Command, args []string) {
|
||
// 默认显示帮助
|
||
if len(args) == 0 {
|
||
cmd.Help()
|
||
return
|
||
}
|
||
},
|
||
}
|
||
|
||
// Execute 执行 CLI
|
||
func Execute() {
|
||
if err := rootCmd.Execute(); err != nil {
|
||
fmt.Fprintln(os.Stderr, err)
|
||
os.Exit(1)
|
||
}
|
||
}
|
||
|
||
func init() {
|
||
cobra.OnInitialize(initConfig)
|
||
|
||
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "配置文件路径 (YAML/JSON)")
|
||
rootCmd.PersistentFlags().String("host", "0.0.0.0", "监听地址")
|
||
rootCmd.PersistentFlags().IntP("port", "p", 8080, "监听端口")
|
||
rootCmd.PersistentFlags().String("mode", "release", "运行模式 (debug/release/test)")
|
||
rootCmd.PersistentFlags().Bool("geoip", false, "启用 IP 地理位置解析")
|
||
rootCmd.PersistentFlags().String("geoip-db-v4", "./data/ip2region_v4.xdb", "ip2region IPv4 数据库路径")
|
||
rootCmd.PersistentFlags().String("geoip-db-v6", "./data/ip2region_v6.xdb", "ip2region IPv6 数据库路径")
|
||
|
||
viper.BindPFlag("host", rootCmd.PersistentFlags().Lookup("host"))
|
||
viper.BindPFlag("port", rootCmd.PersistentFlags().Lookup("port"))
|
||
viper.BindPFlag("mode", rootCmd.PersistentFlags().Lookup("mode"))
|
||
viper.BindPFlag("geoip", rootCmd.PersistentFlags().Lookup("geoip"))
|
||
viper.BindPFlag("geoip_db_v4", rootCmd.PersistentFlags().Lookup("geoip-db-v4"))
|
||
viper.BindPFlag("geoip_db_v6", rootCmd.PersistentFlags().Lookup("geoip-db-v6"))
|
||
|
||
// Auth / RateLimit flags
|
||
rootCmd.PersistentFlags().Bool("auth-enabled", false, "强制要求 API Key 认证")
|
||
rootCmd.PersistentFlags().Bool("ratelimit-enabled", true, "启用限流")
|
||
rootCmd.PersistentFlags().Int("ratelimit-key-rps", 30, "每 Key 每秒请求数")
|
||
rootCmd.PersistentFlags().Int("ratelimit-key-burst", 60, "每 Key 突发容量")
|
||
rootCmd.PersistentFlags().Int("ratelimit-ip-rps", 10, "每 IP 每秒请求数")
|
||
rootCmd.PersistentFlags().Int("ratelimit-ip-burst", 20, "每 IP 突发容量")
|
||
|
||
viper.BindPFlag("auth_enabled", rootCmd.PersistentFlags().Lookup("auth-enabled"))
|
||
viper.BindPFlag("ratelimit_enabled", rootCmd.PersistentFlags().Lookup("ratelimit-enabled"))
|
||
viper.BindPFlag("ratelimit_key_rps", rootCmd.PersistentFlags().Lookup("ratelimit-key-rps"))
|
||
viper.BindPFlag("ratelimit_key_burst", rootCmd.PersistentFlags().Lookup("ratelimit-key-burst"))
|
||
viper.BindPFlag("ratelimit_ip_rps", rootCmd.PersistentFlags().Lookup("ratelimit-ip-rps"))
|
||
viper.BindPFlag("ratelimit_ip_burst", rootCmd.PersistentFlags().Lookup("ratelimit-ip-burst"))
|
||
|
||
// 添加子命令
|
||
rootCmd.AddCommand(serveCmd)
|
||
rootCmd.AddCommand(versionCmd)
|
||
rootCmd.AddCommand(keyCmd)
|
||
rootCmd.AddCommand(userCmd)
|
||
}
|
||
|
||
func initConfig() {
|
||
if cfgFile != "" {
|
||
viper.SetConfigFile(cfgFile)
|
||
} else {
|
||
viper.SetConfigName("config")
|
||
viper.SetConfigType("yaml")
|
||
viper.AddConfigPath(".")
|
||
viper.AddConfigPath("./config")
|
||
}
|
||
|
||
viper.AutomaticEnv()
|
||
|
||
if err := viper.ReadInConfig(); err == nil {
|
||
fmt.Fprintf(os.Stderr, "使用配置文件: %s\n", viper.ConfigFileUsed())
|
||
}
|
||
}
|