handlers.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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 handler
  15. import (
  16. "context"
  17. "fmt"
  18. "net/http"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/log"
  21. "yunion.io/x/pkg/appctx"
  22. "yunion.io/x/pkg/errors"
  23. api "yunion.io/x/onecloud/pkg/apis/compute"
  24. "yunion.io/x/onecloud/pkg/appsrv"
  25. "yunion.io/x/onecloud/pkg/esxi"
  26. "yunion.io/x/onecloud/pkg/hostman/hostutils"
  27. "yunion.io/x/onecloud/pkg/hostman/storageman"
  28. "yunion.io/x/onecloud/pkg/httperrors"
  29. "yunion.io/x/onecloud/pkg/mcclient/auth"
  30. )
  31. const (
  32. AGENT_PREFIX = "disks/agent"
  33. )
  34. func InitHandlers(app *appsrv.Application) {
  35. initESXIHandler(app)
  36. }
  37. var defaultHandler = func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  38. httperrors.NotImplementedError(ctx, w, "")
  39. return
  40. }
  41. func IdAgentPrefix(action string) string {
  42. return fmt.Sprintf("%s/%s/<disk_id>", AGENT_PREFIX, action)
  43. }
  44. func AgentPrefix(action string) string {
  45. return fmt.Sprintf("%s/%s", AGENT_PREFIX, action)
  46. }
  47. func initESXIHandler(app *appsrv.Application) {
  48. app.AddHandler("POST", AgentPrefix("upload"), auth.Authenticate(uploadHandler))
  49. app.AddHandler("POST", AgentPrefix("deploy"), auth.Authenticate(deployHandler))
  50. app.AddHandler("POST", IdAgentPrefix("delete"), auth.Authenticate(deleteHandler))
  51. app.AddHandler("POST", IdAgentPrefix("create"), auth.Authenticate(createHandler))
  52. app.AddHandler("POST", IdAgentPrefix("save-prepare"), auth.Authenticate(savePrepareHandler))
  53. app.AddHandler("POST", IdAgentPrefix("resize"), auth.Authenticate(resizeHandler))
  54. app.AddHandler("POST", IdAgentPrefix("clone"), auth.Authenticate(defaultHandler))
  55. app.AddHandler("POST", IdAgentPrefix("fetch"), auth.Authenticate(defaultHandler))
  56. app.AddHandler("POST", IdAgentPrefix("post-migrate"), auth.Authenticate(defaultHandler))
  57. app.AddHandler("POST", IdAgentPrefix("snapshot"), auth.Authenticate(defaultHandler))
  58. app.AddHandler("POST", IdAgentPrefix("reset"), auth.Authenticate(defaultHandler))
  59. app.AddHandler("POST", IdAgentPrefix("cleanup-snapshots"), auth.Authenticate(defaultHandler))
  60. }
  61. func uploadHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  62. _, _, body := appsrv.FetchEnv(ctx, w, r)
  63. disk, err := body.Get("disk")
  64. if err != nil {
  65. httperrors.MissingParameterError(ctx, w, "miss disk")
  66. return
  67. }
  68. hostutils.DelayTaskWithoutReqctx(ctx, esxi.EsxiAgent.AgentStorage.SaveToGlance, disk)
  69. hostutils.ResponseOk(ctx, w)
  70. }
  71. func deployHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  72. log.Debugf("enter deployHandler")
  73. _, _, body := appsrv.FetchEnv(ctx, w, r)
  74. disk, err := body.Get("disk")
  75. if err != nil {
  76. httperrors.MissingParameterError(ctx, w, "miss disk")
  77. return
  78. }
  79. hostutils.DelayTask(ctx, esxi.EsxiAgent.AgentStorage.AgentDeployGuest, disk)
  80. hostutils.ResponseOk(ctx, w)
  81. }
  82. func deleteHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  83. params, _, _ := appsrv.FetchEnv(ctx, w, r)
  84. diskId := params["<disk_id>"]
  85. disk, err := esxi.EsxiAgent.AgentStorage.GetDiskById(diskId)
  86. if err != nil {
  87. httperrors.GeneralServerError(ctx, w, errors.Wrapf(err, "GetDiskById(%s)", diskId))
  88. return
  89. }
  90. if taskId := ctx.Value(appctx.APP_CONTEXT_KEY_TASK_ID); taskId == nil {
  91. if disk != nil {
  92. _, err := disk.Delete(ctx, nil)
  93. if err != nil {
  94. httperrors.GeneralServerError(ctx, w, err)
  95. return
  96. }
  97. hostutils.ResponseOk(ctx, w)
  98. return
  99. }
  100. }
  101. hostutils.ResponseOk(ctx, w)
  102. hostutils.DelayTask(ctx, disk.Delete, nil)
  103. }
  104. func createHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  105. disk, diskInfo, err := diskAndDiskInfo(ctx, w, r)
  106. if err != nil {
  107. httperrors.GeneralServerError(ctx, w, err)
  108. return
  109. }
  110. params := storageman.SDiskCreateByDiskinfo{DiskId: disk.GetId(), Disk: disk, DiskInfo: api.DiskAllocateInput{}}
  111. diskInfo.Unmarshal(&params.DiskInfo)
  112. hostutils.DelayTask(ctx, esxi.EsxiAgent.AgentStorage.CreateDiskByDiskInfo, params)
  113. hostutils.ResponseOk(ctx, w)
  114. }
  115. func savePrepareHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  116. taskId := ctx.Value(appctx.APP_CONTEXT_KEY_TASK_ID).(string)
  117. disk, diskInfo, err := diskAndDiskInfo(ctx, w, r)
  118. if err != nil {
  119. httperrors.GeneralServerError(ctx, w, err)
  120. return
  121. }
  122. hostutils.DelayTask(ctx, disk.PrepareSaveToGlance, storageman.PrepareSaveToGlanceParams{
  123. TaskId: taskId,
  124. DiskInfo: diskInfo,
  125. })
  126. hostutils.ResponseOk(ctx, w)
  127. }
  128. func resizeHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  129. disk, diskInfo, err := diskAndDiskInfo(ctx, w, r)
  130. if err != nil {
  131. httperrors.GeneralServerError(ctx, w, err)
  132. return
  133. }
  134. resizeDiskInfo := &storageman.SDiskResizeInput{
  135. DiskInfo: diskInfo,
  136. }
  137. resizeFunc := func(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
  138. input, ok := params.(*storageman.SDiskResizeInput)
  139. if !ok {
  140. return nil, hostutils.ParamsError
  141. }
  142. return disk.Resize(ctx, input)
  143. }
  144. hostutils.DelayTask(ctx, resizeFunc, resizeDiskInfo)
  145. hostutils.ResponseOk(ctx, w)
  146. }
  147. /*
  148. func fetchHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
  149. params, _, body := appsrv.FetchEnv(ctx, w, r)
  150. diskId := params["<disk_id>"]
  151. disk := esxi.EsxiAgent.AgentStorage.GetDiskById(diskId)
  152. if disk != nil {
  153. httperrors.GeneralServerError(ctx, w, httperrors.NewDuplicateResourceError("disk '%s'", diskId))
  154. return
  155. }
  156. disk := esxi.EsxiAgent.AgentStorage.CreateDisk(diskId)
  157. diskInfo, err := body.Get("disk")
  158. if err != nil {
  159. httperrors.InputParameterError(ctx, w, "miss disk")
  160. }
  161. url, err := diskInfo.GetString("url")
  162. if err != nil {
  163. httperrors.InputParameterError(ctx, w, "miss disk.url")
  164. }
  165. hostutils.DelayTask(ctx, disk.CreateFromUrl)
  166. hostutils.ResponseOk(ctx, w)
  167. }
  168. */
  169. func diskAndDiskInfo(ctx context.Context, w http.ResponseWriter, r *http.Request) (storageman.IDisk, jsonutils.JSONObject, error) {
  170. params, _, body := appsrv.FetchEnv(ctx, w, r)
  171. diskId := params["<disk_id>"]
  172. disk, err := esxi.EsxiAgent.AgentStorage.GetDiskById(diskId)
  173. if err != nil {
  174. return nil, nil, httperrors.NewGeneralError(errors.Wrapf(err, "GetDiskById(%s)", diskId))
  175. }
  176. diskInfo, err := body.Get("disk")
  177. if err != nil {
  178. return nil, nil, httperrors.NewMissingParameterError("miss disk")
  179. }
  180. return disk, diskInfo, nil
  181. }