Refactor AppConfig and Environment Initialization
- Renamed `appEnv` and `BuildVersion` global variables to a more structured `AppConfig`. - Moved environment variable loading logic to `LoadConfig` function. - Replaced custom parser package with `yaml.v3` for loading YAML configurations. - Moved `GenerateOauthCallbackURL` to be a method of `AppConfig`. - Renamed `OpenYamlFile` to `ParseYAMLFile` to better describe its functionality. - Removed unused `getConfigFile` function and hard-coded paths. - Minor comment and code layout adjustments for better readability.
- commit
- 0905e2acae152634158f7b94c564f11e39e28c58
- author
- bnema · · 2023-10-03 07:20 UTC
- parent
- 8fbd086
- signature
- unsigned
5 files · +34 -31
M internal/app/app.go +31 -27
| @@ -10,13 +10,13 @@ import ( | |||
| 10 | 10 | "github.com/bnema/gordon/internal/gotemplate" | |
| 11 | 11 | "github.com/bnema/gordon/internal/webui" | |
| 12 | 12 | "github.com/bnema/gordon/pkg/utils/docker" | |
| 13 | - | "github.com/bnema/gordon/pkg/utils/parser" | |
| 13 | + | _ "github.com/joho/godotenv/autoload" | |
| 14 | + | "gopkg.in/yaml.v3" | |
| 14 | 15 | ) | |
| 15 | 16 | ||
| 16 | 17 | var ( | |
| 17 | 18 | OauthCallbackURL string | |
| 18 | - | appEnv string | |
| 19 | - | BuildVersion = "0.0.2" | |
| 19 | + | config AppConfig | |
| 20 | 20 | ) | |
| 21 | 21 | ||
| 22 | 22 | type App struct { | |
| @@ -37,9 +37,10 @@ type AppConfig struct { | |||
| 37 | 37 | } | |
| 38 | 38 | ||
| 39 | 39 | type GeneralConfig struct { | |
| 40 | - | RunEnv string `yaml:"runEnv"` | |
| 41 | - | StorageDir string `yaml:"storageDir"` | |
| 40 | + | RunEnv string | |
| 41 | + | BuildDir string | |
| 42 | 42 | BuildVersion string | |
| 43 | + | StorageDir string `yaml:"storageDir"` | |
| 43 | 44 | } | |
| 44 | 45 | ||
| 45 | 46 | type HttpConfig struct { | |
| @@ -59,25 +60,32 @@ type ContainerEngineConfig struct { | |||
| 59 | 60 | Network string `yaml:"network"` | |
| 60 | 61 | } | |
| 61 | 62 | ||
| 62 | - | func InitializeEnvironment() { | |
| 63 | - | config, err := LoadConfig() | |
| 64 | - | if err != nil { | |
| 65 | - | fmt.Errorf("Error initializing environment: %s", err) | |
| 63 | + | func LoadConfig() (AppConfig, error) { | |
| 64 | + | // Load env elements | |
| 65 | + | config.General.BuildVersion = os.Getenv("BUILD_VERSION") | |
| 66 | + | config.General.RunEnv = os.Getenv("RUN_ENV") | |
| 67 | + | config.General.BuildDir = os.Getenv("BUILD_DIR") | |
| 68 | + | ||
| 69 | + | // if RUN_ENV is not set, assume "prod" and config dir is the current dir | |
| 70 | + | if config.General.RunEnv == "" { | |
| 71 | + | config.General.RunEnv = "prod" | |
| 72 | + | config.General.BuildDir = "." | |
| 66 | 73 | } | |
| 67 | - | OauthCallbackURL = GenerateOauthCallbackURL(config) | |
| 68 | - | } | |
| 69 | 74 | ||
| 70 | - | func LoadConfig() (AppConfig, error) { | |
| 71 | - | var config AppConfig | |
| 72 | - | configDir, configFile := getConfigFile() | |
| 73 | - | fsys := os.DirFS(configDir) | |
| 74 | - | err := parser.OpenYamlFile(fsys, configFile, &config) | |
| 75 | + | fmt.Printf("RUN_ENV: %s\n", config.General.RunEnv) | |
| 76 | + | fmt.Printf("BUILD_DIR: %s\n", config.General.BuildDir) | |
| 77 | + | ||
| 78 | + | // Load config file | |
| 79 | + | configFile := fmt.Sprintf("%s/config.yml", config.General.BuildDir) | |
| 80 | + | configData, err := os.ReadFile(configFile) | |
| 75 | 81 | if err != nil { | |
| 76 | 82 | return config, err | |
| 77 | 83 | } | |
| 78 | 84 | ||
| 79 | - | // Set the BuildVersion from the global BuildVersion | |
| 80 | - | config.General.BuildVersion = BuildVersion | |
| 85 | + | err = yaml.Unmarshal(configData, &config) | |
| 86 | + | if err != nil { | |
| 87 | + | return config, err | |
| 88 | + | } | |
| 81 | 89 | ||
| 82 | 90 | return config, nil | |
| 83 | 91 | } | |
| @@ -98,12 +106,11 @@ func NewApp() *App { | |||
| 98 | 106 | Config: config, | |
| 99 | 107 | } | |
| 100 | 108 | ||
| 101 | - | // If you have any other initializations like generating OAuth URL, do them here | |
| 102 | - | OauthCallbackURL = GenerateOauthCallbackURL(config) | |
| 109 | + | OauthCallbackURL = config.GenerateOauthCallbackURL() | |
| 103 | 110 | return a | |
| 104 | 111 | } | |
| 105 | 112 | ||
| 106 | - | // NewDockerConfig creates and returns a new Docker client configuration based on AppConfig. | |
| 113 | + | // NewDockerConfig creates and returns a new Docker client configuration | |
| 107 | 114 | func (config *AppConfig) NewDockerConfig() *docker.Config { | |
| 108 | 115 | if config.ContainerEngine.Podman { | |
| 109 | 116 | return &docker.Config{ | |
| @@ -117,7 +124,8 @@ func (config *AppConfig) NewDockerConfig() *docker.Config { | |||
| 117 | 124 | } | |
| 118 | 125 | } | |
| 119 | 126 | ||
| 120 | - | func GenerateOauthCallbackURL(config AppConfig) string { | |
| 127 | + | // GenerateOauthCallbackURL generates the OAuth callback URL | |
| 128 | + | func (config *AppConfig) GenerateOauthCallbackURL() string { | |
| 121 | 129 | var scheme, port string | |
| 122 | 130 | ||
| 123 | 131 | if config.General.RunEnv == "dev" { | |
| @@ -125,7 +133,7 @@ func GenerateOauthCallbackURL(config AppConfig) string { | |||
| 125 | 133 | port = fmt.Sprintf(":%d", config.Http.Port) | |
| 126 | 134 | } else { // Assuming "prod" | |
| 127 | 135 | scheme = "https" | |
| 128 | - | port = "" // Assuming that HTTPS will run on the default port 443 | |
| 136 | + | port = "" | |
| 129 | 137 | } | |
| 130 | 138 | ||
| 131 | 139 | domain := config.Http.TopDomain | |
| @@ -135,7 +143,3 @@ func GenerateOauthCallbackURL(config AppConfig) string { | |||
| 135 | 143 | ||
| 136 | 144 | return fmt.Sprintf("%s://%s%s%s/login/oauth/callback", scheme, domain, port, config.Admin.Path) | |
| 137 | 145 | } | |
| 138 | - | ||
| 139 | - | func getConfigFile() (string, string) { | |
| 140 | - | return "tmp/", "config.yml" // assuming the file is in the current directory | |
| 141 | - | } | |
| @@ -10,13 +10,13 @@ import ( | |||||
| 10 | "github.com/bnema/gordon/internal/gotemplate" | 10 | "github.com/bnema/gordon/internal/gotemplate" | ||
| 11 | "github.com/bnema/gordon/internal/webui" | 11 | "github.com/bnema/gordon/internal/webui" | ||
| 12 | "github.com/bnema/gordon/pkg/utils/docker" | 12 | "github.com/bnema/gordon/pkg/utils/docker" | ||
| 13 | - | "github.com/bnema/gordon/pkg/utils/parser" | 13 | + | _ "github.com/joho/godotenv/autoload" |
| 14 | + | "gopkg.in/yaml.v3" | |||
| 14 | ) | 15 | ) | ||
| 15 | 16 | ||||
| 16 | var ( | 17 | var ( | ||
| 17 | OauthCallbackURL string | 18 | OauthCallbackURL string | ||
| 18 | - | appEnv string | 19 | + | config AppConfig |
| 19 | - | BuildVersion = "0.0.2" | |||
| 20 | ) | 20 | ) | ||
| 21 | 21 | ||||
| 22 | type App struct { | 22 | type App struct { | ||
| @@ -37,9 +37,10 @@ type AppConfig struct { | |||||
| 37 | } | 37 | } | ||
| 38 | 38 | ||||
| 39 | type GeneralConfig struct { | 39 | type GeneralConfig struct { | ||
| 40 | - | RunEnv string `yaml:"runEnv"` | 40 | + | RunEnv string |
| 41 | - | StorageDir string `yaml:"storageDir"` | 41 | + | BuildDir string |
| 42 | BuildVersion string | 42 | BuildVersion string | ||
| 43 | + | StorageDir string `yaml:"storageDir"` | |||
| 43 | } | 44 | } | ||
| 44 | 45 | ||||
| 45 | type HttpConfig struct { | 46 | type HttpConfig struct { | ||
| @@ -59,25 +60,32 @@ type ContainerEngineConfig struct { | |||||
| 59 | Network string `yaml:"network"` | 60 | Network string `yaml:"network"` | ||
| 60 | } | 61 | } | ||
| 61 | 62 | ||||
| 62 | - | func InitializeEnvironment() { | 63 | + | func LoadConfig() (AppConfig, error) { |
| 63 | - | config, err := LoadConfig() | 64 | + | // Load env elements |
| 64 | - | if err != nil { | 65 | + | config.General.BuildVersion = os.Getenv("BUILD_VERSION") |
| 65 | - | fmt.Errorf("Error initializing environment: %s", err) | 66 | + | config.General.RunEnv = os.Getenv("RUN_ENV") |
| 67 | + | config.General.BuildDir = os.Getenv("BUILD_DIR") | |||
| 68 | + | ||||
| 69 | + | // if RUN_ENV is not set, assume "prod" and config dir is the current dir | |||
| 70 | + | if config.General.RunEnv == "" { | |||
| 71 | + | config.General.RunEnv = "prod" | |||
| 72 | + | config.General.BuildDir = "." | |||
| 66 | } | 73 | } | ||
| 67 | - | OauthCallbackURL = GenerateOauthCallbackURL(config) | |||
| 68 | - | } | |||
| 69 | 74 | ||||
| 70 | - | func LoadConfig() (AppConfig, error) { | 75 | + | fmt.Printf("RUN_ENV: %s\n", config.General.RunEnv) |
| 71 | - | var config AppConfig | 76 | + | fmt.Printf("BUILD_DIR: %s\n", config.General.BuildDir) |
| 72 | - | configDir, configFile := getConfigFile() | 77 | + | |
| 73 | - | fsys := os.DirFS(configDir) | 78 | + | // Load config file |
| 74 | - | err := parser.OpenYamlFile(fsys, configFile, &config) | 79 | + | configFile := fmt.Sprintf("%s/config.yml", config.General.BuildDir) |
| 80 | + | configData, err := os.ReadFile(configFile) | |||
| 75 | if err != nil { | 81 | if err != nil { | ||
| 76 | return config, err | 82 | return config, err | ||
| 77 | } | 83 | } | ||
| 78 | 84 | ||||
| 79 | - | // Set the BuildVersion from the global BuildVersion | 85 | + | err = yaml.Unmarshal(configData, &config) |
| 80 | - | config.General.BuildVersion = BuildVersion | 86 | + | if err != nil { |
| 87 | + | return config, err | |||
| 88 | + | } | |||
| 81 | 89 | ||||
| 82 | return config, nil | 90 | return config, nil | ||
| 83 | } | 91 | } | ||
| @@ -98,12 +106,11 @@ func NewApp() *App { | |||||
| 98 | Config: config, | 106 | Config: config, | ||
| 99 | } | 107 | } | ||
| 100 | 108 | ||||
| 101 | - | // If you have any other initializations like generating OAuth URL, do them here | 109 | + | OauthCallbackURL = config.GenerateOauthCallbackURL() |
| 102 | - | OauthCallbackURL = GenerateOauthCallbackURL(config) | |||
| 103 | return a | 110 | return a | ||
| 104 | } | 111 | } | ||
| 105 | 112 | ||||
| 106 | - | // NewDockerConfig creates and returns a new Docker client configuration based on AppConfig. | 113 | + | // NewDockerConfig creates and returns a new Docker client configuration |
| 107 | func (config *AppConfig) NewDockerConfig() *docker.Config { | 114 | func (config *AppConfig) NewDockerConfig() *docker.Config { | ||
| 108 | if config.ContainerEngine.Podman { | 115 | if config.ContainerEngine.Podman { | ||
| 109 | return &docker.Config{ | 116 | return &docker.Config{ | ||
| @@ -117,7 +124,8 @@ func (config *AppConfig) NewDockerConfig() *docker.Config { | |||||
| 117 | } | 124 | } | ||
| 118 | } | 125 | } | ||
| 119 | 126 | ||||
| 120 | - | func GenerateOauthCallbackURL(config AppConfig) string { | 127 | + | // GenerateOauthCallbackURL generates the OAuth callback URL |
| 128 | + | func (config *AppConfig) GenerateOauthCallbackURL() string { | |||
| 121 | var scheme, port string | 129 | var scheme, port string | ||
| 122 | 130 | ||||
| 123 | if config.General.RunEnv == "dev" { | 131 | if config.General.RunEnv == "dev" { | ||
| @@ -125,7 +133,7 @@ func GenerateOauthCallbackURL(config AppConfig) string { | |||||
| 125 | port = fmt.Sprintf(":%d", config.Http.Port) | 133 | port = fmt.Sprintf(":%d", config.Http.Port) | ||
| 126 | } else { // Assuming "prod" | 134 | } else { // Assuming "prod" | ||
| 127 | scheme = "https" | 135 | scheme = "https" | ||
| 128 | - | port = "" // Assuming that HTTPS will run on the default port 443 | 136 | + | port = "" |
| 129 | } | 137 | } | ||
| 130 | 138 | ||||
| 131 | domain := config.Http.TopDomain | 139 | domain := config.Http.TopDomain | ||
| @@ -135,7 +143,3 @@ func GenerateOauthCallbackURL(config AppConfig) string { | |||||
| 135 | 143 | ||||
| 136 | return fmt.Sprintf("%s://%s%s%s/login/oauth/callback", scheme, domain, port, config.Admin.Path) | 144 | return fmt.Sprintf("%s://%s%s%s/login/oauth/callback", scheme, domain, port, config.Admin.Path) | ||
| 137 | } | 145 | } | ||
| 138 | - | ||||
| 139 | - | func getConfigFile() (string, string) { | |||
| 140 | - | return "tmp/", "config.yml" // assuming the file is in the current directory | |||
| 141 | - | } | |||
M internal/httpserve/handler/oauth.go +1 -1
| @@ -54,7 +54,7 @@ func StartOAuthGithub(c echo.Context, a *app.App) error { | |||
| 54 | 54 | } | |
| 55 | 55 | //Initiate the Github OAuth flow | |
| 56 | 56 | clientID := os.Getenv("GITHUB_APP_ID") | |
| 57 | - | redirectDomain := app.GenerateOauthCallbackURL(a.Config) | |
| 57 | + | redirectDomain := a.Config.GenerateOauthCallbackURL() | |
| 58 | 58 | encodedState := base64.StdEncoding.EncodeToString([]byte("redirectDomain:" + redirectDomain)) | |
| 59 | 59 | // Redirect to Gordon's Proxy to grab the oauth access | |
| 60 | 60 | oauthURL := fmt.Sprintf( | |
| @@ -54,7 +54,7 @@ func StartOAuthGithub(c echo.Context, a *app.App) error { | |||||
| 54 | } | 54 | } | ||
| 55 | //Initiate the Github OAuth flow | 55 | //Initiate the Github OAuth flow | ||
| 56 | clientID := os.Getenv("GITHUB_APP_ID") | 56 | clientID := os.Getenv("GITHUB_APP_ID") | ||
| 57 | - | redirectDomain := app.GenerateOauthCallbackURL(a.Config) | 57 | + | redirectDomain := a.Config.GenerateOauthCallbackURL() |
| 58 | encodedState := base64.StdEncoding.EncodeToString([]byte("redirectDomain:" + redirectDomain)) | 58 | encodedState := base64.StdEncoding.EncodeToString([]byte("redirectDomain:" + redirectDomain)) | ||
| 59 | // Redirect to Gordon's Proxy to grab the oauth access | 59 | // Redirect to Gordon's Proxy to grab the oauth access | ||
| 60 | oauthURL := fmt.Sprintf( | 60 | oauthURL := fmt.Sprintf( | ||
M internal/httpserve/handler/session.go +0 -1
| @@ -5,7 +5,6 @@ import ( | |||
| 5 | 5 | "net/http" | |
| 6 | 6 | "time" | |
| 7 | 7 | ||
| 8 | - | _ "github.com/joho/godotenv/autoload" | |
| 9 | 8 | "github.com/labstack/echo-contrib/session" | |
| 10 | 9 | "github.com/labstack/echo/v4" | |
| 11 | 10 | ) | |
| @@ -5,7 +5,6 @@ import ( | |||||
| 5 | "net/http" | 5 | "net/http" | ||
| 6 | "time" | 6 | "time" | ||
| 7 | 7 | ||||
| 8 | - | _ "github.com/joho/godotenv/autoload" | |||
| 9 | "github.com/labstack/echo-contrib/session" | 8 | "github.com/labstack/echo-contrib/session" | ||
| 10 | "github.com/labstack/echo/v4" | 9 | "github.com/labstack/echo/v4" | ||
| 11 | ) | 10 | ) | ||
M internal/webui/strings.go +1 -1
| @@ -23,7 +23,7 @@ type StringsYamlData struct { | |||
| 23 | 23 | // ReadStringsDataFromYAML reads the strings.yaml file and unmarshals it into the out interface | |
| 24 | 24 | func ReadStringsDataFromYAML(lang string, fs fs.FS, filename string, out interface{}) error { | |
| 25 | 25 | ||
| 26 | - | err := parser.OpenYamlFile(fs, filename, out) | |
| 26 | + | err := parser.ParseYAMLFile(fs, filename, out) | |
| 27 | 27 | if err != nil { | |
| 28 | 28 | return err | |
| 29 | 29 | } | |
| @@ -23,7 +23,7 @@ type StringsYamlData struct { | |||||
| 23 | // ReadStringsDataFromYAML reads the strings.yaml file and unmarshals it into the out interface | 23 | // ReadStringsDataFromYAML reads the strings.yaml file and unmarshals it into the out interface | ||
| 24 | func ReadStringsDataFromYAML(lang string, fs fs.FS, filename string, out interface{}) error { | 24 | func ReadStringsDataFromYAML(lang string, fs fs.FS, filename string, out interface{}) error { | ||
| 25 | 25 | ||||
| 26 | - | err := parser.OpenYamlFile(fs, filename, out) | 26 | + | err := parser.ParseYAMLFile(fs, filename, out) |
| 27 | if err != nil { | 27 | if err != nil { | ||
| 28 | return err | 28 | return err | ||
| 29 | } | 29 | } | ||
M pkg/utils/parser/yaml.go +1 -1
| @@ -33,7 +33,7 @@ import ( | |||
| 33 | 33 | // } | |
| 34 | 34 | ||
| 35 | 35 | // OpenYamlFile opens a YAML file and unmarshals it into the out interface | |
| 36 | - | func OpenYamlFile(fs fs.FS, filename string, out interface{}, dir ...string) error { | |
| 36 | + | func ParseYAMLFile(fs fs.FS, filename string, out interface{}, dir ...string) error { | |
| 37 | 37 | // Construct the full path of the YAML file | |
| 38 | 38 | fullPath := filename | |
| 39 | 39 | if len(dir) > 0 { | |
| @@ -33,7 +33,7 @@ import ( | |||||
| 33 | // } | 33 | // } | ||
| 34 | 34 | ||||
| 35 | // OpenYamlFile opens a YAML file and unmarshals it into the out interface | 35 | // OpenYamlFile opens a YAML file and unmarshals it into the out interface | ||
| 36 | - | func OpenYamlFile(fs fs.FS, filename string, out interface{}, dir ...string) error { | 36 | + | func ParseYAMLFile(fs fs.FS, filename string, out interface{}, dir ...string) error { |
| 37 | // Construct the full path of the YAML file | 37 | // Construct the full path of the YAML file | ||
| 38 | fullPath := filename | 38 | fullPath := filename | ||
| 39 | if len(dir) > 0 { | 39 | if len(dir) > 0 { | ||