mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-11-01 19:56:37 +08:00
630 lines
23 KiB
Go
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
|
|
}
|