identitybase.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  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. "fmt"
  18. "strings"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/log"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/util/rbacscope"
  23. "yunion.io/x/pkg/util/timeutils"
  24. "yunion.io/x/sqlchemy"
  25. "yunion.io/x/onecloud/pkg/apis"
  26. api "yunion.io/x/onecloud/pkg/apis/identity"
  27. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  28. "yunion.io/x/onecloud/pkg/httperrors"
  29. "yunion.io/x/onecloud/pkg/mcclient"
  30. "yunion.io/x/onecloud/pkg/util/stringutils2"
  31. )
  32. // +onecloud:swagger-gen-ignore
  33. type IIdentityModelManager interface {
  34. db.IStandaloneModelManager
  35. GetIIdentityModelManager() IIdentityModelManager
  36. }
  37. type IIdentityModel interface {
  38. db.IStandaloneModel
  39. db.IPendingDeletable
  40. GetDomain() *SDomain
  41. GetIIdentityModelManager() IIdentityModelManager
  42. GetIIdentityModel() IIdentityModel
  43. }
  44. type IEnabledIdentityModelManager interface {
  45. IIdentityModelManager
  46. GetIEnabledIdentityModelManager() IEnabledIdentityModelManager
  47. }
  48. type IEnabledIdentityModel interface {
  49. IIdentityModel
  50. db.IEnabledBaseInterface
  51. GetIEnabledIdentityModelManager() IEnabledIdentityModelManager
  52. GetIEnabledIdentityModel() IEnabledIdentityModel
  53. }
  54. // +onecloud:swagger-gen-ignore
  55. type SIdentityBaseResourceManager struct {
  56. db.SStandaloneResourceBaseManager
  57. db.SDomainizedResourceBaseManager
  58. db.SPendingDeletedBaseManager
  59. }
  60. func NewIdentityBaseResourceManager(dt interface{}, tableName string, keyword string, keywordPlural string) SIdentityBaseResourceManager {
  61. return SIdentityBaseResourceManager{
  62. SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(dt, tableName, keyword, keywordPlural),
  63. }
  64. }
  65. type SIdentityBaseResource struct {
  66. db.SStandaloneResourceBase
  67. db.SDomainizedResourceBase
  68. db.SPendingDeletedBase
  69. // 额外信息
  70. Extra *jsonutils.JSONDict `nullable:"true"`
  71. }
  72. // +onecloud:swagger-gen-ignore
  73. type SEnabledIdentityBaseResourceManager struct {
  74. SIdentityBaseResourceManager
  75. db.SEnabledResourceBaseManager
  76. }
  77. func NewEnabledIdentityBaseResourceManager(dt interface{}, tableName string, keyword string, keywordPlural string) SEnabledIdentityBaseResourceManager {
  78. return SEnabledIdentityBaseResourceManager{
  79. SIdentityBaseResourceManager: NewIdentityBaseResourceManager(dt, tableName, keyword, keywordPlural),
  80. }
  81. }
  82. type SEnabledIdentityBaseResource struct {
  83. SIdentityBaseResource
  84. db.SEnabledResourceBase `"enabled->default":"true" "enabled->list":"user" "enabled->update":"domain" "enabled->create":"domain_optional"`
  85. }
  86. func (model *SIdentityBaseResource) GetIIdentityModelManager() IIdentityModelManager {
  87. return model.GetModelManager().(IIdentityModelManager)
  88. }
  89. func (model *SIdentityBaseResource) GetIIdentityModel() IIdentityModel {
  90. return model.GetVirtualObject().(IIdentityModel)
  91. }
  92. func (model *SIdentityBaseResource) GetDomain() *SDomain {
  93. if len(model.DomainId) > 0 && model.DomainId != api.KeystoneDomainRoot {
  94. domain, err := DomainManager.FetchDomainById(model.DomainId)
  95. if err != nil {
  96. log.Errorf("GetDomain fail %s", err)
  97. }
  98. return domain
  99. }
  100. return nil
  101. }
  102. func (manager *SIdentityBaseResourceManager) GetIIdentityModelManager() IIdentityModelManager {
  103. return manager.GetVirtualObject().(IIdentityModelManager)
  104. }
  105. func (manager *SIdentityBaseResourceManager) FetchByName(ctx context.Context, userCred mcclient.IIdentityProvider, idStr string) (db.IModel, error) {
  106. return db.FetchByName(ctx, manager.GetIIdentityModelManager(), userCred, idStr)
  107. }
  108. func (manager *SIdentityBaseResourceManager) FetchByIdOrName(ctx context.Context, userCred mcclient.IIdentityProvider, idStr string) (db.IModel, error) {
  109. return db.FetchByIdOrName(ctx, manager.GetIIdentityModelManager(), userCred, idStr)
  110. }
  111. func (manager *SIdentityBaseResourceManager) FilterBySystemAttributes(q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
  112. q = manager.SStandaloneResourceBaseManager.FilterBySystemAttributes(q, userCred, query, scope)
  113. q = manager.SPendingDeletedBaseManager.FilterBySystemAttributes(manager.GetIStandaloneModelManager(), q, userCred, query, scope)
  114. return q
  115. }
  116. func (manager *SIdentityBaseResourceManager) ListItemFilter(
  117. ctx context.Context,
  118. q *sqlchemy.SQuery,
  119. userCred mcclient.TokenCredential,
  120. query api.IdentityBaseResourceListInput,
  121. ) (*sqlchemy.SQuery, error) {
  122. var err error
  123. q, err = manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneResourceListInput)
  124. if err != nil {
  125. return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.ListItemFilter")
  126. }
  127. q, err = manager.SDomainizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.DomainizedResourceListInput)
  128. if err != nil {
  129. return nil, errors.Wrap(err, "SDomainizedResourceBaseManager.ListItemFilter")
  130. }
  131. return q, nil
  132. }
  133. func (manager *SEnabledIdentityBaseResourceManager) ListItemFilter(
  134. ctx context.Context,
  135. q *sqlchemy.SQuery,
  136. userCred mcclient.TokenCredential,
  137. query api.EnabledIdentityBaseResourceListInput,
  138. ) (*sqlchemy.SQuery, error) {
  139. q, err := manager.SIdentityBaseResourceManager.ListItemFilter(ctx, q, userCred, query.IdentityBaseResourceListInput)
  140. if err != nil {
  141. return nil, errors.Wrap(err, "SIdentityBaseResourceManager.ListItemFilter")
  142. }
  143. q, err = manager.SEnabledResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledResourceBaseListInput)
  144. if err != nil {
  145. return nil, errors.Wrap(err, "SEnabledResourceBaseManager.ListItemFilter")
  146. }
  147. return q, nil
  148. }
  149. func (manager *SIdentityBaseResourceManager) OrderByExtraFields(
  150. ctx context.Context,
  151. q *sqlchemy.SQuery,
  152. userCred mcclient.TokenCredential,
  153. query api.IdentityBaseResourceListInput,
  154. ) (*sqlchemy.SQuery, error) {
  155. q, err := manager.SStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StandaloneResourceListInput)
  156. if err != nil {
  157. return nil, err
  158. }
  159. orderByDomain := query.OrderByDomain
  160. if sqlchemy.SQL_ORDER_ASC.Equals(orderByDomain) || sqlchemy.SQL_ORDER_DESC.Equals(orderByDomain) {
  161. domains := DomainManager.Query().SubQuery()
  162. q = q.LeftJoin(domains, sqlchemy.Equals(q.Field("domain_id"), domains.Field("id")))
  163. if sqlchemy.SQL_ORDER_ASC.Equals(orderByDomain) {
  164. q = q.Asc(domains.Field("name"))
  165. } else {
  166. q = q.Desc(domains.Field("name"))
  167. }
  168. }
  169. return q, nil
  170. }
  171. func (manager *SEnabledIdentityBaseResourceManager) OrderByExtraFields(
  172. ctx context.Context,
  173. q *sqlchemy.SQuery,
  174. userCred mcclient.TokenCredential,
  175. query api.EnabledIdentityBaseResourceListInput,
  176. ) (*sqlchemy.SQuery, error) {
  177. var err error
  178. q, err = manager.SIdentityBaseResourceManager.OrderByExtraFields(ctx, q, userCred, query.IdentityBaseResourceListInput)
  179. if err != nil {
  180. return nil, errors.Wrap(err, "SIdentityBaseResourceManager.OrderByExtraFields")
  181. }
  182. return q, nil
  183. }
  184. func (manager *SIdentityBaseResourceManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  185. var err error
  186. if field == "domain" {
  187. domainQuery := DomainManager.Query("name", "id").Distinct().SubQuery()
  188. q.AppendField(domainQuery.Field("name", "domain"))
  189. q = q.Join(domainQuery, sqlchemy.Equals(q.Field("domain_id"), domainQuery.Field("id")))
  190. q.GroupBy(domainQuery.Field("name"))
  191. return q, nil
  192. }
  193. q, err = manager.SStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
  194. if err == nil {
  195. return q, nil
  196. }
  197. return q, httperrors.ErrNotFound
  198. }
  199. func (manager *SEnabledIdentityBaseResourceManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  200. q, err := manager.SIdentityBaseResourceManager.QueryDistinctExtraField(q, field)
  201. if err == nil {
  202. return q, nil
  203. }
  204. return q, httperrors.ErrNotFound
  205. }
  206. func (manager *SIdentityBaseResourceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.IdentityBaseResourceCreateInput) (api.IdentityBaseResourceCreateInput, error) {
  207. domain, _ := DomainManager.FetchDomainById(ownerId.GetProjectDomainId())
  208. if domain.Enabled.IsFalse() {
  209. return input, httperrors.NewInvalidStatusError("domain is disabled")
  210. }
  211. var err error
  212. input.StandaloneResourceCreateInput, err = manager.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StandaloneResourceCreateInput)
  213. if err != nil {
  214. return input, err
  215. }
  216. return input, nil
  217. }
  218. func (manager *SEnabledIdentityBaseResourceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.EnabledIdentityBaseResourceCreateInput) (api.EnabledIdentityBaseResourceCreateInput, error) {
  219. var err error
  220. input.IdentityBaseResourceCreateInput, err = manager.SIdentityBaseResourceManager.ValidateCreateData(ctx, userCred, ownerId, query, input.IdentityBaseResourceCreateInput)
  221. if err != nil {
  222. return input, err
  223. }
  224. return input, nil
  225. }
  226. func (model *SIdentityBaseResource) ValidateUpdateData(
  227. ctx context.Context,
  228. userCred mcclient.TokenCredential,
  229. query jsonutils.JSONObject,
  230. input api.IdentityBaseUpdateInput,
  231. ) (api.IdentityBaseUpdateInput, error) {
  232. var err error
  233. input.StandaloneResourceBaseUpdateInput, err = model.SStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, input.StandaloneResourceBaseUpdateInput)
  234. if err != nil {
  235. return input, errors.Wrap(err, "SStandaloneResourceBase.ValidateUpdateData")
  236. }
  237. return input, nil
  238. }
  239. func (model *SEnabledIdentityBaseResource) ValidateUpdateData(
  240. ctx context.Context,
  241. userCred mcclient.TokenCredential,
  242. query jsonutils.JSONObject,
  243. input api.EnabledIdentityBaseUpdateInput,
  244. ) (api.EnabledIdentityBaseUpdateInput, error) {
  245. var err error
  246. input.IdentityBaseUpdateInput, err = model.SIdentityBaseResource.ValidateUpdateData(ctx, userCred, query, input.IdentityBaseUpdateInput)
  247. if err != nil {
  248. return input, errors.Wrap(err, "SIdentityBaseResource.ValidateUpdateData")
  249. }
  250. return input, nil
  251. }
  252. /*func(manager *SIdentityBaseResourceManager) NamespaceScope() rbacutils.TRbacScope {
  253. return rbacutils.ScopeSystem
  254. }*/
  255. func (manager *SIdentityBaseResourceManager) FetchCustomizeColumns(
  256. ctx context.Context,
  257. userCred mcclient.TokenCredential,
  258. query jsonutils.JSONObject,
  259. objs []interface{},
  260. fields stringutils2.SSortedStrings,
  261. isList bool,
  262. ) []api.IdentityBaseResourceDetails {
  263. rows := make([]api.IdentityBaseResourceDetails, len(objs))
  264. stdRows := manager.SStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  265. domainRows := manager.SDomainizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  266. for i := range rows {
  267. rows[i] = api.IdentityBaseResourceDetails{
  268. StandaloneResourceDetails: stdRows[i],
  269. DomainizedResourceInfo: domainRows[i],
  270. }
  271. }
  272. return rows
  273. }
  274. func (manager *SEnabledIdentityBaseResourceManager) FetchCustomizeColumns(
  275. ctx context.Context,
  276. userCred mcclient.TokenCredential,
  277. query jsonutils.JSONObject,
  278. objs []interface{},
  279. fields stringutils2.SSortedStrings,
  280. isList bool,
  281. ) []api.EnabledIdentityBaseResourceDetails {
  282. rows := make([]api.EnabledIdentityBaseResourceDetails, len(objs))
  283. identRows := manager.SIdentityBaseResourceManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  284. for i := range rows {
  285. rows[i] = api.EnabledIdentityBaseResourceDetails{
  286. IdentityBaseResourceDetails: identRows[i],
  287. }
  288. }
  289. return rows
  290. }
  291. func (model *SIdentityBaseResource) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
  292. model.DomainId = ownerId.GetProjectDomainId()
  293. return model.SStandaloneResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
  294. }
  295. /*
  296. func (self *SIdentityBaseResource) ValidateDeleteCondition(ctx context.Context) error {
  297. return self.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
  298. }
  299. func (self *SIdentityBaseResource) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
  300. return self.SStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, data)
  301. }
  302. */
  303. func (ident *SEnabledIdentityBaseResource) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
  304. if ident.Enabled.IsTrue() {
  305. return httperrors.NewResourceBusyError("resource is enabled")
  306. }
  307. return ident.SIdentityBaseResource.ValidateDeleteCondition(ctx, nil)
  308. }
  309. func (model *SIdentityBaseResource) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
  310. model.SStandaloneResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
  311. }
  312. func (model *SIdentityBaseResource) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
  313. model.SStandaloneResourceBase.PostUpdate(ctx, userCred, query, data)
  314. }
  315. func (model *SIdentityBaseResource) PostDelete(ctx context.Context, userCred mcclient.TokenCredential) {
  316. model.SStandaloneResourceBase.PostDelete(ctx, userCred)
  317. }
  318. func (manager *SIdentityBaseResourceManager) totalCount(scope rbacscope.TRbacScope, ownerId mcclient.IIdentityProvider) int {
  319. q := manager.Query()
  320. if scope != rbacscope.ScopeSystem {
  321. q = q.Equals("domain_id", ownerId.GetProjectDomainId())
  322. }
  323. cnt, _ := q.CountWithError()
  324. return cnt
  325. }
  326. func (manager *SIdentityBaseResourceManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
  327. q, err := manager.SStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  328. if err != nil {
  329. return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.ListItemExportKeys")
  330. }
  331. q, err = manager.SDomainizedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  332. if err != nil {
  333. return nil, errors.Wrap(err, "SDomainizedResourceBaseManager.ListItemExportKeys")
  334. }
  335. return q, nil
  336. }
  337. func (manager *SIdentityBaseResourceManager) GetPropertyDomainTagValuePairs(
  338. ctx context.Context,
  339. userCred mcclient.TokenCredential,
  340. query jsonutils.JSONObject,
  341. ) (jsonutils.JSONObject, error) {
  342. return db.GetPropertyTagValuePairs(
  343. manager.GetIIdentityModelManager(),
  344. "domain",
  345. "domain_id",
  346. ctx,
  347. userCred,
  348. query,
  349. )
  350. }
  351. func (manager *SIdentityBaseResourceManager) GetPropertyDomainTagValueTree(
  352. ctx context.Context,
  353. userCred mcclient.TokenCredential,
  354. query jsonutils.JSONObject,
  355. ) (jsonutils.JSONObject, error) {
  356. return db.GetPropertyTagValueTree(
  357. manager.GetIIdentityModelManager(),
  358. "domain",
  359. "domain_id",
  360. "",
  361. ctx,
  362. userCred,
  363. query,
  364. )
  365. }
  366. func (model *SIdentityBaseResource) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  367. if !model.PendingDeleted {
  368. newName := model.Name
  369. if !strings.Contains(model.Name, "-deleted-") {
  370. newName = fmt.Sprintf("%s-deleted-%s", model.Name, timeutils.ShortDate(timeutils.UtcNow()))
  371. }
  372. err := model.SPendingDeletedBase.MarkPendingDelete(model.GetIStandaloneModel(), ctx, userCred, newName)
  373. if err != nil {
  374. return errors.Wrap(err, "MarkPendingDelete")
  375. }
  376. }
  377. err := db.Metadata.RemoveAll(ctx, model, userCred)
  378. if err != nil {
  379. return errors.Wrapf(err, "Metadata.RemoveAll")
  380. }
  381. return nil // DeleteModel(ctx, userCred, model.GetIVirtualModel())
  382. }
  383. func (model *SIdentityBaseResource) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
  384. if !model.PendingDeleted {
  385. err := model.SPendingDeletedBase.MarkPendingDelete(model.GetIStandaloneModel(), ctx, userCred, "")
  386. if err != nil {
  387. return errors.Wrap(err, "MarkPendingDelete")
  388. }
  389. }
  390. return db.DeleteModel(ctx, userCred, model.GetIIdentityModel())
  391. }
  392. func (manager *SEnabledIdentityBaseResourceManager) GetIEnabledIdentityModelManager() IEnabledIdentityModelManager {
  393. return manager.GetVirtualObject().(IEnabledIdentityModelManager)
  394. }
  395. func (model *SEnabledIdentityBaseResource) GetIEnabledIdentityModelManager() IEnabledIdentityModelManager {
  396. return model.GetModelManager().(IEnabledIdentityModelManager)
  397. }
  398. func (model *SEnabledIdentityBaseResource) GetIEnabledIdentityModel() IEnabledIdentityModel {
  399. return model.GetVirtualObject().(IEnabledIdentityModel)
  400. }
  401. // 启用资源
  402. func (model *SEnabledIdentityBaseResource) PerformEnable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformEnableInput) (jsonutils.JSONObject, error) {
  403. err := db.EnabledPerformEnable(model.GetIEnabledIdentityModel(), ctx, userCred, true)
  404. if err != nil {
  405. return nil, errors.Wrap(err, "EnabledPerformEnable")
  406. }
  407. return nil, nil
  408. }
  409. // 禁用资源
  410. func (model *SEnabledIdentityBaseResource) PerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformDisableInput) (jsonutils.JSONObject, error) {
  411. err := db.EnabledPerformEnable(model.GetIEnabledIdentityModel(), ctx, userCred, false)
  412. if err != nil {
  413. return nil, errors.Wrap(err, "EnabledPerformEnable")
  414. }
  415. return nil, nil
  416. }
  417. func (model *SIdentityBaseResource) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
  418. desc := model.SStandaloneAnonResourceBase.GetShortDesc(ctx)
  419. if model.DomainId != api.KeystoneDomainRoot {
  420. desc.Add(jsonutils.NewString(model.DomainId), "domain_id")
  421. domain := model.GetIIdentityModel().GetDomain()
  422. if domain != nil {
  423. desc.Add(jsonutils.NewString(domain.Name), "domain")
  424. }
  425. }
  426. return desc
  427. }
  428. func (model *SEnabledIdentityBaseResource) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
  429. desc := model.SIdentityBaseResource.GetShortDesc(ctx)
  430. desc.Add(jsonutils.NewBool(model.Enabled.Bool()), "enabled")
  431. return desc
  432. }