Files
cloudpods/pkg/cloudid/models/cloudprovider.go
2024-04-01 11:39:24 +08:00

237 lines
7.0 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"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/options"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/informer"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
)
// +onecloud:swagger-gen-ignore
type SCloudproviderManager struct {
db.SStandaloneResourceBaseManager
}
var CloudproviderManager *SCloudproviderManager
func init() {
CloudproviderManager = &SCloudproviderManager{
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
SCloudprovider{},
"cloudproviders_tbl",
"cloudprovider",
"cloudproviders",
),
}
CloudproviderManager.SetVirtualObject(CloudproviderManager)
}
type SCloudprovider struct {
db.SStandaloneResourceBase
Provider string `width:"64" charset:"ascii" list:"domain"`
CloudaccountId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (m *SCloudproviderManager) FetchProvier(id string) (*SCloudprovider, error) {
ret, err := m.FetchById(id)
if err != nil {
return nil, err
}
return ret.(*SCloudprovider), nil
}
func (self *SCloudprovider) GetRole(ctx context.Context, userId string) (*SCloudrole, error) {
groups := CloudgroupManager.Query().Equals("manager_id", self.Id).SubQuery()
sq := SamluserManager.Query("cloudrole_id").Equals("owner_id", userId)
sq = sq.Join(groups, sqlchemy.Equals(groups.Field("id"), sq.Field("cloudgroup_id")))
ret := &SCloudrole{}
ret.SetModelManager(CloudroleManager, ret)
err := CloudroleManager.Query().In("id", sq.SubQuery()).IsNotEmpty("external_id").First(ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (self *SCloudprovider) GetSamlUser(userId string) (*SSamluser, error) {
groups := CloudgroupManager.Query("id").Equals("manager_id", self.Id).SubQuery()
q := SamluserManager.Query().Equals("owner_id", userId).In("cloudgroup_id", groups)
ret := &SSamluser{}
ret.SetModelManager(SamluserManager, ret)
err := q.First(ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (self *SCloudprovider) GetSamlProvider() (*SSAMLProvider, error) {
q := SAMLProviderManager.Query().Equals("status", apis.STATUS_AVAILABLE).
Equals("entity_id", options.Options.ApiServer).Equals("manager_id", self.Id).IsNotEmpty("external_id")
ret := &SSAMLProvider{}
ret.SetModelManager(SAMLProviderManager, ret)
err := q.First(ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error) {
ctx := context.Background()
s := auth.GetAdminSession(ctx, options.Options.Region)
return modules.Cloudproviders.GetProvider(ctx, s, self.Id)
}
func (self *SCloudprovider) GetCloudaccount() (*SCloudaccount, error) {
account, err := CloudaccountManager.FetchById(self.CloudaccountId)
if err != nil {
return nil, errors.Wrapf(err, "FetchById(%s)", self.CloudaccountId)
}
return account.(*SCloudaccount), nil
}
func (self *SCloudprovider) GetDriver() (IProviderDriver, error) {
return GetProviderDriver(self.Provider)
}
func (self *SCloudprovider) StartCloudproviderSyncResourcesTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "CloudproviderSyncResourcesTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
return task.ScheduleRun(nil)
}
func (manager *SCloudproviderManager) GetCloudproviders() ([]SCloudprovider, error) {
ret := []SCloudprovider{}
q := manager.Query()
err := db.FetchModelObjects(manager, q, &ret)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return ret, nil
}
func (manager *SCloudproviderManager) SyncCloudproviderResources(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
managers, err := manager.GetCloudproviders()
if err != nil {
log.Errorf("GetCloudproviders error: %v", err)
return
}
for i := range managers {
err = managers[i].StartCloudproviderSyncResourcesTask(ctx, userCred, "")
if err != nil {
log.Errorf("StartCloudproviderSyncResourcesTask for manager %s(%s) error: %v", managers[i].Name, managers[i].Provider, err)
}
}
}
func (m *SCloudproviderManager) StartWatchInRegion() error {
adminSession := auth.GetAdminSession(context.Background(), "")
watchMan, err := informer.NewWatchManagerBySession(adminSession)
if err != nil {
return err
}
resMan := &modules.Cloudproviders
return watchMan.For(resMan).AddEventHandler(context.Background(), m)
}
func (m *SCloudproviderManager) OnAdd(obj *jsonutils.JSONDict) {
model := &SCloudprovider{}
model.SetModelManager(m, model)
ctx := context.Background()
err := obj.Unmarshal(model)
if err != nil {
return
}
if len(model.Provider) == 0 || len(model.CloudaccountId) == 0 {
s := auth.GetAdminSession(ctx, options.Options.Region)
data, err := modules.Cloudproviders.GetById(s, model.Id, nil)
if err != nil {
return
}
err = data.Unmarshal(model)
if err != nil {
return
}
}
err = m.TableSpec().InsertOrUpdate(ctx, model)
if err != nil {
return
}
model.StartCloudproviderSyncResourcesTask(ctx, auth.AdminCredential(), "")
}
func (self *SCloudprovider) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.purge(ctx)
}
func (m *SCloudproviderManager) OnDelete(obj *jsonutils.JSONDict) {
provider, err := func() (*SCloudprovider, error) {
id, err := obj.GetString("id")
if err != nil {
return nil, errors.Wrapf(err, "get id")
}
provider, err := m.FetchById(id)
if err != nil {
return nil, errors.Wrapf(err, "fetch by id %s", id)
}
return provider.(*SCloudprovider), nil
}()
if err != nil {
log.Errorf("fetch manager error: %v", err)
return
}
err = provider.Delete(context.Background(), nil)
if err != nil {
log.Errorf("purge account error: %v", err)
return
}
}
func (m *SCloudproviderManager) OnUpdate(oldObj, newObj *jsonutils.JSONDict) {
info := struct {
Id string
Name string
}{}
newObj.Unmarshal(&info)
log.Debugf("OnUpdate %s", jsonutils.Marshal(info).String())
_, err := m.FetchProvier(info.Id)
if err != nil && errors.Cause(err) == sql.ErrNoRows {
m.OnAdd(newObj)
return
}
}