config.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package config
  2. import (
  3. "fmt"
  4. "os"
  5. "git.linuxforward.com/byom/byom-core/logger"
  6. "gopkg.in/yaml.v3"
  7. )
  8. type Config struct {
  9. Server *Server `yaml:"server"`
  10. Database *Database `yaml:"database"`
  11. Log *Log `yaml:"log"`
  12. Jwt *Jwt `yaml:"jwt"`
  13. Smtp *Smtp `yaml:"smtp"`
  14. Oauth2 *Oauth2 `yaml:"oauth2"`
  15. Hook *Hook `yaml:"hook"`
  16. }
  17. func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
  18. type plain Config
  19. err := unmarshal((*plain)(c))
  20. if err != nil {
  21. return err
  22. }
  23. if c.Server == nil {
  24. return fmt.Errorf("api config is required")
  25. }
  26. return nil
  27. }
  28. type Server struct {
  29. ListeningPort int `yaml:"listening_port"`
  30. TlsConfig *TlsConfig `yaml:"tls"`
  31. Opts []string `yaml:"opts"`
  32. CorsOrigins []string `yaml:"cors_origins"`
  33. RequestTimeout int `yaml:"request_timeout"` // in seconds
  34. }
  35. func (c *Server) UnmarshalYAML(unmarshal func(interface{}) error) error {
  36. type plain Server
  37. err := unmarshal((*plain)(c))
  38. if err != nil {
  39. return err
  40. }
  41. if c.ListeningPort == 0 {
  42. c.ListeningPort = 8443
  43. }
  44. if c.TlsConfig == nil {
  45. return fmt.Errorf("tls is required")
  46. }
  47. if c.TlsConfig.Enabled && (c.CorsOrigins == nil || len(c.CorsOrigins) == 0) {
  48. return fmt.Errorf("cors_origins must be set when TLS is enabled")
  49. }
  50. return nil
  51. }
  52. type TlsConfig struct {
  53. Enabled bool `yaml:"enabled"`
  54. CertFile string `yaml:"cert"`
  55. KeyFile string `yaml:"key"`
  56. }
  57. func (c *TlsConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
  58. type plain TlsConfig
  59. err := unmarshal((*plain)(c))
  60. if err != nil {
  61. return err
  62. }
  63. if c.CertFile == "" && c.Enabled {
  64. return fmt.Errorf("tls cert is required")
  65. }
  66. if c.KeyFile == "" && c.Enabled {
  67. return fmt.Errorf("tls key is required")
  68. }
  69. return nil
  70. }
  71. type Smtp struct {
  72. Host string `yaml:"host"`
  73. Port int `yaml:"port"`
  74. User string `yaml:"user"`
  75. Pass string `yaml:"pass"`
  76. }
  77. func (c *Smtp) UnmarshalYAML(unmarshal func(interface{}) error) error {
  78. type plain Smtp
  79. err := unmarshal((*plain)(c))
  80. if err != nil {
  81. return err
  82. }
  83. // if c.Host == "" {
  84. // return fmt.Errorf("smtp host is required")
  85. // }
  86. // if c.Port == 0 {
  87. // c.Port = 587
  88. // }
  89. // if c.User == "" {
  90. // return fmt.Errorf("smtp user is required")
  91. // }
  92. // if c.Pass == "" {
  93. // return fmt.Errorf("smtp pass is required")
  94. // }
  95. return nil
  96. }
  97. type Database struct {
  98. Path string `yaml:"path"`
  99. LogMode bool `yaml:"log_mode"`
  100. MaxOpenConns int `yaml:"max_open_conns"`
  101. MaxIdleConns int `yaml:"max_idle_conns"`
  102. ConnMaxLifetime int `yaml:"conn_max_lifetime"`
  103. Pragma []string `yaml:"pragma"`
  104. }
  105. func (c *Database) UnmarshalYAML(unmarshal func(interface{}) error) error {
  106. type plain Database
  107. err := unmarshal((*plain)(c))
  108. if err != nil {
  109. return err
  110. }
  111. if c.Path == "" {
  112. return fmt.Errorf("database path is required")
  113. }
  114. if c.MaxOpenConns == 0 {
  115. c.MaxOpenConns = 10
  116. }
  117. if c.MaxIdleConns == 0 {
  118. c.MaxIdleConns = 5
  119. }
  120. if c.ConnMaxLifetime == 0 {
  121. c.ConnMaxLifetime = 300
  122. }
  123. return nil
  124. }
  125. type Jwt struct {
  126. JwtSecret string `yaml:"jwt_secret"`
  127. }
  128. func (c *Jwt) UnmarshalYAML(unmarshal func(interface{}) error) error {
  129. type plain Jwt
  130. err := unmarshal((*plain)(c))
  131. if err != nil {
  132. return err
  133. }
  134. if c.JwtSecret == "" {
  135. return fmt.Errorf("jwt secret is required")
  136. }
  137. return nil
  138. }
  139. type Oauth2 struct {
  140. ClientID string `yaml:"client_id"`
  141. ClientSecret string `yaml:"client_secret"`
  142. RedirectURL string `yaml:"redirect_url"`
  143. AuthURL string `yaml:"auth_url"`
  144. TokenURL string `yaml:"token_url"`
  145. UserInfoURL string `yaml:"user_info_url"`
  146. }
  147. func (c *Oauth2) UnmarshalYAML(unmarshal func(interface{}) error) error {
  148. type plain Oauth2
  149. err := unmarshal((*plain)(c))
  150. if err != nil {
  151. return err
  152. }
  153. if c.ClientID == "" {
  154. return fmt.Errorf("client id is required")
  155. }
  156. if c.ClientSecret == "" {
  157. return fmt.Errorf("client secret is required")
  158. }
  159. if c.RedirectURL == "" {
  160. return fmt.Errorf("redirect url is required")
  161. }
  162. if c.AuthURL == "" {
  163. return fmt.Errorf("auth url is required")
  164. }
  165. if c.TokenURL == "" {
  166. return fmt.Errorf("token url is required")
  167. }
  168. if c.UserInfoURL == "" {
  169. return fmt.Errorf("user info url is required")
  170. }
  171. return nil
  172. }
  173. type Log struct {
  174. Level string `yaml:"level"`
  175. NoColor bool `yaml:"no_color"`
  176. ForceColors bool `yaml:"force_colors"`
  177. InJson bool `yaml:"in_json"`
  178. FilterComponents []string `yaml:"filter_components"`
  179. }
  180. func (c *Log) UnmarshalYAML(unmarshal func(interface{}) error) error {
  181. type plain Log
  182. err := unmarshal((*plain)(c))
  183. if err != nil {
  184. return err
  185. }
  186. return logger.Configure(c.Level, c.NoColor, c.ForceColors, c.InJson)
  187. }
  188. type Hook struct {
  189. BaseURL string `yaml:"base_url"`
  190. Domain string `yaml:"domain"`
  191. SecretKey string `yaml:"secret_key"`
  192. }
  193. func ReadConfig(configPath string) (*Config, error) {
  194. cnf := &Config{}
  195. b, err := os.ReadFile(configPath)
  196. if err != nil {
  197. return nil, err
  198. }
  199. err = yaml.Unmarshal(b, cnf)
  200. if err != nil {
  201. return nil, err
  202. }
  203. return cnf, nil
  204. }