mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 14:19:49 +08:00
Merge pull request #3578 from ioito/hotfix/qx-dbinstance-privilege
fix: 创建数据库时指定账号权限时,避免数据库出现中间状态
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type DBInstanceAccountListOptions struct {
|
||||
options.BaseListOptions
|
||||
DBInstance string `help:"ID or Name of DBInstance" json:"dbinstance"`
|
||||
}
|
||||
R(&DBInstanceAccountListOptions{}, "dbinstance-account-list", "List DB instance accounts", func(s *mcclient.ClientSession, opts *DBInstanceAccountListOptions) error {
|
||||
params, err := options.ListStructToParams(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := modules.DBInstanceAccounts.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(result, modules.DBInstanceAccounts.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
type DBInstanceAccountIdOptions struct {
|
||||
ID string `help:"ID or Name of DBInstanceaccount"`
|
||||
}
|
||||
|
||||
R(&DBInstanceAccountIdOptions{}, "dbinstance-account-show", "Show DB instance account", func(s *mcclient.ClientSession, opts *DBInstanceAccountIdOptions) error {
|
||||
account, err := modules.DBInstanceAccounts.Get(s, opts.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(account)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&DBInstanceAccountIdOptions{}, "dbinstance-account-delete", "Delete DB instance account", func(s *mcclient.ClientSession, opts *DBInstanceAccountIdOptions) error {
|
||||
account, err := modules.DBInstanceAccounts.Delete(s, opts.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(account)
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
@@ -312,37 +312,6 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
type DBInstanceAccountListOptions struct {
|
||||
options.BaseListOptions
|
||||
DBInstance string `help:"ID or Name of DBInstance" json:"dbinstance"`
|
||||
}
|
||||
R(&DBInstanceAccountListOptions{}, "dbinstance-account-list", "List DB instance accounts", func(s *mcclient.ClientSession, opts *DBInstanceAccountListOptions) error {
|
||||
params, err := options.ListStructToParams(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := modules.DBInstanceAccounts.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(result, modules.DBInstanceAccounts.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
type DBInstanceAccountIdOptions struct {
|
||||
ID string `help:"ID or Name of DBInstanceaccount"`
|
||||
}
|
||||
|
||||
R(&DBInstanceAccountIdOptions{}, "dbinstance-account-show", "Show DB instance account", func(s *mcclient.ClientSession, opts *DBInstanceAccountIdOptions) error {
|
||||
account, err := modules.DBInstanceAccounts.Get(s, opts.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(account)
|
||||
return nil
|
||||
})
|
||||
|
||||
type DBInstancePrivilegeListOptions struct {
|
||||
options.BaseListOptions
|
||||
DBInstanceaccount string `help:"ID or Name of DBInstanceaccount" json:"dbinstanceaccount"`
|
||||
@@ -362,4 +331,21 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
type DBInstanceChangeOwnerOptions struct {
|
||||
ID string `help:"DBInstance to change owner" json:"-"`
|
||||
PROJECT string `help:"Project ID or change" json:"tenant"`
|
||||
}
|
||||
R(&DBInstanceChangeOwnerOptions{}, "dbinstance-change-owner", "Change owner porject of a dbinstance", func(s *mcclient.ClientSession, opts *DBInstanceChangeOwnerOptions) error {
|
||||
params, err := options.StructToParams(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.DBInstance.PerformAction(s, opts.ID, "change-owner", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -56,11 +56,12 @@ const (
|
||||
BACKUP_MODE_MANUAL = "manual" //手动
|
||||
|
||||
//实例数据库状态
|
||||
DBINSTANCE_DATABASE_CREATING = "creating" //创建中
|
||||
DBINSTANCE_DATABASE_CREATE_FAILE = "create_failed" //创建失败
|
||||
DBINSTANCE_DATABASE_RUNNING = "running" //正常
|
||||
DBINSTANCE_DATABASE_DELETING = "deleting" //删除中
|
||||
DBINSTANCE_DATABASE_DELETE_FAILED = "delete_failed" //删除失败
|
||||
DBINSTANCE_DATABASE_CREATING = "creating" //创建中
|
||||
DBINSTANCE_DATABASE_CREATE_FAILE = "create_failed" //创建失败
|
||||
DBINSTANCE_DATABASE_RUNNING = "running" //正常
|
||||
DBINSTANCE_DATABASE_GRANT_PRIVILEGE = "grant_privilege" //赋予权限中
|
||||
DBINSTANCE_DATABASE_DELETING = "deleting" //删除中
|
||||
DBINSTANCE_DATABASE_DELETE_FAILED = "delete_failed" //删除失败
|
||||
|
||||
//实例用户状态
|
||||
DBINSTANCE_USER_UNAVAILABLE = "unavailable" //不可用
|
||||
|
||||
@@ -18,7 +18,7 @@ import "yunion.io/x/onecloud/pkg/apis"
|
||||
|
||||
type SDBInstanceDatabasePrivilege struct {
|
||||
Account string
|
||||
DBInstancedccountId string
|
||||
DBInstanceaccountId string
|
||||
Privilege string
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ func (manager *SDBInstanceDatabaseManager) ValidateCreateData(ctx context.Contex
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("failed to found dbinstance %s(%s) account %s: %v", instance.Name, instance.Id, _account.Account, err)
|
||||
}
|
||||
input.Accounts[i].DBInstancedccountId = account.Id
|
||||
input.Accounts[i].DBInstanceaccountId = account.Id
|
||||
}
|
||||
|
||||
input, err = region.GetDriver().ValidateCreateDBInstanceDatabaseData(ctx, userCred, ownerId, instance, input)
|
||||
@@ -178,6 +178,15 @@ func (self *SDBInstanceDatabase) GetDBInstance() (*SDBInstance, error) {
|
||||
return instance.(*SDBInstance), nil
|
||||
}
|
||||
|
||||
func (self *SDBInstanceDatabase) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
|
||||
extra, err := self.SVirtualResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return self.getMoreDetails(ctx, userCred, extra)
|
||||
}
|
||||
|
||||
func (self *SDBInstanceDatabase) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := self.SVirtualResourceBase.GetCustomizeColumns(ctx, userCred, query)
|
||||
extra, _ = self.getMoreDetails(ctx, userCred, extra)
|
||||
|
||||
@@ -16,6 +16,7 @@ package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
@@ -72,13 +73,58 @@ func (self *DBInstanceAccountCreateTask) CreateDBInstanceAccount(ctx context.Con
|
||||
return
|
||||
}
|
||||
|
||||
account.SetStatus(self.UserCred, api.DBINSTANCE_USER_AVAILABLE, "")
|
||||
|
||||
input := api.SDBInstanceAccountCreateInput{}
|
||||
self.GetParams().Unmarshal(&input)
|
||||
for _, _privilege := range input.Privileges {
|
||||
account.StartGrantPrivilegeTask(ctx, self.UserCred, _privilege.Database, _privilege.Privilege, "")
|
||||
if len(input.Privileges) == 0 {
|
||||
account.SetStatus(self.UserCred, api.DBINSTANCE_USER_AVAILABLE, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
return
|
||||
}
|
||||
|
||||
iAccounts, err := iRds.GetIDBInstanceAccounts()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("failed to found accounts from cloud dbinstance error: %v", err)
|
||||
db.OpsLog.LogEvent(account, db.ACT_GRANT_PRIVILEGE, msg, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, account, logclient.ACT_GRANT_PRIVILEGE, msg, self.UserCred, false)
|
||||
account.SetStatus(self.UserCred, api.DBINSTANCE_USER_AVAILABLE, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
return
|
||||
}
|
||||
|
||||
var iAccount cloudprovider.ICloudDBInstanceAccount = nil
|
||||
for i := range iAccounts {
|
||||
if iAccounts[i].GetName() == account.Name {
|
||||
iAccount = iAccounts[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if iAccount == nil {
|
||||
msg := fmt.Sprintf("failed to found account %s from cloud dbinstance", account.Name)
|
||||
db.OpsLog.LogEvent(account, db.ACT_GRANT_PRIVILEGE, msg, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, account, logclient.ACT_GRANT_PRIVILEGE, msg, self.UserCred, false)
|
||||
account.SetStatus(self.UserCred, api.DBINSTANCE_USER_AVAILABLE, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
return
|
||||
}
|
||||
|
||||
account.SetStatus(self.UserCred, api.DBINSTANCE_USER_GRANT_PRIVILEGE, "")
|
||||
for _, privilege := range input.Privileges {
|
||||
err = iAccount.GrantPrivilege(privilege.Database, privilege.Privilege)
|
||||
if err != nil {
|
||||
db.OpsLog.LogEvent(account, db.ACT_GRANT_PRIVILEGE, err, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, account, logclient.ACT_GRANT_PRIVILEGE, err, self.UserCred, false)
|
||||
continue
|
||||
}
|
||||
_privilege := models.SDBInstancePrivilege{
|
||||
Privilege: privilege.Privilege,
|
||||
DBInstanceaccountId: account.Id,
|
||||
DBInstancedatabaseId: privilege.DBInstancedatabaseId,
|
||||
}
|
||||
models.DBInstancePrivilegeManager.TableSpec().Insert(&_privilege)
|
||||
logclient.AddActionLogWithStartable(self, account, logclient.ACT_GRANT_PRIVILEGE, privilege, self.UserCred, true)
|
||||
}
|
||||
|
||||
account.SetStatus(self.UserCred, api.DBINSTANCE_USER_AVAILABLE, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
@@ -74,18 +74,52 @@ func (self *DBInstanceDatabaseCreateTask) CreateDBInstanceDatabase(ctx context.C
|
||||
return
|
||||
}
|
||||
|
||||
database.SetStatus(self.UserCred, api.DBINSTANCE_DATABASE_RUNNING, "")
|
||||
|
||||
input := api.SDBInstanceDatabaseCreateInput{}
|
||||
self.GetParams().Unmarshal(&input)
|
||||
for _, _account := range input.Accounts {
|
||||
account, err := instance.GetDBInstanceAccount(_account.DBInstancedccountId)
|
||||
if err != nil {
|
||||
log.Errorf("failed to found account %s(%s) for instance %s(%s) error: %v", _account.Account, _account.DBInstancedccountId, instance.Name, instance.Id, err)
|
||||
} else {
|
||||
account.StartGrantPrivilegeTask(ctx, self.UserCred, database.Name, _account.Privilege, "")
|
||||
}
|
||||
if len(input.Accounts) == 0 {
|
||||
database.SetStatus(self.UserCred, api.DBINSTANCE_DATABASE_RUNNING, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
return
|
||||
}
|
||||
|
||||
_iAccounts, err := iRds.GetIDBInstanceAccounts()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("failed to found accounts from cloud dbinstance error: %v", err)
|
||||
db.OpsLog.LogEvent(database, db.ACT_GRANT_PRIVILEGE, msg, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, database, logclient.ACT_GRANT_PRIVILEGE, msg, self.UserCred, false)
|
||||
database.SetStatus(self.UserCred, api.DBINSTANCE_DATABASE_RUNNING, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
return
|
||||
}
|
||||
|
||||
database.SetStatus(self.UserCred, api.DBINSTANCE_DATABASE_GRANT_PRIVILEGE, "")
|
||||
iAccounts := map[string]cloudprovider.ICloudDBInstanceAccount{}
|
||||
for _, iAccount := range _iAccounts {
|
||||
iAccounts[iAccount.GetName()] = iAccount
|
||||
}
|
||||
|
||||
for _, account := range input.Accounts {
|
||||
iAccount, ok := iAccounts[account.Account]
|
||||
if !ok {
|
||||
msg := fmt.Sprintf("failed to found account %s from dbinstance", account.Account)
|
||||
db.OpsLog.LogEvent(database, db.ACT_GRANT_PRIVILEGE, msg, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, database, logclient.ACT_GRANT_PRIVILEGE, msg, self.UserCred, false)
|
||||
continue
|
||||
}
|
||||
err = iAccount.GrantPrivilege(database.Name, account.Privilege)
|
||||
if err != nil {
|
||||
db.OpsLog.LogEvent(database, db.ACT_GRANT_PRIVILEGE, err, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, database, logclient.ACT_GRANT_PRIVILEGE, err, self.UserCred, false)
|
||||
continue
|
||||
}
|
||||
privilege := models.SDBInstancePrivilege{
|
||||
Privilege: account.Privilege,
|
||||
DBInstanceaccountId: account.DBInstanceaccountId,
|
||||
DBInstancedatabaseId: database.Id,
|
||||
}
|
||||
models.DBInstancePrivilegeManager.TableSpec().Insert(&privilege)
|
||||
logclient.AddActionLogWithStartable(self, database, logclient.ACT_GRANT_PRIVILEGE, account, self.UserCred, true)
|
||||
}
|
||||
database.SetStatus(self.UserCred, api.DBINSTANCE_DATABASE_RUNNING, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func init() {
|
||||
AccountType string `help:"account type" choices:"Normal|Super" default:"Normal"`
|
||||
}
|
||||
|
||||
shellutils.R(&DBInstanceAccountResetOptions{}, "dbinstance-account-delete", "Delete dbintance account", func(cli *aliyun.SRegion, args *DBInstanceAccountResetOptions) error {
|
||||
shellutils.R(&DBInstanceAccountResetOptions{}, "dbinstance-account-reset-password", "Reset dbintance account password", func(cli *aliyun.SRegion, args *DBInstanceAccountResetOptions) error {
|
||||
return cli.ResetDBInstanceAccountPassword(args.INSTANCE, args.NAME, args.PASSWORD, args.AccountType)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user