Files
fx-serverless/config/config.go
2019-11-27 18:09:06 +08:00

196 lines
3.7 KiB
Go

package config
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/user"
"path"
"sync"
"github.com/metrue/fx/utils"
"github.com/mitchellh/go-homedir"
"gopkg.in/yaml.v2"
)
// Items data of config file
type Items struct {
Clouds map[string]map[string]string `json:"clouds"`
CurrentCloud string `json:"current_cloud"`
}
// Config config of fx
type Config struct {
mux sync.Mutex
configFile string
Items
}
// LoadDefault load default config
func LoadDefault() (*Config, error) {
configFile, err := homedir.Expand("~/.fx/config.yml")
if err != nil {
return nil, err
}
if os.Getenv("FX_CONFIG") != "" {
configFile = os.Getenv("FX_CONFIG")
}
if _, err := os.Stat(configFile); os.IsNotExist(err) {
if err := utils.EnsureFile(configFile); err != nil {
return nil, err
}
if err := writeDefaultConfig(configFile); err != nil {
return nil, err
}
}
return load(configFile)
}
// Load config
func Load(configFile string) (*Config, error) {
if configFile == "" {
return nil, fmt.Errorf("invalid config file")
}
if _, err := os.Stat(configFile); os.IsNotExist(err) {
if err := utils.EnsureFile(configFile); err != nil {
return nil, err
}
if err := writeDefaultConfig(configFile); err != nil {
return nil, err
}
}
return load(configFile)
}
// AddCloud add a cloud
func (c *Config) addCloud(name string, cloud map[string]string) error {
c.Items.Clouds[name] = cloud
return save(c)
}
// AddDockerCloud add docker cloud
func (c *Config) AddDockerCloud(name string, config []byte) error {
c.mux.Lock()
defer c.mux.Unlock()
var conf map[string]string
err := json.Unmarshal(config, &conf)
if err != nil {
return err
}
cloud := map[string]string{
"type": "docker",
"host": conf["ip"],
"user": conf["user"],
}
return c.addCloud(name, cloud)
}
// AddK8SCloud add k8s cloud
func (c *Config) AddK8SCloud(name string, kubeconfig []byte) error {
c.mux.Lock()
defer c.mux.Unlock()
dir := path.Dir(c.configFile)
kubecfg := path.Join(dir, name+".kubeconfig")
if err := utils.EnsureFile(kubecfg); err != nil {
return err
}
if err := ioutil.WriteFile(kubecfg, kubeconfig, 0666); err != nil {
return err
}
cloud := map[string]string{
"type": "k8s",
"kubeConfig": kubecfg,
}
return c.addCloud(name, cloud)
}
// Use set cloud instance with name as current context
func (c *Config) Use(name string) error {
c.mux.Lock()
defer c.mux.Unlock()
has := false
for n := range c.Clouds {
if n == name {
has = true
break
}
}
if !has {
return fmt.Errorf("no cloud with name = %s", name)
}
c.Items.CurrentCloud = name
return save(c)
}
// View view current config
func (c *Config) View() ([]byte, error) {
c.mux.Lock()
defer c.mux.Unlock()
return ioutil.ReadFile(c.configFile)
}
func load(configFile string) (*Config, error) {
conf, err := ioutil.ReadFile(configFile)
if err != nil {
return nil, err
}
var items Items
if err := yaml.Unmarshal(conf, &items); err != nil {
return nil, err
}
var c = Config{
configFile: configFile,
Items: items,
}
return &c, nil
}
func save(c *Config) error {
conf, err := yaml.Marshal(c.Items)
if err != nil {
return err
}
if err := ioutil.WriteFile(c.configFile, conf, 0666); err != nil {
return err
}
return nil
}
func writeDefaultConfig(configFile string) error {
me, err := user.Current()
if err != nil {
return err
}
items := Items{
Clouds: map[string]map[string]string{
"default": map[string]string{
"type": "docker",
"host": "127.0.0.1",
"user": me.Username,
},
},
CurrentCloud: "default",
}
body, err := yaml.Marshal(items)
if err != nil {
return err
}
if err := ioutil.WriteFile(configFile, body, 0666); err != nil {
return err
}
return nil
}