@@ -2,61 +2,25 @@ package config
22
33import (
44 "encoding/json"
5+ "fmt"
56 "os"
6- "os/exec"
7- "path/filepath"
7+ "strconv"
88 "strings"
9- )
10-
11- var configFile * appConfig
12-
13- func getExcPath () string {
14- file , _ := exec .LookPath (os .Args [0 ])
15- // 获取包含可执行文件名称的路径
16- path , _ := filepath .Abs (file )
17- // 获取可执行文件所在目录
18- index := strings .LastIndex (path , string (os .PathSeparator ))
19- ret := path [:index ]
20- return strings .Replace (ret , "\\ " , "/" , - 1 )
21- }
22-
23- func GetConfig () appConfig {
24- if configFile != nil {
25- return * configFile
26- }
27- path := getExcPath ()
28- var mode modeConfig = readJson [modeConfig ](path + "/config/app.json" )
29-
30- appConfig := readJson [appConfig ](path + "/config/app." + mode .Mode + ".json" )
31- configFile = & appConfig
32- return * configFile
33- }
34-
35- func readJson [T any ](path string ) T {
36- file , err := os .Open (path )
37- if err != nil {
38- panic (path + " config not found" )
39- }
40- defer file .Close ()
41- decoder := json .NewDecoder (file )
9+ "sync"
4210
43- var jsonF T
44- decoder .Decode (& jsonF )
45- return jsonF
46- }
47-
48- type modeConfig struct {
49- Mode string
50- }
11+ "github.com/go-playground/validator/v10"
12+ )
5113
5214type appConfig struct {
5315 DBUser dbConfig
5416 Redis redisConfig
5517 CodePush codePush
5618 UrlPrefix string
5719 Port string
58- ResourceUrl string
20+ ResourceUrl string `json:"resource_url" validate:"required"`
5921 TokenExpireTime int64
22+ Environment string `json:"environment" validate:"required"`
23+ TenantName string `json:"tenant_name" validate:"required"`
6024}
6125type dbConfig struct {
6226 Write dbConfigObj
@@ -65,38 +29,196 @@ type dbConfig struct {
6529 ConnMaxLifetime uint
6630}
6731type dbConfigObj struct {
68- UserName string
69- Password string
70- Host string
71- Port uint
72- DBname string
32+ UserName string `json:"db_username" validate:"required"`
33+ Password string `json:"db_password" validate:"required"`
34+ Host string `json:"db_host" validate:"required"`
35+ Port uint `json:"db_port" validate:"required"`
36+ DBname string `json:"db_name" validate:"required"`
7337}
7438type redisConfig struct {
75- Host string
76- Port uint
77- DBIndex uint
78- UserName string
79- Password string
39+ Host string `json:"redis_host" validate:"required"`
40+ Port uint `json:"redis_port" validate:"required"`
41+ DBIndex uint `json:"redis_db_index"`
42+ UserName string `json:"redis_username"`
43+ Password string `json:"redis_password"`
8044}
8145type codePush struct {
82- FileLocal string
46+ FileLocal string `json:"build_save_location" validate:"required"`
8347 Local localConfig
8448 Aws awsConfig
8549 Ftp ftpConfig
8650}
8751type awsConfig struct {
88- Endpoint string
89- Region string
90- S3ForcePathStyle bool
91- KeyId string
92- Secret string
93- Bucket string
52+ Endpoint string `json:"aws_s3_endpoint" validate:"required"`
53+ Region string `json:"aws_region" validate:"required"`
54+ S3ForcePathStyle bool `json:"aws_s3_force_path_style" validate:"required"`
55+ KeyId string `json:"aws_access_key_id" validate:"required"`
56+ Secret string `json:"aws_secret_access_key" validate:"required"`
57+ Bucket string `json:"aws_s3_bucket_name" validate:"required"`
9458}
9559type ftpConfig struct {
96- ServerUrl string
97- UserName string
98- Password string
60+ ServerUrl string `json:"ftp_server_url"`
61+ UserName string `json:"ftp_username"`
62+ Password string `ftp_password`
9963}
10064type localConfig struct {
101- SavePath string
65+ SavePath string `json:"local_build_save_path"`
66+ }
67+
68+ var config * appConfig
69+ var once sync.Once
70+
71+ func GetConfig () * appConfig {
72+ once .Do (func () {
73+ config = LoadConfig ()
74+ })
75+ return config
76+ }
77+
78+ func LoadConfig () * appConfig {
79+ fmt .Println ("Fetching config from AWS secret manager..." )
80+ keys := []string {
81+ "global" , // Global secrets
82+ "tenant" , // Tendancy punchh-server secrets
83+ "service" , // Email template secrets
84+ "db" , // DB secrets
85+ }
86+
87+ var config appConfig
88+
89+ var dbObj dbConfigObj
90+ var redis redisConfig
91+ var buildSaveLocation codePush
92+ var aws awsConfig
93+ var ftp ftpConfig
94+
95+ // default values
96+ config .DBUser .MaxIdleConns = 5
97+ config .DBUser .MaxOpenConns = 20
98+ config .DBUser .ConnMaxLifetime = 300
99+
100+ config .Port = ":8080"
101+ config .UrlPrefix = "/"
102+ config .ResourceUrl = ""
103+ config .TokenExpireTime = 1 //in days
104+
105+ for _ , key := range keys {
106+ key = key + "_secrets"
107+
108+ data , ok := os .LookupEnv (key )
109+ if ! ok {
110+ fmt .Println ("config: no secrets found for - " , key )
111+ continue
112+ }
113+
114+ secrets := make (map [string ]interface {})
115+ if err := json .Unmarshal ([]byte (data ), & secrets ); err != nil {
116+ fmt .Println ("config: error unmarshalling secrets for - " , key )
117+ panic (err )
118+ }
119+
120+ for k , v := range secrets {
121+ k = strings .ToLower (k )
122+ fmt .Println (k )
123+ // DB
124+ if k == "db_username" {
125+ dbObj .UserName = v .(string )
126+ }
127+ if k == "db_password" {
128+ dbObj .Password = v .(string )
129+ }
130+ if k == "db_host" {
131+ dbObj .Host = v .(string )
132+ }
133+ if k == "db_port" {
134+ u64 , _ := strconv .ParseUint (v .(string ), 10 , 32 )
135+ dbObj .Port = uint (u64 )
136+ }
137+ if k == "db_name" {
138+ dbObj .DBname = v .(string )
139+ }
140+
141+ // Redis
142+ if k == "redis_host" {
143+ redis .Host = v .(string )
144+ }
145+ if k == "redis_port" {
146+ u64 , _ := strconv .ParseUint (v .(string ), 10 , 32 )
147+ redis .Port = uint (u64 )
148+ }
149+ if k == "redis_db_index" {
150+ u64 , _ := strconv .ParseUint (v .(string ), 10 , 32 )
151+ redis .DBIndex = uint (u64 )
152+ }
153+ if k == "redis_username" {
154+ redis .UserName = v .(string )
155+ }
156+ if k == "redis_password" {
157+ redis .Password = v .(string )
158+ }
159+
160+ // local bundle save location
161+ if k == "build_save_location" {
162+ buildSaveLocation .FileLocal = v .(string )
163+ }
164+
165+ // AWS
166+ if k == "aws_s3_endpoint" {
167+ aws .Endpoint = v .(string )
168+ }
169+ if k == "aws_region" {
170+ aws .Region = v .(string )
171+ }
172+ if k == "aws_s3_force_path_style" {
173+ aws .S3ForcePathStyle = true
174+ }
175+ if k == "aws_access_key_id" {
176+ aws .KeyId = v .(string )
177+ }
178+ if k == "aws_secret_access_key" {
179+ aws .Secret = v .(string )
180+ }
181+ if k == "aws_s3_bucket_name" {
182+ aws .Bucket = v .(string )
183+ }
184+
185+ // ftp
186+ if k == "ftp_server_url" {
187+ ftp .ServerUrl = v .(string )
188+ }
189+ if k == "ftp_username" {
190+ ftp .UserName = v .(string )
191+ }
192+ if k == "ftp_password" {
193+ ftp .Password = v .(string )
194+ }
195+ // common
196+
197+ // if build_save_location is set to `local` then resource URL should the self server URL
198+ // if build_save_location is set to `aws` then resource URL should the AWS S3 bucket URL
199+ if k == "resource_url" {
200+ config .ResourceUrl = v .(string )
201+ }
202+ if k == "tenant_name" {
203+ config .TenantName = v .(string )
204+ }
205+
206+ if k == "environment" {
207+ config .Environment = v .(string )
208+ }
209+ }
210+ }
211+ config .DBUser .Write = dbObj
212+ config .Redis = redis
213+ config .CodePush = buildSaveLocation
214+ config .CodePush .Aws = aws
215+ config .CodePush .Ftp = ftp
216+
217+ // validate the config
218+ validate := validator .New ()
219+ if err := validate .Struct (config ); err != nil {
220+ fmt .Println ("config: invalid/missing configuration" , err )
221+ panic (err )
222+ }
223+ return & config
102224}
0 commit comments