| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package drivers
- import (
- "context"
- "fmt"
- "strings"
- cloudid "yunion.io/x/cloudmux/pkg/apis/cloudid"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/utils"
- "yunion.io/x/onecloud/pkg/apis"
- api "yunion.io/x/onecloud/pkg/apis/cloudid"
- "yunion.io/x/onecloud/pkg/cloudcommon/db"
- "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
- "yunion.io/x/onecloud/pkg/cloudcommon/validators"
- "yunion.io/x/onecloud/pkg/cloudid/models"
- "yunion.io/x/onecloud/pkg/cloudid/options"
- "yunion.io/x/onecloud/pkg/httperrors"
- "yunion.io/x/onecloud/pkg/mcclient"
- )
- type SBaseProviderDriver struct {
- }
- func (base SBaseProviderDriver) RequestSyncCloudaccountResources(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, provider cloudprovider.ICloudProvider) error {
- return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSyncCloudaccountResources for %s", account.Provider)
- }
- func (base SBaseProviderDriver) RequestSyncCloudproviderResources(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, provider cloudprovider.ICloudProvider) error {
- return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSyncCloudproviderResources for %s", cp.Provider)
- }
- func (base SBaseProviderDriver) ValidateCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.CloudgroupCreateInput) (*api.CloudgroupCreateInput, error) {
- return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateCloudgroup for %s", cp.Provider)
- }
- func (base SBaseProviderDriver) RequestCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, group *models.SCloudgroup) error {
- return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateCloudgroup for %s", cp.Provider)
- }
- func (base SBaseProviderDriver) ValidateCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.ClouduserCreateInput) (*api.ClouduserCreateInput, error) {
- return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateClouduser for %s", cp.Provider)
- }
- func (base SBaseProviderDriver) RequestCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, user *models.SClouduser) error {
- return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateClouduser for %s", cp.Provider)
- }
- func (base SBaseProviderDriver) RequestCreateSAMLProvider(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount) error {
- return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateSAMLProvider for %s", account.Provider)
- }
- func (base SBaseProviderDriver) RequestCreateRoleForSamlUser(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, group *models.SCloudgroup, user *models.SSamluser) error {
- return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateRoleForSamlUser for %s", account.Provider)
- }
- type SAccountBaseProviderDriver struct {
- SBaseProviderDriver
- }
- func (base SAccountBaseProviderDriver) ValidateCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.CloudgroupCreateInput) (*api.CloudgroupCreateInput, error) {
- for i := range input.CloudpolicyIds {
- policyObj, err := validators.ValidateModel(ctx, userCred, models.CloudpolicyManager, &input.CloudpolicyIds[i])
- if err != nil {
- return nil, err
- }
- policy := policyObj.(*models.SCloudpolicy)
- if policy.CloudaccountId != cp.CloudaccountId {
- return nil, httperrors.NewConflictError("policy %s do not belong to accounts %s", policy.Name, cp.Name)
- }
- }
- return input, nil
- }
- func (base SAccountBaseProviderDriver) RequestCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, group *models.SCloudgroup) error {
- _, err := db.Update(group, func() error {
- group.ManagerId = ""
- return nil
- })
- if err != nil {
- return errors.Wrapf(err, "db.Update")
- }
- driver := &SProviderBaseProviderDriver{}
- return driver.RequestCreateCloudgroup(ctx, userCred, cp, group)
- }
- func (base SAccountBaseProviderDriver) RequestCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, user *models.SClouduser) error {
- _, err := db.Update(user, func() error {
- user.ManagerId = ""
- return nil
- })
- if err != nil {
- return errors.Wrapf(err, "db.Update")
- }
- driver := &SProviderBaseProviderDriver{}
- return driver.RequestCreateClouduser(ctx, userCred, cp, user)
- }
- func (base SAccountBaseProviderDriver) ValidateCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.ClouduserCreateInput) (*api.ClouduserCreateInput, error) {
- for i := range input.CloudpolicyIds {
- policyObj, err := validators.ValidateModel(ctx, userCred, models.CloudpolicyManager, &input.CloudpolicyIds[i])
- if err != nil {
- return nil, err
- }
- policy := policyObj.(*models.SCloudpolicy)
- if policy.CloudaccountId != cp.CloudaccountId {
- return nil, httperrors.NewConflictError("policy %s do not belong to accounts %s", policy.Name, cp.Name)
- }
- }
- for i := range input.CloudgroupIds {
- groupObj, err := validators.ValidateModel(ctx, userCred, models.CloudgroupManager, &input.CloudgroupIds[i])
- if err != nil {
- return nil, err
- }
- group := groupObj.(*models.SCloudgroup)
- if group.CloudaccountId != cp.CloudaccountId {
- return nil, httperrors.NewConflictError("group %s do not belong to accounts %s", group.Name, cp.Name)
- }
- }
- return input, nil
- }
- func (base SAccountBaseProviderDriver) RequestSyncCloudaccountResources(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, provider cloudprovider.ICloudProvider) error {
- func() {
- policies, err := provider.GetICloudpolicies()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get policies for account %s error: %v", account.Name, err)
- }
- return
- }
- result := account.SyncPolicies(ctx, userCred, policies, "")
- log.Infof("Sync %s policies for account %s result: %s", account.Provider, account.Name, result.Result())
- }()
- func() {
- lockman.LockRawObject(ctx, account.Id, models.SAMLProviderManager.Keyword())
- defer lockman.ReleaseRawObject(ctx, account.Id, models.SAMLProviderManager.Keyword())
- samls, err := provider.GetICloudSAMLProviders()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get saml providers for account %s error: %v", account.Name, err)
- }
- return
- }
- result := account.SyncSAMLProviders(ctx, userCred, samls, "")
- log.Infof("Sync SAMLProviders for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
- }()
- func() {
- roles, err := provider.GetICloudroles()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get roles for account %s error: %v", account.Name, err)
- }
- return
- }
- result := account.SyncCloudroles(ctx, userCred, roles, "")
- log.Infof("SyncCloudroles for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
- }()
- func() {
- iGroups, err := provider.GetICloudgroups()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get groups for account %s error: %v", account.Name, err)
- }
- return
- }
- localGroups, remoteGroups, result := account.SyncCloudgroups(ctx, userCred, iGroups, "")
- log.Infof("SyncCloudgroups for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
- for i := 0; i < len(localGroups); i += 1 {
- func() {
- // lock cloudgroup
- lockman.LockObject(ctx, &localGroups[i])
- defer lockman.ReleaseObject(ctx, &localGroups[i])
- localGroups[i].SyncCloudpolicies(ctx, userCred, remoteGroups[i])
- }()
- }
- }()
- func() {
- iUsers, err := provider.GetICloudusers()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get users for account %s error: %v", account.Name, err)
- }
- return
- }
- localUsers, remoteUsers, result := account.SyncCloudusers(ctx, userCred, iUsers, "")
- log.Infof("SyncCloudusers for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
- for i := 0; i < len(localUsers); i += 1 {
- func() {
- // lock clouduser
- lockman.LockObject(ctx, &localUsers[i])
- defer lockman.ReleaseObject(ctx, &localUsers[i])
- localUsers[i].SyncCloudpolicies(ctx, userCred, remoteUsers[i])
- localUsers[i].SyncCloudgroups(ctx, userCred, remoteUsers[i])
- }()
- }
- }()
- return nil
- }
- type SProviderBaseProviderDriver struct {
- SBaseProviderDriver
- }
- func (base SProviderBaseProviderDriver) RequestSyncCloudproviderResources(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, provider cloudprovider.ICloudProvider) error {
- account, err := cp.GetCloudaccount()
- if err != nil {
- return errors.Wrapf(err, "GetCloudaccount")
- }
- func() {
- policies, err := provider.GetICloudpolicies()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get system policies for manager %s error: %v", cp.Name, err)
- }
- return
- }
- result := account.SyncPolicies(ctx, userCred, policies, cp.Id)
- log.Infof("Sync %s policies for manager %s result: %s", cp.Provider, cp.Name, result.Result())
- }()
- func() {
- lockman.LockRawObject(ctx, cp.Id, models.SAMLProviderManager.Keyword())
- defer lockman.ReleaseRawObject(ctx, cp.Id, models.SAMLProviderManager.Keyword())
- samls, err := provider.GetICloudSAMLProviders()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get saml providers for manager %s error: %v", cp.Name, err)
- }
- return
- }
- result := account.SyncSAMLProviders(ctx, userCred, samls, cp.Id)
- log.Infof("Sync SAMLProviders for manager %s(%s) result: %s", cp.Name, cp.Provider, result.Result())
- }()
- func() {
- roles, err := provider.GetICloudroles()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get roles for manager %s error: %v", cp.Name, err)
- }
- return
- }
- result := account.SyncCloudroles(ctx, userCred, roles, cp.Id)
- log.Infof("SyncCloudroles for manager %s(%s) result: %s", cp.Name, cp.Provider, result.Result())
- }()
- func() {
- iGroups, err := provider.GetICloudgroups()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get groups for manager %s error: %v", cp.Name, err)
- }
- return
- }
- localGroups, remoteGroups, result := account.SyncCloudgroups(ctx, userCred, iGroups, cp.Id)
- log.Infof("SyncCloudgroups for manager %s(%s) result: %s", cp.Name, cp.Provider, result.Result())
- for i := 0; i < len(localGroups); i += 1 {
- func() {
- // lock cloudgroup
- lockman.LockObject(ctx, &localGroups[i])
- defer lockman.ReleaseObject(ctx, &localGroups[i])
- localGroups[i].SyncCloudpolicies(ctx, userCred, remoteGroups[i])
- }()
- }
- }()
- func() {
- iUsers, err := provider.GetICloudusers()
- if err != nil {
- if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
- log.Errorf("get users for manager %s error: %v", cp.Name, err)
- }
- return
- }
- localUsers, remoteUsers, result := account.SyncCloudusers(ctx, userCred, iUsers, cp.Id)
- log.Infof("SyncCloudusers for manger %s(%s) result: %s", cp.Name, cp.Provider, result.Result())
- for i := 0; i < len(localUsers); i += 1 {
- func() {
- // lock clouduser
- lockman.LockObject(ctx, &localUsers[i])
- defer lockman.ReleaseObject(ctx, &localUsers[i])
- localUsers[i].SyncCloudpolicies(ctx, userCred, remoteUsers[i])
- localUsers[i].SyncCloudgroups(ctx, userCred, remoteUsers[i])
- }()
- }
- }()
- return nil
- }
- func (base SProviderBaseProviderDriver) ValidateCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.CloudgroupCreateInput) (*api.CloudgroupCreateInput, error) {
- for i := range input.CloudpolicyIds {
- policyObj, err := validators.ValidateModel(ctx, userCred, models.CloudpolicyManager, &input.CloudpolicyIds[i])
- if err != nil {
- return nil, err
- }
- policy := policyObj.(*models.SCloudpolicy)
- if policy.ManagerId != cp.Id {
- return nil, httperrors.NewConflictError("policy %s do not belong to subaccounts %s", policy.Name, cp.Name)
- }
- }
- return input, nil
- }
- func (base SProviderBaseProviderDriver) ValidateCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, input *api.ClouduserCreateInput) (*api.ClouduserCreateInput, error) {
- for i := range input.CloudpolicyIds {
- policyObj, err := validators.ValidateModel(ctx, userCred, models.CloudpolicyManager, &input.CloudpolicyIds[i])
- if err != nil {
- return nil, err
- }
- policy := policyObj.(*models.SCloudpolicy)
- if policy.ManagerId != cp.Id {
- return nil, httperrors.NewConflictError("policy %s do not belong to subaccounts %s", policy.Name, cp.Name)
- }
- }
- for i := range input.CloudgroupIds {
- groupObj, err := validators.ValidateModel(ctx, userCred, models.CloudgroupManager, &input.CloudgroupIds[i])
- if err != nil {
- return nil, err
- }
- group := groupObj.(*models.SCloudgroup)
- if group.ManagerId != cp.Id {
- return nil, httperrors.NewConflictError("group %s do not belong to subaccounts %s", group.Name, cp.Name)
- }
- }
- return input, nil
- }
- func (base SProviderBaseProviderDriver) RequestCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, group *models.SCloudgroup) error {
- provider, err := group.GetProvider()
- if err != nil {
- return errors.Wrapf(err, "GetProvider")
- }
- iGroup, err := provider.CreateICloudgroup(group.Name, group.Description)
- if err != nil {
- return errors.Wrapf(err, "CreateICloudgroup")
- }
- _, err = db.Update(group, func() error {
- group.ExternalId = iGroup.GetGlobalId()
- group.Status = apis.STATUS_AVAILABLE
- return nil
- })
- if err != nil {
- return errors.Wrapf(err, "db.Update")
- }
- policies, err := group.GetCloudpolicies()
- if err != nil {
- return errors.Wrapf(err, "GetCloudpolicies")
- }
- for i := range policies {
- err = iGroup.AttachPolicy(policies[i].ExternalId, cloudid.TPolicyType(policies[i].PolicyType))
- if err != nil {
- return errors.Wrapf(err, "Attach %s policy %s", policies[i].PolicyType, policies[i].ExternalId)
- }
- }
- group.SyncCloudpolicies(ctx, userCred, iGroup)
- return nil
- }
- func (base SProviderBaseProviderDriver) RequestCreateClouduser(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, user *models.SClouduser) error {
- provider, err := user.GetProvider()
- if err != nil {
- return errors.Wrapf(err, "GetProvider")
- }
- opts := &cloudprovider.SClouduserCreateConfig{
- Name: user.Name,
- Desc: user.Description,
- IsConsoleLogin: user.IsConsoleLogin.Bool(),
- Email: user.Email,
- MobilePhone: user.MobilePhone,
- }
- opts.Password, _ = user.GetPassword()
- iUser, err := provider.CreateIClouduser(opts)
- if err != nil {
- return errors.Wrapf(err, "CreateIClouduser")
- }
- _, err = db.Update(user, func() error {
- user.ExternalId = iUser.GetGlobalId()
- return nil
- })
- if err != nil {
- return errors.Wrapf(err, "db.Update")
- }
- policies, err := user.GetCloudpolicies()
- if err != nil {
- return errors.Wrapf(err, "GetCloudpolicies")
- }
- for i := range policies {
- err = iUser.AttachPolicy(policies[i].ExternalId, cloudid.TPolicyType(policies[i].PolicyType))
- if err != nil {
- return errors.Wrapf(err, "Attach %s policy %s", policies[i].PolicyType, policies[i].ExternalId)
- }
- }
- user.SyncCloudpolicies(ctx, userCred, iUser)
- groups, err := user.GetCloudgroups()
- if err != nil {
- return errors.Wrapf(err, "GetCloudgroups")
- }
- for i := range groups {
- iGroup, err := groups[i].GetICloudgroup()
- if err != nil {
- return errors.Wrapf(err, "GetICloudgroup")
- }
- err = iGroup.AddUser(user.Name)
- if err != nil {
- return errors.Wrapf(err, "join group %s", groups[i].Name)
- }
- }
- user.SyncCloudgroups(ctx, userCred, iUser)
- return nil
- }
- func (base SProviderBaseProviderDriver) RequestCreateSAMLProvider(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount) error {
- providers, err := account.GetCloudproviders()
- if err != nil {
- return errors.Wrapf(err, "GetCloudproviders")
- }
- for i := range providers {
- err = func() error {
- lockman.LockRawObject(ctx, providers[i].Id, models.SAMLProviderManager.Keyword())
- defer lockman.ReleaseRawObject(ctx, providers[i].Id, models.SAMLProviderManager.Keyword())
- samlProviders, err := providers[i].GetSamlProviders()
- if err != nil {
- return errors.Wrapf(err, "GetSamlProviders")
- }
- iProvider, err := providers[i].GetProvider()
- if err != nil {
- return errors.Wrapf(err, "GetProvider")
- }
- for j := range samlProviders {
- if samlProviders[j].EntityId != options.Options.ApiServer {
- continue
- }
- if strings.Contains(samlProviders[j].MetadataDocument, "login/"+providers[i].Id) {
- return nil
- }
- iSamlProviders, err := iProvider.GetICloudSAMLProviders()
- if err != nil {
- return errors.Wrapf(err, "GetICloudSAMLProviders")
- }
- for _, iSaml := range iSamlProviders {
- if iSaml.GetGlobalId() != samlProviders[j].ExternalId {
- continue
- }
- doc := models.SamlIdpInstance().GetMetadata(providers[i].Id)
- err := iSaml.UpdateMetadata(doc)
- if err != nil {
- return errors.Wrapf(err, "UpdateMetadata")
- }
- _, err = db.Update(&samlProviders[j], func() error {
- samlProviders[j].Status = apis.STATUS_AVAILABLE
- samlProviders[j].MetadataDocument = doc.String()
- return nil
- })
- return err
- }
- }
- opts := &cloudprovider.SAMLProviderCreateOptions{
- Metadata: models.SamlIdpInstance().GetMetadata(providers[i].Id),
- Name: strings.TrimPrefix(options.Options.ApiServer, "https://"),
- Desc: "create by cloudpods",
- }
- log.Debugf("create saml provider for manager %s(%s) %s", providers[i].Name, providers[i].Id, opts.Metadata.String())
- opts.Name = strings.TrimPrefix(opts.Name, "http://")
- iSaml, err := iProvider.CreateICloudSAMLProvider(opts)
- if err != nil {
- return errors.Wrapf(err, "CreateICloudSAMLProvider")
- }
- saml := &models.SSAMLProvider{}
- saml.SetModelManager(models.SAMLProviderManager, saml)
- saml.Name = opts.Name
- saml.DomainId = account.DomainId
- saml.ManagerId = providers[i].Id
- saml.CloudaccountId = account.Id
- saml.ExternalId = iSaml.GetGlobalId()
- saml.Status = apis.STATUS_AVAILABLE
- saml.EntityId = options.Options.ApiServer
- err = models.SAMLProviderManager.TableSpec().Insert(ctx, saml)
- if err != nil {
- return err
- }
- return saml.SyncWithCloudSAMLProvider(ctx, userCred, iSaml, providers[i].Id)
- }()
- if err != nil {
- log.Errorf("create saml provider for manager %s error: %v", providers[i].Name, err)
- }
- }
- return nil
- }
- func (base SProviderBaseProviderDriver) RequestCreateRoleForSamlUser(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, group *models.SCloudgroup, user *models.SSamluser) error {
- provider, err := group.GetCloudprovider()
- if err != nil {
- return errors.Wrapf(err, "GetCloudprovider")
- }
- samlProvider, err := provider.GetSamlProvider()
- if err != nil {
- return errors.Wrapf(err, "GetSamlProvider")
- }
- policies, err := group.GetCloudpolicies()
- if err != nil {
- return errors.Wrapf(err, "GetCloudpolicies")
- }
- roles, err := account.GetCloudroles(provider.Id)
- if err != nil {
- return errors.Wrapf(err, "GetCloudroles")
- }
- for i := range roles {
- if roles[i].Status == apis.STATUS_AVAILABLE && len(roles[i].ExternalId) > 0 && roles[i].SAMLProviderId == samlProvider.Id && roles[i].CloudgroupId == group.Id {
- _, err := db.Update(user, func() error {
- user.CloudroleId = roles[i].Id
- return nil
- })
- if err != nil {
- return err
- }
- existPolicies := []string{}
- iRole, err := roles[i].GetICloudrole()
- if err != nil {
- return err
- }
- iPolicies, err := iRole.GetICloudpolicies()
- if err != nil {
- return errors.Wrapf(err, "GetICloudpolicies")
- }
- for _, policy := range iPolicies {
- existPolicies = append(existPolicies, policy.GetGlobalId())
- }
- for _, policy := range policies {
- if !utils.IsInStringArray(policy.ExternalId, existPolicies) {
- err = iRole.AttachPolicy(policy.ExternalId, cloudid.TPolicyType(policy.PolicyType))
- if err != nil {
- return errors.Wrapf(err, "attach %s policy %s", policy.PolicyType, policy.ExternalId)
- }
- }
- }
- return nil
- }
- }
- iProvider, err := group.GetProvider()
- if err != nil {
- return errors.Wrapf(err, "GetProvider")
- }
- opts := &cloudprovider.SRoleCreateOptions{
- Name: fmt.Sprintf("%s-%s", group.Name, utils.GenRequestId(5)),
- Desc: fmt.Sprintf("auto create by cloudpods"),
- SAMLProvider: samlProvider.ExternalId,
- }
- iRole, err := iProvider.CreateICloudrole(opts)
- if err != nil {
- return errors.Wrapf(err, "CreateICloudrole")
- }
- role := &models.SCloudrole{}
- role.SetModelManager(models.CloudroleManager, role)
- role.ExternalId = iRole.GetGlobalId()
- role.Name = iRole.GetName()
- role.Document = iRole.GetDocument()
- role.CloudaccountId = account.Id
- role.ManagerId = group.ManagerId
- role.SAMLProviderId = samlProvider.Id
- role.CloudgroupId = group.Id
- role.Status = apis.STATUS_AVAILABLE
- role.SetEnabled(true)
- err = models.CloudroleManager.TableSpec().Insert(ctx, role)
- if err != nil {
- return errors.Wrapf(err, "")
- }
- _, err = db.Update(user, func() error {
- user.CloudroleId = role.Id
- return nil
- })
- if err != nil {
- return err
- }
- for _, policy := range policies {
- err := iRole.AttachPolicy(policy.ExternalId, cloudid.TPolicyType(policy.PolicyType))
- if err != nil {
- return errors.Wrapf(err, "attach %s policy %s", policy.PolicyType, policy.ExternalId)
- }
- }
- return nil
- }
|