Files
cloudpods/pkg/cloudid/drivers/base.go
T

630 lines
23 KiB
Go

// 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
}