feature.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package misc
  15. import (
  16. "fmt"
  17. "yunion.io/x/jsonutils"
  18. "yunion.io/x/pkg/errors"
  19. "yunion.io/x/pkg/util/sets"
  20. "yunion.io/x/pkg/utils"
  21. "yunion.io/x/onecloud/pkg/mcclient"
  22. "yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
  23. )
  24. type GlobalSettingsValue struct {
  25. SetupKeys []string `json:"setupKeys"`
  26. SetupKeysVersion string `json:"setupKeysVersion"`
  27. SetupOneStackInitialized bool `json:"setupOneStackInitialized"`
  28. ProductVersion string `json:"productVersion"`
  29. UserDefinedKeys map[string]bool `json:"userDefinedKeys"`
  30. }
  31. func NewGlobalSettingsValue(setupKeys []string, setupOneStack bool) *GlobalSettingsValue {
  32. settings := &GlobalSettingsValue{
  33. SetupOneStackInitialized: setupOneStack,
  34. UserDefinedKeys: make(map[string]bool),
  35. }
  36. for _, key := range setupKeys {
  37. settings.Switch(key, true)
  38. }
  39. return settings
  40. }
  41. func (g *GlobalSettingsValue) Switch(featureKey string, on bool) {
  42. if g.UserDefinedKeys == nil {
  43. g.UserDefinedKeys = map[string]bool{}
  44. }
  45. g.UserDefinedKeys[featureKey] = on
  46. ss := sets.NewString(g.SetupKeys...)
  47. if on {
  48. ss.Insert(featureKey)
  49. } else {
  50. ss.Delete(featureKey)
  51. }
  52. g.SetupKeys = ss.List()
  53. }
  54. func init() {
  55. var storageFeatures = []string{
  56. "s3", "xsky", "ceph",
  57. }
  58. var features = []string{
  59. "onestack",
  60. "baremetal",
  61. "lb",
  62. "aliyun",
  63. "aws",
  64. "azure",
  65. "ctyun",
  66. "google",
  67. "huawei",
  68. "qcloud",
  69. "ucloud",
  70. "ecloud",
  71. "jdcloud",
  72. "vmware",
  73. "openstack",
  74. "dstack",
  75. "zstack",
  76. "apsara",
  77. "cloudpods",
  78. "hcso",
  79. "nutanix",
  80. "bill",
  81. "auth",
  82. "onecloud",
  83. "proxmox",
  84. "public",
  85. "private",
  86. "storage",
  87. "default",
  88. "k8s",
  89. "pod",
  90. "monitor",
  91. "bingocloud",
  92. "ksyun",
  93. "baidu",
  94. "cucloud",
  95. "qingcloud",
  96. "volcengine",
  97. "oraclecloud",
  98. "sangfor",
  99. "cephfs",
  100. "cnware",
  101. }
  102. features = append(features, storageFeatures...)
  103. const (
  104. GlobalSettings = "global-settings"
  105. SystemScope = "system"
  106. YunionAgent = "yunionagent"
  107. )
  108. type FeatureCfgOpts struct {
  109. Switch string `help:"Config feature on or off" choices:"on|off"`
  110. }
  111. featureR := func(name string) {
  112. R(&FeatureCfgOpts{}, fmt.Sprintf("feature-config-%s", name), fmt.Sprintf("Set feature %s on or off", name), func(s *mcclient.ClientSession, args *FeatureCfgOpts) error {
  113. enable := true
  114. if args.Switch == "off" {
  115. enable = false
  116. }
  117. items, err := yunionconf.Parameters.List(s, jsonutils.Marshal(map[string]string{
  118. "name": GlobalSettings,
  119. "scope": "system"}))
  120. if err != nil {
  121. return errors.Wrapf(err, "get %s from yunionconf", GlobalSettings)
  122. }
  123. if len(items.Data) == 0 {
  124. // create it if enabled
  125. if enable {
  126. value := []string{name}
  127. if utils.IsInStringArray(name, storageFeatures) {
  128. value = append(value, "storage")
  129. }
  130. input := map[string]interface{}{
  131. "name": GlobalSettings,
  132. "service_id": YunionAgent,
  133. "value": NewGlobalSettingsValue(value, true),
  134. }
  135. params := jsonutils.Marshal(input)
  136. if _, err := yunionconf.Parameters.Create(s, params); err != nil {
  137. return errors.Errorf("create %s for feature %q", GlobalSettings, name)
  138. }
  139. return nil
  140. } else {
  141. return errors.Errorf("not found %s", GlobalSettings)
  142. }
  143. }
  144. if len(items.Data) != 1 {
  145. return errors.Errorf("found %d %q from yunionconf", len(items.Data), GlobalSettings)
  146. }
  147. // update it
  148. ss := items.Data[0]
  149. value, err := ss.Get("value")
  150. if err != nil {
  151. return errors.Wrap(err, "get value")
  152. }
  153. curConf := new(GlobalSettingsValue)
  154. if err := value.Unmarshal(curConf); err != nil {
  155. return errors.Wrapf(err, "unmarshal to GlobalSettingsValue: %s", value)
  156. }
  157. if !enable {
  158. curConf.Switch(name, false)
  159. } else {
  160. curConf.Switch(name, true)
  161. if utils.IsInStringArray(name, storageFeatures) {
  162. curConf.Switch("storage", true)
  163. }
  164. }
  165. id, err := ss.GetString("id")
  166. if err != nil {
  167. return errors.Errorf("get id from %s", ss)
  168. }
  169. ss.(*jsonutils.JSONDict).Set("value", jsonutils.Marshal(curConf))
  170. obj, err := yunionconf.Parameters.Update(s, id, ss)
  171. if err != nil {
  172. return errors.Wrapf(err, "update %s(%s)", GlobalSettings, id)
  173. }
  174. printObject(obj)
  175. return nil
  176. })
  177. }
  178. for _, name := range features {
  179. featureR(name)
  180. }
  181. }