base.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  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 drivers
  15. import (
  16. "context"
  17. "fmt"
  18. "strings"
  19. cloudid "yunion.io/x/cloudmux/pkg/apis/cloudid"
  20. "yunion.io/x/cloudmux/pkg/cloudprovider"
  21. "yunion.io/x/log"
  22. "yunion.io/x/pkg/errors"
  23. "yunion.io/x/pkg/utils"
  24. "yunion.io/x/onecloud/pkg/apis"
  25. api "yunion.io/x/onecloud/pkg/apis/cloudid"
  26. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  27. "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
  28. "yunion.io/x/onecloud/pkg/cloudcommon/validators"
  29. "yunion.io/x/onecloud/pkg/cloudid/models"
  30. "yunion.io/x/onecloud/pkg/cloudid/options"
  31. "yunion.io/x/onecloud/pkg/httperrors"
  32. "yunion.io/x/onecloud/pkg/mcclient"
  33. )
  34. type SBaseProviderDriver struct {
  35. }
  36. func (base SBaseProviderDriver) RequestSyncCloudaccountResources(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, provider cloudprovider.ICloudProvider) error {
  37. return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSyncCloudaccountResources for %s", account.Provider)
  38. }
  39. func (base SBaseProviderDriver) RequestSyncCloudproviderResources(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, provider cloudprovider.ICloudProvider) error {
  40. return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSyncCloudproviderResources for %s", cp.Provider)
  41. }
  42. func (base SBaseProviderDriver) ValidateCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.CloudgroupCreateInput) (*api.CloudgroupCreateInput, error) {
  43. return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateCloudgroup for %s", cp.Provider)
  44. }
  45. func (base SBaseProviderDriver) RequestCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, group *models.SCloudgroup) error {
  46. return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateCloudgroup for %s", cp.Provider)
  47. }
  48. func (base SBaseProviderDriver) ValidateCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.ClouduserCreateInput) (*api.ClouduserCreateInput, error) {
  49. return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateClouduser for %s", cp.Provider)
  50. }
  51. func (base SBaseProviderDriver) RequestCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, user *models.SClouduser) error {
  52. return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateClouduser for %s", cp.Provider)
  53. }
  54. func (base SBaseProviderDriver) RequestCreateSAMLProvider(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount) error {
  55. return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateSAMLProvider for %s", account.Provider)
  56. }
  57. func (base SBaseProviderDriver) RequestCreateRoleForSamlUser(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, group *models.SCloudgroup, user *models.SSamluser) error {
  58. return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateRoleForSamlUser for %s", account.Provider)
  59. }
  60. type SAccountBaseProviderDriver struct {
  61. SBaseProviderDriver
  62. }
  63. func (base SAccountBaseProviderDriver) ValidateCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.CloudgroupCreateInput) (*api.CloudgroupCreateInput, error) {
  64. for i := range input.CloudpolicyIds {
  65. policyObj, err := validators.ValidateModel(ctx, userCred, models.CloudpolicyManager, &input.CloudpolicyIds[i])
  66. if err != nil {
  67. return nil, err
  68. }
  69. policy := policyObj.(*models.SCloudpolicy)
  70. if policy.CloudaccountId != cp.CloudaccountId {
  71. return nil, httperrors.NewConflictError("policy %s do not belong to accounts %s", policy.Name, cp.Name)
  72. }
  73. }
  74. return input, nil
  75. }
  76. func (base SAccountBaseProviderDriver) RequestCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, group *models.SCloudgroup) error {
  77. _, err := db.Update(group, func() error {
  78. group.ManagerId = ""
  79. return nil
  80. })
  81. if err != nil {
  82. return errors.Wrapf(err, "db.Update")
  83. }
  84. driver := &SProviderBaseProviderDriver{}
  85. return driver.RequestCreateCloudgroup(ctx, userCred, cp, group)
  86. }
  87. func (base SAccountBaseProviderDriver) RequestCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, user *models.SClouduser) error {
  88. _, err := db.Update(user, func() error {
  89. user.ManagerId = ""
  90. return nil
  91. })
  92. if err != nil {
  93. return errors.Wrapf(err, "db.Update")
  94. }
  95. driver := &SProviderBaseProviderDriver{}
  96. return driver.RequestCreateClouduser(ctx, userCred, cp, user)
  97. }
  98. func (base SAccountBaseProviderDriver) ValidateCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.ClouduserCreateInput) (*api.ClouduserCreateInput, error) {
  99. for i := range input.CloudpolicyIds {
  100. policyObj, err := validators.ValidateModel(ctx, userCred, models.CloudpolicyManager, &input.CloudpolicyIds[i])
  101. if err != nil {
  102. return nil, err
  103. }
  104. policy := policyObj.(*models.SCloudpolicy)
  105. if policy.CloudaccountId != cp.CloudaccountId {
  106. return nil, httperrors.NewConflictError("policy %s do not belong to accounts %s", policy.Name, cp.Name)
  107. }
  108. }
  109. for i := range input.CloudgroupIds {
  110. groupObj, err := validators.ValidateModel(ctx, userCred, models.CloudgroupManager, &input.CloudgroupIds[i])
  111. if err != nil {
  112. return nil, err
  113. }
  114. group := groupObj.(*models.SCloudgroup)
  115. if group.CloudaccountId != cp.CloudaccountId {
  116. return nil, httperrors.NewConflictError("group %s do not belong to accounts %s", group.Name, cp.Name)
  117. }
  118. }
  119. return input, nil
  120. }
  121. func (base SAccountBaseProviderDriver) RequestSyncCloudaccountResources(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, provider cloudprovider.ICloudProvider) error {
  122. func() {
  123. policies, err := provider.GetICloudpolicies()
  124. if err != nil {
  125. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  126. log.Errorf("get policies for account %s error: %v", account.Name, err)
  127. }
  128. return
  129. }
  130. result := account.SyncPolicies(ctx, userCred, policies, "")
  131. log.Infof("Sync %s policies for account %s result: %s", account.Provider, account.Name, result.Result())
  132. }()
  133. func() {
  134. lockman.LockRawObject(ctx, account.Id, models.SAMLProviderManager.Keyword())
  135. defer lockman.ReleaseRawObject(ctx, account.Id, models.SAMLProviderManager.Keyword())
  136. samls, err := provider.GetICloudSAMLProviders()
  137. if err != nil {
  138. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  139. log.Errorf("get saml providers for account %s error: %v", account.Name, err)
  140. }
  141. return
  142. }
  143. result := account.SyncSAMLProviders(ctx, userCred, samls, "")
  144. log.Infof("Sync SAMLProviders for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
  145. }()
  146. func() {
  147. roles, err := provider.GetICloudroles()
  148. if err != nil {
  149. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  150. log.Errorf("get roles for account %s error: %v", account.Name, err)
  151. }
  152. return
  153. }
  154. result := account.SyncCloudroles(ctx, userCred, roles, "")
  155. log.Infof("SyncCloudroles for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
  156. }()
  157. func() {
  158. iGroups, err := provider.GetICloudgroups()
  159. if err != nil {
  160. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  161. log.Errorf("get groups for account %s error: %v", account.Name, err)
  162. }
  163. return
  164. }
  165. localGroups, remoteGroups, result := account.SyncCloudgroups(ctx, userCred, iGroups, "")
  166. log.Infof("SyncCloudgroups for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
  167. for i := 0; i < len(localGroups); i += 1 {
  168. func() {
  169. // lock cloudgroup
  170. lockman.LockObject(ctx, &localGroups[i])
  171. defer lockman.ReleaseObject(ctx, &localGroups[i])
  172. localGroups[i].SyncCloudpolicies(ctx, userCred, remoteGroups[i])
  173. }()
  174. }
  175. }()
  176. func() {
  177. iUsers, err := provider.GetICloudusers()
  178. if err != nil {
  179. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  180. log.Errorf("get users for account %s error: %v", account.Name, err)
  181. }
  182. return
  183. }
  184. localUsers, remoteUsers, result := account.SyncCloudusers(ctx, userCred, iUsers, "")
  185. log.Infof("SyncCloudusers for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
  186. for i := 0; i < len(localUsers); i += 1 {
  187. func() {
  188. // lock clouduser
  189. lockman.LockObject(ctx, &localUsers[i])
  190. defer lockman.ReleaseObject(ctx, &localUsers[i])
  191. localUsers[i].SyncCloudpolicies(ctx, userCred, remoteUsers[i])
  192. localUsers[i].SyncCloudgroups(ctx, userCred, remoteUsers[i])
  193. }()
  194. }
  195. }()
  196. return nil
  197. }
  198. type SProviderBaseProviderDriver struct {
  199. SBaseProviderDriver
  200. }
  201. func (base SProviderBaseProviderDriver) RequestSyncCloudproviderResources(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, provider cloudprovider.ICloudProvider) error {
  202. account, err := cp.GetCloudaccount()
  203. if err != nil {
  204. return errors.Wrapf(err, "GetCloudaccount")
  205. }
  206. func() {
  207. policies, err := provider.GetICloudpolicies()
  208. if err != nil {
  209. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  210. log.Errorf("get system policies for manager %s error: %v", cp.Name, err)
  211. }
  212. return
  213. }
  214. result := account.SyncPolicies(ctx, userCred, policies, cp.Id)
  215. log.Infof("Sync %s policies for manager %s result: %s", cp.Provider, cp.Name, result.Result())
  216. }()
  217. func() {
  218. lockman.LockRawObject(ctx, cp.Id, models.SAMLProviderManager.Keyword())
  219. defer lockman.ReleaseRawObject(ctx, cp.Id, models.SAMLProviderManager.Keyword())
  220. samls, err := provider.GetICloudSAMLProviders()
  221. if err != nil {
  222. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  223. log.Errorf("get saml providers for manager %s error: %v", cp.Name, err)
  224. }
  225. return
  226. }
  227. result := account.SyncSAMLProviders(ctx, userCred, samls, cp.Id)
  228. log.Infof("Sync SAMLProviders for manager %s(%s) result: %s", cp.Name, cp.Provider, result.Result())
  229. }()
  230. func() {
  231. roles, err := provider.GetICloudroles()
  232. if err != nil {
  233. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  234. log.Errorf("get roles for manager %s error: %v", cp.Name, err)
  235. }
  236. return
  237. }
  238. result := account.SyncCloudroles(ctx, userCred, roles, cp.Id)
  239. log.Infof("SyncCloudroles for manager %s(%s) result: %s", cp.Name, cp.Provider, result.Result())
  240. }()
  241. func() {
  242. iGroups, err := provider.GetICloudgroups()
  243. if err != nil {
  244. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  245. log.Errorf("get groups for manager %s error: %v", cp.Name, err)
  246. }
  247. return
  248. }
  249. localGroups, remoteGroups, result := account.SyncCloudgroups(ctx, userCred, iGroups, cp.Id)
  250. log.Infof("SyncCloudgroups for manager %s(%s) result: %s", cp.Name, cp.Provider, result.Result())
  251. for i := 0; i < len(localGroups); i += 1 {
  252. func() {
  253. // lock cloudgroup
  254. lockman.LockObject(ctx, &localGroups[i])
  255. defer lockman.ReleaseObject(ctx, &localGroups[i])
  256. localGroups[i].SyncCloudpolicies(ctx, userCred, remoteGroups[i])
  257. }()
  258. }
  259. }()
  260. func() {
  261. iUsers, err := provider.GetICloudusers()
  262. if err != nil {
  263. if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
  264. log.Errorf("get users for manager %s error: %v", cp.Name, err)
  265. }
  266. return
  267. }
  268. localUsers, remoteUsers, result := account.SyncCloudusers(ctx, userCred, iUsers, cp.Id)
  269. log.Infof("SyncCloudusers for manger %s(%s) result: %s", cp.Name, cp.Provider, result.Result())
  270. for i := 0; i < len(localUsers); i += 1 {
  271. func() {
  272. // lock clouduser
  273. lockman.LockObject(ctx, &localUsers[i])
  274. defer lockman.ReleaseObject(ctx, &localUsers[i])
  275. localUsers[i].SyncCloudpolicies(ctx, userCred, remoteUsers[i])
  276. localUsers[i].SyncCloudgroups(ctx, userCred, remoteUsers[i])
  277. }()
  278. }
  279. }()
  280. return nil
  281. }
  282. func (base SProviderBaseProviderDriver) ValidateCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.CloudgroupCreateInput) (*api.CloudgroupCreateInput, error) {
  283. for i := range input.CloudpolicyIds {
  284. policyObj, err := validators.ValidateModel(ctx, userCred, models.CloudpolicyManager, &input.CloudpolicyIds[i])
  285. if err != nil {
  286. return nil, err
  287. }
  288. policy := policyObj.(*models.SCloudpolicy)
  289. if policy.ManagerId != cp.Id {
  290. return nil, httperrors.NewConflictError("policy %s do not belong to subaccounts %s", policy.Name, cp.Name)
  291. }
  292. }
  293. return input, nil
  294. }
  295. func (base SProviderBaseProviderDriver) ValidateCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.ClouduserCreateInput) (*api.ClouduserCreateInput, error) {
  296. for i := range input.CloudpolicyIds {
  297. policyObj, err := validators.ValidateModel(ctx, userCred, models.CloudpolicyManager, &input.CloudpolicyIds[i])
  298. if err != nil {
  299. return nil, err
  300. }
  301. policy := policyObj.(*models.SCloudpolicy)
  302. if policy.ManagerId != cp.Id {
  303. return nil, httperrors.NewConflictError("policy %s do not belong to subaccounts %s", policy.Name, cp.Name)
  304. }
  305. }
  306. for i := range input.CloudgroupIds {
  307. groupObj, err := validators.ValidateModel(ctx, userCred, models.CloudgroupManager, &input.CloudgroupIds[i])
  308. if err != nil {
  309. return nil, err
  310. }
  311. group := groupObj.(*models.SCloudgroup)
  312. if group.ManagerId != cp.Id {
  313. return nil, httperrors.NewConflictError("group %s do not belong to subaccounts %s", group.Name, cp.Name)
  314. }
  315. }
  316. return input, nil
  317. }
  318. func (base SProviderBaseProviderDriver) RequestCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, group *models.SCloudgroup) error {
  319. provider, err := group.GetProvider()
  320. if err != nil {
  321. return errors.Wrapf(err, "GetProvider")
  322. }
  323. iGroup, err := provider.CreateICloudgroup(group.Name, group.Description)
  324. if err != nil {
  325. return errors.Wrapf(err, "CreateICloudgroup")
  326. }
  327. _, err = db.Update(group, func() error {
  328. group.ExternalId = iGroup.GetGlobalId()
  329. group.Status = apis.STATUS_AVAILABLE
  330. return nil
  331. })
  332. if err != nil {
  333. return errors.Wrapf(err, "db.Update")
  334. }
  335. policies, err := group.GetCloudpolicies()
  336. if err != nil {
  337. return errors.Wrapf(err, "GetCloudpolicies")
  338. }
  339. for i := range policies {
  340. err = iGroup.AttachPolicy(policies[i].ExternalId, cloudid.TPolicyType(policies[i].PolicyType))
  341. if err != nil {
  342. return errors.Wrapf(err, "Attach %s policy %s", policies[i].PolicyType, policies[i].ExternalId)
  343. }
  344. }
  345. group.SyncCloudpolicies(ctx, userCred, iGroup)
  346. return nil
  347. }
  348. func (base SProviderBaseProviderDriver) RequestCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, user *models.SClouduser) error {
  349. provider, err := user.GetProvider()
  350. if err != nil {
  351. return errors.Wrapf(err, "GetProvider")
  352. }
  353. opts := &cloudprovider.SClouduserCreateConfig{
  354. Name: user.Name,
  355. Desc: user.Description,
  356. IsConsoleLogin: user.IsConsoleLogin.Bool(),
  357. Email: user.Email,
  358. MobilePhone: user.MobilePhone,
  359. }
  360. opts.Password, _ = user.GetPassword()
  361. iUser, err := provider.CreateIClouduser(opts)
  362. if err != nil {
  363. return errors.Wrapf(err, "CreateIClouduser")
  364. }
  365. _, err = db.Update(user, func() error {
  366. user.ExternalId = iUser.GetGlobalId()
  367. return nil
  368. })
  369. if err != nil {
  370. return errors.Wrapf(err, "db.Update")
  371. }
  372. policies, err := user.GetCloudpolicies()
  373. if err != nil {
  374. return errors.Wrapf(err, "GetCloudpolicies")
  375. }
  376. for i := range policies {
  377. err = iUser.AttachPolicy(policies[i].ExternalId, cloudid.TPolicyType(policies[i].PolicyType))
  378. if err != nil {
  379. return errors.Wrapf(err, "Attach %s policy %s", policies[i].PolicyType, policies[i].ExternalId)
  380. }
  381. }
  382. user.SyncCloudpolicies(ctx, userCred, iUser)
  383. groups, err := user.GetCloudgroups()
  384. if err != nil {
  385. return errors.Wrapf(err, "GetCloudgroups")
  386. }
  387. for i := range groups {
  388. iGroup, err := groups[i].GetICloudgroup()
  389. if err != nil {
  390. return errors.Wrapf(err, "GetICloudgroup")
  391. }
  392. err = iGroup.AddUser(user.Name)
  393. if err != nil {
  394. return errors.Wrapf(err, "join group %s", groups[i].Name)
  395. }
  396. }
  397. user.SyncCloudgroups(ctx, userCred, iUser)
  398. return nil
  399. }
  400. func (base SProviderBaseProviderDriver) RequestCreateSAMLProvider(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount) error {
  401. providers, err := account.GetCloudproviders()
  402. if err != nil {
  403. return errors.Wrapf(err, "GetCloudproviders")
  404. }
  405. for i := range providers {
  406. err = func() error {
  407. lockman.LockRawObject(ctx, providers[i].Id, models.SAMLProviderManager.Keyword())
  408. defer lockman.ReleaseRawObject(ctx, providers[i].Id, models.SAMLProviderManager.Keyword())
  409. samlProviders, err := providers[i].GetSamlProviders()
  410. if err != nil {
  411. return errors.Wrapf(err, "GetSamlProviders")
  412. }
  413. iProvider, err := providers[i].GetProvider()
  414. if err != nil {
  415. return errors.Wrapf(err, "GetProvider")
  416. }
  417. for j := range samlProviders {
  418. if samlProviders[j].EntityId != options.Options.ApiServer {
  419. continue
  420. }
  421. if strings.Contains(samlProviders[j].MetadataDocument, "login/"+providers[i].Id) {
  422. return nil
  423. }
  424. iSamlProviders, err := iProvider.GetICloudSAMLProviders()
  425. if err != nil {
  426. return errors.Wrapf(err, "GetICloudSAMLProviders")
  427. }
  428. for _, iSaml := range iSamlProviders {
  429. if iSaml.GetGlobalId() != samlProviders[j].ExternalId {
  430. continue
  431. }
  432. doc := models.SamlIdpInstance().GetMetadata(providers[i].Id)
  433. err := iSaml.UpdateMetadata(doc)
  434. if err != nil {
  435. return errors.Wrapf(err, "UpdateMetadata")
  436. }
  437. _, err = db.Update(&samlProviders[j], func() error {
  438. samlProviders[j].Status = apis.STATUS_AVAILABLE
  439. samlProviders[j].MetadataDocument = doc.String()
  440. return nil
  441. })
  442. return err
  443. }
  444. }
  445. opts := &cloudprovider.SAMLProviderCreateOptions{
  446. Metadata: models.SamlIdpInstance().GetMetadata(providers[i].Id),
  447. Name: strings.TrimPrefix(options.Options.ApiServer, "https://"),
  448. Desc: "create by cloudpods",
  449. }
  450. log.Debugf("create saml provider for manager %s(%s) %s", providers[i].Name, providers[i].Id, opts.Metadata.String())
  451. opts.Name = strings.TrimPrefix(opts.Name, "http://")
  452. iSaml, err := iProvider.CreateICloudSAMLProvider(opts)
  453. if err != nil {
  454. return errors.Wrapf(err, "CreateICloudSAMLProvider")
  455. }
  456. saml := &models.SSAMLProvider{}
  457. saml.SetModelManager(models.SAMLProviderManager, saml)
  458. saml.Name = opts.Name
  459. saml.DomainId = account.DomainId
  460. saml.ManagerId = providers[i].Id
  461. saml.CloudaccountId = account.Id
  462. saml.ExternalId = iSaml.GetGlobalId()
  463. saml.Status = apis.STATUS_AVAILABLE
  464. saml.EntityId = options.Options.ApiServer
  465. err = models.SAMLProviderManager.TableSpec().Insert(ctx, saml)
  466. if err != nil {
  467. return err
  468. }
  469. return saml.SyncWithCloudSAMLProvider(ctx, userCred, iSaml, providers[i].Id)
  470. }()
  471. if err != nil {
  472. log.Errorf("create saml provider for manager %s error: %v", providers[i].Name, err)
  473. }
  474. }
  475. return nil
  476. }
  477. func (base SProviderBaseProviderDriver) RequestCreateRoleForSamlUser(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, group *models.SCloudgroup, user *models.SSamluser) error {
  478. provider, err := group.GetCloudprovider()
  479. if err != nil {
  480. return errors.Wrapf(err, "GetCloudprovider")
  481. }
  482. samlProvider, err := provider.GetSamlProvider()
  483. if err != nil {
  484. return errors.Wrapf(err, "GetSamlProvider")
  485. }
  486. policies, err := group.GetCloudpolicies()
  487. if err != nil {
  488. return errors.Wrapf(err, "GetCloudpolicies")
  489. }
  490. roles, err := account.GetCloudroles(provider.Id)
  491. if err != nil {
  492. return errors.Wrapf(err, "GetCloudroles")
  493. }
  494. for i := range roles {
  495. if roles[i].Status == apis.STATUS_AVAILABLE && len(roles[i].ExternalId) > 0 && roles[i].SAMLProviderId == samlProvider.Id && roles[i].CloudgroupId == group.Id {
  496. _, err := db.Update(user, func() error {
  497. user.CloudroleId = roles[i].Id
  498. return nil
  499. })
  500. if err != nil {
  501. return err
  502. }
  503. existPolicies := []string{}
  504. iRole, err := roles[i].GetICloudrole()
  505. if err != nil {
  506. return err
  507. }
  508. iPolicies, err := iRole.GetICloudpolicies()
  509. if err != nil {
  510. return errors.Wrapf(err, "GetICloudpolicies")
  511. }
  512. for _, policy := range iPolicies {
  513. existPolicies = append(existPolicies, policy.GetGlobalId())
  514. }
  515. for _, policy := range policies {
  516. if !utils.IsInStringArray(policy.ExternalId, existPolicies) {
  517. err = iRole.AttachPolicy(policy.ExternalId, cloudid.TPolicyType(policy.PolicyType))
  518. if err != nil {
  519. return errors.Wrapf(err, "attach %s policy %s", policy.PolicyType, policy.ExternalId)
  520. }
  521. }
  522. }
  523. return nil
  524. }
  525. }
  526. iProvider, err := group.GetProvider()
  527. if err != nil {
  528. return errors.Wrapf(err, "GetProvider")
  529. }
  530. opts := &cloudprovider.SRoleCreateOptions{
  531. Name: fmt.Sprintf("%s-%s", group.Name, utils.GenRequestId(5)),
  532. Desc: fmt.Sprintf("auto create by cloudpods"),
  533. SAMLProvider: samlProvider.ExternalId,
  534. }
  535. iRole, err := iProvider.CreateICloudrole(opts)
  536. if err != nil {
  537. return errors.Wrapf(err, "CreateICloudrole")
  538. }
  539. role := &models.SCloudrole{}
  540. role.SetModelManager(models.CloudroleManager, role)
  541. role.ExternalId = iRole.GetGlobalId()
  542. role.Name = iRole.GetName()
  543. role.Document = iRole.GetDocument()
  544. role.CloudaccountId = account.Id
  545. role.ManagerId = group.ManagerId
  546. role.SAMLProviderId = samlProvider.Id
  547. role.CloudgroupId = group.Id
  548. role.Status = apis.STATUS_AVAILABLE
  549. role.SetEnabled(true)
  550. err = models.CloudroleManager.TableSpec().Insert(ctx, role)
  551. if err != nil {
  552. return errors.Wrapf(err, "")
  553. }
  554. _, err = db.Update(user, func() error {
  555. user.CloudroleId = role.Id
  556. return nil
  557. })
  558. if err != nil {
  559. return err
  560. }
  561. for _, policy := range policies {
  562. err := iRole.AttachPolicy(policy.ExternalId, cloudid.TPolicyType(policy.PolicyType))
  563. if err != nil {
  564. return errors.Wrapf(err, "attach %s policy %s", policy.PolicyType, policy.ExternalId)
  565. }
  566. }
  567. return nil
  568. }