feat(license): dual-path opsx-licence client alongside HMAC

Wire LIC-/LICOFF- activate/verify/heartbeat to licence.rlwj.cn/api,
keep legacy HMAC accepted with deprecation banner, add instance_id
fingerprint and licensing docs (product lokistack still needs admin create).
This commit is contained in:
opsx committed 2026-11-01 02:55:37 +08:00
1 parent 5f42d9f696
commit af0298e994
13 files changed
+888 -37

No files matched your search

+47 -16
View File
@@ -17,14 +17,15 @@ var (
)
type Config struct {
ServerPort string
DatabasePath string
JWTSecret string
EncryptionKey string // 独立加密密钥,必须与JWT_SECRET分离
DataDir string
KubeDir string
LogLevel string // 新增:日志级别 debug/info/warn/error
HostKeyDir string // 新增:SSH主机密钥存储目录
ServerPort string
DatabasePath string
JWTSecret string
EncryptionKey string // 独立加密密钥,必须与JWT_SECRET分离
DataDir string
KubeDir string
LogLevel string // 新增:日志级别 debug/info/warn/error
HostKeyDir string // 新增:SSH主机密钥存储目录
LicenseAPIBase string // opsx-licence API 根(须以 /api 结尾)
}
// resolveSecrets 密钥解析(所有部署形态统一的零配置体验):
@@ -88,14 +89,15 @@ func GetConfig() *Config {
}
instance = &Config{
ServerPort: getEnv("SERVER_PORT", "8080"),
DatabasePath: databasePath(dataDir),
JWTSecret: jwtSecret,
EncryptionKey: encKey,
DataDir: dataDir,
KubeDir: filepath.Join(dataDir, "kubeconfigs"),
LogLevel: getEnv("LOG_LEVEL", "info"),
HostKeyDir: filepath.Join(dataDir, "known_hosts"),
ServerPort: getEnv("SERVER_PORT", "8080"),
DatabasePath: databasePath(dataDir),
JWTSecret: jwtSecret,
EncryptionKey: encKey,
DataDir: dataDir,
KubeDir: filepath.Join(dataDir, "kubeconfigs"),
LogLevel: getEnv("LOG_LEVEL", "info"),
HostKeyDir: filepath.Join(dataDir, "known_hosts"),
LicenseAPIBase: resolveLicenseAPIBase(),
}
_ = os.MkdirAll(instance.KubeDir, 0700)
@@ -104,6 +106,35 @@ func GetConfig() *Config {
return instance
}
// resolveLicenseAPIBase 国内主节点默认;LICENSE_API_BASE / OPSX_LICENSE_API_BASE 可覆盖。
// 备灾节点 l123 不写死进默认路径,需显式配置。
func resolveLicenseAPIBase() string {
for _, key := range []string{"LICENSE_API_BASE", "OPSX_LICENSE_API_BASE"} {
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
return normalizeLicenseAPIBase(v)
}
}
return "https://licence.rlwj.cn/api"
}
func normalizeLicenseAPIBase(raw string) string {
base := strings.TrimRight(strings.TrimSpace(raw), "/")
if base == "" {
return "https://licence.rlwj.cn/api"
}
if strings.HasSuffix(base, "/api/v1") {
return strings.TrimSuffix(base, "/v1")
}
if strings.HasSuffix(base, "/v1") && !strings.HasSuffix(base, "/api/v1") {
return strings.TrimSuffix(base, "/v1") + "/api"
}
if !strings.HasSuffix(base, "/api") {
return base + "/api"
}
return base
}
func getEnv(key, defaultVal string) string {
if val := os.Getenv(key); val != "" {
return val