actions.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 models
  15. import (
  16. "context"
  17. "strings"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/errors"
  21. apis "yunion.io/x/onecloud/pkg/apis/ansible"
  22. apiidentity "yunion.io/x/onecloud/pkg/apis/identity"
  23. "yunion.io/x/onecloud/pkg/cloudcommon/tsdb"
  24. "yunion.io/x/onecloud/pkg/mcclient"
  25. "yunion.io/x/onecloud/pkg/mcclient/auth"
  26. ansible_modules "yunion.io/x/onecloud/pkg/mcclient/modules/ansible"
  27. "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
  28. "yunion.io/x/onecloud/pkg/mcclient/modules/devtool"
  29. "yunion.io/x/onecloud/pkg/mcclient/options"
  30. )
  31. func getServerAttrs(ID string, s *mcclient.ClientSession) (map[string]string, error) {
  32. keys := []string{
  33. "hypervisor",
  34. "id",
  35. "ips",
  36. "name",
  37. "region_id",
  38. "zone_id",
  39. }
  40. params := make(map[string]string)
  41. result, err := compute.Servers.Get(s, ID, nil)
  42. if err != nil {
  43. log.Errorf("Error show server: %s", err)
  44. return nil, err
  45. }
  46. for _, key := range keys {
  47. value, _ := result.GetString(key)
  48. if key == "ips" {
  49. key = "ip"
  50. if strings.Contains(value, ",") {
  51. value = strings.Split(value, ",")[0]
  52. }
  53. }
  54. params["server_"+key] = value
  55. }
  56. return params, err
  57. }
  58. func getTSDBURL() (string, error) {
  59. s := auth.GetAdminSessionWithPublic(nil, "")
  60. url, err := tsdb.GetDefaultServiceSourceURL(s, apiidentity.EndpointInterfacePublic)
  61. if err != nil {
  62. return "", errors.Wrap(err, "get influxdb Endpoint error")
  63. }
  64. return url, nil
  65. }
  66. func renderExtraVars(vars map[string]string) {
  67. tsdbURL, err := getTSDBURL()
  68. if err != nil {
  69. log.Errorf("template binding: get influxdb url error: %s", err)
  70. return
  71. }
  72. for key, value := range vars {
  73. if key == "influxdb" && value == "INFLUXDB" {
  74. vars[key] = tsdbURL
  75. }
  76. }
  77. }
  78. func deleteAnsiblePlaybook(id string, s *mcclient.ClientSession) (jsonutils.JSONObject, error) {
  79. apb, err := ansible_modules.AnsiblePlaybooks.Get(s, id, nil)
  80. if err != nil {
  81. log.Errorf("[deleteAnsiblePlaybook] get Ansible playbook error %s", err)
  82. return apb, err
  83. }
  84. status, _ := apb.GetString("status")
  85. if status == apis.AnsiblePlaybookStatusRunning {
  86. apb, err = ansible_modules.AnsiblePlaybooks.PerformAction(s, id, "stop", nil)
  87. if err != nil {
  88. log.Errorf("[deleteAnsiblePlaybook] stop Ansible playbook error %s", err)
  89. return apb, err
  90. }
  91. }
  92. apb, err = ansible_modules.AnsiblePlaybooks.Delete(s, id, nil)
  93. if err != nil {
  94. log.Errorf("[deleteAnsiblePlaybook] Delete Ansible playbook error %s", err)
  95. return apb, err
  96. }
  97. log.Debugf("ansible playbook %s has been deleted successfully.", id)
  98. return apb, nil
  99. }
  100. func (obj *SDevtoolTemplate) Binding(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  101. // * get server id
  102. // * get playbook struct and create obj
  103. // * get cronjob struct and create obj
  104. // * create playbook
  105. template := obj
  106. s := auth.GetSession(ctx, userCred, "")
  107. ServerID, err := data.GetString("server_id")
  108. attrs, err := getServerAttrs(ServerID, s)
  109. if err != nil {
  110. log.Errorf("TemplateBindingServers getServerAttrs failed %s", err)
  111. return nil, err
  112. }
  113. newPlaybookName := template.Name + "-" + template.Id[0:8] + "-" + ServerID[0:8]
  114. if len(newPlaybookName) > 32 {
  115. newPlaybookName = newPlaybookName[0:32]
  116. }
  117. playbook := template.Playbook
  118. playbook.Inventory.Hosts[0].Name = ServerID
  119. for key, value := range attrs {
  120. playbook.Inventory.Hosts[0].Vars[key] = value
  121. }
  122. renderExtraVars(playbook.Inventory.Hosts[0].Vars)
  123. params := jsonutils.Marshal(&playbook)
  124. host, _ := params.Get("inventory")
  125. file, _ := params.Get("files")
  126. mod, _ := params.Get("modules")
  127. newAnsiblPlaybookParams := jsonutils.NewDict()
  128. newAnsiblPlaybookParams.Add(jsonutils.NewString(newPlaybookName), "name")
  129. newAnsiblPlaybookParams.Add(host, "playbook", "inventory")
  130. newAnsiblPlaybookParams.Add(file, "playbook", "files")
  131. newAnsiblPlaybookParams.Add(mod, "playbook", "modules")
  132. apb, err := ansible_modules.AnsiblePlaybooks.Create(s, newAnsiblPlaybookParams)
  133. if err != nil {
  134. log.Errorf("TemplateBindingServers AnsiblePlaybooks.Create failed %s", err)
  135. return nil, err
  136. }
  137. ansibleId, _ := apb.GetString("id")
  138. //get cronjob struct and create template
  139. newCronjobName := template.Name + "-" + template.Id[0:8] + "-" + ansibleId[0:8]
  140. if len(newCronjobName) > 32 {
  141. newCronjobName = newCronjobName[0:32]
  142. }
  143. newCronjobParams := jsonutils.NewDict()
  144. newCronjobParams.Add(jsonutils.NewString(newCronjobName), "name")
  145. newCronjobParams.Add(jsonutils.NewInt(int64(template.Day)), "day")
  146. newCronjobParams.Add(jsonutils.NewInt(int64(template.Hour)), "hour")
  147. newCronjobParams.Add(jsonutils.NewInt(int64(template.Min)), "min")
  148. newCronjobParams.Add(jsonutils.NewInt(int64(template.Sec)), "sec")
  149. newCronjobParams.Add(jsonutils.NewInt(int64(template.Interval)), "interval")
  150. newCronjobParams.Add(jsonutils.NewBool(template.Start), "start")
  151. newCronjobParams.Add(jsonutils.NewBool(template.Enabled), "enabled")
  152. newCronjobParams.Add(jsonutils.NewString(ansibleId), "ansible_playbook_id")
  153. newCronjobParams.Add(jsonutils.NewString(template.Id), "template_id")
  154. newCronjobParams.Add(jsonutils.NewString(ServerID), "server_id")
  155. _, err = devtool.DevToolCronjobs.Create(s, newCronjobParams)
  156. if err != nil {
  157. log.Errorf("TemplateBindingServers failed %s", err)
  158. return nil, err
  159. }
  160. return nil, nil
  161. }
  162. func (obj *SDevtoolTemplate) Unbinding(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  163. // * get server id
  164. // * get playbook struct and create obj
  165. // * get cronjob struct and create obj
  166. // * create playbook
  167. template := obj
  168. s := auth.GetSession(ctx, userCred, "")
  169. ServerID, err := data.GetString("server_id")
  170. newPlaybookName := template.Name + "-" + template.Id[0:8] + "-" + ServerID[0:8]
  171. if len(newPlaybookName) > 32 {
  172. newPlaybookName = newPlaybookName[0:32]
  173. }
  174. apb, err := deleteAnsiblePlaybook(newPlaybookName, s)
  175. if err != nil {
  176. log.Errorf("TemplateUnbindingServers failed %s", err)
  177. return nil, err
  178. }
  179. ansibleId, _ := apb.GetString("id")
  180. newCronjobName := template.Name + "-" + template.Id[0:8] + "-" + ansibleId[0:8]
  181. if len(newCronjobName) > 32 {
  182. newCronjobName = newCronjobName[0:32]
  183. }
  184. _, err = devtool.DevToolCronjobs.Delete(s, newCronjobName, nil)
  185. if err != nil {
  186. log.Errorf("err: %+v", err)
  187. log.Errorf("TemplateUnbindingServers failed %s", err)
  188. return nil, err
  189. }
  190. return nil, nil
  191. }
  192. func (obj *SDevtoolTemplate) TaskUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  193. template := obj
  194. template.SVirtualResourceBase.PostUpdate(ctx, userCred, query, data)
  195. opt := options.DevtoolTemplateUpdateOptions{}
  196. data.Unmarshal(&opt)
  197. if !opt.Rebind {
  198. return nil, nil
  199. }
  200. items := make([]SCronjob, 0)
  201. q := CronjobManager.Query().Equals("template_id", template.Id)
  202. err := q.All(&items)
  203. if err != nil {
  204. log.Errorf("query error: %s", err)
  205. return nil, err
  206. }
  207. for _, item := range items {
  208. params := jsonutils.NewDict()
  209. params.Add(jsonutils.NewString(item.ServerID), "server_id")
  210. template.Unbinding(ctx, userCred, nil, params)
  211. template.Binding(ctx, userCred, nil, params)
  212. }
  213. return nil, nil
  214. }