agent/session/plugin/config/configuration.go (182 lines of code) (raw):

// Copyright (c) 2009-present, Alibaba Cloud All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "encoding/json" "fmt" "io/ioutil" "os" "runtime" "github.com/aliyun/aliyun_assist_client/agent/session/plugin/cli" ) const ( configPath = "/.aliyun" configFile = "config_ecs.json" DefaultConfigProfileName = "default" ) type Configuration struct { CurrentProfile string `json:"current"` Profiles []Profile `json:"profiles"` MetaPath string `json:"meta_path"` //Plugins []Plugin `json:"plugin"` } var hookGetHomePath = func(fn func() string) func() string { return fn } func NewConfiguration() *Configuration { return &Configuration{ CurrentProfile: DefaultConfigProfileName, Profiles: []Profile{ NewProfile(DefaultConfigProfileName), }, } } func (c *Configuration) NewProfile(pn string) Profile { p, ok := c.GetProfile(pn) if !ok { p = NewProfile(pn) c.PutProfile(p) } return p } func (c *Configuration) GetProfile(pn string) (Profile, bool) { for _, p := range c.Profiles { if p.Name == pn { return p, true } } return Profile{Name: pn}, false } func (c *Configuration) GetCurrentProfile(ctx *cli.Context) Profile { profileName := ProfileFlag(ctx.Flags()).GetStringOrDefault(c.CurrentProfile) if profileName == "" || profileName == "default" { switch { case os.Getenv("ALIBABACLOUD_PROFILE") != "": profileName = os.Getenv("ALIBABACLOUD_PROFILE") case os.Getenv("ALIBABA_CLOUD_PROFILE") != "": profileName = os.Getenv("ALIBABA_CLOUD_PROFILE") case os.Getenv("ALICLOUD_PROFILE") != "": profileName = os.Getenv("ALICLOUD_PROFILE") } } p, _ := c.GetProfile(profileName) p.OverwriteWithFlags(ctx) return p } func (c *Configuration) PutProfile(profile Profile) { for i, p := range c.Profiles { if p.Name == profile.Name { c.Profiles[i] = profile return } } c.Profiles = append(c.Profiles, profile) } func LoadCurrentProfile() (Profile, error) { return LoadProfile(GetConfigPath2(), "") } func LoadProfile(path string, name string) (Profile, error) { var p Profile config, err := hookLoadConfiguration(LoadConfiguration)(path) if err != nil { return p, fmt.Errorf("init config failed %v", err) } if name == "" { name = config.CurrentProfile } p, ok := config.GetProfile(name) p.parent = config if !ok { return p, fmt.Errorf("unknown profile %s, run configure to check", name) } return p, nil } func LoadProfileWithContext(ctx *cli.Context) (profile Profile, err error) { var currentPath string if path, ok := ConfigurePathFlag(ctx.Flags()).GetValue(); ok { currentPath = path } else { currentPath = GetConfigPath2() } if name, ok := ProfileFlag(ctx.Flags()).GetValue(); ok { profile, err = LoadProfile(currentPath, name) } else { profile, err = LoadProfile(currentPath, "") } if err != nil { return } //Load from flags profile.OverwriteWithFlags(ctx) err = profile.Validate() return } func LoadConfiguration(path string) (conf *Configuration, err error) { _, statErr := os.Stat(path) if os.IsNotExist(statErr) { conf, err = MigrateLegacyConfiguration() if err != nil { return } if conf != nil { err = SaveConfiguration(conf) if err != nil { err = fmt.Errorf("save failed %v", err) return } return } conf = NewConfiguration() return } bytes, err := ioutil.ReadFile(path) if err != nil { err = fmt.Errorf("reading config from '%s' failed %v", path, err) return } conf, err = NewConfigFromBytes(bytes) return } func SaveConfiguration(config *Configuration) (err error) { // fmt.Printf("conf %v\n", config) bytes, err := json.MarshalIndent(config, "", "\t") if err != nil { return } path := GetConfigPath2() err = ioutil.WriteFile(path, bytes, 0600) return } func NewConfigFromBytes(bytes []byte) (conf *Configuration, err error) { conf = NewConfiguration() err = json.Unmarshal(bytes, conf) return } func GetConfigPath() string { path := hookGetHomePath(GetHomePath)() + configPath if _, err := os.Stat(path); os.IsNotExist(err) { err = os.MkdirAll(path, 0755) if err != nil { panic(err) } } return path } func GetConfigPath2() string { path := hookGetHomePath(GetHomePath)() + configPath if _, err := os.Stat(path); os.IsNotExist(err) { err = os.MkdirAll(path, 0755) if err != nil { panic(err) } } if _, err := os.Stat(path + "/config_ecs.json"); os.IsNotExist(err) { return path + "/config.json" } return path + "/config_ecs.json" } func GetHomePath() string { if runtime.GOOS == "windows" { home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") if home == "" { home = os.Getenv("USERPROFILE") } return home } return os.Getenv("HOME") }