mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-22 12:32:36 +08:00
1078 lines
35 KiB
Go
1078 lines
35 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 models
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"gopkg.in/fatih/set.v0"
|
|
|
|
"yunion.io/x/cloudmux/pkg/apis/cloudid"
|
|
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/log"
|
|
"yunion.io/x/pkg/errors"
|
|
"yunion.io/x/pkg/util/compare"
|
|
"yunion.io/x/pkg/util/httputils"
|
|
"yunion.io/x/sqlchemy"
|
|
|
|
"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/db/taskman"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
|
|
"yunion.io/x/onecloud/pkg/cloudid/options"
|
|
"yunion.io/x/onecloud/pkg/httperrors"
|
|
"yunion.io/x/onecloud/pkg/mcclient"
|
|
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
|
)
|
|
|
|
type SCloudgroupManager struct {
|
|
db.SStatusInfrasResourceBaseManager
|
|
SCloudaccountResourceBaseManager
|
|
SCloudproviderResourceBaseManager
|
|
}
|
|
|
|
var CloudgroupManager *SCloudgroupManager
|
|
|
|
func init() {
|
|
CloudgroupManager = &SCloudgroupManager{
|
|
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
|
|
SCloudgroup{},
|
|
"cloudgroups_tbl",
|
|
"cloudgroup",
|
|
"cloudgroups",
|
|
),
|
|
}
|
|
CloudgroupManager.SetVirtualObject(CloudgroupManager)
|
|
}
|
|
|
|
type SCloudgroup struct {
|
|
db.SStatusInfrasResourceBase
|
|
db.SExternalizedResourceBase
|
|
|
|
SCloudaccountResourceBase
|
|
SCloudproviderResourceBase
|
|
}
|
|
|
|
// 权限组列表
|
|
func (manager *SCloudgroupManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.CloudgroupListInput) (*sqlchemy.SQuery, error) {
|
|
var err error
|
|
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
q, err = manager.SCloudaccountResourceBaseManager.ListItemFilter(ctx, q, userCred, query.CloudaccountResourceListInput)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
q, err = manager.SCloudproviderResourceBaseManager.ListItemFilter(ctx, q, userCred, query.CloudproviderResourceListInput)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(query.ClouduserId) > 0 {
|
|
_, err = ClouduserManager.FetchById(query.ClouduserId)
|
|
if err != nil {
|
|
if errors.Cause(err) == sql.ErrNoRows {
|
|
return nil, httperrors.NewResourceNotFoundError2("clouduser", query.ClouduserId)
|
|
}
|
|
return q, httperrors.NewGeneralError(errors.Wrap(err, "ClouduserManager.FetchById"))
|
|
}
|
|
sq := CloudgroupUserManager.Query("cloudgroup_id").Equals("clouduser_id", query.ClouduserId)
|
|
q = q.In("id", sq.SubQuery())
|
|
}
|
|
|
|
if len(query.CloudpolicyId) > 0 {
|
|
_, err = CloudpolicyManager.FetchById(query.CloudpolicyId)
|
|
if err != nil {
|
|
if errors.Cause(err) == sql.ErrNoRows {
|
|
return nil, httperrors.NewResourceNotFoundError2("cloudpolicy", query.CloudpolicyId)
|
|
}
|
|
return q, httperrors.NewGeneralError(errors.Wrap(err, "CloudpolicyManager.FetchById"))
|
|
}
|
|
sq := CloudgroupPolicyManager.Query("cloudgroup_id").Equals("cloudpolicy_id", query.CloudpolicyId)
|
|
q = q.In("id", sq.SubQuery())
|
|
}
|
|
|
|
return q, nil
|
|
}
|
|
|
|
func (self *SCloudgroup) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
|
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupDeleteTask", self, userCred, nil, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(ctx, userCred, apis.STATUS_DELETING, "")
|
|
return task.ScheduleRun(nil)
|
|
}
|
|
|
|
func (self *SCloudgroup) StartSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
|
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupSyncstatusTask", self, userCred, nil, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(ctx, userCred, apis.STATUS_SYNC_STATUS, "")
|
|
return task.ScheduleRun(nil)
|
|
}
|
|
|
|
func (manager *SCloudgroupManager) FetchUniqValues(ctx context.Context, data jsonutils.JSONObject) jsonutils.JSONObject {
|
|
accountId, _ := data.GetString("cloudaccount_id")
|
|
managerId, _ := data.GetString("manager_id")
|
|
return jsonutils.Marshal(map[string]string{"cloudaccount_id": accountId, "manager_id": managerId})
|
|
}
|
|
|
|
func (manager *SCloudgroupManager) FilterByUniqValues(q *sqlchemy.SQuery, values jsonutils.JSONObject) *sqlchemy.SQuery {
|
|
accountId, _ := values.GetString("cloudaccount_id")
|
|
if len(accountId) > 0 {
|
|
q = q.Equals("cloudaccount_id", accountId)
|
|
}
|
|
|
|
providerId, _ := values.GetString("manager_id")
|
|
if len(providerId) > 0 {
|
|
q = q.Equals("manager_id", providerId)
|
|
}
|
|
|
|
return q
|
|
}
|
|
|
|
// 更新权限组
|
|
func (self *SCloudgroup) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupUpdateInput) (api.CloudgroupUpdateInput, error) {
|
|
return input, nil
|
|
}
|
|
|
|
// 获取权限组详情
|
|
func (manager *SCloudgroupManager) FetchCustomizeColumns(
|
|
ctx context.Context,
|
|
userCred mcclient.TokenCredential,
|
|
query jsonutils.JSONObject,
|
|
objs []interface{},
|
|
fields stringutils2.SSortedStrings,
|
|
isList bool,
|
|
) []api.CloudgroupDetails {
|
|
rows := make([]api.CloudgroupDetails, len(objs))
|
|
statusRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
|
acRows := manager.SCloudaccountResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
|
mRows := manager.SCloudproviderResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
|
groupIds := make([]string, len(objs))
|
|
for i := range rows {
|
|
rows[i] = api.CloudgroupDetails{
|
|
StatusInfrasResourceBaseDetails: statusRows[i],
|
|
CloudaccountResourceDetails: acRows[i],
|
|
CloudproviderResourceDetails: mRows[i],
|
|
Cloudpolicies: []api.SCloudIdBaseResource{},
|
|
}
|
|
group := objs[i].(*SCloudgroup)
|
|
groupIds[i] = group.Id
|
|
}
|
|
|
|
userSQ := ClouduserManager.Query().SubQuery()
|
|
ugQ := CloudgroupUserManager.Query().SubQuery()
|
|
q := userSQ.Query(
|
|
userSQ.Field("id"),
|
|
userSQ.Field("name"),
|
|
ugQ.Field("cloudgroup_id"),
|
|
).
|
|
Join(ugQ, sqlchemy.Equals(ugQ.Field("clouduser_id"), userSQ.Field("id"))).
|
|
Filter(sqlchemy.In(ugQ.Field("cloudgroup_id"), groupIds))
|
|
|
|
userInfo := []struct {
|
|
Id string
|
|
Name string
|
|
CloudgroupId string
|
|
}{}
|
|
err := q.All(&userInfo)
|
|
if err != nil {
|
|
log.Errorf("query group user info error: %v", err)
|
|
return rows
|
|
}
|
|
|
|
users := map[string][]api.SCloudIdBaseResource{}
|
|
for _, user := range userInfo {
|
|
_, ok := users[user.CloudgroupId]
|
|
if !ok {
|
|
users[user.CloudgroupId] = []api.SCloudIdBaseResource{}
|
|
}
|
|
users[user.CloudgroupId] = append(users[user.CloudgroupId], api.SCloudIdBaseResource{
|
|
Id: user.Id,
|
|
Name: user.Name,
|
|
})
|
|
}
|
|
|
|
policySQ := CloudpolicyManager.Query().SubQuery()
|
|
pgQ := CloudgroupPolicyManager.Query().SubQuery()
|
|
q = policySQ.Query(
|
|
policySQ.Field("id"),
|
|
policySQ.Field("name"),
|
|
pgQ.Field("cloudgroup_id"),
|
|
).
|
|
Join(pgQ, sqlchemy.Equals(pgQ.Field("cloudpolicy_id"), policySQ.Field("id"))).
|
|
Filter(sqlchemy.In(pgQ.Field("cloudgroup_id"), groupIds))
|
|
|
|
policyInfo := []struct {
|
|
Id string
|
|
Name string
|
|
CloudgroupId string
|
|
}{}
|
|
err = q.All(&policyInfo)
|
|
if err != nil {
|
|
log.Errorf("query group policy info error: %v", err)
|
|
return rows
|
|
}
|
|
|
|
policies := map[string][]api.SCloudIdBaseResource{}
|
|
for _, policy := range policyInfo {
|
|
_, ok := policies[policy.CloudgroupId]
|
|
if !ok {
|
|
policies[policy.CloudgroupId] = []api.SCloudIdBaseResource{}
|
|
}
|
|
policies[policy.CloudgroupId] = append(policies[policy.CloudgroupId], api.SCloudIdBaseResource{
|
|
Id: policy.Id,
|
|
Name: policy.Name,
|
|
})
|
|
}
|
|
|
|
for i := range rows {
|
|
rows[i].Cloudusers, _ = users[groupIds[i]]
|
|
rows[i].ClouduserCount = len(rows[i].Cloudusers)
|
|
rows[i].Cloudpolicies, _ = policies[groupIds[i]]
|
|
rows[i].CloudpolicyCount = len(rows[i].Cloudpolicies)
|
|
}
|
|
|
|
return rows
|
|
}
|
|
|
|
func (manager *SCloudgroupManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
|
switch field {
|
|
case "manager":
|
|
managerQuery := CloudproviderManager.Query("name", "id").SubQuery()
|
|
q.AppendField(managerQuery.Field("name", field)).Distinct()
|
|
q = q.Join(managerQuery, sqlchemy.Equals(q.Field("manager_id"), managerQuery.Field("id")))
|
|
return q, nil
|
|
case "account":
|
|
accountQuery := CloudaccountManager.Query("name", "id").SubQuery()
|
|
providers := CloudproviderManager.Query("id", "cloudaccount_id").SubQuery()
|
|
q.AppendField(accountQuery.Field("name", field)).Distinct()
|
|
q = q.Join(providers, sqlchemy.Equals(q.Field("manager_id"), providers.Field("id")))
|
|
q = q.Join(accountQuery, sqlchemy.Equals(providers.Field("cloudaccount_id"), accountQuery.Field("id")))
|
|
return q, nil
|
|
case "provider", "brand":
|
|
accountQuery := CloudaccountManager.Query(field, "id").Distinct().SubQuery()
|
|
providers := CloudproviderManager.Query("id", "cloudaccount_id").SubQuery()
|
|
q.AppendField(accountQuery.Field(field)).Distinct()
|
|
q = q.Join(providers, sqlchemy.Equals(q.Field("manager_id"), providers.Field("id")))
|
|
q = q.Join(accountQuery, sqlchemy.Equals(providers.Field("cloudaccount_id"), accountQuery.Field("id")))
|
|
return q, nil
|
|
}
|
|
return q, httperrors.ErrNotFound
|
|
}
|
|
|
|
// 创建权限组
|
|
func (manager *SCloudgroupManager) ValidateCreateData(
|
|
ctx context.Context,
|
|
userCred mcclient.TokenCredential,
|
|
ownerId mcclient.IIdentityProvider,
|
|
query jsonutils.JSONObject,
|
|
input *api.CloudgroupCreateInput,
|
|
) (*api.CloudgroupCreateInput, error) {
|
|
if len(input.ManagerId) == 0 {
|
|
return nil, httperrors.NewMissingParameterError("manager_id")
|
|
}
|
|
providerObj, err := validators.ValidateModel(ctx, userCred, CloudproviderManager, &input.ManagerId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
provider := providerObj.(*SCloudprovider)
|
|
input.CloudaccountId = provider.CloudaccountId
|
|
driver, err := provider.GetDriver()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
input, err = driver.ValidateCreateCloudgroup(ctx, userCred, provider, input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
input.Status = apis.STATUS_CREATING
|
|
return input, nil
|
|
}
|
|
|
|
func (self *SCloudgroup) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
|
input := api.CloudgroupCreateInput{}
|
|
data.Unmarshal(&input)
|
|
for _, policyId := range input.CloudpolicyIds {
|
|
self.attachPolicy(policyId)
|
|
}
|
|
self.StartCreateTask(ctx, userCred, "")
|
|
}
|
|
|
|
func (self *SCloudgroup) StartCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
|
params := jsonutils.NewDict()
|
|
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupCreateTask", self, userCred, params, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "NewTask")
|
|
}
|
|
return task.ScheduleRun(nil)
|
|
}
|
|
|
|
// 删除权限组
|
|
func (self *SCloudgroup) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
|
params := jsonutils.NewDict()
|
|
return self.StartCloudgroupDeleteTask(ctx, userCred, params, "")
|
|
}
|
|
|
|
func (self *SCloudgroup) StartCloudgroupDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, parentTaskId string) error {
|
|
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupDeleteTask", self, userCred, data, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(ctx, userCred, apis.STATUS_DELETING, "")
|
|
return task.ScheduleRun(nil)
|
|
}
|
|
|
|
func (self *SCloudgroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
|
return nil
|
|
}
|
|
|
|
func (self *SCloudgroup) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
|
return self.purge(ctx)
|
|
}
|
|
|
|
func (self *SCloudgroup) GetSamlusers() ([]SSamluser, error) {
|
|
q := SamluserManager.Query().Equals("cloudgroup_id", self.Id)
|
|
users := []SSamluser{}
|
|
err := db.FetchModelObjects(SamluserManager, q, &users)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "db.FetchModelObjects")
|
|
}
|
|
return users, nil
|
|
}
|
|
|
|
func (self *SCloudgroup) GetCloudpolicyQuery() *sqlchemy.SQuery {
|
|
sq := CloudgroupPolicyManager.Query("cloudpolicy_id").Equals("cloudgroup_id", self.Id).SubQuery()
|
|
return CloudpolicyManager.Query().In("id", sq)
|
|
}
|
|
|
|
func (self *SCloudgroup) GetCloudpolicyCount() (int, error) {
|
|
return self.GetCloudpolicyQuery().CountWithError()
|
|
}
|
|
|
|
func (self *SCloudgroup) GetCloudpolicies() ([]SCloudpolicy, error) {
|
|
policies := []SCloudpolicy{}
|
|
q := self.GetCloudpolicyQuery()
|
|
err := db.FetchModelObjects(CloudpolicyManager, q, &policies)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
|
}
|
|
return policies, nil
|
|
}
|
|
|
|
func (self *SCloudgroup) GetCloudpolicy(policyId string) (*SCloudpolicy, error) {
|
|
policies := []SCloudpolicy{}
|
|
q := self.GetCloudpolicyQuery().Equals("id", policyId)
|
|
err := db.FetchModelObjects(CloudpolicyManager, q, &policies)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
|
}
|
|
if len(policies) > 1 {
|
|
return nil, sqlchemy.ErrDuplicateEntry
|
|
}
|
|
if len(policies) == 0 {
|
|
return nil, sql.ErrNoRows
|
|
}
|
|
return &policies[0], nil
|
|
}
|
|
|
|
func (self *SCloudgroup) detachPolicy(policyId string) error {
|
|
policies := []SCloudgroupPolicy{}
|
|
q := CloudgroupPolicyManager.Query().Equals("cloudgroup_id", self.Id).Equals("cloudpolicy_id", policyId)
|
|
err := db.FetchModelObjects(CloudgroupPolicyManager, q, &policies)
|
|
if err != nil {
|
|
return errors.Wrap(err, "db.FetchModelObjects")
|
|
}
|
|
for i := range policies {
|
|
err = policies[i].Delete(context.Background(), nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "Delete")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (self *SCloudgroup) GetClouduserQuery() *sqlchemy.SQuery {
|
|
sq := CloudgroupUserManager.Query("clouduser_id").Equals("cloudgroup_id", self.Id).SubQuery()
|
|
return ClouduserManager.Query().In("id", sq)
|
|
}
|
|
|
|
func (self *SCloudgroup) GetClouduserCount() (int, error) {
|
|
return self.GetClouduserQuery().CountWithError()
|
|
}
|
|
|
|
func (self *SCloudgroup) GetClouduser(userId string) (*SClouduser, error) {
|
|
users := []SClouduser{}
|
|
q := self.GetClouduserQuery().Equals("id", userId)
|
|
err := db.FetchModelObjects(ClouduserManager, q, &users)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
|
}
|
|
if len(users) > 1 {
|
|
return nil, sqlchemy.ErrDuplicateEntry
|
|
}
|
|
if len(users) == 0 {
|
|
return nil, sql.ErrNoRows
|
|
}
|
|
return &users[0], nil
|
|
}
|
|
|
|
func (self *SCloudgroup) GetCloudusers() ([]SClouduser, error) {
|
|
users := []SClouduser{}
|
|
q := self.GetClouduserQuery()
|
|
err := db.FetchModelObjects(ClouduserManager, q, &users)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
|
}
|
|
return users, nil
|
|
}
|
|
|
|
func (self *SCloudgroup) removeUser(userId string) error {
|
|
users := []SCloudgroupUser{}
|
|
q := CloudgroupUserManager.Query().Equals("cloudgroup_id", self.Id).Equals("clouduser_id", userId)
|
|
err := db.FetchModelObjects(CloudgroupUserManager, q, &users)
|
|
if err != nil {
|
|
return errors.Wrap(err, "db.FetchModelObjects")
|
|
}
|
|
for i := range users {
|
|
err = users[i].Delete(context.Background(), nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "Delete")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 向权限组加入用户
|
|
// 权限组状态必须为: available
|
|
func (self *SCloudgroup) PerformAddUser(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupAddUserInput) (jsonutils.JSONObject, error) {
|
|
if self.Status != apis.STATUS_AVAILABLE {
|
|
return nil, httperrors.NewInvalidStatusError("Can not remove user in status %s", self.Status)
|
|
}
|
|
userObj, err := validators.ValidateModel(ctx, userCred, ClouduserManager, &input.ClouduserId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
user := userObj.(*SClouduser)
|
|
if user.ManagerId != self.ManagerId || user.CloudaccountId != self.CloudaccountId {
|
|
return nil, httperrors.NewConflictError("Users and user groups do not belong to the same account")
|
|
}
|
|
_, err = self.GetClouduser(input.ClouduserId)
|
|
if err == nil || errors.Cause(err) == sqlchemy.ErrDuplicateEntry {
|
|
return nil, httperrors.NewDuplicateResourceError("user %s has aleady in this group", input.ClouduserId)
|
|
}
|
|
|
|
add := []api.GroupUser{
|
|
{
|
|
Name: user.Name,
|
|
ExternalId: user.ExternalId,
|
|
},
|
|
}
|
|
|
|
return nil, self.StartSetUsersTask(ctx, userCred, add, nil, "")
|
|
}
|
|
|
|
func (self *SCloudgroup) StartSetUsersTask(ctx context.Context, userCred mcclient.TokenCredential, add, del []api.GroupUser, parentTaskId string) error {
|
|
params := jsonutils.NewDict()
|
|
if len(add) > 0 {
|
|
params.Set("add", jsonutils.Marshal(add))
|
|
}
|
|
if len(del) > 0 {
|
|
params.Set("del", jsonutils.Marshal(del))
|
|
}
|
|
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupSetUsersTask", self, userCred, params, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(ctx, userCred, apis.STATUS_SYNC_STATUS, "")
|
|
return task.ScheduleRun(nil)
|
|
}
|
|
|
|
func (self *SCloudgroup) StartCloudgroupSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
|
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupSyncstatusTask", self, userCred, nil, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(ctx, userCred, apis.STATUS_SYNC_STATUS, "")
|
|
return task.ScheduleRun(nil)
|
|
}
|
|
|
|
// 恢复权限组状态
|
|
func (self *SCloudgroup) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupSyncstatusInput) (jsonutils.JSONObject, error) {
|
|
return nil, self.StartCloudgroupSyncstatusTask(ctx, userCred, "")
|
|
}
|
|
|
|
// 从权限组移除用户
|
|
// 权限组状态必须为: available
|
|
func (self *SCloudgroup) PerformRemoveUser(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupRemoveUserInput) (jsonutils.JSONObject, error) {
|
|
if self.Status != apis.STATUS_AVAILABLE {
|
|
return nil, httperrors.NewInvalidStatusError("Can not remove user in status %s", self.Status)
|
|
}
|
|
|
|
userObj, err := validators.ValidateModel(ctx, userCred, ClouduserManager, &input.ClouduserId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
user := userObj.(*SClouduser)
|
|
|
|
_, err = self.GetClouduser(input.ClouduserId)
|
|
if err != nil {
|
|
if errors.Cause(err) == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, httperrors.NewGeneralError(err)
|
|
}
|
|
|
|
del := []api.GroupUser{
|
|
{
|
|
Name: user.Name,
|
|
ExternalId: user.ExternalId,
|
|
},
|
|
}
|
|
|
|
return nil, self.StartSetUsersTask(ctx, userCred, nil, del, "")
|
|
}
|
|
|
|
func (self *SCloudgroup) addUser(userId string) error {
|
|
gu := &SCloudgroupUser{}
|
|
gu.SetModelManager(CloudgroupUserManager, gu)
|
|
gu.ClouduserId = userId
|
|
gu.CloudgroupId = self.Id
|
|
return CloudgroupUserManager.TableSpec().Insert(context.Background(), gu)
|
|
}
|
|
|
|
// 设置权限组用户(全量覆盖)
|
|
// 权限组状态必须为: available
|
|
func (self *SCloudgroup) PerformSetUsers(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupSetUsersInput) (jsonutils.JSONObject, error) {
|
|
if self.Status != apis.STATUS_AVAILABLE {
|
|
return nil, httperrors.NewInvalidStatusError("Can not set users in status %s", self.Status)
|
|
}
|
|
|
|
users, err := self.GetCloudusers()
|
|
if err != nil {
|
|
return nil, httperrors.NewGeneralError(err)
|
|
}
|
|
|
|
userMap := map[string]*SClouduser{}
|
|
local := set.New(set.ThreadSafe)
|
|
for i := range users {
|
|
local.Add(users[i].Id)
|
|
userMap[users[i].Id] = &users[i]
|
|
}
|
|
|
|
newU := set.New(set.ThreadSafe)
|
|
for i := range input.ClouduserIds {
|
|
_user, err := validators.ValidateModel(ctx, userCred, ClouduserManager, &input.ClouduserIds[i])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
user := _user.(*SClouduser)
|
|
if user.ManagerId != self.ManagerId || user.CloudaccountId != self.CloudaccountId {
|
|
return nil, httperrors.NewConflictError("Users and user groups do not belong to the same account")
|
|
}
|
|
newU.Add(user.Id)
|
|
userMap[user.Id] = user
|
|
}
|
|
|
|
del, add := []api.GroupUser{}, []api.GroupUser{}
|
|
for _, id := range set.Difference(local, newU).List() {
|
|
user := userMap[id.(string)]
|
|
del = append(del, api.GroupUser{
|
|
Name: user.Name,
|
|
ExternalId: user.ExternalId,
|
|
})
|
|
}
|
|
for _, id := range set.Difference(newU, local).List() {
|
|
user := userMap[id.(string)]
|
|
add = append(add, api.GroupUser{
|
|
Name: user.Name,
|
|
ExternalId: user.ExternalId,
|
|
})
|
|
}
|
|
|
|
return nil, self.StartSetUsersTask(ctx, userCred, add, del, "")
|
|
}
|
|
|
|
// 设置权限组添权限(全量覆盖)
|
|
// 权限组状态必须为: available
|
|
func (self *SCloudgroup) PerformSetPolicies(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupSetPoliciesInput) (jsonutils.JSONObject, error) {
|
|
if self.Status != apis.STATUS_AVAILABLE {
|
|
return nil, httperrors.NewInvalidStatusError("Can not set policies in status %s", self.Status)
|
|
}
|
|
|
|
policies, err := self.GetCloudpolicies()
|
|
if err != nil {
|
|
return nil, httperrors.NewGeneralError(err)
|
|
}
|
|
|
|
policyMap := map[string]*SCloudpolicy{}
|
|
local := set.New(set.ThreadSafe)
|
|
for i := range policies {
|
|
local.Add(policies[i].Id)
|
|
policyMap[policies[i].Id] = &policies[i]
|
|
}
|
|
|
|
newP := set.New(set.ThreadSafe)
|
|
for i := range input.CloudpolicyIds {
|
|
policObj, err := validators.ValidateModel(ctx, userCred, CloudpolicyManager, &input.CloudpolicyIds[i])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
policy := policObj.(*SCloudpolicy)
|
|
if (policy.ManagerId != self.ManagerId && len(self.ManagerId) > 0) || policy.CloudaccountId != self.CloudaccountId {
|
|
return nil, httperrors.NewConflictError("Policies and groups do not belong to the same account")
|
|
}
|
|
newP.Add(policy.Id)
|
|
policyMap[policy.Id] = policy
|
|
}
|
|
|
|
del, add := []api.SPolicy{}, []api.SPolicy{}
|
|
for _, id := range set.Difference(local, newP).List() {
|
|
policy := policyMap[id.(string)]
|
|
del = append(del, api.SPolicy{
|
|
Name: policy.Name,
|
|
ExternalId: policy.ExternalId,
|
|
PolicyType: policy.PolicyType,
|
|
})
|
|
}
|
|
for _, id := range set.Difference(newP, local).List() {
|
|
policy := policyMap[id.(string)]
|
|
add = append(add, api.SPolicy{
|
|
Name: policy.Name,
|
|
ExternalId: policy.ExternalId,
|
|
PolicyType: policy.PolicyType,
|
|
})
|
|
}
|
|
|
|
return nil, self.StartSetPoliciesTask(ctx, userCred, add, del, "")
|
|
}
|
|
|
|
func (self *SCloudgroup) StartSetPoliciesTask(ctx context.Context, userCred mcclient.TokenCredential, add, del []api.SPolicy, parentTaskId string) error {
|
|
params := jsonutils.NewDict()
|
|
if len(add) > 0 {
|
|
params.Set("add", jsonutils.Marshal(add))
|
|
}
|
|
if len(del) > 0 {
|
|
params.Set("del", jsonutils.Marshal(del))
|
|
}
|
|
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupSetPoliciesTask", self, userCred, params, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(ctx, userCred, apis.STATUS_SYNC_STATUS, "")
|
|
return task.ScheduleRun(nil)
|
|
}
|
|
|
|
// 向权限组添加权限
|
|
// 权限组状态必须为: available
|
|
func (self *SCloudgroup) PerformAttachPolicy(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupAttachPolicyInput) (jsonutils.JSONObject, error) {
|
|
if self.Status != apis.STATUS_AVAILABLE {
|
|
return nil, httperrors.NewInvalidStatusError("Can not attach policy in status %s", self.Status)
|
|
}
|
|
policyObj, err := validators.ValidateModel(ctx, userCred, CloudpolicyManager, &input.CloudpolicyId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
policy := policyObj.(*SCloudpolicy)
|
|
if policy.ManagerId != self.ManagerId || policy.CloudaccountId != self.CloudaccountId {
|
|
return nil, httperrors.NewConflictError("policy and groups do not belong to the same account")
|
|
}
|
|
_, err = self.GetCloudpolicy(input.CloudpolicyId)
|
|
if err == nil || errors.Cause(err) == sqlchemy.ErrDuplicateEntry {
|
|
return nil, httperrors.NewDuplicateResourceError("policy %s has aleady in this group", input.CloudpolicyId)
|
|
}
|
|
|
|
add := []api.SPolicy{
|
|
{
|
|
Name: policy.Name,
|
|
ExternalId: policy.ExternalId,
|
|
PolicyType: policy.PolicyType,
|
|
},
|
|
}
|
|
|
|
return nil, self.StartSetPoliciesTask(ctx, userCred, add, nil, "")
|
|
}
|
|
|
|
// 从权限组移除权限
|
|
// 权限组状态必须为: available
|
|
func (self *SCloudgroup) PerformDetachPolicy(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupDetachPolicyInput) (jsonutils.JSONObject, error) {
|
|
if self.Status != apis.STATUS_AVAILABLE {
|
|
return nil, httperrors.NewInvalidStatusError("Can not detach policy in status %s", self.Status)
|
|
}
|
|
|
|
policObj, err := validators.ValidateModel(ctx, userCred, CloudpolicyManager, &input.CloudpolicyId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
policy := policObj.(*SCloudpolicy)
|
|
|
|
_, err = self.GetCloudpolicy(input.CloudpolicyId)
|
|
if err != nil && errors.Cause(err) == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
|
|
del := []api.SPolicy{
|
|
{
|
|
Name: policy.Name,
|
|
ExternalId: policy.ExternalId,
|
|
PolicyType: policy.PolicyType,
|
|
},
|
|
}
|
|
|
|
return nil, self.StartSetPoliciesTask(ctx, userCred, nil, del, "")
|
|
}
|
|
|
|
func (self *SCloudgroup) attachPolicy(policyId string) error {
|
|
gp := &SCloudgroupPolicy{}
|
|
gp.SetModelManager(CloudgroupPolicyManager, gp)
|
|
gp.CloudpolicyId = policyId
|
|
gp.CloudgroupId = self.Id
|
|
return CloudgroupPolicyManager.TableSpec().Insert(context.Background(), gp)
|
|
}
|
|
|
|
func (self *SCloudaccount) SyncCloudgroups(ctx context.Context, userCred mcclient.TokenCredential, iGroups []cloudprovider.ICloudgroup, managerId string) ([]SCloudgroup, []cloudprovider.ICloudgroup, compare.SyncResult) {
|
|
lockman.LockRawObject(ctx, CloudgroupManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, managerId))
|
|
defer lockman.ReleaseRawObject(ctx, CloudgroupManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, managerId))
|
|
|
|
result := compare.SyncResult{}
|
|
dbGroups, err := self.GetCloudgroups(managerId)
|
|
if err != nil {
|
|
result.Error(errors.Wrap(err, "GetCloudgroups"))
|
|
return nil, nil, result
|
|
}
|
|
|
|
localGroups := []SCloudgroup{}
|
|
remoteGroups := []cloudprovider.ICloudgroup{}
|
|
|
|
removed := make([]SCloudgroup, 0)
|
|
commondb := make([]SCloudgroup, 0)
|
|
commonext := make([]cloudprovider.ICloudgroup, 0)
|
|
added := make([]cloudprovider.ICloudgroup, 0)
|
|
|
|
err = compare.CompareSets(dbGroups, iGroups, &removed, &commondb, &commonext, &added)
|
|
if err != nil {
|
|
result.Error(errors.Wrap(err, "compare.CompareSets"))
|
|
return nil, nil, result
|
|
}
|
|
|
|
for i := 0; i < len(removed); i++ {
|
|
err = removed[i].RealDelete(ctx, userCred)
|
|
if err != nil {
|
|
result.DeleteError(err)
|
|
continue
|
|
}
|
|
result.Delete()
|
|
}
|
|
|
|
for i := 0; i < len(commondb); i++ {
|
|
err = commondb[i].SyncWithCloudgroup(ctx, userCred, commonext[i])
|
|
if err != nil {
|
|
result.UpdateError(err)
|
|
continue
|
|
}
|
|
localGroups = append(localGroups, commondb[i])
|
|
remoteGroups = append(remoteGroups, commonext[i])
|
|
result.Update()
|
|
}
|
|
|
|
for i := 0; i < len(added); i++ {
|
|
group, err := self.newCloudgroup(ctx, userCred, added[i], managerId)
|
|
if err != nil {
|
|
result.AddError(err)
|
|
continue
|
|
}
|
|
localGroups = append(localGroups, *group)
|
|
remoteGroups = append(remoteGroups, added[i])
|
|
result.Add()
|
|
}
|
|
|
|
return localGroups, remoteGroups, result
|
|
}
|
|
|
|
func (group *SCloudgroup) GetCloudprovider() (*SCloudprovider, error) {
|
|
provider, err := CloudproviderManager.FetchById(group.ManagerId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return provider.(*SCloudprovider), nil
|
|
}
|
|
|
|
func (self *SCloudgroup) GetProvider() (cloudprovider.ICloudProvider, error) {
|
|
if len(self.ManagerId) > 0 {
|
|
provider, err := self.GetCloudprovider()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return provider.GetProvider()
|
|
}
|
|
if len(self.CloudaccountId) > 0 {
|
|
account, err := self.GetCloudaccount()
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return account.GetProvider()
|
|
}
|
|
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty account info")
|
|
}
|
|
|
|
func (group *SCloudgroup) GetICloudgroup() (cloudprovider.ICloudgroup, error) {
|
|
if len(group.ExternalId) == 0 {
|
|
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
|
|
}
|
|
provider, err := group.GetProvider()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
groups, err := provider.GetICloudgroups()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for i := range groups {
|
|
if groups[i].GetGlobalId() == group.ExternalId {
|
|
return groups[i], nil
|
|
}
|
|
}
|
|
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%v", group.ExternalId)
|
|
}
|
|
|
|
func (group *SCloudgroup) SyncWithCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, iGroup cloudprovider.ICloudgroup) error {
|
|
_, err := db.Update(group, func() error {
|
|
group.Name = iGroup.GetName()
|
|
group.Status = apis.STATUS_AVAILABLE
|
|
return nil
|
|
})
|
|
return err
|
|
}
|
|
|
|
func (self *SCloudaccount) newCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, iGroup cloudprovider.ICloudgroup, managerId string) (*SCloudgroup, error) {
|
|
group := &SCloudgroup{}
|
|
group.SetModelManager(CloudgroupManager, group)
|
|
group.Name = iGroup.GetName()
|
|
group.ExternalId = iGroup.GetGlobalId()
|
|
group.Status = apis.STATUS_AVAILABLE
|
|
group.CloudaccountId = self.Id
|
|
group.ManagerId = managerId
|
|
group.DomainId = self.DomainId
|
|
err := CloudgroupManager.TableSpec().Insert(ctx, group)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Insert")
|
|
}
|
|
return group, nil
|
|
}
|
|
|
|
func (self *SCloudgroup) SyncCloudusers(ctx context.Context, userCred mcclient.TokenCredential, iGroup cloudprovider.ICloudgroup) {
|
|
iUsers, err := iGroup.GetICloudusers()
|
|
if err == nil {
|
|
result := self.SyncUsers(ctx, userCred, iUsers)
|
|
log.Debugf("sync cloudusers for group %s result: %s", self.Name, result.Result())
|
|
}
|
|
}
|
|
|
|
func (self *SCloudgroup) SyncUsers(ctx context.Context, userCred mcclient.TokenCredential, iUsers []cloudprovider.IClouduser) compare.SyncResult {
|
|
lockman.LockRawObject(ctx, ClouduserManager.Keyword(), self.Id)
|
|
defer lockman.ReleaseRawObject(ctx, ClouduserManager.Keyword(), self.Id)
|
|
|
|
result := compare.SyncResult{}
|
|
dbUsers, err := self.GetCloudusers()
|
|
if err != nil {
|
|
result.Error(errors.Wrap(err, "GetCloudusers"))
|
|
return result
|
|
}
|
|
|
|
removed := make([]SClouduser, 0)
|
|
commondb := make([]SClouduser, 0)
|
|
commonext := make([]cloudprovider.IClouduser, 0)
|
|
added := make([]cloudprovider.IClouduser, 0)
|
|
|
|
err = compare.CompareSets(dbUsers, iUsers, &removed, &commondb, &commonext, &added)
|
|
if err != nil {
|
|
result.Error(errors.Wrap(err, "compare.CompareSets"))
|
|
return result
|
|
}
|
|
|
|
for i := 0; i < len(removed); i++ {
|
|
self.removeUser(removed[i].Id)
|
|
if err != nil {
|
|
result.DeleteError(err)
|
|
continue
|
|
}
|
|
result.Delete()
|
|
}
|
|
|
|
result.UpdateCnt = len(commondb)
|
|
|
|
for i := 0; i < len(added); i++ {
|
|
user, err := db.FetchByExternalIdAndManagerId(ClouduserManager, added[i].GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
|
if len(self.ManagerId) > 0 {
|
|
return q.Equals("manager_id", self.ManagerId)
|
|
}
|
|
return q.Equals("cloudaccount_id", self.CloudaccountId)
|
|
})
|
|
if err != nil {
|
|
result.AddError(errors.Wrapf(err, "Fetch %s", added[i].GetGlobalId()))
|
|
continue
|
|
}
|
|
err = self.addUser(user.GetId())
|
|
if err != nil {
|
|
result.AddError(err)
|
|
continue
|
|
}
|
|
result.Add()
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func (self *SCloudgroup) SyncCloudpolicies(ctx context.Context, userCred mcclient.TokenCredential, iGroup cloudprovider.ICloudgroup) {
|
|
iPolicies, err := iGroup.GetICloudpolicies()
|
|
if err == nil {
|
|
result := self.SyncPolicies(ctx, userCred, iPolicies)
|
|
log.Infof("SyncCloudpolicies for group %s(%s) result: %s", self.Name, self.Id, result.Result())
|
|
}
|
|
}
|
|
|
|
func (self *SCloudgroup) SyncPolicies(ctx context.Context, userCred mcclient.TokenCredential, iPolicies []cloudprovider.ICloudpolicy) compare.SyncResult {
|
|
result := compare.SyncResult{}
|
|
dbPolicies, err := self.GetCloudpolicies()
|
|
if err != nil {
|
|
result.Error(errors.Wrapf(err, "GetCloudpolicies"))
|
|
return result
|
|
}
|
|
|
|
removed := make([]SCloudpolicy, 0)
|
|
commondb := make([]SCloudpolicy, 0)
|
|
commonext := make([]cloudprovider.ICloudpolicy, 0)
|
|
added := make([]cloudprovider.ICloudpolicy, 0)
|
|
|
|
err = compare.CompareSets(dbPolicies, iPolicies, &removed, &commondb, &commonext, &added)
|
|
if err != nil {
|
|
result.Error(errors.Wrap(err, "compare.CompareSets"))
|
|
return result
|
|
}
|
|
|
|
for i := 0; i < len(removed); i++ {
|
|
err := self.detachPolicy(removed[i].Id)
|
|
if err != nil {
|
|
result.DeleteError(err)
|
|
continue
|
|
}
|
|
result.Delete()
|
|
}
|
|
|
|
result.UpdateCnt = len(commondb)
|
|
|
|
for i := 0; i < len(added); i++ {
|
|
policy, err := db.FetchByExternalIdAndManagerId(CloudpolicyManager, added[i].GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
|
if len(self.ManagerId) > 0 {
|
|
return q.Equals("manager_id", self.ManagerId)
|
|
}
|
|
return q.Equals("cloudaccount_id", self.CloudaccountId)
|
|
})
|
|
if err != nil {
|
|
result.AddError(errors.Wrapf(err, "add %s(%s)", added[i].GetName(), added[i].GetGlobalId()))
|
|
continue
|
|
}
|
|
err = self.attachPolicy(policy.GetId())
|
|
if err != nil {
|
|
result.AddError(err)
|
|
continue
|
|
}
|
|
result.Add()
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (self *SCloudgroup) GetSamlProvider() (*SSAMLProvider, error) {
|
|
q := SAMLProviderManager.Query().Equals("status", apis.STATUS_AVAILABLE).
|
|
Equals("entity_id", options.Options.ApiServer).
|
|
Equals("cloudaccount_id", self.CloudaccountId).
|
|
IsNotEmpty("external_id")
|
|
if len(self.ManagerId) > 0 {
|
|
q = q.Equals("manager_id", self.ManagerId)
|
|
}
|
|
ret := &SSAMLProvider{}
|
|
ret.SetModelManager(SAMLProviderManager, ret)
|
|
err := q.First(ret)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return ret, nil
|
|
}
|
|
|
|
func (self *SCloudgroup) GetCloudroles() ([]SCloudrole, error) {
|
|
sq := SamluserManager.Query("cloudrole_id").Equals("cloudgroup_id", self.Id).SubQuery()
|
|
q := CloudroleManager.Query().Equals("cloudgroup_id", self.Id).IsNotEmpty("external_id").In("id", sq)
|
|
ret := []SCloudrole{}
|
|
err := db.FetchModelObjects(CloudroleManager, q, &ret)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return ret, nil
|
|
}
|
|
|
|
func (self *SCloudgroup) GetDetailsSaml(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*api.GetCloudaccountSamlOutput, error) {
|
|
output := &api.GetCloudaccountSamlOutput{}
|
|
|
|
account, err := self.GetCloudaccount()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if account.SAMLAuth.IsFalse() {
|
|
return output, httperrors.NewNotSupportedError("account %s not enable saml auth", account.Name)
|
|
}
|
|
|
|
provider, err := account.GetProvider()
|
|
if err != nil {
|
|
return output, errors.Wrap(err, "GetProviderFactory")
|
|
}
|
|
|
|
samlProvider, err := self.GetSamlProvider()
|
|
if err != nil {
|
|
if errors.Cause(err) == sql.ErrNoRows {
|
|
return nil, httperrors.NewResourceNotReadyError("no available saml provider")
|
|
}
|
|
return nil, errors.Wrapf(err, "GetSamlProvider")
|
|
}
|
|
|
|
output.EntityId = provider.GetSamlEntityId()
|
|
if len(output.EntityId) == 0 {
|
|
return output, errors.Wrap(httperrors.ErrNotSupported, "SAML login not supported")
|
|
}
|
|
|
|
id := self.CloudaccountId
|
|
if len(self.ManagerId) > 0 {
|
|
id = self.ManagerId
|
|
}
|
|
|
|
output.RedirectLoginUrl = httputils.JoinPath(options.Options.ApiServer, cloudid.SAML_IDP_PREFIX, "redirect/login", id)
|
|
output.RedirectLogoutUrl = httputils.JoinPath(options.Options.ApiServer, cloudid.SAML_IDP_PREFIX, "redirect/logout", id)
|
|
output.MetadataUrl = httputils.JoinPath(options.Options.ApiServer, cloudid.SAML_IDP_PREFIX, "metadata", id)
|
|
output.InitLoginUrl = samlProvider.AuthUrl
|
|
return output, nil
|
|
}
|