service_catalog.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. "database/sql"
  18. "net/url"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/pkg/errors"
  21. "yunion.io/x/sqlchemy"
  22. computeapis "yunion.io/x/onecloud/pkg/apis/compute"
  23. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  24. "yunion.io/x/onecloud/pkg/compute/options"
  25. "yunion.io/x/onecloud/pkg/httperrors"
  26. "yunion.io/x/onecloud/pkg/mcclient"
  27. "yunion.io/x/onecloud/pkg/mcclient/auth"
  28. "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
  29. "yunion.io/x/onecloud/pkg/util/stringutils2"
  30. )
  31. // +onecloud:swagger-gen-model-singular=servicecatalog
  32. // +onecloud:swagger-gen-model-plural=servicecatalogs
  33. type SServiceCatalogManager struct {
  34. db.SSharableVirtualResourceBaseManager
  35. }
  36. type SServiceCatalog struct {
  37. db.SSharableVirtualResourceBase
  38. IconUrl string `charset:"ascii" create:"optional" list:"user" get:"user" update:"user"`
  39. GuestTemplateID string `width:"128" charset:"ascii" create:"optional" list:"user" get:"user" update:"user"`
  40. }
  41. var ServiceCatalogManager *SServiceCatalogManager
  42. func init() {
  43. ServiceCatalogManager = &SServiceCatalogManager{
  44. SSharableVirtualResourceBaseManager: db.NewSharableVirtualResourceBaseManager(
  45. SServiceCatalog{},
  46. "servicecatalogs_tbl",
  47. "servicecatalog",
  48. "servicecatalogs",
  49. ),
  50. }
  51. ServiceCatalogManager.SetVirtualObject(ServiceCatalogManager)
  52. }
  53. func (scm *SServiceCatalog) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential,
  54. query jsonutils.JSONObject, input *computeapis.ServiceCatalogUpdateInput) (*jsonutils.JSONDict, error) {
  55. data := jsonutils.NewDict()
  56. if len(input.GuestTemplate) > 0 {
  57. // check
  58. model, err := GuestTemplateManager.FetchByIdOrName(ctx, userCred, input.GuestTemplate)
  59. if errors.Cause(err) == sql.ErrNoRows {
  60. return nil, httperrors.NewResourceNotFoundError("no such guest template")
  61. }
  62. if err != nil {
  63. return nil, err
  64. }
  65. data.Add(jsonutils.NewString(model.GetId()), "guest_template_id")
  66. }
  67. if len(input.Name) > 0 {
  68. // no need to check name
  69. data.Add(jsonutils.NewString(input.Name), "name")
  70. }
  71. if len(input.IconUrl) > 0 {
  72. //check icon url
  73. url, err := url.Parse(input.IconUrl)
  74. if err != nil {
  75. return nil, httperrors.NewInputParameterError("fail to parse icon url '%s'", input.IconUrl)
  76. }
  77. data.Add(jsonutils.NewString(url.String()), "icon_url")
  78. }
  79. return data, nil
  80. }
  81. func (scm *SServiceCatalogManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential,
  82. ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input *computeapis.ServiceCatalogCreateInput) (*jsonutils.JSONDict,
  83. error) {
  84. if len(input.GuestTemplate) == 0 {
  85. return nil, httperrors.NewMissingParameterError("guest_template")
  86. }
  87. model, err := GuestTemplateManager.FetchByIdOrName(ctx, userCred, input.GuestTemplate)
  88. if errors.Cause(err) == sql.ErrNoRows {
  89. return nil, httperrors.NewResourceNotFoundError("no such guest template")
  90. }
  91. if err != nil {
  92. return nil, err
  93. }
  94. /*
  95. gt := model.(*SGuestTemplate)
  96. //scope := rbacutils.String2Scope(gt.PublicScope)
  97. //if !gt.IsPublic || scope != rbacutils.ScopeSystem {
  98. // return nil, httperrors.NewForbiddenError("guest template must be public in scope system")
  99. //}
  100. if userCred.GetProjectId() != gt.ProjectId {
  101. return nil, httperrors.NewForbiddenError("guest template must has same project id with the request")
  102. }
  103. */
  104. data := input.JSON(input)
  105. data.Remove("guest_template")
  106. data.Add(jsonutils.NewString(model.GetId()), "guest_template_id")
  107. // check url
  108. if len(input.IconUrl) == 0 {
  109. return data, nil
  110. }
  111. url, err := url.Parse(input.IconUrl)
  112. if err != nil {
  113. return nil, httperrors.NewInputParameterError("fail to parse icon url '%s'", input.IconUrl)
  114. }
  115. data.Add(jsonutils.NewString(url.String()), "icon_url")
  116. return data, nil
  117. }
  118. func (sc *SServiceCatalog) PerformDeploy(ctx context.Context, userCred mcclient.TokenCredential,
  119. query jsonutils.JSONObject, input *computeapis.ServiceCatalogDeploy) (jsonutils.JSONObject, error) {
  120. if len(input.Name) == 0 && len(input.GenerateName) == 0 {
  121. return nil, httperrors.NewMissingParameterError("name or generate_name")
  122. }
  123. model, err := GuestTemplateManager.FetchById(sc.GuestTemplateID)
  124. if errors.Cause(err) == sql.ErrNoRows {
  125. return nil, httperrors.NewResourceNotFoundError("no such guest_template %s", sc.GuestTemplateID)
  126. }
  127. if err != nil {
  128. return nil, err
  129. }
  130. guestTempalte := model.(*SGuestTemplate)
  131. content := guestTempalte.Content
  132. contentDict := content.(*jsonutils.JSONDict)
  133. if len(input.GenerateName) != 0 {
  134. contentDict.Add(jsonutils.NewString(input.GenerateName), "generate_name")
  135. } else {
  136. contentDict.Add(jsonutils.NewString(input.Name), "name")
  137. }
  138. if input.Count != 0 {
  139. input.Count = 1
  140. }
  141. contentDict.Add(jsonutils.NewInt(int64(input.Count)), "count")
  142. s := auth.GetSession(ctx, userCred, options.Options.Region)
  143. _, err = compute.Servers.Create(s, content)
  144. if err != nil {
  145. return nil, errors.Wrap(err, "fail to create guest")
  146. }
  147. return nil, err
  148. }
  149. // 服务目录列表
  150. func (manager *SServiceCatalogManager) ListItemFilter(
  151. ctx context.Context,
  152. q *sqlchemy.SQuery,
  153. userCred mcclient.TokenCredential,
  154. input computeapis.ServiceCatalogListInput,
  155. ) (*sqlchemy.SQuery, error) {
  156. q, err := manager.SSharableVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, input.SharableVirtualResourceListInput)
  157. if err != nil {
  158. return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.ListItemFilter")
  159. }
  160. if len(input.GuestTemplateId) > 0 {
  161. gtObj, err := GuestTemplateManager.FetchByIdOrName(ctx, userCred, input.GuestTemplateId)
  162. if err != nil {
  163. if errors.Cause(err) == sql.ErrNoRows {
  164. return nil, httperrors.NewResourceNotFoundError2(GuestTemplateManager.Keyword(), input.GuestTemplateId)
  165. } else {
  166. return nil, errors.Wrap(err, "GuestTemplateManager.FetchByIdOrName")
  167. }
  168. }
  169. q = q.Equals("guest_template_id", gtObj.GetId())
  170. }
  171. return q, nil
  172. }
  173. func (manager *SServiceCatalogManager) OrderByExtraFields(
  174. ctx context.Context,
  175. q *sqlchemy.SQuery,
  176. userCred mcclient.TokenCredential,
  177. input computeapis.ServiceCatalogListInput,
  178. ) (*sqlchemy.SQuery, error) {
  179. q, err := manager.SSharableVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, input.SharableVirtualResourceListInput)
  180. if err != nil {
  181. return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.OrderByExtraFields")
  182. }
  183. return q, nil
  184. }
  185. func (manager *SServiceCatalogManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  186. var err error
  187. q, err = manager.SSharableVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
  188. if err == nil {
  189. return q, nil
  190. }
  191. return q, httperrors.ErrNotFound
  192. }
  193. func (manager *SServiceCatalogManager) FetchCustomizeColumns(
  194. ctx context.Context,
  195. userCred mcclient.TokenCredential,
  196. query jsonutils.JSONObject,
  197. objs []interface{},
  198. fields stringutils2.SSortedStrings,
  199. isList bool,
  200. ) []computeapis.ServiceCatalogDetails {
  201. rows := make([]computeapis.ServiceCatalogDetails, len(objs))
  202. virtRows := manager.SSharableVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  203. for i := range rows {
  204. rows[i] = computeapis.ServiceCatalogDetails{
  205. SharableVirtualResourceDetails: virtRows[i],
  206. }
  207. }
  208. return rows
  209. }