portainer-devtool/go/configs/config.go

177 lines
4.1 KiB
Go
Raw Normal View History

package configs
import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
2022-12-25 23:10:59 +11:00
"path"
)
const (
ConfigFileName string = ".devtool"
)
var (
ErrConfigNotInitialized error = errors.New("Config file is not initialized")
)
type Config struct {
2022-12-25 23:10:59 +11:00
// ProjectPath is the location on your host where all dev relevant folders will be stored to
ProjectPath string
2022-12-25 23:10:59 +11:00
// VolumePath is where all the persisitant data will be stored
VolumePath string
2022-12-25 23:10:59 +11:00
// Credentials for UI login
LoginCredential LoginCredential
2022-12-25 23:10:59 +11:00
// key is repository name, for example, "repository-ee"
RepositoryConfig map[string]RepositoryConfig
}
// LoginCredential stores the user credential for API request
type LoginCredential struct {
Username string
Password string
Address string
}
type RepositoryConfig struct {
Name string
URL string
Directory string
Private bool
GitUsername string
GitPassword string
}
func GetConfig() (*Config, error) {
file, err := getConfigFile(ConfigFileName)
if err != nil {
if err == ErrConfigNotInitialized {
return initializeConfig(file)
}
return nil, err
}
defer file.Close()
return getConfig(file)
}
func (config *Config) Summarize() {
fmt.Printf("The project path is %s\nThe volume path is %s\n", config.ProjectPath, config.VolumePath)
if config.LoginCredential.Username != "" && config.LoginCredential.Password != "" {
fmt.Printf("Login credential [%s] is configured\n", config.LoginCredential.Username)
}
if len(config.RepositoryConfig) > 0 {
for name := range config.RepositoryConfig {
fmt.Printf("Repository [%s] is added\n", name)
}
} else {
fmt.Println("No repository is added")
}
}
2022-12-25 23:10:59 +11:00
// initializeConfig will set up the mandatory dev information for the first time.
// such as devtool path, login credential
// The configuration also can be updated later
func initializeConfig(w io.WriteCloser) (*Config, error) {
config := &Config{}
2022-12-25 23:10:59 +11:00
fmt.Printf("Initialize devtool path:\n (Project path will store volumes and repositories)")
fmt.Scanf("%s", &(config.ProjectPath))
2022-12-25 23:10:59 +11:00
// generate volume path automatically
config.VolumePath = path.Join(config.ProjectPath, "volumes")
var loginCredential LoginCredential
fmt.Printf("Set login credential username(admin): ")
fmt.Scanf("%s", &(loginCredential.Username))
if loginCredential.Username == "" {
loginCredential.Username = "admin"
}
for {
fmt.Printf("Set login credential password(******): ")
fmt.Scanf("%s", &(loginCredential.Password))
if loginCredential.Password != "" {
break
}
fmt.Println("Login credential password must be provided")
}
fmt.Printf("Set login address(127.0.0.1): ")
fmt.Scanf("%s", &(loginCredential.Address))
if loginCredential.Address == "" {
loginCredential.Address = "http://127.0.0.1:9000/api/auth"
} else {
loginCredential.Address = fmt.Sprintf("http://%s:9000/api/auth", loginCredential.Address)
}
config.LoginCredential = loginCredential
// able to configure multiple project
// if utils.PromptConfirm("Do you want to configure the repository now?") {
// // configure repository
// }
bytes, err := json.Marshal(config)
if err != nil {
return nil, err
}
_, err = w.Write(bytes)
if err != nil {
return nil, err
}
return config, nil
}
func getConfig(f *os.File) (*Config, error) {
config := &Config{}
info, err := f.Stat()
if err != nil {
return nil, err
}
bytes := make([]byte, info.Size())
n, err := f.Read(bytes)
if err != nil {
return nil, err
}
if n == 0 {
// The file exists, but it's empty file, so we need to initalize
return initializeConfig(f)
}
err = json.Unmarshal(bytes, &config)
if err != nil {
return nil, err
}
return config, nil
}
// getConfigFile get the config file handler
func getConfigFile(name string) (*os.File, error) {
_, err := os.Stat(name)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
//create file
file, err := os.Create(name)
if err != nil {
return nil, fmt.Errorf("fail to create config file: %w", err)
}
// first set up the git project path and volume path
// git credential
return file, err
} else {
return nil, err
}
}
return os.OpenFile(name, os.O_RDWR, 0644)
}