| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- // 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"
- "strings"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/tristate"
- "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 SCloudaccountManager struct {
- db.SDomainLevelResourceBaseManager
- }
- var CloudaccountManager *SCloudaccountManager
- func init() {
- CloudaccountManager = &SCloudaccountManager{
- SDomainLevelResourceBaseManager: db.NewDomainLevelResourceBaseManager(
- SCloudaccount{},
- "cloudaccounts_tbl",
- "cloudaccount",
- "cloudaccounts",
- ),
- }
- CloudaccountManager.SetVirtualObject(CloudaccountManager)
- }
- type SCloudaccount struct {
- db.SStandaloneResourceBase
- db.SDomainizedResourceBase
- AccountId string `width:"128" charset:"utf8" nullable:"true" list:"domain" create:"domain_optional"`
- Provider string `width:"64" charset:"ascii" list:"domain"`
- Brand string `width:"64" charset:"utf8" nullable:"true" list:"domain"`
- IamLoginUrl string `width:"512" charset:"ascii"`
- SAMLAuth tristate.TriState `list:"domain" default:"false"`
- AccessUrl string `width:"64" charset:"ascii" nullable:"true" list:"domain" update:"domain" create:"domain_optional"`
- ReadOnly bool `default:"false" create:"domain_optional" list:"domain" update:"domain"`
- }
- func (manager *SCloudaccountManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
- return []db.SScopeResourceCount{}, nil
- }
- func (manager *SCloudaccountManager) GetCloudaccounts() ([]SCloudaccount, error) {
- accounts := []SCloudaccount{}
- q := manager.Query()
- err := db.FetchModelObjects(manager, q, &accounts)
- if err != nil {
- return nil, err
- }
- return accounts, nil
- }
- func (self *SCloudaccount) GetCloudproviderId() string {
- return ""
- }
- func (self *SCloudaccount) GetSamlusers() ([]SSamluser, error) {
- q := SamluserManager.Query().Equals("cloudaccount_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 *SCloudaccount) GetProvider() (cloudprovider.ICloudProvider, error) {
- ctx := context.Background()
- s := auth.GetAdminSession(ctx, options.Options.Region)
- return modules.Cloudaccounts.GetProvider(ctx, s, self.Id)
- }
- func (self *SCloudaccount) GetDriver() (IProviderDriver, error) {
- return GetProviderDriver(self.Provider)
- }
- func (self *SCloudaccount) GetCloudpolicies(managerId string) ([]SCloudpolicy, error) {
- q := CloudpolicyManager.Query().Equals("cloudaccount_id", self.Id)
- if len(managerId) > 0 {
- q = q.Equals("manager_id", managerId)
- }
- policies := []SCloudpolicy{}
- err := db.FetchModelObjects(CloudpolicyManager, q, &policies)
- if err != nil {
- return nil, errors.Wrap(err, "db.FetchModelObjects")
- }
- return policies, nil
- }
- func (self *SCloudaccount) GetCloudproviders() ([]SCloudprovider, error) {
- q := CloudproviderManager.Query().Equals("cloudaccount_id", self.Id)
- providers := []SCloudprovider{}
- err := db.FetchModelObjects(CloudproviderManager, q, &providers)
- if err != nil {
- return nil, errors.Wrap(err, "db.FetchModelObjects")
- }
- return providers, nil
- }
- func (self *SCloudaccount) GetCloudgroups(managerId string) ([]SCloudgroup, error) {
- groups := []SCloudgroup{}
- q := CloudgroupManager.Query().Equals("cloudaccount_id", self.Id)
- if len(managerId) > 0 {
- q = q.Equals("manager_id", managerId)
- }
- err := db.FetchModelObjects(CloudgroupManager, q, &groups)
- if err != nil {
- return nil, errors.Wrap(err, "db.FetchModelObjects")
- }
- return groups, nil
- }
- func (manager *SCloudaccountManager) SyncCloudaccountResources(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
- accounts, err := manager.GetCloudaccounts()
- if err != nil {
- log.Errorf("GetCloudaccounts error: %v", err)
- return
- }
- for i := range accounts {
- err = accounts[i].StartSyncCloudaccountResourcesTask(ctx, userCred, "")
- if err != nil {
- log.Errorf("StartCloudaccountSyncResourcesTask for account %s(%s) error: %v", accounts[i].Name, accounts[i].Provider, err)
- }
- }
- }
- func (self *SCloudaccount) IsSAMLProviderValid() (*SSAMLProvider, bool) {
- provider, err := self.RegisterSAMProvider()
- if err != nil {
- return provider, false
- }
- if len(provider.ExternalId) == 0 {
- return provider, false
- }
- return provider, true
- }
- func (self *SCloudaccount) RegisterSAMProvider() (*SSAMLProvider, error) {
- if len(options.Options.ApiServer) == 0 {
- return nil, fmt.Errorf("empty api server")
- }
- sps, err := self.GetSAMLProviders("")
- if err != nil {
- return nil, errors.Wrapf(err, "GetSAMLProviders")
- }
- for i := range sps {
- if sps[i].EntityId == options.Options.ApiServer {
- return &sps[i], nil
- }
- }
- sp := &SSAMLProvider{}
- sp.SetModelManager(SAMLProviderManager, sp)
- sp.Name = func() string {
- name := strings.TrimPrefix(options.Options.ApiServer, "https://")
- name = strings.TrimPrefix(name, "http://")
- return name
- }()
- sp.EntityId = options.Options.ApiServer
- sp.CloudaccountId = self.Id
- sp.DomainId = self.DomainId
- sp.Status = apis.STATUS_CREATING
- metadata := SamlIdpInstance().GetMetadata(self.Id).String()
- sp.MetadataDocument = metadata
- err = SAMLProviderManager.TableSpec().Insert(context.TODO(), sp)
- if err != nil {
- return nil, errors.Wrapf(err, "Insert")
- }
- return sp, nil
- }
- func (self *SCloudaccount) StartSAMLProviderCreateTask(ctx context.Context, userCred mcclient.TokenCredential) error {
- params := jsonutils.NewDict()
- task, err := taskman.TaskManager.NewTask(ctx, "SAMLProviderCreateTask", self, userCred, params, "", "", nil)
- if err != nil {
- return errors.Wrap(err, "NewTask")
- }
- return task.ScheduleRun(nil)
- }
- func (self *SCloudaccount) GetSAMLProviders(managerId string) ([]SSAMLProvider, error) {
- q := SAMLProviderManager.Query().Equals("cloudaccount_id", self.Id).Desc("external_id")
- if len(managerId) > 0 {
- q = q.Equals("manager_id", managerId)
- }
- samls := []SSAMLProvider{}
- err := db.FetchModelObjects(SAMLProviderManager, q, &samls)
- if err != nil {
- return nil, errors.Wrapf(err, "db.FetchModelObjects")
- }
- return samls, nil
- }
- func (self *SCloudaccount) StartSyncCloudaccountResourcesTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
- params := jsonutils.NewDict()
- task, err := taskman.TaskManager.NewTask(ctx, "CloudaccountSyncResourcesTask", self, userCred, params, parentTaskId, "", nil)
- if err != nil {
- return errors.Wrap(err, "NewTask")
- }
- return task.ScheduleRun(nil)
- }
- func (self *SCloudaccount) GetCloudroles(managerId string) ([]SCloudrole, error) {
- roles := []SCloudrole{}
- q := CloudroleManager.Query().Equals("cloudaccount_id", self.Id)
- if len(managerId) > 0 {
- q = q.Equals("manager_id", managerId)
- }
- err := db.FetchModelObjects(CloudroleManager, q, &roles)
- if err != nil {
- return nil, errors.Wrapf(err, "db.FetchModelObjects")
- }
- return roles, nil
- }
- func (m *SCloudaccountManager) StartWatchSAMLInRegion() error {
- adminSession := auth.GetAdminSession(context.Background(), "")
- watchMan, err := informer.NewWatchManagerBySession(adminSession)
- if err != nil {
- return err
- }
- resMan := &modules.Cloudaccounts
- return watchMan.For(resMan).AddEventHandler(context.Background(), m)
- }
- func (m *SCloudaccountManager) OnAdd(obj *jsonutils.JSONDict) {
- account := &SCloudaccount{}
- obj.Unmarshal(account)
- log.Debugf("OnAdd provider %s %s(%s)", account.Provider, account.Name, account.Id)
- account.SetModelManager(m, account)
- ctx := context.Background()
- if len(account.Provider) == 0 {
- s := auth.GetAdminSession(ctx, options.Options.Region)
- data, err := modules.Cloudaccounts.GetById(s, account.Id, nil)
- if err != nil {
- return
- }
- err = data.Unmarshal(account)
- if err != nil {
- return
- }
- }
- err := m.TableSpec().Insert(ctx, account)
- if err != nil {
- return
- }
- account.StartSyncCloudaccountResourcesTask(ctx, auth.AdminCredential(), "")
- }
- func (m *SCloudaccountManager) FetchAccount(id string) (*SCloudaccount, error) {
- account, err := m.FetchById(id)
- if err != nil {
- return nil, errors.Wrapf(err, "fetch by id %s", id)
- }
- return account.(*SCloudaccount), nil
- }
- func (self *SCloudaccount) GetSamlProvider() (*SSAMLProvider, error) {
- q := SAMLProviderManager.Query().Equals("status", apis.STATUS_AVAILABLE).
- Equals("entity_id", options.Options.ApiServer).Equals("cloudaccount_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 (m *SCloudaccountManager) OnDelete(obj *jsonutils.JSONDict) {
- log.Debugf("OnDelete %s", obj)
- account, err := func() (*SCloudaccount, error) {
- id, err := obj.GetString("id")
- if err != nil {
- return nil, errors.Wrapf(err, "get id")
- }
- return m.FetchAccount(id)
- }()
- if err != nil {
- log.Errorf("fetch account error: %v", err)
- return
- }
- err = account.purge(context.Background())
- if err != nil {
- log.Errorf("purge account error: %v", err)
- return
- }
- }
- func (m *SCloudaccountManager) OnUpdate(oldObj, newObj *jsonutils.JSONDict) {
- id, err := newObj.GetString("id")
- if err != nil {
- return
- }
- account, err := m.FetchAccount(id)
- if err != nil {
- if errors.Cause(err) == sql.ErrNoRows {
- m.OnAdd(newObj)
- return
- }
- return
- }
- db.Update(account, func() error {
- newObj.Unmarshal(account)
- return nil
- })
- oSaml, _ := oldObj.Bool("saml_auth")
- nSaml, _ := newObj.Bool("saml_auth")
- if !oSaml && nSaml {
- log.Debugf("OnUpdate provider %s %s(%s) enable saml auth", account.Provider, account.Name, account.Id)
- account.StartSAMLProviderCreateTask(context.Background(), auth.AdminCredential())
- }
- }
|