// Copyright 2019 Yunion // // 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 misc import ( "fmt" "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/sets" "yunion.io/x/pkg/utils" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf" ) type GlobalSettingsValue struct { SetupKeys []string `json:"setupKeys"` SetupKeysVersion string `json:"setupKeysVersion"` SetupOneStackInitialized bool `json:"setupOneStackInitialized"` ProductVersion string `json:"productVersion"` UserDefinedKeys map[string]bool `json:"userDefinedKeys"` } func NewGlobalSettingsValue(setupKeys []string, setupOneStack bool) *GlobalSettingsValue { settings := &GlobalSettingsValue{ SetupOneStackInitialized: setupOneStack, UserDefinedKeys: make(map[string]bool), } for _, key := range setupKeys { settings.Switch(key, true) } return settings } func (g *GlobalSettingsValue) Switch(featureKey string, on bool) { if g.UserDefinedKeys == nil { g.UserDefinedKeys = map[string]bool{} } g.UserDefinedKeys[featureKey] = on ss := sets.NewString(g.SetupKeys...) if on { ss.Insert(featureKey) } else { ss.Delete(featureKey) } g.SetupKeys = ss.List() } func init() { var storageFeatures = []string{ "s3", "xsky", "ceph", } var features = []string{ "onestack", "baremetal", "lb", "aliyun", "aws", "azure", "ctyun", "google", "huawei", "qcloud", "ucloud", "ecloud", "jdcloud", "vmware", "openstack", "dstack", "zstack", "apsara", "cloudpods", "hcso", "nutanix", "bill", "auth", "onecloud", "proxmox", "public", "private", "storage", "default", "k8s", "pod", "monitor", "bingocloud", "ksyun", "baidu", "cucloud", "qingcloud", "volcengine", "oraclecloud", "sangfor", "cephfs", "cnware", } features = append(features, storageFeatures...) const ( GlobalSettings = "global-settings" SystemScope = "system" YunionAgent = "yunionagent" ) type FeatureCfgOpts struct { Switch string `help:"Config feature on or off" choices:"on|off"` } featureR := func(name string) { R(&FeatureCfgOpts{}, fmt.Sprintf("feature-config-%s", name), fmt.Sprintf("Set feature %s on or off", name), func(s *mcclient.ClientSession, args *FeatureCfgOpts) error { enable := true if args.Switch == "off" { enable = false } items, err := yunionconf.Parameters.List(s, jsonutils.Marshal(map[string]string{ "name": GlobalSettings, "scope": "system"})) if err != nil { return errors.Wrapf(err, "get %s from yunionconf", GlobalSettings) } if len(items.Data) == 0 { // create it if enabled if enable { value := []string{name} if utils.IsInStringArray(name, storageFeatures) { value = append(value, "storage") } input := map[string]interface{}{ "name": GlobalSettings, "service_id": YunionAgent, "value": NewGlobalSettingsValue(value, true), } params := jsonutils.Marshal(input) if _, err := yunionconf.Parameters.Create(s, params); err != nil { return errors.Errorf("create %s for feature %q", GlobalSettings, name) } return nil } else { return errors.Errorf("not found %s", GlobalSettings) } } if len(items.Data) != 1 { return errors.Errorf("found %d %q from yunionconf", len(items.Data), GlobalSettings) } // update it ss := items.Data[0] value, err := ss.Get("value") if err != nil { return errors.Wrap(err, "get value") } curConf := new(GlobalSettingsValue) if err := value.Unmarshal(curConf); err != nil { return errors.Wrapf(err, "unmarshal to GlobalSettingsValue: %s", value) } if !enable { curConf.Switch(name, false) } else { curConf.Switch(name, true) if utils.IsInStringArray(name, storageFeatures) { curConf.Switch("storage", true) } } id, err := ss.GetString("id") if err != nil { return errors.Errorf("get id from %s", ss) } ss.(*jsonutils.JSONDict).Set("value", jsonutils.Marshal(curConf)) obj, err := yunionconf.Parameters.Update(s, id, ss) if err != nil { return errors.Wrapf(err, "update %s(%s)", GlobalSettings, id) } printObject(obj) return nil }) } for _, name := range features { featureR(name) } }