conf_util.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // Copyright 2021 EMQ Technologies Co., Ltd.
  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 main
  15. import (
  16. "fmt"
  17. "gopkg.in/yaml.v3"
  18. "io/ioutil"
  19. "os"
  20. "strconv"
  21. "strings"
  22. )
  23. var khome = os.Getenv("KUIPER_HOME")
  24. var fileMap = map[string]string{
  25. "edgex": khome + "/etc/sources/edgex.yaml",
  26. "random": khome + "/etc/sources/random.yaml",
  27. "zmq": khome + "/etc/sources/zmq.yaml",
  28. "httppull": khome + "/etc/sources/httppull.yaml",
  29. "mqtt_source": khome + "/etc/mqtt_source.yaml",
  30. "kuiper": khome + "/etc/kuiper.yaml",
  31. "client": khome + "/etc/client.yaml",
  32. }
  33. var file_keys_map = map[string]map[string]string{
  34. "edgex": {
  35. "CLIENTID": "ClientId",
  36. "USERNAME": "Username",
  37. "PASSWORD": "Password",
  38. "QOS": "Qos",
  39. "KEEPALIVE": "KeepAlive",
  40. "RETAINED": "Retained",
  41. "CONNECTIONPAYLOAD": "ConnectionPayload",
  42. "CERTFILE": "CertFile",
  43. "KEYFILE": "KeyFile",
  44. "CERTPEMBLOCK": "CertPEMBlock",
  45. "KEYPEMBLOCK": "KeyPEMBlock",
  46. "SKIPCERTVERIFY": "SkipCertVerify",
  47. "MESSAGETYPE": "messageType",
  48. },
  49. "mqtt_source": {
  50. "SHAREDSUBSCRIPTION": "sharedSubscription",
  51. "CERTIFICATIONPATH": "certificationPath",
  52. "PRIVATEKEYPATH": "privateKeyPath",
  53. "KUBEEDGEVERSION": "kubeedgeVersion",
  54. "KUBEEDGEMODELFILE": "kubeedgeModelFile",
  55. },
  56. "kuiper": {
  57. "CONSOLELOG": "consoleLog",
  58. "FILELOG": "fileLog",
  59. "RESTPORT": "restPort",
  60. "RESTTLS": "restTls",
  61. "PROMETHEUSPORT": "prometheusPort",
  62. "PLUGINHOSTS": "pluginHosts",
  63. "CHECKPOINTINTERVAL": "checkpointInterval",
  64. "CACHETHRESHOLD": "cacheThreshold",
  65. "CACHETRIGGERCOUNT": "cacheTriggerCount",
  66. "DISABLECACHE": "disableCache",
  67. },
  68. }
  69. func main() {
  70. fmt.Println(fileMap["edgex"])
  71. files := make(map[string]map[string]interface{})
  72. ProcessEnv(files, os.Environ())
  73. for f, v := range files {
  74. if bs, err := yaml.Marshal(v); err != nil {
  75. fmt.Println(err)
  76. } else {
  77. message := fmt.Sprintf("-------------------\nConf file %s: \n %s", f, toPrintableString(v))
  78. fmt.Println(message)
  79. if fname, ok := fileMap[f]; ok {
  80. if e := ioutil.WriteFile(fname, bs, 0644); e != nil {
  81. fmt.Println(e)
  82. } else {
  83. fmt.Printf("%s updated\n", fname)
  84. }
  85. }
  86. }
  87. }
  88. }
  89. func printable(m map[string]interface{}) map[string]interface{} {
  90. printableMap := make(map[string]interface{})
  91. for k, v := range m {
  92. if strings.EqualFold(k, "password") {
  93. printableMap[k] = "*"
  94. } else {
  95. if vm, ok := v.(map[string]interface{}); ok {
  96. printableMap[k] = printable(vm)
  97. } else {
  98. printableMap[k] = v
  99. }
  100. }
  101. }
  102. return printableMap
  103. }
  104. func toPrintableString(m map[string]interface{}) string {
  105. p := printable(m)
  106. b, _ := yaml.Marshal(p)
  107. return string(b)
  108. }
  109. func ProcessEnv(files map[string]map[string]interface{}, vars []string) {
  110. for _, e := range vars {
  111. pair := strings.SplitN(e, "=", 2)
  112. if len(pair) != 2 {
  113. fmt.Printf("invalid env %s, skip it.\n", e)
  114. continue
  115. }
  116. valid := false
  117. for k := range fileMap {
  118. if strings.HasPrefix(pair[0], strings.ToUpper(k)) {
  119. valid = true
  120. break
  121. }
  122. }
  123. if !valid {
  124. continue
  125. } else {
  126. fmt.Printf("Find env: %s, start to handle it.\n", e)
  127. }
  128. env_v := strings.ReplaceAll(pair[0], "__", ".")
  129. keys := strings.Split(env_v, ".")
  130. for i, v := range keys {
  131. keys[i] = v
  132. }
  133. if len(keys) < 2 {
  134. fmt.Printf("not concerned env %s, skip it.\n", e)
  135. continue
  136. } else {
  137. k := strings.ToLower(keys[0])
  138. if v, ok := files[k]; !ok {
  139. if data, err := ioutil.ReadFile(fileMap[k]); err != nil {
  140. fmt.Printf("%s\n", err)
  141. } else {
  142. m := make(map[string]interface{})
  143. err = yaml.Unmarshal(data, &m)
  144. if err != nil {
  145. fmt.Println(err)
  146. }
  147. files[k] = m
  148. Handle(k, m, keys[1:], pair[1])
  149. }
  150. } else {
  151. Handle(k, v, keys[1:], pair[1])
  152. }
  153. }
  154. }
  155. }
  156. func Handle(file string, conf map[string]interface{}, skeys []string, val string) {
  157. key := getKey(file, skeys[0])
  158. if len(skeys) == 1 {
  159. conf[key] = getValueType(val)
  160. } else if len(skeys) >= 2 {
  161. if v, ok := conf[key]; ok {
  162. if v1, ok1 := v.(map[string]interface{}); ok1 {
  163. Handle(file, v1, skeys[1:], val)
  164. } else {
  165. fmt.Printf("Not expected map: %v\n", v)
  166. }
  167. } else {
  168. v1 := make(map[string]interface{})
  169. conf[key] = v1
  170. Handle(file, v1, skeys[1:], val)
  171. }
  172. }
  173. }
  174. func getKey(file string, key string) string {
  175. if m, ok := file_keys_map[file][key]; ok {
  176. return m
  177. } else {
  178. return strings.ToLower(key)
  179. }
  180. }
  181. func getValueType(val string) interface{} {
  182. val = strings.Trim(val, " ")
  183. if strings.HasPrefix(val, "[") && strings.HasSuffix(val, "]") {
  184. val = strings.ReplaceAll(val, "[", "")
  185. val = strings.ReplaceAll(val, "]", "")
  186. vals := strings.Split(val, ",")
  187. var ret []interface{}
  188. for _, v := range vals {
  189. if i, err := strconv.ParseInt(v, 10, 64); err == nil {
  190. ret = append(ret, i)
  191. } else if b, err := strconv.ParseBool(v); err == nil {
  192. ret = append(ret, b)
  193. } else if f, err := strconv.ParseFloat(v, 64); err == nil {
  194. ret = append(ret, f)
  195. } else {
  196. ret = append(ret, v)
  197. }
  198. }
  199. return ret
  200. } else if i, err := strconv.ParseInt(val, 10, 64); err == nil {
  201. return i
  202. } else if b, err := strconv.ParseBool(val); err == nil {
  203. return b
  204. } else if f, err := strconv.ParseFloat(val, 64); err == nil {
  205. return f
  206. }
  207. return val
  208. }