mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
Add region service.
This commit is contained in:
@@ -4,8 +4,9 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
)
|
||||
|
||||
func InitDB(options *DBOptions) {
|
||||
|
||||
@@ -3,9 +3,9 @@ package db
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
|
||||
@@ -40,12 +40,16 @@ func (dispatcher *DBModelDispatcher) KeywordPlural() string {
|
||||
return dispatcher.modelManager.KeywordPlural()
|
||||
}
|
||||
|
||||
func (dispatcher *DBModelDispatcher) ContextKeywordPlural() string {
|
||||
ctxMan := dispatcher.modelManager.GetContextManager()
|
||||
if ctxMan != nil {
|
||||
return ctxMan.KeywordPlural()
|
||||
func (dispatcher *DBModelDispatcher) ContextKeywordPlural() []string {
|
||||
ctxMans := dispatcher.modelManager.GetContextManager()
|
||||
if ctxMans != nil {
|
||||
keys := make([]string, len(ctxMans))
|
||||
for i := 0; i < len(ctxMans); i += 1 {
|
||||
keys[i] = ctxMans[i].KeywordPlural()
|
||||
}
|
||||
return keys
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -332,21 +336,34 @@ func query2List(manager IModelManager, ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
|
||||
func fetchContextObjectId(manager IModelManager, ctx context.Context, userCred mcclient.TokenCredential, ctxId string, queryDict *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
ctxMan := manager.GetContextManager()
|
||||
if ctxMan == nil {
|
||||
ctxMans := manager.GetContextManager()
|
||||
if ctxMans == nil {
|
||||
return nil, fmt.Errorf("No context manager")
|
||||
}
|
||||
ctxObj, err := fetchItem(ctxMan, ctx, userCred, ctxId, nil)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError("Resource %s %s not found", ctxMan.Keyword(), ctxId)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
find := false
|
||||
keys := make([]string, 0)
|
||||
for i := 0; i < len(ctxMans); i += 1 {
|
||||
ctxObj, err := fetchItem(ctxMans[i], ctx, userCred, ctxId, nil)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
keys = append(keys, ctxMans[i].KeywordPlural())
|
||||
continue
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
find = true
|
||||
queryDict.Add(jsonutils.NewString(ctxObj.GetId()), fmt.Sprintf("%s_id", ctxObj.GetModelManager().Keyword()))
|
||||
if len(ctxObj.GetModelManager().Alias()) > 0 {
|
||||
queryDict.Add(jsonutils.NewString(ctxObj.GetId()), fmt.Sprintf("%s_id", ctxObj.GetModelManager().Alias()))
|
||||
}
|
||||
}
|
||||
}
|
||||
queryDict.Add(jsonutils.NewString(ctxObj.GetId()), fmt.Sprintf("%s_id", ctxObj.GetModelManager().Keyword()))
|
||||
if len(ctxObj.GetModelManager().Alias()) > 0 {
|
||||
queryDict.Add(jsonutils.NewString(ctxObj.GetId()), fmt.Sprintf("%s_id", ctxObj.GetModelManager().Alias()))
|
||||
if !find {
|
||||
return nil, httperrors.NewResourceNotFoundError("Resource %s not found in %s", ctxId, strings.Join(keys, ", "))
|
||||
} else {
|
||||
return queryDict, nil
|
||||
}
|
||||
return queryDict, nil
|
||||
}
|
||||
|
||||
func listItems(manager IModelManager, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, ctxId string) (*modules.ListResult, error) {
|
||||
@@ -440,6 +457,12 @@ func getModelExtraDetails(item IModel, ctx context.Context, extra *jsonutils.JSO
|
||||
} else {
|
||||
extra.Add(jsonutils.JSONTrue, "can_delete")
|
||||
}
|
||||
err = item.ValidateUpdateCondition(ctx)
|
||||
if err != nil {
|
||||
extra.Add(jsonutils.JSONFalse, "can_update")
|
||||
} else {
|
||||
extra.Add(jsonutils.JSONTrue, "can_update")
|
||||
}
|
||||
return extra
|
||||
}
|
||||
|
||||
@@ -584,7 +607,7 @@ func (dispatcher *DBModelDispatcher) GetSpecific(ctx context.Context, idStr stri
|
||||
func fetchOwnerProjectId(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject) (string, error) {
|
||||
var projId string
|
||||
if data != nil {
|
||||
projId, _ := data.GetString("project")
|
||||
projId, _ = data.GetString("project")
|
||||
if len(projId) == 0 {
|
||||
projId, _ = data.GetString("tenant")
|
||||
}
|
||||
@@ -726,13 +749,13 @@ func expandMultiCreateParams(data jsonutils.JSONObject, count int) ([]jsonutils.
|
||||
if !ok {
|
||||
return nil, httperrors.NewInputParameterError("body is not a json?")
|
||||
}
|
||||
name, _ := jsonDict.GetString("generated_name")
|
||||
name, _ := jsonDict.GetString("generate_name")
|
||||
if len(name) == 0 {
|
||||
name, _ = jsonDict.GetString("name")
|
||||
if len(name) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("Missing name or generate_name")
|
||||
}
|
||||
jsonDict.Add(jsonutils.NewString(name), "generated_name")
|
||||
jsonDict.Add(jsonutils.NewString(name), "generate_name")
|
||||
jsonDict.Remove("name", false)
|
||||
}
|
||||
ret := make([]jsonutils.JSONObject, count)
|
||||
@@ -799,7 +822,9 @@ func (dispatcher *DBModelDispatcher) BatchCreate(ctx context.Context, query json
|
||||
}
|
||||
results[i] = result
|
||||
}
|
||||
dispatcher.modelManager.OnCreateComplete(ctx, models, userCred, query, data)
|
||||
if len(models) > 0 {
|
||||
dispatcher.modelManager.OnCreateComplete(ctx, models, userCred, query, data)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
@@ -918,11 +943,20 @@ func updateItem(manager IModelManager, item IModel, ctx context.Context, userCre
|
||||
if !item.AllowUpdateItem(ctx, userCred) {
|
||||
return nil, httperrors.NewForbiddenError(fmt.Sprintf("Not allow to update item"))
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
err = item.ValidateUpdateCondition(ctx)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("validate update condition error: %s", err)
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
|
||||
dataDict, ok := data.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, httperrors.NewInternalServerError("Invalid data JSONObject")
|
||||
}
|
||||
var err error
|
||||
|
||||
name, _ := data.GetString("name")
|
||||
if len(name) > 0 {
|
||||
@@ -1028,6 +1062,8 @@ func deleteItem(manager IModelManager, model IModel, ctx context.Context, userCr
|
||||
return nil, err
|
||||
}
|
||||
|
||||
model.PostDelete(ctx, userCred)
|
||||
|
||||
return details, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ func (dispatcher *DBJointModelDispatcher) SlaveKeywordPlural() string {
|
||||
}
|
||||
|
||||
func (dispatcher *DBJointModelDispatcher) ListMasterDescendent(ctx context.Context, idStr string, query jsonutils.JSONObject) (*modules.ListResult, error) {
|
||||
log.Debugf("ListMasterDescendent %s %s", dispatcher.JointModelManager().GetMasterManager().Keyword(), idStr)
|
||||
userCred := fetchUserCredential(ctx)
|
||||
|
||||
var queryDict *jsonutils.JSONDict
|
||||
@@ -70,6 +71,8 @@ func (dispatcher *DBJointModelDispatcher) ListMasterDescendent(ctx context.Conte
|
||||
}
|
||||
|
||||
func (dispatcher *DBJointModelDispatcher) ListSlaveDescendent(ctx context.Context, idStr string, query jsonutils.JSONObject) (*modules.ListResult, error) {
|
||||
log.Debugf("ListSlaveDescendent %s %s", dispatcher.JointModelManager().GetMasterManager().Keyword(), idStr)
|
||||
|
||||
userCred := fetchUserCredential(ctx)
|
||||
|
||||
var queryDict *jsonutils.JSONDict
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
type SEnabledStatusStandaloneResourceBase struct {
|
||||
SStatusStandaloneResourceBase
|
||||
|
||||
Enabled bool `nullable:"false" default:"false" list:"user"` // = Column(Boolean, nullable=False, default=False)
|
||||
Enabled bool `nullable:"false" default:"false" list:"user" create:"optional"` // = Column(Boolean, nullable=False, default=False)
|
||||
}
|
||||
|
||||
type SEnabledStatusStandaloneResourceBaseManager struct {
|
||||
|
||||
9
pkg/cloudcommon/db/global.go
Normal file
9
pkg/cloudcommon/db/global.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package db
|
||||
|
||||
/// Global virtual resource namespace
|
||||
|
||||
var globalVirtualResourceNamespace = false
|
||||
|
||||
func EnableGlobalVirtualResourceNamespace() {
|
||||
globalVirtualResourceNamespace = true
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
type IModelManager interface {
|
||||
lockman.ILockedClass
|
||||
|
||||
GetContextManager() IModelManager
|
||||
GetContextManager() []IModelManager
|
||||
|
||||
// Table() *sqlchemy.STable
|
||||
TableSpec() *sqlchemy.STableSpec
|
||||
@@ -83,6 +83,8 @@ type IModel interface {
|
||||
PerformAction(ctx context.Context, userCred mcclient.TokenCredential, action string, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error)
|
||||
|
||||
// update hooks
|
||||
ValidateUpdateCondition(ctx context.Context) error
|
||||
|
||||
AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool
|
||||
ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
|
||||
PreUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject)
|
||||
@@ -95,6 +97,7 @@ type IModel interface {
|
||||
PreDelete(ctx context.Context, userCred mcclient.TokenCredential)
|
||||
MarkDelete() error
|
||||
Delete(ctx context.Context, userCred mcclient.TokenCredential) error
|
||||
PostDelete(ctx context.Context, userCred mcclient.TokenCredential)
|
||||
|
||||
GetOwnerProjectId() string
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
// "reflect"
|
||||
"database/sql"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
@@ -46,7 +45,7 @@ func (manager *SModelBaseManager) KeywordPlural() string {
|
||||
return manager.keywordPlural
|
||||
}
|
||||
|
||||
func (manager *SModelBaseManager) GetContextManager() IModelManager {
|
||||
func (manager *SModelBaseManager) GetContextManager() []IModelManager {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -229,6 +228,10 @@ func (model *SModelBase) AllowDeleteItem(ctx context.Context, userCred mcclient.
|
||||
return false
|
||||
}
|
||||
|
||||
func (model *SModelBase) ValidateUpdateCondition(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SModelBase) ValidateDeleteCondition(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
@@ -242,6 +245,10 @@ func (model *SModelBase) PreDelete(ctx context.Context, userCred mcclient.TokenC
|
||||
// do nothing
|
||||
}
|
||||
|
||||
func (model *SModelBase) PostDelete(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
func (model *SModelBase) MarkDelete() error {
|
||||
// do nothing
|
||||
return nil
|
||||
|
||||
@@ -10,7 +10,9 @@ import (
|
||||
func isNameUnique(manager IModelManager, ownerProjId string, name string) bool {
|
||||
q := manager.Query()
|
||||
q = manager.FilterByName(q, name)
|
||||
q = manager.FilterByOwner(q, ownerProjId)
|
||||
if !globalVirtualResourceNamespace {
|
||||
q = manager.FilterByOwner(q, ownerProjId)
|
||||
}
|
||||
return q.Count() == 0
|
||||
}
|
||||
|
||||
@@ -29,7 +31,9 @@ func isAlterNameUnique(model IModel, name string) bool {
|
||||
manager := model.GetModelManager()
|
||||
q := manager.Query()
|
||||
q = manager.FilterByName(q, name)
|
||||
q = manager.FilterByOwner(q, model.GetOwnerProjectId())
|
||||
if !globalVirtualResourceNamespace {
|
||||
q = manager.FilterByOwner(q, model.GetOwnerProjectId())
|
||||
}
|
||||
q = manager.FilterByNotId(q, model.GetId())
|
||||
return q.Count() == 0
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/util/timeutils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/util/timeutils"
|
||||
)
|
||||
|
||||
type SResourceBase struct {
|
||||
|
||||
@@ -5,14 +5,14 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
"github.com/yunionio/pkg/util/stringutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
type SStandaloneResourceBase struct {
|
||||
@@ -23,6 +23,8 @@ type SStandaloneResourceBase struct {
|
||||
ExternalId string `width:"128" charset:"ascii" index:"true" get:"admin" create:"admin_optional"`
|
||||
|
||||
Description string `width:"256" charset:"utf8" get:"user" update:"user" create:"optional"`
|
||||
|
||||
IsEmulated bool `nullable:"false" default:"false" list:"admin" update:"true" create:"admin_optional"`
|
||||
}
|
||||
|
||||
func (model *SStandaloneResourceBase) BeforeInsert() {
|
||||
@@ -100,6 +102,20 @@ func (manager *SStandaloneResourceBaseManager) FetchByExternalId(idStr string) (
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SStandaloneResourceBaseManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return q, err
|
||||
}
|
||||
|
||||
showEmulated := jsonutils.QueryBoolean(query, "show_emulated", false)
|
||||
if ! showEmulated {
|
||||
q = q.Filter(sqlchemy.IsFalse(q.Field("is_emulated")))
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (model *SStandaloneResourceBase) StandaloneModelManager() IStandaloneModelManager {
|
||||
return model.GetModelManager().(IStandaloneModelManager)
|
||||
}
|
||||
@@ -224,9 +240,11 @@ func (model *SStandaloneResourceBase) PostCreate(ctx context.Context, userCred m
|
||||
}
|
||||
}
|
||||
|
||||
func (model *SStandaloneResourceBase) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
model.SResourceBase.PreDelete(ctx, userCred)
|
||||
model.RemoveAllMetadata(ctx, userCred)
|
||||
func (model *SStandaloneResourceBase) PostDelete(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
if model.Deleted {
|
||||
model.RemoveAllMetadata(ctx, userCred)
|
||||
}
|
||||
model.SResourceBase.PostDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (model *SStandaloneResourceBase) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
|
||||
@@ -207,6 +207,7 @@ func (manager *STaskManager) NewParallelTask(ctx context.Context, taskName strin
|
||||
return nil, fmt.Errorf("task %s not found", taskName)
|
||||
}
|
||||
|
||||
log.Debugf("number of objs: %d", len(objs))
|
||||
lockman.LockClass(ctx, objs[0].GetModelManager(), userCred.GetProjectId())
|
||||
defer lockman.ReleaseClass(ctx, objs[0].GetModelManager(), userCred.GetProjectId())
|
||||
|
||||
|
||||
@@ -31,21 +31,25 @@ var TenantCacheManager *STenantCacheManager
|
||||
|
||||
func init() {
|
||||
TenantCacheManager = &STenantCacheManager{NewKeystoneCacheObjectManager(STenant{}, "tenant_cache_tbl", "tenant", "tenants")}
|
||||
log.Debugf("Initialize tenant cache manager %s %s", TenantCacheManager.KeywordPlural(), TenantCacheManager)
|
||||
// log.Debugf("Initialize tenant cache manager %s %s", TenantCacheManager.KeywordPlural(), TenantCacheManager)
|
||||
}
|
||||
|
||||
func (manager *STenantCacheManager) FetchTenantByIdOrName(ctx context.Context, idStr string) (*STenant, error) {
|
||||
tenant, err := manager.SKeystoneCacheObjectManager.FetchByIdOrName("", idStr)
|
||||
if err == sql.ErrNoRows {
|
||||
return manager.fetchTenantFromKeystone(ctx, idStr)
|
||||
tenant, err := manager.FetchByIdOrName("", idStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return manager.fetchTenantFromKeystone(ctx, idStr)
|
||||
} else {
|
||||
log.Errorf("FetchTenantByIdOrName fail: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
kObj := tenant.(*SKeystoneCacheObject)
|
||||
return &STenant{*kObj}, err
|
||||
return tenant.(*STenant), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *STenantCacheManager) FetchTenantById(ctx context.Context, idStr string) (*STenant, error) {
|
||||
tenant, err := manager.SKeystoneCacheObjectManager.FetchById(idStr)
|
||||
tenant, err := manager.FetchById(idStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return manager.fetchTenantFromKeystone(ctx, idStr)
|
||||
@@ -54,12 +58,12 @@ func (manager *STenantCacheManager) FetchTenantById(ctx context.Context, idStr s
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return tenant.(*STenant), err
|
||||
return tenant.(*STenant), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *STenantCacheManager) FetchTenantByName(ctx context.Context, idStr string) (*STenant, error) {
|
||||
tenant, err := manager.SKeystoneCacheObjectManager.FetchByName("", idStr)
|
||||
tenant, err := manager.FetchByName("", idStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return manager.fetchTenantFromKeystone(ctx, idStr)
|
||||
@@ -68,7 +72,7 @@ func (manager *STenantCacheManager) FetchTenantByName(ctx context.Context, idStr
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return tenant.(*STenant), err
|
||||
return tenant.(*STenant), nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package db
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
@@ -24,7 +25,7 @@ var UserCacheManager *SUserCacheManager
|
||||
|
||||
func init() {
|
||||
UserCacheManager = &SUserCacheManager{NewKeystoneCacheObjectManager(SUser{}, "users_cache_tbl", "user", "users")}
|
||||
log.Debugf("initialize user cache manager %s", UserCacheManager.KeywordPlural())
|
||||
// log.Debugf("initialize user cache manager %s", UserCacheManager.KeywordPlural())
|
||||
}
|
||||
|
||||
func (manager *SUserCacheManager) FetchUserByIdOrName(idStr string) (*SUser, error) {
|
||||
|
||||
@@ -79,7 +79,7 @@ func (manager *SVirtualResourceBaseManager) ListItemFilter(ctx context.Context,
|
||||
}
|
||||
admin, _ := query.GetString("admin")
|
||||
if utils.ToBool(admin) { // admin
|
||||
tenant, _ := query.GetString("tenant")
|
||||
tenant := jsonutils.GetAnyString(query, []string{"project", "project_id", "tenant", "tenant_id"})
|
||||
if len(tenant) > 0 {
|
||||
tobj, _ := TenantCacheManager.FetchTenantByIdOrName(ctx, tenant)
|
||||
if tobj != nil {
|
||||
@@ -161,29 +161,32 @@ func (model *SVirtualResourceBase) AllowPerformMetadata(ctx context.Context, use
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) GetTenantCache(ctx context.Context) (*STenant, error) {
|
||||
log.Debugf("Get tenant by Id %s", model.ProjectId)
|
||||
return TenantCacheManager.FetchTenantById(ctx, model.ProjectId)
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) getMoreDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, extra *jsonutils.JSONDict) *jsonutils.JSONDict {
|
||||
if userCred.IsSystemAdmin() {
|
||||
log.Debugf("GetCustomizeColumns")
|
||||
tobj, err := model.GetTenantCache(ctx)
|
||||
if err == nil {
|
||||
log.Debugf("GetTenantFromCache %s", jsonutils.Marshal(tobj))
|
||||
extra.Add(jsonutils.NewString(tobj.GetName()), "tenant")
|
||||
} else {
|
||||
log.Errorf("GetTenantCache fail %s", err)
|
||||
}
|
||||
}
|
||||
return extra
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := model.SStandaloneResourceBase.GetCustomizeColumns(ctx, userCred, query)
|
||||
if userCred.IsSystemAdmin() {
|
||||
tobj, err := model.GetTenantCache(ctx)
|
||||
if err == nil {
|
||||
extra.Add(jsonutils.NewString(tobj.GetName()), "tenant")
|
||||
}
|
||||
}
|
||||
return extra
|
||||
return model.getMoreDetails(ctx, userCred, query, extra)
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := model.SStandaloneResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
if userCred.IsSystemAdmin() {
|
||||
tobj, err := model.GetTenantCache(ctx)
|
||||
if err == nil {
|
||||
extra.Add(jsonutils.NewString(tobj.GetId()), "tenant")
|
||||
}
|
||||
}
|
||||
return extra
|
||||
return model.getMoreDetails(ctx, userCred, query, extra)
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) AllowPerformChangeOwner(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
@@ -191,7 +194,7 @@ func (model *SVirtualResourceBase) AllowPerformChangeOwner(ctx context.Context,
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
tenant, _ := data.GetString("tenant")
|
||||
tenant := jsonutils.GetAnyString(data, []string{"project", "tenant", "project_id", "tenant_id"})
|
||||
if len(tenant) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("missing parameter tenant")
|
||||
}
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"path"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/pkg/util/version"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/structarg"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/pkg/util/version"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
@@ -32,6 +32,8 @@ type Options struct {
|
||||
|
||||
NotifyAdminUser string `default:"sysadmin" help:"System administrator user ID or name to notify"`
|
||||
|
||||
GlobalVirtualResourceNamespace bool `help:"Per project namespace or global namespace for virtual resources"`
|
||||
|
||||
structarg.BaseOptions
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,11 @@ package cloudprovider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
)
|
||||
|
||||
type ICloudProviderFactory interface {
|
||||
GetProvider(providerId, url, account, secret string) (ICloudProvider, error)
|
||||
GetProvider(providerId, providerName, url, account, secret string) (ICloudProvider, error)
|
||||
GetId() string
|
||||
}
|
||||
|
||||
@@ -19,6 +18,11 @@ type ICloudProvider interface {
|
||||
IsPublicCloud() bool
|
||||
|
||||
GetIRegionById(id string) (ICloudRegion, error)
|
||||
|
||||
GetIHostById(id string) (ICloudHost, error)
|
||||
GetIVpcById(id string) (ICloudVpc, error)
|
||||
GetIStorageById(id string) (ICloudStorage, error)
|
||||
GetIStoragecacheById(id string) (ICloudStoragecache, error)
|
||||
}
|
||||
|
||||
var providerTable map[string]ICloudProviderFactory
|
||||
@@ -31,10 +35,10 @@ func RegisterFactory(factory ICloudProviderFactory) {
|
||||
providerTable[factory.GetId()] = factory
|
||||
}
|
||||
|
||||
func GetProvider(providerId, accessUrl, account, secret, provider string) (ICloudProvider, error) {
|
||||
func GetProvider(providerId, providerName, accessUrl, account, secret, provider string) (ICloudProvider, error) {
|
||||
factory, ok := providerTable[provider]
|
||||
if ok {
|
||||
return factory.GetProvider(providerId, accessUrl, account, secret)
|
||||
return factory.GetProvider(providerId, providerName, accessUrl, account, secret)
|
||||
}
|
||||
return nil, fmt.Errorf("No such provider %s", provider)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package cloudprovider
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
)
|
||||
@@ -11,26 +10,38 @@ type ICloudResource interface {
|
||||
GetId() string
|
||||
GetName() string
|
||||
GetGlobalId() string
|
||||
|
||||
GetStatus() string
|
||||
|
||||
Refresh() error
|
||||
|
||||
IsEmulated() bool
|
||||
}
|
||||
|
||||
type ICloudRegion interface {
|
||||
ICloudResource
|
||||
|
||||
GetLatitude() float32
|
||||
GetLongitude() float32
|
||||
GetStatus() string
|
||||
|
||||
GetIZones() ([]ICloudZone, error)
|
||||
GetIVpcs() ([]ICloudVpc, error)
|
||||
|
||||
GetIZoneById(id string) (ICloudZone, error)
|
||||
GetIVpcById(id string) (ICloudVpc, error)
|
||||
GetIHostById(id string) (ICloudHost, error)
|
||||
GetIStorageById(id string) (ICloudStorage, error)
|
||||
GetIStoragecacheById(id string) (ICloudStoragecache, error)
|
||||
|
||||
CreateIVpc(name string, desc string, cidr string) (ICloudVpc, error)
|
||||
|
||||
GetProvider() string
|
||||
}
|
||||
|
||||
type ICloudZone interface {
|
||||
ICloudResource
|
||||
|
||||
GetIRegion() ICloudRegion
|
||||
GetStatus() string
|
||||
|
||||
GetIHosts() ([]ICloudHost, error)
|
||||
GetIHostById(id string) (ICloudHost, error)
|
||||
@@ -43,7 +54,6 @@ type ICloudImage interface {
|
||||
ICloudResource
|
||||
|
||||
GetIStoragecache() ICloudStoragecache
|
||||
GetStatus() string
|
||||
}
|
||||
|
||||
type ICloudStoragecache interface {
|
||||
@@ -51,6 +61,8 @@ type ICloudStoragecache interface {
|
||||
|
||||
GetIImages() ([]ICloudImage, error)
|
||||
|
||||
GetManagerId() string
|
||||
|
||||
UploadImage(userCred mcclient.TokenCredential, imageId string, extId string, isForce bool) (string, error)
|
||||
}
|
||||
|
||||
@@ -66,8 +78,11 @@ type ICloudStorage interface {
|
||||
GetMediumType() string
|
||||
GetCapacityMB() int // MB
|
||||
GetStorageConf() jsonutils.JSONObject
|
||||
GetStatus() string
|
||||
GetEnabled() bool
|
||||
|
||||
GetManagerId() string
|
||||
|
||||
CreateIDisk(name string, sizeGb int, desc string) (ICloudDisk, error)
|
||||
}
|
||||
|
||||
type ICloudHost interface {
|
||||
@@ -78,8 +93,9 @@ type ICloudHost interface {
|
||||
|
||||
GetIWires() ([]ICloudWire, error)
|
||||
GetIStorages() ([]ICloudStorage, error)
|
||||
GetIStorageById(id string) (ICloudStorage, error)
|
||||
|
||||
GetStatus() string // os status
|
||||
// GetStatus() string // os status
|
||||
GetEnabled() bool // is enabled
|
||||
GetHostStatus() string // service status
|
||||
GetAccessIp() string //
|
||||
@@ -97,8 +113,8 @@ type ICloudHost interface {
|
||||
|
||||
GetManagerId() string
|
||||
|
||||
CreateVM(name string, imgId string, cpu int, memMB int, vswitchId string, ipAddr string, desc string,
|
||||
passwd string, storageType string, diskSizes []int) (ICloudVM, error)
|
||||
CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, vswitchId string, ipAddr string, desc string,
|
||||
passwd string, storageType string, diskSizes []int, publicKey string) (ICloudVM, error)
|
||||
}
|
||||
|
||||
type ICloudVM interface {
|
||||
@@ -112,7 +128,7 @@ type ICloudVM interface {
|
||||
|
||||
GetEIP() ICloudEIP
|
||||
|
||||
GetStatus() string
|
||||
// GetStatus() string
|
||||
GetRemoteStatus() string
|
||||
|
||||
GetVcpuCount() int8
|
||||
@@ -158,7 +174,7 @@ type ICloudDisk interface {
|
||||
|
||||
GetIStorge() ICloudStorage
|
||||
|
||||
GetStatus() string
|
||||
// GetStatus() string
|
||||
GetDiskFormat() string
|
||||
GetDiskSizeMB() int // MB
|
||||
GetIsAutoDelete() bool
|
||||
@@ -178,8 +194,14 @@ type ICloudVpc interface {
|
||||
GetRegion() ICloudRegion
|
||||
GetIsDefault() bool
|
||||
GetCidrBlock() string
|
||||
GetStatus() string
|
||||
// GetStatus() string
|
||||
GetIWires() ([]ICloudWire, error)
|
||||
|
||||
GetManagerId() string
|
||||
|
||||
Delete() error
|
||||
|
||||
GetIWireById(wireId string) (ICloudWire, error)
|
||||
}
|
||||
|
||||
type ICloudWire interface {
|
||||
@@ -188,17 +210,23 @@ type ICloudWire interface {
|
||||
GetIZone() ICloudZone
|
||||
GetINetworks() ([]ICloudNetwork, error)
|
||||
GetBandwidth() int
|
||||
|
||||
GetINetworkById(netid string) (ICloudNetwork, error)
|
||||
|
||||
CreateINetwork(name string, cidr string, desc string) (ICloudNetwork, error)
|
||||
}
|
||||
|
||||
type ICloudNetwork interface {
|
||||
ICloudResource
|
||||
|
||||
GetIWire() ICloudWire
|
||||
GetStatus() string
|
||||
// GetStatus() string
|
||||
GetIpStart() string
|
||||
GetIpEnd() string
|
||||
GetIpMask() int8
|
||||
GetGateway() string
|
||||
GetServerType() string
|
||||
GetIsPublic() bool
|
||||
|
||||
Delete() error
|
||||
}
|
||||
|
||||
34
pkg/cloudprovider/waitstatus.go
Normal file
34
pkg/cloudprovider/waitstatus.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package cloudprovider
|
||||
|
||||
import "time"
|
||||
|
||||
func WaitStatus(res ICloudResource, expect string, interval time.Duration, timeout time.Duration) error {
|
||||
startTime := time.Now()
|
||||
for time.Now().Sub(startTime) < timeout {
|
||||
err := res.Refresh()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if res.GetStatus() == expect {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(interval)
|
||||
}
|
||||
return ErrTimeout
|
||||
}
|
||||
|
||||
func WaitDeleted(res ICloudResource, interval time.Duration, timeout time.Duration) error {
|
||||
startTime := time.Now()
|
||||
for time.Now().Sub(startTime) < timeout {
|
||||
err := res.Refresh()
|
||||
if err != nil {
|
||||
if err == ErrNotFound {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
time.Sleep(interval)
|
||||
}
|
||||
return ErrTimeout
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package guestdrivers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
@@ -11,9 +12,10 @@ import (
|
||||
"github.com/yunionio/pkg/util/seclib"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
|
||||
"github.com/yunionio/oneclone/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/oneclone/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/oneclone/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SAliyunGuestDriver struct {
|
||||
@@ -66,7 +68,9 @@ type SAliyunVMCreateConfig struct {
|
||||
IpAddr string
|
||||
Description string
|
||||
StorageType string
|
||||
SysDiskSize int
|
||||
DataDisks []int
|
||||
PublicKey string
|
||||
}
|
||||
|
||||
func (self *SAliyunGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject {
|
||||
@@ -76,6 +80,10 @@ func (self *SAliyunGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *mo
|
||||
config.Memory = guest.VmemSize
|
||||
config.Description = guest.Description
|
||||
|
||||
if len(guest.KeypairId) > 0 {
|
||||
config.PublicKey = guest.GetKeypairPublicKey()
|
||||
}
|
||||
|
||||
nics := guest.GetNetworks()
|
||||
net := nics[0].GetNetwork()
|
||||
config.ExternalNetworkId = net.ExternalId
|
||||
@@ -93,6 +101,7 @@ func (self *SAliyunGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *mo
|
||||
imageId := disk.GetTemplateId()
|
||||
scimg := models.StoragecachedimageManager.GetStoragecachedimage(cache.Id, imageId)
|
||||
config.ExternalImageId = scimg.ExternalId
|
||||
config.SysDiskSize = disk.DiskSize
|
||||
} else {
|
||||
config.DataDisks[i-1] = disk.DiskSize / 1024 // MB => GB
|
||||
}
|
||||
@@ -136,11 +145,17 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu
|
||||
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
|
||||
passwd := seclib.RandomPassword(12)
|
||||
|
||||
iVM, err := ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.Cpu, desc.Memory, desc.ExternalNetworkId,
|
||||
desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks)
|
||||
iVM, err := ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId,
|
||||
desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, desc.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("VMcreated %s, wait status ready ...", iVM.GetGlobalId())
|
||||
err = cloudprovider.WaitStatus(iVM, models.VM_READY, time.Second*5, time.Second*1800)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("VMcreated %s, and status is ready", iVM.GetGlobalId())
|
||||
|
||||
iVM, err = ihost.GetIVMById(iVM.GetGlobalId())
|
||||
if err != nil {
|
||||
|
||||
@@ -6,8 +6,9 @@ import (
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
|
||||
"github.com/yunionio/oneclone/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/oneclone/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SBaremetalGuestDriver struct {
|
||||
@@ -15,16 +16,46 @@ type SBaremetalGuestDriver struct {
|
||||
}
|
||||
|
||||
func init() {
|
||||
// driver := SBaremetalGuestDriver{}
|
||||
// models.RegisterGuestDriver(&driver)
|
||||
driver := SBaremetalGuestDriver{}
|
||||
models.RegisterGuestDriver(&driver)
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) GetHypervisor() string {
|
||||
return "baremetal"
|
||||
return models.HYPERVISOR_BAREMETAL
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) PrepareDiskRaidConfig(host *models.SHost, params *jsonutils.JSONDict) {
|
||||
func (self *SBaremetalGuestDriver) GetMaxVCpuCount() int {
|
||||
return 1024
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) GetMaxVMemSizeGB() int {
|
||||
return 4096
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) PrepareDiskRaidConfig(host *models.SHost, params *jsonutils.JSONDict) error {
|
||||
/*confs := params.GetArray()
|
||||
baremetal.CalculateLayout()
|
||||
from clouds.baremetal import diskconfig
|
||||
confs = task.params.get('baremetal_disk_config', None)
|
||||
if confs is None:
|
||||
confs = [diskconfig.parse_diskconfig('')]
|
||||
layouts = diskconfig.calculate_layout(confs, baremetal.storage_info)
|
||||
baremetal.update_disk_config(layouts)*/
|
||||
|
||||
// TODO
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *models.SGuest, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig) (*models.SNetwork, string, int8, models.IPAddlocationDirection) {
|
||||
net, _ := host.GetNetworkWithIdAndCredential(netConfig.Network, userCred, netConfig.Reserved)
|
||||
return net, netConfig.Mac, -1, models.IPAllocationStepdown
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig, pendingUsage quotas.IQuota) error {
|
||||
// TODO
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) ChooseHostStorage(host *models.SHost, backend string) *models.SStorage {
|
||||
@@ -32,22 +63,94 @@ func (self *SBaremetalGuestDriver) ChooseHostStorage(host *models.SHost, backend
|
||||
return bs.GetStorage()
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestGuestCreateAllDisks(guest *models.SGuest, task taskman.ITask) {
|
||||
func (self *SBaremetalGuestDriver) RequestGuestCreateAllDisks(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
task.ScheduleRun(nil) // skip
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestGuestCreateInsertIso(imageId string, guest *models.SGuest, task taskman.ITask) {
|
||||
func (self *SBaremetalGuestDriver) RequestGuestCreateInsertIso(ctx context.Context, imageId string, guest *models.SGuest, task taskman.ITask) error {
|
||||
task.ScheduleRun(nil) // skip
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) ValidateCreateData(userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
func (self *SBaremetalGuestDriver) RequestStartOnHost(guest *models.SGuest, host *models.SHost, userCred mcclient.TokenCredential, task taskman.ITask) (jsonutils.JSONObject, error) {
|
||||
data := jsonutils.NewDict()
|
||||
// TODO
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) ValidateCreateHostData(userCred mcclient.TokenCredential, bmName string, host *models.SHost, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
func (self *SBaremetalGuestDriver) RequestStopGuestForDelete(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestStopOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) StartGuestStopTask(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestUndeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestSyncstatusOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, userCred mcclient.TokenCredential) (jsonutils.JSONObject, error) {
|
||||
data := jsonutils.NewDict()
|
||||
// TODO
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) StartGuestSyncstatusTask(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) ValidateCreateHostData(ctx context.Context, userCred mcclient.TokenCredential, bmName string, host *models.SHost, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject {
|
||||
return guest.GetJsonDescAtBaremetal(ctx, host)
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) GetGuestVncInfo(userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewString(host.Id), "host_id")
|
||||
zone := host.GetZone()
|
||||
data.Add(jsonutils.NewString(zone.Name), "zone")
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) PerformStart(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, data *jsonutils.JSONDict) error {
|
||||
return guest.StartGueststartTask(ctx, userCred, data, "")
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) CheckDiskTemplateOnStorage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, storageId string, task taskman.ITask) error {
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) OnGuestDeployTaskComplete(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Context, guest *models.SGuest, task taskman.ITask, data jsonutils.JSONObject) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
|
||||
// TODO
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -80,19 +80,3 @@ func (self *SBaseGuestDriver) RequestDetachDisksFromGuestForDelete(ctx context.C
|
||||
func (self *SBaseGuestDriver) OnDeleteGuestFinalCleanup(ctx context.Context, guest *models.SGuest, userCred mcclient.TokenCredential) error {
|
||||
return guest.DeleteAllDisksInDB(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) PerformStart(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, data *jsonutils.JSONDict) error {
|
||||
return guest.StartGueststartTask(ctx, userCred, data, "")
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) CheckDiskTemplateOnStorage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, storageId string, parentTaskId string) error {
|
||||
storage := models.StorageManager.FetchStorageById(storageId)
|
||||
if storage == nil {
|
||||
return fmt.Errorf("No such storage?? %s", storageId)
|
||||
}
|
||||
cache := storage.GetStoragecache()
|
||||
if cache == nil {
|
||||
return fmt.Errorf("Cache is missing from storage")
|
||||
}
|
||||
return cache.StartImageCacheTask(ctx, userCred, imageId, false, parentTaskId)
|
||||
}
|
||||
|
||||
27
pkg/compute/guestdrivers/esxi.go
Normal file
27
pkg/compute/guestdrivers/esxi.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package guestdrivers
|
||||
|
||||
import (
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SESXiGuestDriver struct {
|
||||
SManagedVirtualizedGuestDriver
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SESXiGuestDriver{}
|
||||
models.RegisterGuestDriver(&driver)
|
||||
}
|
||||
|
||||
func (self *SESXiGuestDriver) GetHypervisor() string {
|
||||
return models.HYPERVISOR_ESXI
|
||||
}
|
||||
|
||||
func (self *SESXiGuestDriver) GetGuestVncInfo(userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
|
||||
data := jsonutils.NewDict()
|
||||
// TODO
|
||||
return data, nil
|
||||
}
|
||||
@@ -2,17 +2,31 @@ package guestdrivers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
|
||||
"github.com/yunionio/oneclone/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/oneclone/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SKVMGuestDriver struct {
|
||||
SVirtualizedGuestDriver
|
||||
}
|
||||
|
||||
func init() {
|
||||
driver := SKVMGuestDriver{}
|
||||
models.RegisterGuestDriver(&driver)
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) GetHypervisor() string {
|
||||
return models.HYPERVISOR_KVM
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestDetachDisksFromGuestForDelete(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
subtask, err := taskman.TaskManager.NewTask(ctx, "GuestDetachAllDisksTask", guest, task.GetUserCred(), task.GetParams(), task.GetTaskId(), "", nil)
|
||||
if err != nil {
|
||||
@@ -22,7 +36,94 @@ func (self *SKVMGuestDriver) RequestDetachDisksFromGuestForDelete(ctx context.Co
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) OnDeleteGuestFinalCleanup(ctx context.Context, guest *models.SGuest, userCred mcclient.TokenCredential) {
|
||||
func (self *SKVMGuestDriver) OnDeleteGuestFinalCleanup(ctx context.Context, guest *models.SGuest, userCred mcclient.TokenCredential) error {
|
||||
// guest.DeleteAllDisksInDB(ctx, userCred)
|
||||
// do nothing
|
||||
return nil
|
||||
}
|
||||
|
||||
func findVNCPort(results string) int {
|
||||
reg := regexp.MustCompile(`(\d+\.\d+\.\d+\.\d+):([\d]+)`)
|
||||
finds := reg.FindStringSubmatch(results)
|
||||
log.Debugf("finds=%s", finds)
|
||||
port, _ := strconv.Atoi(finds[2])
|
||||
return port
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) GetGuestVncInfo(userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
|
||||
url := fmt.Sprintf("/servers/%s/monitor", guest.Id)
|
||||
body := jsonutils.NewDict()
|
||||
var cmd string
|
||||
if guest.GetVdi() == "spice" {
|
||||
cmd = "info spice"
|
||||
} else {
|
||||
cmd = "info vnc"
|
||||
}
|
||||
body.Add(jsonutils.NewString(cmd), "cmd")
|
||||
ret, err := host.Request(userCred, "POST", url, nil, body)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Fail to request VNC info %s", err)
|
||||
log.Errorf(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
results, _ := ret.GetString("results")
|
||||
if len(results) == 0 {
|
||||
err = fmt.Errorf("Can't get vnc information from host.")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/***
|
||||
Server:
|
||||
address: 0.0.0.0:5901
|
||||
auth: none
|
||||
Client: none
|
||||
***/
|
||||
|
||||
// info_vnc = result['results'].split('\n')
|
||||
// port = int(info_vnc[1].split(':')[-1].split()[0])
|
||||
|
||||
port := findVNCPort(results)
|
||||
retval := jsonutils.NewDict()
|
||||
retval.Add(jsonutils.NewString(host.AccessIp), "host")
|
||||
retval.Add(jsonutils.NewString(guest.GetVdi()), "protocol")
|
||||
retval.Add(jsonutils.NewInt(int64(port)), "port")
|
||||
return retval, nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Context, guest *models.SGuest, task taskman.ITask, data jsonutils.JSONObject) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
|
||||
// TODO
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestGuestCreateAllDisks(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestStartOnHost(guest *models.SGuest, host *models.SHost, userCred mcclient.TokenCredential, task taskman.ITask) (jsonutils.JSONObject, error) {
|
||||
data := jsonutils.NewDict()
|
||||
// TODO
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestStopOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestSyncstatusOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, userCred mcclient.TokenCredential) (jsonutils.JSONObject, error) {
|
||||
data := jsonutils.NewDict()
|
||||
// TODO
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestUndeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
11
pkg/compute/guestdrivers/kvm_test.go
Normal file
11
pkg/compute/guestdrivers/kvm_test.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package guestdrivers
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSKVMGuestDriver_GetGuestVncInfo(t *testing.T) {
|
||||
results := `Server:
|
||||
address: 0.0.0.0:5901
|
||||
auth: none
|
||||
Client: none`
|
||||
t.Logf("port=%d", findVNCPort(results))
|
||||
}
|
||||
@@ -133,3 +133,19 @@ func (self *SVirtualizedGuestDriver) ValidateCreateHostData(ctx context.Context,
|
||||
func (self *SVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject {
|
||||
return guest.GetJsonDescAtHypervisor(ctx, host)
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) PerformStart(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, data *jsonutils.JSONDict) error {
|
||||
return guest.StartGueststartTask(ctx, userCred, data, "")
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) CheckDiskTemplateOnStorage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, storageId string, task taskman.ITask) error {
|
||||
storage := models.StorageManager.FetchStorageById(storageId)
|
||||
if storage == nil {
|
||||
return fmt.Errorf("No such storage?? %s", storageId)
|
||||
}
|
||||
cache := storage.GetStoragecache()
|
||||
if cache == nil {
|
||||
return fmt.Errorf("Cache is missing from storage")
|
||||
}
|
||||
return cache.StartImageCacheTask(ctx, userCred, imageId, false, task.GetTaskId())
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ import (
|
||||
"github.com/yunionio/pkg/util/timeutils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/oneclone/pkg/compute/options"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -110,6 +110,7 @@ func (self *SCachedimage) getStoragecacheCount() int {
|
||||
|
||||
func (self *SCachedimage) getImage() (*SImage, error) {
|
||||
image := SImage{}
|
||||
|
||||
err := self.Info.Unmarshal(&image)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -59,7 +59,11 @@ type SCloudprovider struct {
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if self.GetHostCount() > 0 {
|
||||
if self.Enabled {
|
||||
return httperrors.NewInvalidStatusError("provider is enabled")
|
||||
}
|
||||
usage := self.getUsage()
|
||||
if !usage.isEmpty() {
|
||||
return httperrors.NewNotEmptyError("Not an empty cloud provider")
|
||||
}
|
||||
return self.SEnabledStatusStandaloneResourceBase.ValidateDeleteCondition(ctx)
|
||||
@@ -69,6 +73,18 @@ func (self *SCloudprovider) GetHostCount() int {
|
||||
return HostManager.Query().Equals("manager_id", self.Id).Count()
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) getVpcCount() int {
|
||||
return VpcManager.Query().Equals("manager_id", self.Id).Count()
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) getStorageCount() int {
|
||||
return StorageManager.Query().Equals("manager_id", self.Id).Count()
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) getStoragecacheCount() int {
|
||||
return StoragecacheManager.Query().Equals("manager_id", self.Id).Count()
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return self.SEnabledStatusStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, data)
|
||||
}
|
||||
@@ -99,7 +115,10 @@ func (self *SCloudproviderManager) ValidateCreateData(ctx context.Context, userC
|
||||
func (self *SCloudprovider) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
self.SEnabledStatusStandaloneResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data)
|
||||
self.savePassword(self.Secret)
|
||||
self.startSyncCloudProviderInfoTask(ctx, userCred, nil, "")
|
||||
|
||||
if self.Enabled {
|
||||
self.startSyncCloudProviderInfoTask(ctx, userCred, nil, "")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) savePassword(secret string) error {
|
||||
@@ -230,11 +249,14 @@ func (self *SCloudprovider) MarkStartSync(userCred mcclient.TokenCredential) {
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) GetDriver() (cloudprovider.ICloudProvider, error) {
|
||||
if !self.Enabled {
|
||||
return nil, fmt.Errorf("Cloud provider is not enabled")
|
||||
}
|
||||
secret, err := self.getPassword()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Invalid password %s", err)
|
||||
}
|
||||
return cloudprovider.GetProvider(self.Id, self.AccessUrl, self.Account, secret, self.Provider)
|
||||
return cloudprovider.GetProvider(self.Id, self.Name, self.AccessUrl, self.Account, secret, self.Provider)
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) SaveSysInfo(info jsonutils.JSONObject) {
|
||||
@@ -253,10 +275,67 @@ func (manager *SCloudproviderManager) FetchCloudproviderById(providerId string)
|
||||
return providerObj.(*SCloudprovider)
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderManager) GetDriverByManagerId(managerId string) (cloudprovider.ICloudProvider, error) {
|
||||
func (manager *SCloudproviderManager) FetchCloudproviderByIdOrName(providerId string) *SCloudprovider {
|
||||
providerObj, err := manager.FetchByIdOrName("", providerId)
|
||||
if err != nil {
|
||||
log.Errorf("%s", err)
|
||||
return nil
|
||||
}
|
||||
return providerObj.(*SCloudprovider)
|
||||
}
|
||||
|
||||
/*func (manager *SCloudproviderManager) GetDriverByManagerId(managerId string) (cloudprovider.ICloudProvider, error) {
|
||||
provider := manager.FetchCloudproviderById(managerId)
|
||||
if provider == nil {
|
||||
return nil, fmt.Errorf("no valid cloud provider")
|
||||
}
|
||||
return provider.GetDriver()
|
||||
}*/
|
||||
|
||||
type SCloudproviderUsage struct {
|
||||
HostCount int
|
||||
VpcCount int
|
||||
StorageCount int
|
||||
StorageCacheCount int
|
||||
}
|
||||
|
||||
func (usage *SCloudproviderUsage) isEmpty() bool {
|
||||
if usage.HostCount > 0 {
|
||||
return false
|
||||
}
|
||||
if usage.VpcCount > 0 {
|
||||
return false
|
||||
}
|
||||
if usage.StorageCount > 0 {
|
||||
return false
|
||||
}
|
||||
if usage.StorageCacheCount > 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) getUsage() *SCloudproviderUsage {
|
||||
usage := SCloudproviderUsage{}
|
||||
usage.HostCount = self.GetHostCount()
|
||||
usage.VpcCount = self.getVpcCount()
|
||||
usage.StorageCount = self.getStorageCount()
|
||||
usage.StorageCacheCount = self.getStoragecacheCount()
|
||||
|
||||
return &usage
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
|
||||
extra.Update(jsonutils.Marshal(self.getUsage()))
|
||||
return extra
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := self.SEnabledStatusStandaloneResourceBase.GetCustomizeColumns(ctx, userCred, query)
|
||||
return self.getMoreDetails(extra)
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
extra := self.SEnabledStatusStandaloneResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
return self.getMoreDetails(extra)
|
||||
}
|
||||
|
||||
@@ -181,6 +181,10 @@ func (self *SCloudregion) syncWithCloudRegion(cloudRegion cloudprovider.ICloudRe
|
||||
self.Status = cloudRegion.GetStatus()
|
||||
self.Latitude = cloudRegion.GetLatitude()
|
||||
self.Longitude = cloudRegion.GetLongitude()
|
||||
self.Provider = cloudRegion.GetProvider()
|
||||
|
||||
self.IsEmulated = cloudRegion.IsEmulated()
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -198,6 +202,11 @@ func (manager *SCloudregionManager) newFromCloudRegion(cloudRegion cloudprovider
|
||||
region.Latitude = cloudRegion.GetLatitude()
|
||||
region.Longitude = cloudRegion.GetLongitude()
|
||||
region.Status = cloudRegion.GetStatus()
|
||||
region.Enabled = true
|
||||
region.Provider = cloudRegion.GetProvider()
|
||||
|
||||
region.IsEmulated = cloudRegion.IsEmulated()
|
||||
|
||||
err := manager.TableSpec().Insert(®ion)
|
||||
if err != nil {
|
||||
log.Errorf("newFromCloudRegion fail %s", err)
|
||||
@@ -246,6 +255,7 @@ func (manager *SCloudregionManager) FetchRegionById(id string) *SCloudregion {
|
||||
obj, err := manager.FetchById(id)
|
||||
if err != nil {
|
||||
log.Errorf("%s", err)
|
||||
return nil
|
||||
}
|
||||
return obj.(*SCloudregion)
|
||||
}
|
||||
@@ -258,7 +268,9 @@ func (manager *SCloudregionManager) InitializeData() error {
|
||||
defRegion := SCloudregion{}
|
||||
defRegion.Id = "default"
|
||||
defRegion.Name = "Default"
|
||||
defRegion.Enabled = true
|
||||
defRegion.Description = "Default Region"
|
||||
defRegion.Status = CLOUD_REGION_STATUS_INSERVER
|
||||
err = manager.TableSpec().Insert(&defRegion)
|
||||
if err != nil {
|
||||
log.Errorf("Insert default region fails: %s", err)
|
||||
@@ -270,3 +282,51 @@ func (manager *SCloudregionManager) InitializeData() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SCloudregionManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SEnabledStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if jsonutils.QueryBoolean(query, "is_private", false) {
|
||||
q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(q.Field("external_id")),
|
||||
sqlchemy.IsEmpty(q.Field("external_id"))))
|
||||
}
|
||||
if jsonutils.QueryBoolean(query, "is_public", false) {
|
||||
q = q.Filter(sqlchemy.AND(sqlchemy.IsNotNull(q.Field("external_id")),
|
||||
sqlchemy.IsNotEmpty(q.Field("external_id"))))
|
||||
}
|
||||
managerStr, _ := query.GetString("manager")
|
||||
if len(managerStr) > 0 {
|
||||
manager := CloudproviderManager.FetchCloudproviderByIdOrName(managerStr)
|
||||
if manager == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Cloud provider/manager %s not found", managerStr)
|
||||
}
|
||||
q = q.Equals("provider", manager.Provider)
|
||||
}
|
||||
if jsonutils.QueryBoolean(query, "usable", false) {
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
sq := vpcs.Query(sqlchemy.DISTINCT("cloudregion_id", vpcs.Field("cloudregion_id"))).Equals("status", VPC_STATUS_AVAILABLE)
|
||||
q = q.Filter(sqlchemy.In(q.Field("id"), sq.SubQuery()))
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SCloudregionManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return manager.SEnabledStatusStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data)
|
||||
}
|
||||
|
||||
func (self *SCloudregion) isManaged() bool {
|
||||
if len(self.ExternalId) > 0 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SCloudregion) ValidateUpdateCondition(ctx context.Context) error {
|
||||
if len(self.ExternalId) > 0 {
|
||||
return httperrors.NewConflictError("Cannot update external resource")
|
||||
}
|
||||
return self.SEnabledStatusStandaloneResourceBase.ValidateUpdateCondition(ctx)
|
||||
}
|
||||
|
||||
@@ -123,6 +123,15 @@ func (manager *SDiskManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu
|
||||
sqlchemy.IsFalse(storages.Field("deleted")))).
|
||||
Filter(sqlchemy.Equals(storages.Field("id"), q.Field("storage_id")))
|
||||
}
|
||||
|
||||
storageStr := jsonutils.GetAnyString(queryDict, []string{"storage", "storage_id"})
|
||||
if len(storageStr) > 0 {
|
||||
storageObj, err := StorageManager.FetchByIdOrName(userCred.GetProjectId(), storageStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("storage %s not found: %s", storageStr, err)
|
||||
}
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("storage_id"), storageObj.GetId()))
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
@@ -307,6 +316,8 @@ func (self *SDisk) syncWithCloudDisk(userCred mcclient.TokenCredential, extDisk
|
||||
// self.FsFormat = extDisk.GetFsFormat()
|
||||
self.Nonpersistent = extDisk.GetIsNonPersistent()
|
||||
|
||||
self.IsEmulated = extDisk.IsEmulated()
|
||||
|
||||
self.ProjectId = userCred.GetProjectId()
|
||||
|
||||
return nil
|
||||
@@ -333,6 +344,8 @@ func (manager *SDiskManager) newFromCloudDisk(userCred mcclient.TokenCredential,
|
||||
disk.DiskType = extDisk.GetDiskType()
|
||||
disk.Nonpersistent = extDisk.GetIsNonPersistent()
|
||||
|
||||
disk.IsEmulated = extDisk.IsEmulated()
|
||||
|
||||
err := manager.TableSpec().Insert(&disk)
|
||||
if err != nil {
|
||||
log.Errorf("newFromCloudZone fail %s", err)
|
||||
|
||||
@@ -201,6 +201,8 @@ func (man *SDnsRecordManager) QueryDns(projectId, name string) *SDnsRecord {
|
||||
}
|
||||
|
||||
rec := &SDnsRecord{}
|
||||
rec.SetModelManager(DnsRecordManager)
|
||||
|
||||
err := q.First(rec)
|
||||
if err != nil {
|
||||
log.Errorf("QueryDns %q fail: %s", name, err)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
import "github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
|
||||
type SGroupJointsManager struct {
|
||||
db.SVirtualJointResourceBaseManager
|
||||
|
||||
@@ -3,9 +3,11 @@ package models
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SGuestcdromManager struct {
|
||||
|
||||
@@ -3,10 +3,12 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SGuestdiskManager struct {
|
||||
|
||||
@@ -65,7 +65,7 @@ type IGuestDriver interface {
|
||||
|
||||
PerformStart(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, data *jsonutils.JSONDict) error
|
||||
|
||||
CheckDiskTemplateOnStorage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, storageId string, parentTaskId string) error
|
||||
CheckDiskTemplateOnStorage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, storageId string, task taskman.ITask) error
|
||||
|
||||
GetGuestVncInfo(userCred mcclient.TokenCredential, guest *SGuest, host *SHost) (*jsonutils.JSONDict, error)
|
||||
}
|
||||
|
||||
@@ -8,15 +8,17 @@ import (
|
||||
"io"
|
||||
"regexp"
|
||||
"time"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"yunion.io/yunioncloud/pkg/sqlchemy"
|
||||
"yunion.io/yunioncloud/pkg/util/netutils"
|
||||
"yunion.io/yunioncloud/pkg/util/regutils"
|
||||
"github.com/yunionio/pkg/util/netutils"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -107,7 +109,10 @@ func (manager *SGuestnetworkManager) GenerateMac(netId string, suggestion string
|
||||
func (manager *SGuestnetworkManager) newGuestNetwork(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, network *SNetwork,
|
||||
index int8, address string, mac string, driver string, bwLimit int, virtual bool, reserved bool,
|
||||
allocDir IPAddlocationDirection, requiredDesignatedIp bool) (*SGuestnetwork, error) {
|
||||
|
||||
gn := SGuestnetwork{}
|
||||
gn.SetModelManager(GuestnetworkManager)
|
||||
|
||||
gn.GuestId = guest.Id
|
||||
gn.NetworkId = network.Id
|
||||
gn.Index = index
|
||||
@@ -259,6 +264,8 @@ func (self *SGuestnetwork) GetJsonDescAtHost(host *SHost) jsonutils.JSONObject {
|
||||
|
||||
func (manager *SGuestnetworkManager) GetGuestByAddress(address string) *SGuest {
|
||||
gn := SGuestnetwork{}
|
||||
gn.SetModelManager(GuestnetworkManager)
|
||||
|
||||
err := manager.Query().Equals("ip_addr", address).First(&gn)
|
||||
if err != nil {
|
||||
log.Errorf("GetGuestByAddress query fail: %s", err)
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/mcclient/auth"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/pkg/util/fileutils"
|
||||
"github.com/yunionio/pkg/util/osprofile"
|
||||
@@ -113,8 +114,9 @@ const (
|
||||
var VM_RUNNING_STATUS = []string{VM_START_START, VM_STARTING, VM_RUNNING, VM_SNAPSHOT_STREAM}
|
||||
var VM_CREATING_STATUS = []string{VM_CREATE_NETWORK, VM_CREATE_DISK, VM_START_DEPLOY, VM_DEPLOYING}
|
||||
|
||||
// var HYPERVISORS = []string{HYPERVISOR_KVM, HYPERVISOR_BAREMETAL, HYPERVISOR_ESXI, HYPERVISOR_CONTAINER, HYPERVISOR_ALIYUN}
|
||||
var HYPERVISORS = []string{HYPERVISOR_ALIYUN}
|
||||
var HYPERVISORS = []string{HYPERVISOR_KVM, HYPERVISOR_BAREMETAL, HYPERVISOR_ESXI, HYPERVISOR_CONTAINER, HYPERVISOR_ALIYUN}
|
||||
|
||||
// var HYPERVISORS = []string{HYPERVISOR_ALIYUN}
|
||||
|
||||
var HYPERVISOR_HOSTTYPE = map[string]string{
|
||||
HYPERVISOR_KVM: HOST_TYPE_HYPERVISOR,
|
||||
@@ -151,8 +153,8 @@ type SGuest struct {
|
||||
|
||||
BootOrder string `width:"8" charset:"ascii" nullable:"true" default:"cdn" list:"user" update:"user" create:"optional"` // Column(VARCHAR(8, charset='ascii'), nullable=True, default='cdn')
|
||||
|
||||
DisableDelete bool `nullable:"false" default:"true" list:"user" update:"user" create:"optional"` // Column(Boolean, nullable=False, default=True)
|
||||
ShutdownBehavior string `width:"16" charset:"ascii" default:"stop" list:"user" update:"user" create:"optional"` // Column(VARCHAR(16, charset='ascii'), default=SHUTDOWN_STOP)
|
||||
DisableDelete tristate.TriState `nullable:"false" default:"true" list:"user" update:"user" create:"optional"` // Column(Boolean, nullable=False, default=True)
|
||||
ShutdownBehavior string `width:"16" charset:"ascii" default:"stop" list:"user" update:"user" create:"optional"` // Column(VARCHAR(16, charset='ascii'), default=SHUTDOWN_STOP)
|
||||
|
||||
KeypairId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"` // Column(VARCHAR(36, charset='ascii'), nullable=True)
|
||||
|
||||
@@ -322,7 +324,7 @@ func (guest *SGuest) GetDriver() IGuestDriver {
|
||||
}
|
||||
|
||||
func (guest *SGuest) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if guest.DisableDelete {
|
||||
if guest.DisableDelete.IsTrue() {
|
||||
return fmt.Errorf("Virtual server is locked, cannot delete")
|
||||
}
|
||||
return guest.SVirtualResourceBase.ValidateDeleteCondition(ctx)
|
||||
@@ -785,17 +787,6 @@ func getGuestResourceRequirements(ctx context.Context, userCred mcclient.TokenCr
|
||||
func (guest *SGuest) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
guest.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data)
|
||||
|
||||
log.Debugf("POST Create %s", data)
|
||||
if data.Contains("disable_delete") {
|
||||
_, err := guest.GetModelManager().TableSpec().Update(guest, func() error {
|
||||
guest.DisableDelete = jsonutils.QueryBoolean(data, "disable_delete", true)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("save disable_delete failed: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
osProfileJson, _ := data.Get("__os_profile__")
|
||||
if osProfileJson != nil {
|
||||
guest.setOSProfile(ctx, userCred, osProfileJson)
|
||||
@@ -947,6 +938,8 @@ func (self *SGuest) getDiskSize() int {
|
||||
|
||||
func (self *SGuest) getCdrom() *SGuestcdrom {
|
||||
cdrom := SGuestcdrom{}
|
||||
cdrom.SetModelManager(GuestcdromManager)
|
||||
|
||||
err := GuestcdromManager.Query().Equals("id", self.Id).First(&cdrom)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
@@ -1117,6 +1110,8 @@ func (self *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.Token
|
||||
self.ProjectId = userCred.GetProjectId()
|
||||
self.Hypervisor = extVM.GetHypervisor()
|
||||
|
||||
self.IsEmulated = extVM.IsEmulated()
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -1150,6 +1145,8 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient.
|
||||
guest.Machine = extVM.GetMachine()
|
||||
guest.Hypervisor = extVM.GetHypervisor()
|
||||
|
||||
guest.IsEmulated = extVM.IsEmulated()
|
||||
|
||||
guest.HostId = host.Id
|
||||
guest.ProjectId = userCred.GetProjectId()
|
||||
|
||||
@@ -2113,7 +2110,7 @@ func (self *SGuest) getVga() string {
|
||||
return "std"
|
||||
}
|
||||
|
||||
func (self *SGuest) getVdi() string {
|
||||
func (self *SGuest) GetVdi() string {
|
||||
if utils.IsInStringArray(self.Vdi, []string{"vnc", "spice"}) {
|
||||
return self.Vdi
|
||||
}
|
||||
@@ -2153,7 +2150,7 @@ func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *j
|
||||
desc.Add(jsonutils.NewInt(int64(self.VmemSize)), "mem")
|
||||
desc.Add(jsonutils.NewInt(int64(self.VcpuCount)), "cpu")
|
||||
desc.Add(jsonutils.NewString(self.getVga()), "vga")
|
||||
desc.Add(jsonutils.NewString(self.getVdi()), "vdi")
|
||||
desc.Add(jsonutils.NewString(self.GetVdi()), "vdi")
|
||||
desc.Add(jsonutils.NewString(self.getMachine()), "machine")
|
||||
desc.Add(jsonutils.NewString(self.getBios()), "bios")
|
||||
desc.Add(jsonutils.NewString(self.BootOrder), "boot_order")
|
||||
@@ -2543,3 +2540,15 @@ func (self *SGuest) GetDetailsVnc(ctx context.Context, userCred mcclient.TokenCr
|
||||
func (model *SGuestManager) AllowPerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
func (self *SGuest) GetKeypairPublicKey() string {
|
||||
keypair := self.getKeypair()
|
||||
if keypair != nil {
|
||||
return keypair.PublicKey
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (model *SGuest) AllowPerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
@@ -6,23 +6,23 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"net/http"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/mcclient/auth"
|
||||
"github.com/yunionio/mcclient/modules"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/pkg/util/netutils"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
"github.com/yunionio/pkg/util/sysutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -82,6 +82,7 @@ func init() {
|
||||
type SHost struct {
|
||||
db.SEnabledStatusStandaloneResourceBase
|
||||
SInfrastructure
|
||||
SManagedResourceBase
|
||||
|
||||
Rack string `width:"16" charset:"ascii" nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True)
|
||||
Slots string `width:"16" charset:"ascii" nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True)
|
||||
@@ -123,8 +124,6 @@ type SHost struct {
|
||||
|
||||
IsBaremetal bool `nullable:"true" default:"false" list:"admin" update:"true" create:"admin_optional"` // Column(Boolean, nullable=True, default=False)
|
||||
|
||||
ManagerId string `width:"128" charset:"ascii" nullable:"true" list:"admin"` // Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=True)
|
||||
|
||||
IsMaintenance bool `nullable:"true" default:"false" list:"admin"` // Column(Boolean, nullable=True, default=False)
|
||||
}
|
||||
|
||||
@@ -147,36 +146,59 @@ func (manager *SHostManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu
|
||||
}
|
||||
}
|
||||
var scopeQuery *sqlchemy.SSubQuery
|
||||
schedTagStr, _ := query.GetString("schedtag")
|
||||
|
||||
|
||||
schedTagStr := jsonutils.GetAnyString(query, []string{"schedtag", "schedtag_id"})
|
||||
if len(schedTagStr) > 0 {
|
||||
schedTag, _ := SchedtagManager.FetchByIdOrName("", schedTagStr)
|
||||
if schedTag == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Schedtag %s not found", schedTag)
|
||||
return nil, httperrors.NewResourceNotFoundError("Schedtag %s not found", schedTagStr)
|
||||
}
|
||||
hostschedtags := HostschedtagManager.Query().SubQuery()
|
||||
scopeQuery = hostschedtags.Query(hostschedtags.Field("host_id")).Equals("schedtag_id", schedTag.GetId()).SubQuery()
|
||||
}
|
||||
wireStr, _ := query.GetString("wire")
|
||||
|
||||
wireStr :=jsonutils.GetAnyString(query, []string{"wire", "wire_id"})
|
||||
if len(wireStr) > 0 {
|
||||
wire, _ := WireManager.FetchByIdOrName("", wireStr)
|
||||
if wire == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Wire %s not found", wire)
|
||||
return nil, httperrors.NewResourceNotFoundError("Wire %s not found", wireStr)
|
||||
}
|
||||
hostwires := HostwireManager.Query().SubQuery()
|
||||
scopeQuery = hostwires.Query(hostwires.Field("host_id")).Equals("wire_id", wire.GetId()).SubQuery()
|
||||
}
|
||||
storageStr, _ := query.GetString("storage")
|
||||
|
||||
storageStr := jsonutils.GetAnyString(query, []string{"storage", "storage_id"})
|
||||
if len(storageStr) > 0 {
|
||||
storage, _ := StorageManager.FetchByIdOrName("", storageStr)
|
||||
if storage == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Storage %s not found", storage)
|
||||
return nil, httperrors.NewResourceNotFoundError("Storage %s not found", storageStr)
|
||||
}
|
||||
hoststorages := HoststorageManager.Query().SubQuery()
|
||||
scopeQuery = hoststorages.Query(hoststorages.Field("host_id")).Equals("storage_id", storage.GetId()).SubQuery()
|
||||
}
|
||||
|
||||
zoneStr := jsonutils.GetAnyString(query, []string{"zone", "zone_id"})
|
||||
if len(zoneStr) > 0 {
|
||||
zone, _ := ZoneManager.FetchByIdOrName("", zoneStr)
|
||||
if zone == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Zone %s not found", zoneStr)
|
||||
}
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("zone_id"), zone.GetId()))
|
||||
}
|
||||
// vcenter
|
||||
// zone
|
||||
// cachedimage
|
||||
|
||||
managerStr := jsonutils.GetAnyString(query, []string{"manager", "provider", "manager_id", "provider_id"})
|
||||
if len(managerStr) > 0 {
|
||||
provider := CloudproviderManager.FetchCloudproviderByIdOrName(managerStr)
|
||||
if provider == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("provider %s not found", managerStr)
|
||||
}
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("manager_id"), provider.GetId()))
|
||||
}
|
||||
|
||||
if scopeQuery != nil {
|
||||
q = q.In("id", scopeQuery)
|
||||
}
|
||||
@@ -282,7 +304,7 @@ func (self *SHost) Delete(ctx context.Context, userCred mcclient.TokenCredential
|
||||
}
|
||||
|
||||
func (self *SHost) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if self.HostType == HOST_TYPE_BAREMETAL {
|
||||
if self.IsBaremetal {
|
||||
return self.StartDeleteBaremetalTask(userCred)
|
||||
} else {
|
||||
return self.RealDelete(ctx, userCred)
|
||||
@@ -360,6 +382,7 @@ func (self *SHost) GetHoststorages() []SHoststorage {
|
||||
|
||||
func (self *SHost) GetHoststorageOfId(storageId string) *SHoststorage {
|
||||
hoststorage := SHoststorage{}
|
||||
hoststorage.SetModelManager(HoststorageManager)
|
||||
err := self.GetHoststoragesQuery().Equals("storage_id", storageId).First(&hoststorage)
|
||||
if err != nil {
|
||||
log.Errorf("GetHoststorageOfId fail %s", err)
|
||||
@@ -578,6 +601,8 @@ func (self *SHost) getAttachedWires() []SWire {
|
||||
|
||||
func (self *SHost) GetMasterHostwire() *SHostwire {
|
||||
hw := SHostwire{}
|
||||
hw.SetModelManager(HostwireManager)
|
||||
|
||||
q := self.GetWiresQuery().IsTrue("is_master")
|
||||
err := q.First(&hw)
|
||||
if err != nil {
|
||||
@@ -596,6 +621,8 @@ func (self *SHost) GetMasterWire() *SWire {
|
||||
q = q.Filter(sqlchemy.Equals(hostwires.Field("host_id"), self.Id))
|
||||
q = q.Filter(sqlchemy.IsTrue(hostwires.Field("is_master")))
|
||||
wire := SWire{}
|
||||
wire.SetModelManager(WireManager)
|
||||
|
||||
err := q.First(&wire)
|
||||
if err != nil {
|
||||
log.Errorf("GetMasterWire fail %s", err)
|
||||
@@ -606,6 +633,8 @@ func (self *SHost) GetMasterWire() *SWire {
|
||||
|
||||
func (self *SHost) getHostwireOfId(wireId string) *SHostwire {
|
||||
hostwire := SHostwire{}
|
||||
hostwire.SetModelManager(HostwireManager)
|
||||
|
||||
q := self.GetWiresQuery().Equals("wire_id", wireId)
|
||||
err := q.First(&hostwire)
|
||||
if err != nil {
|
||||
@@ -665,6 +694,8 @@ func (self *SHost) GetAttach2Network(network *SNetwork) *SHostnetwork {
|
||||
q := self.GetBaremetalnetworksQuery()
|
||||
q = q.Equals("network_id", network.Id)
|
||||
hn := SHostnetwork{}
|
||||
hn.SetModelManager(HostnetworkManager)
|
||||
|
||||
err := q.First(&hn)
|
||||
if err != nil {
|
||||
log.Errorf("GetAttach2Network fail %s", err)
|
||||
@@ -691,6 +722,8 @@ func (self *SHost) GetNetInterfaces() []SNetInterface {
|
||||
|
||||
func (self *SHost) GetAdminNetInterface() *SNetInterface {
|
||||
netif := SNetInterface{}
|
||||
netif.SetModelManager(NetInterfaceManager)
|
||||
|
||||
q := NetInterfaceManager.Query().Equals("baremetal_id", self.Id).Equals("nic_type", NIC_TYPE_ADMIN)
|
||||
err := q.First(&netif)
|
||||
if err != nil {
|
||||
@@ -814,6 +847,7 @@ func (self *SHost) syncWithCloudHost(extHost cloudprovider.ICloudHost) error {
|
||||
self.HostType = extHost.GetHostType()
|
||||
|
||||
self.ManagerId = extHost.GetManagerId()
|
||||
self.IsEmulated = extHost.IsEmulated()
|
||||
|
||||
return nil
|
||||
})
|
||||
@@ -850,6 +884,7 @@ func (manager *SHostManager) newFromCloudHost(extHost cloudprovider.ICloudHost,
|
||||
host.StorageType = extHost.GetStorageType()
|
||||
|
||||
host.ManagerId = extHost.GetManagerId()
|
||||
host.IsEmulated = extHost.IsEmulated()
|
||||
|
||||
err := manager.TableSpec().Insert(&host)
|
||||
if err != nil {
|
||||
@@ -876,6 +911,7 @@ func (self *SHost) SyncHostStorages(ctx context.Context, userCred mcclient.Token
|
||||
}
|
||||
|
||||
for i := 0; i < len(removed); i += 1 {
|
||||
log.Infof("host %s not connected with %s any more, to detach...", self.Id, removed[i].Id)
|
||||
hs := self.GetHoststorageOfId(removed[i].Id)
|
||||
err := hs.Detach(ctx, userCred)
|
||||
if err != nil {
|
||||
@@ -886,6 +922,7 @@ func (self *SHost) SyncHostStorages(ctx context.Context, userCred mcclient.Token
|
||||
}
|
||||
|
||||
for i := 0; i < len(commondb); i += 1 {
|
||||
log.Infof("host %s is still connected with %s, to update ...", self.Id, commondb[i].Id)
|
||||
err := self.syncWithCloudHostStorage(commonext[i])
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
@@ -895,6 +932,7 @@ func (self *SHost) SyncHostStorages(ctx context.Context, userCred mcclient.Token
|
||||
}
|
||||
|
||||
for i := 0; i < len(added); i += 1 {
|
||||
log.Infof("host %s is found connected with %s, to add ...", self.Id, added[i].GetId())
|
||||
err := self.newCloudHostStorage(ctx, userCred, added[i])
|
||||
if err != nil {
|
||||
syncResult.AddError(err)
|
||||
@@ -956,6 +994,7 @@ func (self *SHost) SyncHostWires(ctx context.Context, userCred mcclient.TokenCre
|
||||
}
|
||||
|
||||
for i := 0; i < len(removed); i += 1 {
|
||||
log.Infof("host %s not connected with %s any more, to detach...", self.Id, removed[i].Id)
|
||||
hw := self.getHostwireOfId(removed[i].Id)
|
||||
err := hw.Detach(ctx, userCred)
|
||||
if err != nil {
|
||||
@@ -966,6 +1005,7 @@ func (self *SHost) SyncHostWires(ctx context.Context, userCred mcclient.TokenCre
|
||||
}
|
||||
|
||||
for i := 0; i < len(commondb); i += 1 {
|
||||
log.Infof("host %s is still connected with %s, to update...", self.Id, commondb[i].Id)
|
||||
err := self.syncWithCloudHostWire(commonext[i])
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
@@ -975,6 +1015,7 @@ func (self *SHost) SyncHostWires(ctx context.Context, userCred mcclient.TokenCre
|
||||
}
|
||||
|
||||
for i := 0; i < len(added); i += 1 {
|
||||
log.Infof("host %s is found connected with %s, to add...", self.Id, added[i].GetId())
|
||||
err := self.newCloudHostWire(ctx, userCred, added[i])
|
||||
if err != nil {
|
||||
syncResult.AddError(err)
|
||||
@@ -1274,13 +1315,7 @@ func (manager *SHostManager) TotalCount(
|
||||
return stat1
|
||||
}
|
||||
|
||||
func (self *SHost) GetCloudProvider() (cloudprovider.ICloudProvider, error) {
|
||||
if len(self.ManagerId) == 0 {
|
||||
return nil, fmt.Errorf("Host is self managed")
|
||||
}
|
||||
return CloudproviderManager.GetDriverByManagerId(self.ManagerId)
|
||||
}
|
||||
|
||||
/*
|
||||
func (self *SHost) GetIZone() (cloudprovider.ICloudZone, error) {
|
||||
provider, err := self.GetCloudProvider()
|
||||
if err != nil {
|
||||
@@ -1304,14 +1339,23 @@ func (self *SHost) GetIZone() (cloudprovider.ICloudZone, error) {
|
||||
}
|
||||
return izone, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (self *SHost) GetIHost() (cloudprovider.ICloudHost, error) {
|
||||
izone, err := self.GetIZone()
|
||||
provider, err := self.GetDriver()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("No cloudprovide for host: %s", err)
|
||||
}
|
||||
ihost, err := provider.GetIHostById(self.ExternalId)
|
||||
|
||||
/* izone, err := self.GetIZone()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to find izone by id %s", err)
|
||||
}
|
||||
ihost, err := izone.GetIHostById(self.ExternalId)
|
||||
ihost, err := izone.GetIHostById(self.ExternalId)*/
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("fail to find ihost by id %s", err)
|
||||
return nil, fmt.Errorf("fail to find ihost by id %s", err)
|
||||
}
|
||||
return ihost, nil
|
||||
@@ -1447,3 +1491,25 @@ func (self *SHost) GetExtraDetails(ctx context.Context, userCred mcclient.TokenC
|
||||
extra := self.SEnabledStatusStandaloneResourceBase.GetExtraDetails(ctx, userCred, query)
|
||||
return self.getMoreDetails(extra)
|
||||
}
|
||||
|
||||
func (manager *SHostManager) GetHostsByManagerAndRegion(managerId string, regionId string) []SHost {
|
||||
hosts := HostManager.Query().SubQuery()
|
||||
zones := ZoneManager.Query().SubQuery()
|
||||
q := hosts.Query()
|
||||
q = q.Join(zones, sqlchemy.Equals(hosts.Field("zone_id"), zones.Field("id")))
|
||||
q = q.Filter(sqlchemy.Equals(hosts.Field("manager_id"), managerId))
|
||||
q = q.Filter(sqlchemy.Equals(zones.Field("cloudregion_id"), regionId))
|
||||
ret := make([]SHost, 0)
|
||||
err := db.FetchModelObjects(HostManager, q, &ret)
|
||||
if err != nil {
|
||||
log.Errorf("GetHostsByManagerAndRegion fail %s", err)
|
||||
return nil
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SHost) Request(userCred mcclient.TokenCredential, method string, url string, headers http.Header, body jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
s := auth.GetSession(userCred, "", "")
|
||||
_, ret, err := s.JSONRequest(self.ManagerUri, "", method, url, headers, body)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
@@ -2,12 +2,10 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SHostschedtagManager struct {
|
||||
|
||||
@@ -3,14 +3,12 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
)
|
||||
|
||||
type SHoststorageManager struct {
|
||||
|
||||
@@ -2,13 +2,11 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SHostwireManager struct {
|
||||
|
||||
@@ -2,7 +2,6 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
func InitDB() error {
|
||||
@@ -14,6 +13,7 @@ func InitDB() error {
|
||||
WireManager,
|
||||
StorageManager,
|
||||
SecurityGroupManager,
|
||||
NetworkManager,
|
||||
} {
|
||||
err := manager.InitializeData()
|
||||
if err != nil {
|
||||
|
||||
@@ -5,15 +5,14 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -80,6 +79,11 @@ func (manager *SIsolatedDeviceManager) AllowListItems(ctx context.Context, userC
|
||||
return true
|
||||
}
|
||||
|
||||
func (manager *SIsolatedDeviceManager) ExtraSearchConditions(ctx context.Context, q *sqlchemy.SQuery, like string) []sqlchemy.ICondition {
|
||||
sq := HostManager.Query("id").Contains("name", like).SubQuery()
|
||||
return []sqlchemy.ICondition{sqlchemy.In(q.Field("host_id"), sq)}
|
||||
}
|
||||
|
||||
func (manager *SIsolatedDeviceManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
@@ -96,12 +100,15 @@ func (manager *SIsolatedDeviceManager) ListItemFilter(ctx context.Context, q *sq
|
||||
q = q.Equals("dev_type", "USB")
|
||||
}
|
||||
hostStr, _ := query.GetString("host")
|
||||
var sq *sqlchemy.SSubQuery
|
||||
if len(hostStr) > 0 {
|
||||
host, _ := HostManager.FetchByIdOrName("", hostStr)
|
||||
if host == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Host %s not found", hostStr)
|
||||
}
|
||||
q = q.Equals("host_id", host.GetId())
|
||||
hosts := HostManager.Query().SubQuery()
|
||||
sq = hosts.Query(hosts.Field("id")).Filter(sqlchemy.OR(
|
||||
sqlchemy.Equals(hosts.Field("id"), hostStr),
|
||||
sqlchemy.Equals(hosts.Field("name"), hostStr))).SubQuery()
|
||||
}
|
||||
if sq != nil {
|
||||
q = q.Filter(sqlchemy.In(q.Field("host_id"), sq))
|
||||
}
|
||||
if jsonutils.QueryBoolean(query, "unused", false) {
|
||||
q = q.IsEmpty("guest_id")
|
||||
|
||||
@@ -2,13 +2,11 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SKeypairManager struct {
|
||||
|
||||
30
pkg/compute/models/managedresource.go
Normal file
30
pkg/compute/models/managedresource.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SManagedResourceBase struct {
|
||||
ManagerId string `width:"128" charset:"ascii" nullable:"true" list:"admin" create:"admin_optional"` // Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=True)
|
||||
}
|
||||
|
||||
func (self *SManagedResourceBase) GetCloudprovider() *SCloudprovider {
|
||||
if len(self.ManagerId) > 0 {
|
||||
return CloudproviderManager.FetchCloudproviderById(self.ManagerId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SManagedResourceBase) GetDriver() (cloudprovider.ICloudProvider, error) {
|
||||
provider := self.GetCloudprovider()
|
||||
if provider == nil {
|
||||
return nil, fmt.Errorf("Resource is self managed")
|
||||
}
|
||||
return provider.GetDriver()
|
||||
}
|
||||
|
||||
func (self *SManagedResourceBase) IsManaged() bool {
|
||||
return len(self.ManagerId) > 0
|
||||
}
|
||||
@@ -3,13 +3,11 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SNetInterface struct {
|
||||
@@ -73,6 +71,8 @@ func (netif *SNetInterface) GetBaremetal() *SHost {
|
||||
|
||||
func (netif *SNetInterface) GetBaremetalNetwork() *SHostnetwork {
|
||||
bn := SHostnetwork{}
|
||||
bn.SetModelManager(HostnetworkManager)
|
||||
|
||||
q := HostnetworkManager.Query()
|
||||
q = q.Equals("baremetal_id", netif.BaremetalId).Equals("mac_addr", netif.Mac)
|
||||
err := q.First(&bn)
|
||||
|
||||
@@ -6,21 +6,21 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/pkg/util/fileutils"
|
||||
"github.com/yunionio/pkg/util/netutils"
|
||||
"github.com/yunionio/pkg/util/regutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -35,6 +35,15 @@ const (
|
||||
MAX_NETWORK_NAME_LEN = 11
|
||||
|
||||
EXTRA_DNS_UPDATE_TARGETS = "__extra_dns_update_targets"
|
||||
|
||||
NETWORK_STATUS_INIT = "init"
|
||||
NETWORK_STATUS_PENDING = "pending"
|
||||
NETWORK_STATUS_AVAILABLE = "available"
|
||||
NETWORK_STATUS_FAILED = "failed"
|
||||
NETWORK_STATUS_START_DELETE = "start_delete"
|
||||
NETWORK_STATUS_DELETING = "deleting"
|
||||
NETWORK_STATUS_DELETED = "deleted"
|
||||
NETWORK_STATUS_DELETE_FAILED = "delete_failed"
|
||||
)
|
||||
|
||||
type IPAddlocationDirection string
|
||||
@@ -90,6 +99,10 @@ type SNetwork struct {
|
||||
AllocPolicy string `width:"16" charset:"ascii" nullable:"true" get:"user" update:"user" create:"optional"` // Column(VARCHAR(16, charset='ascii'), nullable=True)
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) GetContextManager() []db.IModelManager {
|
||||
return []db.IModelManager{WireManager}
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetWire() *SWire {
|
||||
w, _ := WireManager.FetchById(self.WireId)
|
||||
if w != nil {
|
||||
@@ -98,6 +111,14 @@ func (self *SNetwork) GetWire() *SWire {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetVpc() *SVpc {
|
||||
wire := self.GetWire()
|
||||
if wire != nil {
|
||||
return wire.getVpc()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
@@ -404,7 +425,7 @@ func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mccli
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(commondb); i += 1 {
|
||||
err = commondb[i].syncWithCloudNetwork(userCred, commonext[i])
|
||||
err = commondb[i].SyncWithCloudNetwork(userCred, commonext[i])
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
@@ -427,7 +448,7 @@ func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mccli
|
||||
return localNets, remoteNets, syncResult
|
||||
}
|
||||
|
||||
func (self *SNetwork) syncWithCloudNetwork(userCred mcclient.TokenCredential, extNet cloudprovider.ICloudNetwork) error {
|
||||
func (self *SNetwork) SyncWithCloudNetwork(userCred mcclient.TokenCredential, extNet cloudprovider.ICloudNetwork) error {
|
||||
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.Name = extNet.GetName()
|
||||
self.Status = extNet.GetStatus()
|
||||
@@ -787,3 +808,439 @@ func (self *SNetwork) GetDetailsReservedIps(ctx context.Context, userCred mcclie
|
||||
ret.Add(ripArray, "reserved_ips")
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func isValidMaskLen(maskLen int64) bool {
|
||||
if maskLen < 12 || maskLen > 30 {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
prefixStr, _ := data.GetString("guest_ip_prefix")
|
||||
var maskLen64 int64
|
||||
var err error
|
||||
var startIp, endIp netutils.IPV4Addr
|
||||
if len(prefixStr) > 0 {
|
||||
prefix, err := netutils.NewIPV4Prefix(prefixStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("ip_prefix error: %s", err)
|
||||
}
|
||||
iprange := prefix.ToIPRange()
|
||||
startIp = iprange.StartIp().StepUp()
|
||||
endIp = iprange.EndIp().StepDown()
|
||||
maskLen64 = int64(prefix.MaskLen)
|
||||
} else {
|
||||
ipStartStr, _ := data.GetString("guest_ip_start")
|
||||
ipEndStr, _ := data.GetString("guest_ip_start")
|
||||
startIp, err = netutils.NewIPV4Addr(ipStartStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Invalid start ip: %s %s", ipStartStr, err)
|
||||
}
|
||||
endIp, err = netutils.NewIPV4Addr(ipEndStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid end ip: %s %s", ipEndStr, err)
|
||||
}
|
||||
if startIp > endIp {
|
||||
tmp := startIp
|
||||
startIp = endIp
|
||||
endIp = tmp
|
||||
}
|
||||
maskLen64, _ = data.Int("guest_ip_mask")
|
||||
}
|
||||
if !isValidMaskLen(maskLen64) {
|
||||
return nil, httperrors.NewInputParameterError("Invalid masklen %d", maskLen64)
|
||||
}
|
||||
data.Add(jsonutils.NewInt(maskLen64), "guest_ip_mask")
|
||||
data.Add(jsonutils.NewString(startIp.String()), "guest_ip_start")
|
||||
data.Add(jsonutils.NewString(endIp.String()), "guest_ip_end")
|
||||
|
||||
for _, key := range []string{"guest_gateway", "guest_dns", "guest_dhcp"} {
|
||||
ipStr, _ := data.GetString(key)
|
||||
if len(ipStr) > 0 && !regutils.MatchIPAddr(ipStr) {
|
||||
return nil, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipStr)
|
||||
}
|
||||
}
|
||||
|
||||
nets := manager.getAllNetworks("")
|
||||
if nets == nil {
|
||||
return nil, httperrors.NewInternalServerError("query all networks fail")
|
||||
}
|
||||
|
||||
if isOverlapNetworks(nets, startIp, endIp) {
|
||||
return nil, httperrors.NewInputParameterError("Conflict address space with existing networks")
|
||||
}
|
||||
|
||||
wireStr := jsonutils.GetAnyString(data, []string{"wire", "wire_id"})
|
||||
if len(wireStr) > 0 {
|
||||
wireObj, err := WireManager.FetchByIdOrName(userCred.GetProjectId(), wireStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("wire %s not found", wireStr)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("query wire %s error %s", wireStr, err)
|
||||
}
|
||||
}
|
||||
data.Add(jsonutils.NewString(wireObj.GetId()), "wire_id")
|
||||
} else {
|
||||
zoneStr := jsonutils.GetAnyString(data, []string{"zone", "zone_id"})
|
||||
if len(zoneStr) > 0 {
|
||||
vpcStr := jsonutils.GetAnyString(data, []string{"vpc", "vpc_id"})
|
||||
if len(vpcStr) > 0 {
|
||||
zoneObj, err := ZoneManager.FetchByIdOrName(userCred.GetProjectId(), zoneStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("zone %s not found", zoneStr)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("query zone %s error %s", zoneStr, err)
|
||||
}
|
||||
}
|
||||
vpcObj, err := VpcManager.FetchByIdOrName(userCred.GetProjectId(), vpcStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("vpc %s not found", vpcStr)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("query vpc %s error %s", vpcStr, err)
|
||||
}
|
||||
}
|
||||
vpc := vpcObj.(*SVpc)
|
||||
zone := zoneObj.(*SZone)
|
||||
wires, err := WireManager.getWiresByVpcAndZone(vpc, zone)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("wire not found for zone %s and vpc %s", zoneStr, vpcStr)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("query wire for zone %s and vpc %s error %s", zoneStr, vpcStr, err)
|
||||
}
|
||||
}
|
||||
if len(wires) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("wire not found for zone %s and vpc %s", zoneStr, vpcStr)
|
||||
} else if len(wires) > 1 {
|
||||
return nil, httperrors.NewConflictError("more than 1 wire found for zone %s and vpc %s", zoneStr, vpcStr)
|
||||
} else {
|
||||
data.Add(jsonutils.NewString(wires[0].Id), "wire_id")
|
||||
}
|
||||
} else {
|
||||
return nil, httperrors.NewInputParameterError("No either wire or vpc provided")
|
||||
}
|
||||
} else {
|
||||
return nil, httperrors.NewInvalidStatusError("No either wire or zone provided")
|
||||
}
|
||||
}
|
||||
|
||||
wireId, _ := data.GetString("wire_id")
|
||||
if len(wireId) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("missing wire_id")
|
||||
}
|
||||
wire := WireManager.FetchWireById(wireId)
|
||||
if wire == nil {
|
||||
return nil, httperrors.NewInputParameterError("wire_id %s not valid", wireId)
|
||||
}
|
||||
vpc := wire.getVpc()
|
||||
if vpc == nil {
|
||||
return nil, httperrors.NewInputParameterError("no valid vpc ???")
|
||||
}
|
||||
|
||||
if vpc.Status != VPC_STATUS_AVAILABLE {
|
||||
return nil, httperrors.NewInvalidStatusError("VPC not ready")
|
||||
}
|
||||
|
||||
vpcRange := vpc.getIPRange()
|
||||
|
||||
netRange := netutils.NewIPV4AddrRange(startIp, endIp)
|
||||
|
||||
if !vpcRange.ContainsRange(netRange) {
|
||||
return nil, httperrors.NewInputParameterError("Network not in range of VPC cidrblock %s", vpc.CidrBlock)
|
||||
}
|
||||
|
||||
serverTypeStr, _ := data.GetString("server_type")
|
||||
if len(serverTypeStr) == 0 {
|
||||
serverTypeStr = SERVER_TYPE_GUEST
|
||||
} else if serverTypeStr != SERVER_TYPE_GUEST && serverTypeStr != SERVER_TYPE_BAREMETAL {
|
||||
return nil, httperrors.NewInputParameterError("Invalid server_type: %s", serverTypeStr)
|
||||
}
|
||||
data.Add(jsonutils.NewString(serverTypeStr), "server_type")
|
||||
|
||||
return manager.SSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data)
|
||||
}
|
||||
|
||||
func (self *SNetwork) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
var startIp, endIp netutils.IPV4Addr
|
||||
var err error
|
||||
|
||||
ipStartStr, _ := data.GetString("guest_ip_start")
|
||||
ipEndStr, _ := data.GetString("guest_ip_start")
|
||||
|
||||
if len(ipStartStr) > 0 || len(ipEndStr) > 0 {
|
||||
if self.isManaged() {
|
||||
return nil, httperrors.NewForbiddenError("Cannot update a managed network")
|
||||
}
|
||||
|
||||
if len(ipStartStr) > 0 {
|
||||
startIp, err = netutils.NewIPV4Addr(ipStartStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Invalid start ip: %s %s", ipStartStr, err)
|
||||
}
|
||||
} else {
|
||||
startIp, _ = netutils.NewIPV4Addr(self.GuestIpStart)
|
||||
}
|
||||
if len(ipEndStr) > 0 {
|
||||
endIp, err = netutils.NewIPV4Addr(ipEndStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid end ip: %s %s", ipEndStr, err)
|
||||
}
|
||||
} else {
|
||||
endIp, _ = netutils.NewIPV4Addr(self.GuestIpEnd)
|
||||
}
|
||||
|
||||
if startIp > endIp {
|
||||
tmp := startIp
|
||||
startIp = endIp
|
||||
endIp = tmp
|
||||
}
|
||||
|
||||
nets := NetworkManager.getAllNetworks(self.Id)
|
||||
if nets == nil {
|
||||
return nil, httperrors.NewInternalServerError("query all networks fail")
|
||||
}
|
||||
|
||||
if isOverlapNetworks(nets, startIp, endIp) {
|
||||
return nil, httperrors.NewInputParameterError("Conflict address space with existing networks")
|
||||
}
|
||||
|
||||
vpc := self.GetVpc()
|
||||
|
||||
vpcRange := vpc.getIPRange()
|
||||
|
||||
netRange := netutils.NewIPV4AddrRange(startIp, endIp)
|
||||
|
||||
if !vpcRange.ContainsRange(netRange) {
|
||||
return nil, httperrors.NewInputParameterError("Network not in range of VPC cidrblock %s", vpc.CidrBlock)
|
||||
}
|
||||
|
||||
usedMap := self.GetUsedAddresses()
|
||||
for usedIpStr := range usedMap {
|
||||
usedIp, _ := netutils.NewIPV4Addr(usedIpStr)
|
||||
if !netRange.Contains(usedIp) {
|
||||
return nil, httperrors.NewInputParameterError("Address been assigned out of new range")
|
||||
}
|
||||
}
|
||||
|
||||
data.Add(jsonutils.NewString(startIp.String()), "guest_ip_start")
|
||||
data.Add(jsonutils.NewString(endIp.String()), "guest_ip_end")
|
||||
|
||||
}
|
||||
|
||||
if data.Contains("guest_ip_mask") {
|
||||
if self.isManaged() {
|
||||
return nil, httperrors.NewForbiddenError("Cannot update a managed network")
|
||||
}
|
||||
|
||||
maskLen64, _ := data.Int("guest_ip_mask")
|
||||
if !isValidMaskLen(maskLen64) {
|
||||
return nil, httperrors.NewInputParameterError("Invalid masklen %d", maskLen64)
|
||||
}
|
||||
}
|
||||
|
||||
for _, key := range []string{"guest_gateway", "guest_dns", "guest_dhcp"} {
|
||||
ipStr, _ := data.GetString(key)
|
||||
if len(ipStr) > 0 {
|
||||
if self.isManaged() {
|
||||
return nil, httperrors.NewForbiddenError("Cannot update a managed network")
|
||||
} else if !regutils.MatchIPAddr(ipStr) {
|
||||
return nil, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self.SSharableVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, data)
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) getAllNetworks(excludeId string) []SNetwork {
|
||||
nets := make([]SNetwork, 0)
|
||||
q := manager.Query()
|
||||
if len(excludeId) > 0 {
|
||||
q = q.NotEquals("id", excludeId)
|
||||
}
|
||||
err := db.FetchModelObjects(manager, q, &nets)
|
||||
if err != nil {
|
||||
log.Errorf("getAllNetworks fail %s", err)
|
||||
return nil
|
||||
}
|
||||
return nets
|
||||
}
|
||||
|
||||
func isOverlapNetworks(nets []SNetwork, startIp netutils.IPV4Addr, endIp netutils.IPV4Addr) bool {
|
||||
ipRange := netutils.NewIPV4AddrRange(startIp, endIp)
|
||||
for i := 0; i < len(nets); i += 1 {
|
||||
ipRange2 := nets[i].getIPRange()
|
||||
if ipRange2.IsOverlap(ipRange) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SNetwork) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if userCred.IsSystemAdmin() && ownerProjId == userCred.GetProjectId() {
|
||||
self.IsPublic = true
|
||||
} else {
|
||||
self.IsPublic = false
|
||||
}
|
||||
return self.SSharableVirtualResourceBase.CustomizeCreate(ctx, userCred, ownerProjId, query, data)
|
||||
}
|
||||
|
||||
func (self *SNetwork) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
self.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data)
|
||||
wire := self.GetWire()
|
||||
if wire == nil {
|
||||
log.Errorf("cannot find wire???")
|
||||
} else {
|
||||
wire.clearHostSchedDescCache()
|
||||
}
|
||||
vpc := self.GetVpc()
|
||||
if vpc != nil && vpc.IsManaged() {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "NetworkCreateTask", self, userCred, nil, "", "", nil)
|
||||
if err != nil {
|
||||
log.Errorf("networkcreateTask create fail: %s", err)
|
||||
} else {
|
||||
task.ScheduleRun(nil)
|
||||
}
|
||||
} else {
|
||||
self.SetStatus(userCred, NETWORK_STATUS_AVAILABLE, "")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetPrefix() (netutils.IPV4Prefix, error) {
|
||||
addr, err := netutils.NewIPV4Addr(self.GuestIpStart)
|
||||
if err != nil {
|
||||
return netutils.IPV4Prefix{}, err
|
||||
}
|
||||
addr = addr.NetAddr(self.GuestIpMask)
|
||||
return netutils.IPV4Prefix{Address: addr, MaskLen: self.GuestIpMask}, nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
log.Infof("SNetwork delete do nothing")
|
||||
self.SetStatus(userCred, NETWORK_STATUS_START_DELETE, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if len(self.ExternalId) > 0 {
|
||||
return self.StartDeleteNetworkTask(ctx, userCred)
|
||||
} else {
|
||||
return self.RealDelete(ctx, userCred)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SNetwork) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
db.OpsLog.LogEvent(self, db.ACT_DELOCATE, self.GetShortDesc(), userCred)
|
||||
self.SetStatus(userCred, NETWORK_STATUS_DELETED, "real delete")
|
||||
return self.SSharableVirtualResourceBase.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SNetwork) StartDeleteNetworkTask(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "NetworkDeleteTask", self, userCred, nil, "", "", nil)
|
||||
if err != nil {
|
||||
log.Errorf("Start NetworkDeleteTask fail %s", err)
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetINetwork() (cloudprovider.ICloudNetwork, error) {
|
||||
wire := self.GetWire()
|
||||
if wire == nil {
|
||||
msg := "No wire for this network????"
|
||||
log.Errorf(msg)
|
||||
return nil, fmt.Errorf(msg)
|
||||
}
|
||||
iwire, err := wire.GetIWire()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return iwire.GetINetworkById(self.GetExternalId())
|
||||
}
|
||||
|
||||
func (self *SNetwork) isManaged() bool {
|
||||
if len(self.ExternalId) > 0 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SSharableVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
zoneStr, _ := query.GetString("zone")
|
||||
if len(zoneStr) > 0 {
|
||||
zoneObj, err := ZoneManager.FetchByIdOrName(userCred.GetProjectId(), zoneStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("Zone %s not found", zoneStr)
|
||||
}
|
||||
sq := WireManager.Query("id").Equals("zone_id", zoneObj.GetId())
|
||||
q = q.Filter(sqlchemy.In(q.Field("wire_id"), sq.SubQuery()))
|
||||
}
|
||||
vpcStr, _ := query.GetString("vpc")
|
||||
if len(vpcStr) > 0 {
|
||||
vpcObj, err := VpcManager.FetchByIdOrName(userCred.GetProjectId(), vpcStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("VPC %s not found", vpcStr)
|
||||
}
|
||||
sq := WireManager.Query("id").Equals("vpc_id", vpcObj.GetId())
|
||||
q = q.Filter(sqlchemy.In(q.Field("wire_id"), sq.SubQuery()))
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) InitializeData() error {
|
||||
// set network status
|
||||
networks := make([]SNetwork, 0)
|
||||
q := manager.Query()
|
||||
err := db.FetchModelObjects(manager, q, &networks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range networks {
|
||||
if len(n.ExternalId) == 0 && len(n.WireId) > 0 && n.Status == NETWORK_STATUS_INIT {
|
||||
manager.TableSpec().Update(&n, func() error {
|
||||
n.Status = NETWORK_STATUS_AVAILABLE
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) ValidateUpdateCondition(ctx context.Context) error {
|
||||
if len(self.ExternalId) > 0 {
|
||||
return httperrors.NewConflictError("Cannot update external resource")
|
||||
}
|
||||
return self.SSharableVirtualResourceBase.ValidateUpdateCondition(ctx)
|
||||
}
|
||||
|
||||
func (self *SNetwork) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
func (self *SNetwork) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vpc := self.GetVpc()
|
||||
if vpc != nil && len(vpc.ExternalId) > 0 {
|
||||
provider := vpc.GetCloudprovider()
|
||||
if provider != nil && provider.Enabled {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot purge network on enabled cloud provider")
|
||||
}
|
||||
}
|
||||
err = self.RealDelete(ctx, userCred)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@ package models
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
)
|
||||
|
||||
var QuotaManager *quotas.SQuotaManager
|
||||
|
||||
@@ -3,14 +3,12 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SReservedipManager struct {
|
||||
|
||||
@@ -4,15 +4,13 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
type SchedStrategyType string
|
||||
|
||||
@@ -6,15 +6,14 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/util/secrules"
|
||||
"github.com/yunionio/pkg/util/stringutils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SSecurityGroupRuleManager struct {
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/yunioncloud/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"yunion.io/yunioncloud/pkg/sqlchemy"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
type SSecurityGroupManager struct {
|
||||
@@ -129,6 +129,8 @@ func (self *SSecurityGroup) PerformClone(ctx context.Context, userCred mcclient.
|
||||
}
|
||||
|
||||
secgroup := &SSecurityGroup{}
|
||||
secgroup.SetModelManager(SecurityGroupManager)
|
||||
|
||||
secgroup.Name, _ = data.GetString("name")
|
||||
secgroup.Description, _ = data.GetString("description")
|
||||
secgroup.ProjectId = userCred.GetTenantId()
|
||||
@@ -139,6 +141,8 @@ func (self *SSecurityGroup) PerformClone(ctx context.Context, userCred mcclient.
|
||||
secgrouprules := self.getSecurityRules()
|
||||
for _, rule := range secgrouprules {
|
||||
secgrouprule := &SSecurityGroupRule{}
|
||||
secgrouprule.SetModelManager(SecurityGroupRuleManager)
|
||||
|
||||
secgrouprule.Priority = rule.Priority
|
||||
secgrouprule.Protocol = rule.Protocol
|
||||
secgrouprule.Ports = rule.Ports
|
||||
|
||||
@@ -4,16 +4,14 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -3,15 +3,14 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
)
|
||||
|
||||
type SStoragecacheManager struct {
|
||||
@@ -28,6 +27,7 @@ func init() {
|
||||
type SStoragecache struct {
|
||||
db.SStandaloneResourceBase
|
||||
SInfrastructure
|
||||
SManagedResourceBase
|
||||
|
||||
Path string `width:"256" charset:"utf8" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // = Column(VARCHAR(256, charset='utf8'), nullable=True)
|
||||
}
|
||||
@@ -77,6 +77,9 @@ func (manager *SStoragecacheManager) newFromCloudStoragecache(cloudCache cloudpr
|
||||
local.Name = cloudCache.GetName()
|
||||
local.ExternalId = cloudCache.GetGlobalId()
|
||||
|
||||
local.IsEmulated = cloudCache.IsEmulated()
|
||||
local.ManagerId = cloudCache.GetManagerId()
|
||||
|
||||
err := manager.TableSpec().Insert(&local)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -88,6 +91,10 @@ func (manager *SStoragecacheManager) newFromCloudStoragecache(cloudCache cloudpr
|
||||
func (self *SStoragecache) syncWithCloudStoragecache(cloudCache cloudprovider.ICloudStoragecache) error {
|
||||
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.Name = cloudCache.GetName()
|
||||
|
||||
self.IsEmulated = cloudCache.IsEmulated()
|
||||
self.ManagerId = cloudCache.GetManagerId()
|
||||
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
@@ -157,9 +164,19 @@ func (self *SStoragecache) StartImageCacheTask(ctx context.Context, userCred mcc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) StartImageUncacheTask(ctx context.Context, userCred mcclient.TokenCredential, imageId string, parentTaskId string) error {
|
||||
func (self *SStoragecache) StartImageUncacheTask(ctx context.Context, userCred mcclient.TokenCredential, imageId string, isForce bool, parentTaskId string) error {
|
||||
if ! isForce {
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewString(imageId), "image_id")
|
||||
if isForce {
|
||||
data.Add(jsonutils.JSONTrue, "is_force")
|
||||
}
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "StorageUncacheImageTask", self, userCred, data, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -169,15 +186,96 @@ func (self *SStoragecache) StartImageUncacheTask(ctx context.Context, userCred m
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetIStorageCache() (cloudprovider.ICloudStoragecache, error) {
|
||||
storages := self.getStorages()
|
||||
if storages == nil {
|
||||
return nil, fmt.Errorf("no valid storages")
|
||||
provider, err := self.GetDriver()
|
||||
if err != nil {
|
||||
log.Errorf("fail to find cloud provider")
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(storages); i += 1 {
|
||||
istorage, err := storages[i].GetIStorage()
|
||||
if err == nil {
|
||||
return istorage.GetIStoragecache(), nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("not valid storage cache")
|
||||
return provider.GetIStoragecacheById(self.GetExternalId())
|
||||
}
|
||||
|
||||
func (manager *SStoragecacheManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
managerStr := jsonutils.GetAnyString(query, []string{"manager", "provider", "manager_id", "provider_id"})
|
||||
if len(managerStr) > 0 {
|
||||
provider := CloudproviderManager.FetchCloudproviderByIdOrName(managerStr)
|
||||
if provider == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("provider %s not found", managerStr)
|
||||
}
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("manager_id"), provider.GetId()))
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if self.getCachedImageCount() > 0 {
|
||||
return httperrors.NewNotEmptyError("storage cache not empty")
|
||||
}
|
||||
return self.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
|
||||
}
|
||||
|
||||
|
||||
func (self *SStoragecache) AllowPerformUncacheImage(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
func (self *SStoragecache) PerformUncacheImage(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
imageStr, _ := data.GetString("image")
|
||||
if len(imageStr) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("missing image id or name")
|
||||
}
|
||||
isForce := jsonutils.QueryBoolean(data, "is_force", false)
|
||||
|
||||
image, err := CachedimageManager.getImageInfo(ctx, userCred, imageStr, isForce)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewImageNotFoundError("image %s not found: %s", imageStr, err)
|
||||
}
|
||||
|
||||
scimg := StoragecachedimageManager.GetStoragecachedimage(self.Id, image.Id)
|
||||
if scimg == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("storage not cache image")
|
||||
}
|
||||
|
||||
if scimg.Status == CACHED_IMAGE_STATUS_INIT {
|
||||
err = scimg.Detach(ctx, userCred)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = scimg.markDeleting(ctx, userCred)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInvalidStatusError("Fail to mark cache status: %s", err)
|
||||
}
|
||||
|
||||
err = self.StartImageUncacheTask(ctx, userCred, image.Id, isForce, "")
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (self *SStoragecache) AllowPerformCacheImage(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
func (self *SStoragecache) PerformCacheImage(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
imageStr, _ := data.GetString("image")
|
||||
if len(imageStr) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("missing image id or name")
|
||||
}
|
||||
isForce := jsonutils.QueryBoolean(data, "is_force", false)
|
||||
|
||||
image, err := CachedimageManager.getImageInfo(ctx, userCred, imageStr, isForce)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewImageNotFoundError("image %s not found: %s", imageStr, err)
|
||||
}
|
||||
|
||||
if len(image.Checksum) == 0 {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot cache image with no checksum")
|
||||
}
|
||||
|
||||
err = self.StartImageCacheTask(ctx, userCred, image.Id, isForce, "")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,19 +2,16 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"yunion.io/yunioncloud/pkg/tristate"
|
||||
"yunion.io/yunioncloud/pkg/util/compare"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -30,6 +27,7 @@ const (
|
||||
STORAGE_ENABLED = "enabled"
|
||||
STORAGE_DISABLED = "disabled"
|
||||
STORAGE_OFFLINE = "offline"
|
||||
STORAGE_ONLINE = "offline"
|
||||
|
||||
DISK_TYPE_ROTATE = "rotate"
|
||||
DISK_TYPE_SSD = "ssd"
|
||||
@@ -61,6 +59,7 @@ func init() {
|
||||
type SStorage struct {
|
||||
db.SEnabledStatusStandaloneResourceBase
|
||||
SInfrastructure
|
||||
SManagedResourceBase
|
||||
|
||||
Capacity int `nullable:"false" list:"admin" update:"admin" create:"admin_required"` // Column(Integer, nullable=False) # capacity of disk in MB
|
||||
Reserved int `nullable:"true" default:"0" list:"admin" update:"admin"` // Column(Integer, nullable=True, default=0)
|
||||
@@ -74,8 +73,8 @@ type SStorage struct {
|
||||
StoragecacheId string `width:"36" charset:"ascii" nullable:"true" get:"admin"`
|
||||
}
|
||||
|
||||
func (manager *SStorageManager) GetContextManager() db.IModelManager {
|
||||
return CloudregionManager
|
||||
func (manager *SStorageManager) GetContextManager() []db.IModelManager {
|
||||
return []db.IModelManager{ZoneManager, StoragecacheManager}
|
||||
}
|
||||
|
||||
func (self *SStorage) ValidateDeleteCondition(ctx context.Context) error {
|
||||
@@ -106,6 +105,9 @@ func (self *SStorage) GetUsedCapacity(isReady tristate.TriState) int {
|
||||
case tristate.False:
|
||||
q = q.NotEquals("status", DISK_READY)
|
||||
}
|
||||
if q.Count() == 0 {
|
||||
return 0
|
||||
}
|
||||
row := q.Row()
|
||||
var sum int
|
||||
err := row.Scan(&sum)
|
||||
@@ -134,6 +136,7 @@ func (self *SStorage) GetMasterHost() *SHost {
|
||||
q = q.IsTrue("enabled")
|
||||
q = q.Equals("host_status", HOST_ONLINE).Asc("id")
|
||||
host := SHost{}
|
||||
host.SetModelManager(HostManager)
|
||||
err := q.First(&host)
|
||||
if err != nil {
|
||||
log.Errorf("GetMasterHost fail %s", err)
|
||||
@@ -341,6 +344,9 @@ func (self *SStorage) syncWithCloudStorage(extStorage cloudprovider.ICloudStorag
|
||||
|
||||
self.Enabled = extStorage.GetEnabled()
|
||||
|
||||
self.IsEmulated = extStorage.IsEmulated()
|
||||
self.ManagerId = extStorage.GetManagerId()
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -364,6 +370,9 @@ func (manager *SStorageManager) newFromCloudStorage(extStorage cloudprovider.ICl
|
||||
|
||||
storage.Enabled = extStorage.GetEnabled()
|
||||
|
||||
storage.IsEmulated = extStorage.IsEmulated()
|
||||
storage.ManagerId = extStorage.GetManagerId()
|
||||
|
||||
err := manager.TableSpec().Insert(&storage)
|
||||
if err != nil {
|
||||
log.Errorf("newFromCloudStorage fail %s", err)
|
||||
@@ -540,28 +549,12 @@ func (self *SStorage) GetStoragecache() *SStoragecache {
|
||||
}
|
||||
|
||||
func (self *SStorage) PerformCacheImage(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
imageStr, _ := data.GetString("image")
|
||||
if len(imageStr) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("missing image id or name")
|
||||
}
|
||||
isForce := jsonutils.QueryBoolean(data, "is_force", false)
|
||||
|
||||
image, err := CachedimageManager.getImageInfo(ctx, userCred, imageStr, isForce)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewImageNotFoundError("image %s not found: %s", imageStr, err)
|
||||
}
|
||||
|
||||
if len(image.Checksum) == 0 {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot cache image with no checksum")
|
||||
}
|
||||
|
||||
cache := self.GetStoragecache()
|
||||
if cache == nil {
|
||||
return nil, httperrors.NewInternalServerError("storage cache is missing")
|
||||
}
|
||||
|
||||
err = cache.StartImageCacheTask(ctx, userCred, image.Id, isForce, "")
|
||||
return nil, err
|
||||
return cache.PerformCacheImage(ctx, userCred, query, data)
|
||||
}
|
||||
|
||||
func (self *SStorage) AllowPerformUncacheImage(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
@@ -569,54 +562,21 @@ func (self *SStorage) AllowPerformUncacheImage(ctx context.Context, userCred mcc
|
||||
}
|
||||
|
||||
func (self *SStorage) PerformUncacheImage(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
imageStr, _ := data.GetString("image")
|
||||
if len(imageStr) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("missing image id or name")
|
||||
}
|
||||
isForce := jsonutils.QueryBoolean(data, "is_force", false)
|
||||
|
||||
image, err := CachedimageManager.getImageInfo(ctx, userCred, imageStr, isForce)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewImageNotFoundError("image %s not found: %s", imageStr, err)
|
||||
}
|
||||
|
||||
scimg := StoragecachedimageManager.GetStoragecachedimage(self.StoragecacheId, image.Id)
|
||||
if scimg == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("storage not cache image")
|
||||
}
|
||||
|
||||
if scimg.Status == CACHED_IMAGE_STATUS_INIT {
|
||||
err = scimg.Detach(ctx, userCred)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = scimg.markDeleting(ctx, userCred)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInvalidStatusError("Fail to mark cache status: %s", err)
|
||||
}
|
||||
|
||||
cache := self.GetStoragecache()
|
||||
if cache == nil {
|
||||
return nil, httperrors.NewInternalServerError("storage cache is missing")
|
||||
}
|
||||
|
||||
err = cache.StartImageUncacheTask(ctx, userCred, image.Id, "")
|
||||
|
||||
return nil, err
|
||||
return cache.PerformUncacheImage(ctx, userCred, query, data)
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIStorage() (cloudprovider.ICloudStorage, error) {
|
||||
host := self.GetMasterHost()
|
||||
if host == nil {
|
||||
return nil, fmt.Errorf("no valid host")
|
||||
}
|
||||
|
||||
izone, err := host.GetIZone()
|
||||
provider, err := self.GetDriver()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("not valid izone: %s", err)
|
||||
log.Errorf("fail to find cloud provider")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return izone.GetIStorageById(self.ExternalId)
|
||||
return provider.GetIStorageById(self.GetExternalId())
|
||||
}
|
||||
|
||||
func (manager *SStorageManager) FetchStorageById(storageId string) *SStorage {
|
||||
@@ -670,3 +630,31 @@ func (manager *SStorageManager) InitializeData() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SStorageManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
regionStr, _ := query.GetString("region")
|
||||
if len(regionStr) > 0 {
|
||||
regionObj, err := CloudregionManager.FetchByIdOrName(userCred.GetProjectId(), regionStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("Region %s not found: %s", regionStr, err)
|
||||
}
|
||||
sq := ZoneManager.Query("id").Equals("cloudregion_id", regionObj.GetId())
|
||||
q = q.Filter(sqlchemy.In(q.Field("zone_id"), sq.SubQuery()))
|
||||
}
|
||||
|
||||
managerStr := jsonutils.GetAnyString(query, []string{"manager", "provider", "manager_id", "provider_id"})
|
||||
if len(managerStr) > 0 {
|
||||
provider := CloudproviderManager.FetchCloudproviderByIdOrName(managerStr)
|
||||
if provider == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("provider %s not found", managerStr)
|
||||
}
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("manager_id"), provider.GetId()))
|
||||
}
|
||||
|
||||
return q, err
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
)
|
||||
|
||||
|
||||
@@ -3,11 +3,9 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/mcclient"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
type SVCenterManager struct {
|
||||
|
||||
@@ -4,20 +4,29 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"fmt"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/pkg/util/netutils"
|
||||
)
|
||||
|
||||
const (
|
||||
VPC_STATUS_PENDING = "pending"
|
||||
VPC_STATUS_AVAILABLE = "available"
|
||||
VPC_STATUS_PENDING = "pending"
|
||||
VPC_STATUS_AVAILABLE = "available"
|
||||
VPC_STATUS_FAILED = "failed"
|
||||
VPC_STATUS_START_DELETE = "start_delete"
|
||||
VPC_STATUS_DELETING = "deleting"
|
||||
VPC_STATUS_DELETE_FAILED = "delete_failed"
|
||||
VPC_STATUS_DELETED = "deleted"
|
||||
|
||||
MAX_VPC_PER_REGION = 3
|
||||
)
|
||||
|
||||
type SVpcManager struct {
|
||||
@@ -34,14 +43,17 @@ func init() {
|
||||
type SVpc struct {
|
||||
db.SEnabledStatusStandaloneResourceBase
|
||||
SInfrastructure
|
||||
SManagedResourceBase
|
||||
|
||||
IsDefault bool `default:"false" list:"admin" create:"admin_optional"`
|
||||
|
||||
CidrBlock string `width:"64" charset:"ascii" nullable:"true" list:"admin" create:"admin_required"`
|
||||
|
||||
IsDefault bool `default:"false" list:"admin" create:"admin_required"`
|
||||
CidrBlock string `width:"64" charset:"ascii" nullable:"true" list:"admin" create:"admin_required"`
|
||||
CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"admin_required"`
|
||||
}
|
||||
|
||||
func (manager *SVpcManager) GetContextManager() db.IModelManager {
|
||||
return CloudregionManager
|
||||
func (manager *SVpcManager) GetContextManager() []db.IModelManager {
|
||||
return []db.IModelManager{CloudregionManager}
|
||||
}
|
||||
|
||||
func (self *SVpc) GetCloudRegionId() string {
|
||||
@@ -61,25 +73,54 @@ func (self *SVpc) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCr
|
||||
}
|
||||
|
||||
func (self *SVpc) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if self.GetWireCount() > 0 {
|
||||
if self.GetNetworkCount() > 0 {
|
||||
return httperrors.NewNotEmptyError("VPC not empty")
|
||||
}
|
||||
return self.SEnabledStatusStandaloneResourceBase.ValidateDeleteCondition(ctx)
|
||||
}
|
||||
|
||||
func (self *SVpc) GetWireCount() int {
|
||||
func (self *SVpc) getWireQuery() *sqlchemy.SQuery {
|
||||
wires := WireManager.Query()
|
||||
if self.Id == "default" {
|
||||
return wires.Filter(sqlchemy.OR(sqlchemy.IsNull(wires.Field("vpc_id")),
|
||||
sqlchemy.IsEmpty(wires.Field("vpc_id")),
|
||||
sqlchemy.Equals(wires.Field("vpc_id"), self.Id))).Count()
|
||||
sqlchemy.Equals(wires.Field("vpc_id"), self.Id)))
|
||||
} else {
|
||||
return wires.Equals("vpc_id", self.Id).Count()
|
||||
return wires.Equals("vpc_id", self.Id)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SVpc) GetWireCount() int {
|
||||
q := self.getWireQuery()
|
||||
return q.Count()
|
||||
}
|
||||
|
||||
func (self *SVpc) GetWires() []SWire {
|
||||
wires := make([]SWire, 0)
|
||||
q := self.getWireQuery()
|
||||
err := db.FetchModelObjects(WireManager, q, &wires)
|
||||
if err != nil {
|
||||
log.Errorf("getWires fail %s", err)
|
||||
return nil
|
||||
}
|
||||
return wires
|
||||
}
|
||||
|
||||
func (self *SVpc) getNetworkQuery() *sqlchemy.SQuery {
|
||||
q := NetworkManager.Query()
|
||||
wireQ := self.getWireQuery().SubQuery()
|
||||
q = q.In("wire_id", wireQ.Query(wireQ.Field("id")).SubQuery())
|
||||
return q
|
||||
}
|
||||
|
||||
func (self *SVpc) GetNetworkCount() int {
|
||||
q := self.getNetworkQuery()
|
||||
return q.Count()
|
||||
}
|
||||
|
||||
func (self *SVpc) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
|
||||
extra.Add(jsonutils.NewInt(int64(self.GetWireCount())), "wire_count")
|
||||
extra.Add(jsonutils.NewInt(int64(self.GetNetworkCount())), "network_count")
|
||||
region := self.GetRegion()
|
||||
extra.Add(jsonutils.NewString(region.GetName()), "region")
|
||||
return extra
|
||||
@@ -169,7 +210,7 @@ func (manager *SVpcManager) SyncVPCs(ctx context.Context, userCred mcclient.Toke
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(commondb); i += 1 {
|
||||
err = commondb[i].syncWithCloudVpc(commonext[i])
|
||||
err = commondb[i].SyncWithCloudVpc(commonext[i])
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
@@ -192,12 +233,16 @@ func (manager *SVpcManager) SyncVPCs(ctx context.Context, userCred mcclient.Toke
|
||||
return localVPCs, remoteVPCs, syncResult
|
||||
}
|
||||
|
||||
func (self *SVpc) syncWithCloudVpc(extVPC cloudprovider.ICloudVpc) error {
|
||||
func (self *SVpc) SyncWithCloudVpc(extVPC cloudprovider.ICloudVpc) error {
|
||||
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.Name = extVPC.GetName()
|
||||
self.Status = extVPC.GetStatus()
|
||||
self.CidrBlock = extVPC.GetCidrBlock()
|
||||
self.IsDefault = extVPC.GetIsDefault()
|
||||
self.ExternalId = extVPC.GetGlobalId()
|
||||
|
||||
self.IsEmulated = extVPC.IsEmulated()
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -217,6 +262,10 @@ func (manager *SVpcManager) newFromCloudVpc(extVPC cloudprovider.ICloudVpc, regi
|
||||
vpc.CidrBlock = extVPC.GetCidrBlock()
|
||||
vpc.CloudregionId = region.Id
|
||||
|
||||
vpc.ManagerId = extVPC.GetManagerId()
|
||||
|
||||
vpc.IsEmulated = extVPC.IsEmulated()
|
||||
|
||||
err := manager.TableSpec().Insert(&vpc)
|
||||
if err != nil {
|
||||
log.Errorf("newFromCloudVpc fail %s", err)
|
||||
@@ -226,14 +275,17 @@ func (manager *SVpcManager) newFromCloudVpc(extVPC cloudprovider.ICloudVpc, regi
|
||||
}
|
||||
|
||||
func (manager *SVpcManager) InitializeData() error {
|
||||
_, err := manager.FetchById("default")
|
||||
vpcObj, err := manager.FetchById("default")
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
defVpc := SVpc{}
|
||||
defVpc.SetModelManager(VpcManager)
|
||||
|
||||
defVpc.Id = "default"
|
||||
defVpc.Name = "Default"
|
||||
defVpc.CloudregionId = "default"
|
||||
defVpc.Description = "Default VPC"
|
||||
defVpc.Status = VPC_STATUS_AVAILABLE
|
||||
defVpc.IsDefault = true
|
||||
err = manager.TableSpec().Insert(&defVpc)
|
||||
if err != nil {
|
||||
@@ -243,6 +295,170 @@ func (manager *SVpcManager) InitializeData() error {
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
vpc := vpcObj.(*SVpc)
|
||||
if vpc.Status != VPC_STATUS_AVAILABLE {
|
||||
_, err = manager.TableSpec().Update(vpc, func() error {
|
||||
vpc.Status = VPC_STATUS_AVAILABLE
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SVpcManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
regionId, err := data.GetString("cloudregion_id")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("No cloudregion_id")
|
||||
}
|
||||
region := CloudregionManager.FetchRegionById(regionId)
|
||||
if region == nil {
|
||||
return nil, httperrors.NewInputParameterError("Invalid cloudregion_id")
|
||||
}
|
||||
if region.isManaged() {
|
||||
if region.GetVpcCount() >= MAX_VPC_PER_REGION {
|
||||
return nil, httperrors.NewNotAcceptableError("Too many vpcs per region")
|
||||
}
|
||||
|
||||
managerStr, _ := data.GetString("manager_id")
|
||||
if len(managerStr) == 0 {
|
||||
managerStr, _ = data.GetString("manager")
|
||||
if len(managerStr) == 0 {
|
||||
return nil, httperrors.NewInputParameterError("cloud provider/manager must be provided")
|
||||
}
|
||||
}
|
||||
managerObj := CloudproviderManager.FetchCloudproviderByIdOrName(managerStr)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Cloud provider/manager %s not found", managerStr)
|
||||
}
|
||||
data.Add(jsonutils.NewString(managerObj.GetId()), "manager_id")
|
||||
} else {
|
||||
return nil, httperrors.NewNotImplementedError("Cannot create VPC in private cloud")
|
||||
}
|
||||
|
||||
cidrBlock, _ := data.GetString("cidr_block")
|
||||
if len(cidrBlock) > 0 {
|
||||
_, err = netutils.NewIPV4Prefix(cidrBlock)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid cidr_block %s", cidrBlock)
|
||||
}
|
||||
}
|
||||
return manager.SEnabledStatusStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data)
|
||||
}
|
||||
|
||||
func (self *SVpc) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
if len(self.ManagerId) == 0 {
|
||||
return
|
||||
}
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "VpcCreateTask", self, userCred, nil, "", "", nil)
|
||||
if err != nil {
|
||||
log.Errorf("VpcCreateTask newTask error %s", err)
|
||||
} else {
|
||||
task.ScheduleRun(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIRegion() (cloudprovider.ICloudRegion, error) {
|
||||
region := self.GetRegion()
|
||||
if region == nil {
|
||||
log.Errorf("cannot find region for this vpc??")
|
||||
return nil, fmt.Errorf("Cannot find region")
|
||||
}
|
||||
provider, err := self.GetDriver()
|
||||
if err != nil {
|
||||
log.Errorf("fail to find cloud provider")
|
||||
return nil, err
|
||||
}
|
||||
return provider.GetIRegionById(region.GetExternalId())
|
||||
}
|
||||
|
||||
func (self *SVpc) GetIVpc() (cloudprovider.ICloudVpc, error) {
|
||||
provider, err := self.GetDriver()
|
||||
if err != nil {
|
||||
log.Errorf("fail to find cloud provider")
|
||||
return nil, err
|
||||
}
|
||||
return provider.GetIVpcById(self.GetExternalId())
|
||||
}
|
||||
|
||||
func (self *SVpc) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
log.Infof("SVpc delete do nothing")
|
||||
self.SetStatus(userCred, VPC_STATUS_START_DELETE, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVpc) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if len(self.ExternalId) > 0 {
|
||||
return self.StartDeleteVpcTask(ctx, userCred)
|
||||
} else {
|
||||
return self.RealDelete(ctx, userCred)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SVpc) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
db.OpsLog.LogEvent(self, db.ACT_DELOCATE, self.GetShortDesc(), userCred)
|
||||
self.SetStatus(userCred, VPC_STATUS_DELETED, "real delete")
|
||||
return self.SEnabledStatusStandaloneResourceBase.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SVpc) StartDeleteVpcTask(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "VpcDeleteTask", self, userCred, nil, "", "", nil)
|
||||
if err != nil {
|
||||
log.Errorf("Start vpcdeleteTask fail %s", err)
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVpc) getPrefix() netutils.IPV4Prefix {
|
||||
if len(self.CidrBlock) > 0 {
|
||||
prefix, _ := netutils.NewIPV4Prefix(self.CidrBlock)
|
||||
return prefix
|
||||
}
|
||||
return netutils.IPV4Prefix{}
|
||||
}
|
||||
|
||||
func (self *SVpc) getIPRange() netutils.IPV4AddrRange {
|
||||
pref := self.getPrefix()
|
||||
return pref.ToIPRange()
|
||||
}
|
||||
|
||||
func (self *SVpc) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return userCred.IsSystemAdmin()
|
||||
}
|
||||
|
||||
func (self *SVpc) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
provider := self.GetCloudprovider()
|
||||
if provider != nil {
|
||||
if provider.Enabled {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot purge vpc on enabled cloud provider")
|
||||
}
|
||||
}
|
||||
err = self.RealDelete(ctx, userCred)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (manager *SVpcManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
managerStr := jsonutils.GetAnyString(query, []string{"manager", "provider", "manager_id", "provider_id"})
|
||||
if len(managerStr) > 0 {
|
||||
provider := CloudproviderManager.FetchCloudproviderByIdOrName(managerStr)
|
||||
if provider == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("provider %s not found", managerStr)
|
||||
}
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("manager_id"), provider.GetId()))
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
@@ -2,16 +2,17 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"fmt"
|
||||
"database/sql"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
)
|
||||
|
||||
type SWireManager struct {
|
||||
@@ -37,8 +38,8 @@ type SWire struct {
|
||||
VpcId string `wdith:"36" charset:"ascii" nullable:"false" list:"admin" create:"admin_required"`
|
||||
}
|
||||
|
||||
func (manager *SWireManager) GetContextManager() db.IModelManager {
|
||||
return ZoneManager
|
||||
func (manager *SWireManager) GetContextManager() []db.IModelManager {
|
||||
return []db.IModelManager{ZoneManager, VpcManager}
|
||||
}
|
||||
|
||||
func (manager *SWireManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
@@ -46,6 +47,24 @@ func (manager *SWireManager) ValidateCreateData(ctx context.Context, userCred mc
|
||||
if err != nil || bandwidth == 0 {
|
||||
return nil, httperrors.NewInputParameterError("invalid bandwidth")
|
||||
}
|
||||
|
||||
vpcStr := jsonutils.GetAnyString(data, []string{"vpc", "vpc_id"})
|
||||
if len(vpcStr) == 0 {
|
||||
return nil, httperrors.NewInternalServerError("missing vpc")
|
||||
}
|
||||
|
||||
if len(vpcStr) > 0 {
|
||||
vpcObj, err := VpcManager.FetchByIdOrName(userCred.GetProjectId(), vpcStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("Vpc %s not found", vpcStr)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("Fetch Vpc %s error %s", vpcStr, err)
|
||||
}
|
||||
}
|
||||
data.Add(jsonutils.NewString(vpcObj.GetId()), "vpc_id")
|
||||
}
|
||||
|
||||
return manager.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data)
|
||||
}
|
||||
|
||||
@@ -82,12 +101,18 @@ func (wire *SWire) GetVpcId() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SWireManager) getWiresByVpc(vpc *SVpc) ([]SWire, error) {
|
||||
func (manager *SWireManager) getWiresByVpcAndZone(vpc *SVpc, zone *SZone) ([]SWire, error) {
|
||||
wires := make([]SWire, 0)
|
||||
q := manager.Query().Equals("vpc_id", vpc.Id)
|
||||
q := manager.Query()
|
||||
if vpc != nil {
|
||||
q = q.Equals("vpc_id", vpc.Id)
|
||||
}
|
||||
if zone != nil {
|
||||
q = q.Equals("zone_id", zone.Id)
|
||||
}
|
||||
err := db.FetchModelObjects(manager, q, &wires)
|
||||
if err != nil {
|
||||
log.Errorf("getWiresByVpc error %s", err)
|
||||
log.Errorf("getWiresByVpcAndZone error %s", err)
|
||||
return nil, err
|
||||
}
|
||||
return wires, nil
|
||||
@@ -98,7 +123,7 @@ func (manager *SWireManager) SyncWires(ctx context.Context, userCred mcclient.To
|
||||
remoteWires := make([]cloudprovider.ICloudWire, 0)
|
||||
syncResult := compare.SyncResult{}
|
||||
|
||||
dbWires, err := manager.getWiresByVpc(vpc)
|
||||
dbWires, err := manager.getWiresByVpcAndZone(vpc, nil)
|
||||
if err != nil {
|
||||
syncResult.Error(err)
|
||||
return nil, nil, syncResult
|
||||
@@ -156,6 +181,9 @@ func (self *SWire) syncWithCloudWire(extWire cloudprovider.ICloudWire) error {
|
||||
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.Name = extWire.GetName()
|
||||
self.Bandwidth = extWire.GetBandwidth() // 10G
|
||||
|
||||
self.IsEmulated = extWire.IsEmulated()
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -178,6 +206,9 @@ func (manager *SWireManager) newFromCloudWire(extWire cloudprovider.ICloudWire,
|
||||
return nil, err
|
||||
}
|
||||
wire.ZoneId = zoneObj.(*SZone).Id
|
||||
|
||||
wire.IsEmulated = extWire.IsEmulated()
|
||||
|
||||
err = manager.TableSpec().Insert(&wire)
|
||||
if err != nil {
|
||||
log.Errorf("newFromCloudWire fail %s", err)
|
||||
@@ -384,3 +415,106 @@ func (manager *SWireManager) InitializeData() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wire *SWire) getEnabledHosts() []SHost {
|
||||
hosts := make([]SHost, 0)
|
||||
|
||||
hostQuery := HostManager.Query().SubQuery()
|
||||
hostwireQuery := HostwireManager.Query().SubQuery()
|
||||
|
||||
q := hostQuery.Query()
|
||||
q = q.Join(hostwireQuery, sqlchemy.AND(sqlchemy.Equals(hostQuery.Field("id"), hostwireQuery.Field("host_id")),
|
||||
sqlchemy.IsFalse(hostwireQuery.Field("deleted"))))
|
||||
q = q.Filter(sqlchemy.Equals(hostwireQuery.Field("wire_id"), wire.Id))
|
||||
q = q.Filter(sqlchemy.IsTrue(hostQuery.Field("enabled")))
|
||||
q = q.Filter(sqlchemy.Equals(hostQuery.Field("host_status"), HOST_ONLINE))
|
||||
|
||||
err := db.FetchModelObjects(HostManager, q, &hosts)
|
||||
if err != nil {
|
||||
log.Errorf("getEnabledHosts fail %s", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (wire *SWire) clearHostSchedDescCache() error {
|
||||
hosts := wire.getEnabledHosts()
|
||||
if hosts != nil {
|
||||
for i := 0; i < len(hosts); i += 1 {
|
||||
err := hosts[i].ClearSchedDescCache()
|
||||
if err != nil {
|
||||
log.Errorf("%s", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wire *SWire) getVpc() *SVpc {
|
||||
vpcObj, err := VpcManager.FetchById(wire.VpcId)
|
||||
if err != nil {
|
||||
log.Errorf("getVpc fail %s", err)
|
||||
return nil
|
||||
}
|
||||
return vpcObj.(*SVpc)
|
||||
}
|
||||
|
||||
func (self *SWire) GetIWire() (cloudprovider.ICloudWire, error) {
|
||||
vpc := self.getVpc()
|
||||
if vpc == nil {
|
||||
log.Errorf("Cannot find VPC for wire???")
|
||||
return nil, fmt.Errorf("No VPC?????")
|
||||
}
|
||||
ivpc, err := vpc.GetIVpc()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ivpc.GetIWireById(self.GetExternalId())
|
||||
}
|
||||
|
||||
func (manager *SWireManager) FetchWireById(wireId string) *SWire {
|
||||
wireObj, err := manager.FetchById(wireId)
|
||||
if err != nil {
|
||||
log.Errorf("FetchWireById fail %s", err)
|
||||
return nil
|
||||
}
|
||||
return wireObj.(*SWire)
|
||||
}
|
||||
|
||||
func (manager *SWireManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vpcStr := jsonutils.GetAnyString(query, []string{"vpc_id", "vpc"})
|
||||
if len(vpcStr) > 0 {
|
||||
vpc, err := VpcManager.FetchByIdOrName(userCred.GetProjectId(), vpcStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("vpc %s not found", vpcStr)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("vpc %s query fail %s", vpcStr, err)
|
||||
}
|
||||
}
|
||||
q = q.Equals("vpc_id", vpc.GetId())
|
||||
}
|
||||
|
||||
regionStr := jsonutils.GetAnyString(query, []string{"region_id", "region", "cloudregion_id", "cloudregion"})
|
||||
if len(regionStr) > 0 {
|
||||
region, err := CloudregionManager.FetchByIdOrName(userCred.GetProjectId(), regionStr)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("region %s not found", regionStr)
|
||||
} else {
|
||||
return nil, httperrors.NewInternalServerError("region %s query fail %s", regionStr, err)
|
||||
}
|
||||
}
|
||||
sq := VpcManager.Query("id").Equals("cloudregion_id", region.GetId())
|
||||
q = q.In("vpc_id", sq.SubQuery())
|
||||
}
|
||||
|
||||
return q, err
|
||||
}
|
||||
|
||||
@@ -3,15 +3,16 @@ package models
|
||||
import (
|
||||
"context"
|
||||
|
||||
"fmt"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/sqlchemy"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/util/compare"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -43,11 +44,11 @@ type SZone struct {
|
||||
// status = Column(VARCHAR(36, charset='ascii'), nullable=False, default=ZONE_DISABLE)
|
||||
ManagerUri string `width:"256" charset:"ascii" list:"admin" update:"admin"` // = Column(VARCHAR(256, charset='ascii'), nullable=True)
|
||||
// admin_id = Column(VARCHAR(36, charset='ascii'), nullable=False)
|
||||
CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"admin_required"`
|
||||
CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"admin_required"`
|
||||
}
|
||||
|
||||
func (manager *SZoneManager) GetContextManager() db.IModelManager {
|
||||
return CloudregionManager
|
||||
func (manager *SZoneManager) GetContextManager() []db.IModelManager {
|
||||
return []db.IModelManager{CloudregionManager}
|
||||
}
|
||||
|
||||
func (manager *SZoneManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
@@ -55,7 +56,8 @@ func (manager *SZoneManager) AllowListItems(ctx context.Context, userCred mcclie
|
||||
}
|
||||
|
||||
func (zone *SZone) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if zone.HostCount("", "", tristate.None, "", tristate.None) > 0 || zone.WireCount() > 0 {
|
||||
usage := zone.GeneralUsage()
|
||||
if ! usage.isEmpty() {
|
||||
return httperrors.NewNotEmptyError("not empty zone")
|
||||
}
|
||||
return zone.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
|
||||
@@ -111,6 +113,24 @@ type ZoneGeneralUsage struct {
|
||||
Baremetals int
|
||||
BaremetalsEnabled int
|
||||
Wires int
|
||||
Networks int
|
||||
Storages int
|
||||
}
|
||||
|
||||
func (usage *ZoneGeneralUsage) isEmpty() bool {
|
||||
if usage.Hosts > 0 {
|
||||
return false
|
||||
}
|
||||
if usage.Wires > 0 {
|
||||
return false
|
||||
}
|
||||
if usage.Networks > 0 {
|
||||
return false
|
||||
}
|
||||
if usage.Storages > 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (zone *SZone) GeneralUsage() ZoneGeneralUsage {
|
||||
@@ -119,7 +139,9 @@ func (zone *SZone) GeneralUsage() ZoneGeneralUsage {
|
||||
usage.HostsEnabled = zone.HostCount("", "", tristate.True, "", tristate.None)
|
||||
usage.Baremetals = zone.HostCount("", "", tristate.None, "", tristate.True)
|
||||
usage.BaremetalsEnabled = zone.HostCount("", "", tristate.True, "", tristate.True)
|
||||
usage.Wires = zone.WireCount()
|
||||
usage.Wires = zone.getWireCount()
|
||||
usage.Networks = zone.getNetworkCount()
|
||||
usage.Storages = zone.getStorageCount()
|
||||
return usage
|
||||
}
|
||||
|
||||
@@ -147,11 +169,28 @@ func (zone *SZone) HostCount(status string, hostStatus string, enabled tristate.
|
||||
return q.Count()
|
||||
}
|
||||
|
||||
func (zone *SZone) WireCount() int {
|
||||
func (zone *SZone) getWireCount() int {
|
||||
q := WireManager.Query().Equals("zone_id", zone.Id)
|
||||
return q.Count()
|
||||
}
|
||||
|
||||
func (zone *SZone) getStorageCount() int {
|
||||
q := StorageManager.Query().Equals("zone_id", zone.Id)
|
||||
return q.Count()
|
||||
}
|
||||
|
||||
func (zone *SZone) getNetworkCount() int {
|
||||
networks := NetworkManager.Query().SubQuery()
|
||||
wires := WireManager.Query().SubQuery()
|
||||
|
||||
q := networks.Query()
|
||||
q = q.Join(wires, sqlchemy.Equals(networks.Field("wire_id"), wires.Field("id")))
|
||||
q = q.Filter(sqlchemy.Equals(wires.Field("zone_id"), zone.Id))
|
||||
q = q.Filter(sqlchemy.Equals(networks.Field("status"), NETWORK_STATUS_AVAILABLE))
|
||||
|
||||
return q.Count()
|
||||
}
|
||||
|
||||
/*def host_count(self, status=None, host_status=None, enabled=None, host_type=None, is_baremetal=None):
|
||||
from hosts import Hosts
|
||||
q = Hosts.query().filter(Hosts.zone_id==self.id)
|
||||
@@ -321,7 +360,7 @@ func (manager *SZoneManager) SyncZones(ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(commondb); i += 1 {
|
||||
err = commondb[i].syncWithCloudZone(commonext[i])
|
||||
err = commondb[i].syncWithCloudZone(commonext[i], region)
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
@@ -344,10 +383,15 @@ func (manager *SZoneManager) SyncZones(ctx context.Context, userCred mcclient.To
|
||||
return localZones, remoteZones, syncResult
|
||||
}
|
||||
|
||||
func (self *SZone) syncWithCloudZone(extZone cloudprovider.ICloudZone) error {
|
||||
func (self *SZone) syncWithCloudZone(extZone cloudprovider.ICloudZone, region *SCloudregion) error {
|
||||
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
|
||||
self.Name = extZone.GetName()
|
||||
self.Status = extZone.GetStatus()
|
||||
|
||||
self.IsEmulated = extZone.IsEmulated()
|
||||
|
||||
self.CloudregionId = region.Id
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -363,7 +407,11 @@ func (manager *SZoneManager) newFromCloudZone(extZone cloudprovider.ICloudZone,
|
||||
zone.Name = extZone.GetName()
|
||||
zone.Status = extZone.GetStatus()
|
||||
zone.ExternalId = extZone.GetGlobalId()
|
||||
|
||||
zone.IsEmulated = extZone.IsEmulated()
|
||||
|
||||
zone.CloudregionId = region.Id
|
||||
|
||||
err := manager.TableSpec().Insert(&zone)
|
||||
if err != nil {
|
||||
log.Errorf("newFromCloudZone fail %s", err)
|
||||
@@ -402,3 +450,160 @@ func (manager *SZoneManager) InitializeData() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SZoneManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if jsonutils.QueryBoolean(query, "is_private", false) {
|
||||
q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(q.Field("external_id")),
|
||||
sqlchemy.IsEmpty(q.Field("external_id"))))
|
||||
}
|
||||
if jsonutils.QueryBoolean(query, "is_public", false) {
|
||||
q = q.Filter(sqlchemy.AND(sqlchemy.IsNotNull(q.Field("external_id")),
|
||||
sqlchemy.IsNotEmpty(q.Field("external_id"))))
|
||||
}
|
||||
|
||||
if jsonutils.QueryBoolean(query, "usable", false) {
|
||||
networks := NetworkManager.Query().SubQuery()
|
||||
wires := WireManager.Query().SubQuery()
|
||||
|
||||
zoneQ := wires.Query(sqlchemy.DISTINCT("zone_id", wires.Field("zone_id")))
|
||||
zoneQ = zoneQ.Join(networks, sqlchemy.Equals(wires.Field("id"), networks.Field("wire_id")))
|
||||
zoneQ = zoneQ.Filter(sqlchemy.Equals(networks.Field("status"), NETWORK_STATUS_AVAILABLE))
|
||||
|
||||
q = q.Filter(sqlchemy.In(q.Field("id"), zoneQ.SubQuery()))
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (self *SZone) AllowGetDetailsCapabilities(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type SZoneCapabilities struct {
|
||||
Hypervisors []string
|
||||
StorageTypes []string
|
||||
GPUModels []string
|
||||
MinNicCount int
|
||||
MaxNicCount int
|
||||
MinDataDiskCount int
|
||||
MaxDataDiskCount int
|
||||
SchedPolicySupport bool
|
||||
Usable bool
|
||||
}
|
||||
|
||||
func (self *SZone) GetDetailsCapabilities(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
capa := SZoneCapabilities{}
|
||||
capa.Hypervisors = self.getHypervisors()
|
||||
capa.StorageTypes = self.getStorageTypes()
|
||||
capa.GPUModels = self.getGPUs()
|
||||
capa.SchedPolicySupport = self.isSchedPolicySupported()
|
||||
capa.MinNicCount = self.getMinNicCount()
|
||||
capa.MaxNicCount = self.getMaxNicCount()
|
||||
capa.MinDataDiskCount = self.getMinDataDiskCount()
|
||||
capa.MaxDataDiskCount = self.getMaxDataDiskCount()
|
||||
capa.Usable = self.isUsable()
|
||||
return jsonutils.Marshal(&capa), nil
|
||||
}
|
||||
|
||||
func (self *SZone) getHypervisors() []string {
|
||||
q := HostManager.Query("host_type").Equals("zone_id", self.Id)
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
hypervisors := make([]string, 0)
|
||||
for rows.Next() {
|
||||
var hostType string
|
||||
rows.Scan(&hostType)
|
||||
if len(hostType) > 0 {
|
||||
hypervisors = append(hypervisors, HOSTTYPE_HYPERVISOR[hostType])
|
||||
}
|
||||
}
|
||||
return hypervisors
|
||||
}
|
||||
|
||||
func (self *SZone) getStorageTypes() []string {
|
||||
q := StorageManager.Query("storage_type", "medium_type").Equals("zone_id", self.Id).Distinct()
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
storageTypes := make([]string, 0)
|
||||
for rows.Next() {
|
||||
var storageType, mediumType string
|
||||
rows.Scan(&storageType, &mediumType)
|
||||
if len(storageType) > 0 && len(mediumType) > 0 {
|
||||
storageTypes = append(storageTypes, fmt.Sprintf("%s/%s", storageType, mediumType))
|
||||
}
|
||||
}
|
||||
return storageTypes
|
||||
}
|
||||
|
||||
func (self *SZone) getGPUs() []string {
|
||||
devices := IsolatedDeviceManager.Query().SubQuery()
|
||||
hosts := HostManager.Query().SubQuery()
|
||||
|
||||
q := devices.Query(devices.Field("model"))
|
||||
q = q.Join(hosts, sqlchemy.Equals(devices.Field("host_id"), hosts.Field("id")))
|
||||
q = q.Filter(sqlchemy.Equals(hosts.Field("zone_id"), self.Id))
|
||||
q = q.Distinct()
|
||||
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
gpus := make([]string, 0)
|
||||
for rows.Next() {
|
||||
var model string
|
||||
rows.Scan(&model)
|
||||
if len(model) > 0 {
|
||||
gpus = append(gpus, model)
|
||||
}
|
||||
}
|
||||
return gpus
|
||||
}
|
||||
|
||||
func (self *SZone) isManaged() bool {
|
||||
region := self.GetRegion()
|
||||
if region != nil && len(region.ExternalId) == 0 {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SZone) isSchedPolicySupported() bool {
|
||||
return !self.isManaged()
|
||||
}
|
||||
|
||||
func (self *SZone) getMinNicCount() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (self *SZone) getMaxNicCount() int {
|
||||
if self.isManaged() {
|
||||
return 1
|
||||
} else {
|
||||
return 8
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SZone) getMinDataDiskCount() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SZone) getMaxDataDiskCount() int {
|
||||
return 6
|
||||
}
|
||||
|
||||
func (self *SZone) isUsable() bool {
|
||||
if self.getNetworkCount() > 0 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,18 @@ import (
|
||||
"os"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"yunion.io/yunioncloud/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/compute"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
_ "github.com/yunionio/onecloud/pkg/compute/tasks"
|
||||
|
||||
_ "github.com/yunionio/onecloud/pkg/compute/guestdrivers"
|
||||
_ "github.com/yunionio/onecloud/pkg/compute/tasks"
|
||||
|
||||
_ "github.com/yunionio/onecloud/pkg/util/aliyun/provider"
|
||||
)
|
||||
|
||||
@@ -29,6 +31,10 @@ func StartService() {
|
||||
log.Infof("Auth complete!!")
|
||||
})
|
||||
|
||||
if options.Options.GlobalVirtualResourceNamespace {
|
||||
db.EnableGlobalVirtualResourceNamespace()
|
||||
}
|
||||
|
||||
cloudcommon.InitDB(&options.Options.DBOptions)
|
||||
defer cloudcommon.CloseDB()
|
||||
|
||||
|
||||
@@ -3,12 +3,11 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -4,14 +4,13 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
type CloudProviderSyncInfoTask struct {
|
||||
@@ -62,8 +61,8 @@ func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStand
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func logSyncFailed(provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, reason string) {
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, reason, task.UserCred)
|
||||
func logSyncFailed(provider *models.SCloudprovider, task taskman.ITask, reason string) {
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, reason, task.GetUserCred())
|
||||
}
|
||||
|
||||
func syncCloudProviderInfo(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, driver cloudprovider.ICloudProvider, syncRange *models.SSyncRange) {
|
||||
@@ -144,7 +143,7 @@ func syncRegionVPCs(ctx context.Context, provider *models.SCloudprovider, task *
|
||||
}
|
||||
}
|
||||
|
||||
func syncVpcWires(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localVpc *models.SVpc, remoteVpc cloudprovider.ICloudVpc) {
|
||||
func syncVpcWires(ctx context.Context, provider *models.SCloudprovider, task taskman.ITask, localVpc *models.SVpc, remoteVpc cloudprovider.ICloudVpc) {
|
||||
wires, err := remoteVpc.GetIWires()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetIWires for vps %s failed %s", remoteVpc.GetId(), err)
|
||||
@@ -152,20 +151,20 @@ func syncVpcWires(ctx context.Context, provider *models.SCloudprovider, task *Cl
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
localWires, remoteWires, result := models.WireManager.SyncWires(ctx, task.UserCred, localVpc, wires)
|
||||
localWires, remoteWires, result := models.WireManager.SyncWires(ctx, task.GetUserCred(), localVpc, wires)
|
||||
msg := result.Result()
|
||||
log.Infof("SyncWires for VPC %s result: %s", localVpc.Name, msg)
|
||||
if result.IsError() {
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.GetUserCred())
|
||||
for i := 0; i < len(localWires); i += 1 {
|
||||
syncWireNetworks(ctx, provider, task, &localWires[i], remoteWires[i])
|
||||
}
|
||||
}
|
||||
|
||||
func syncWireNetworks(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localWire *models.SWire, remoteWire cloudprovider.ICloudWire) {
|
||||
func syncWireNetworks(ctx context.Context, provider *models.SCloudprovider, task taskman.ITask, localWire *models.SWire, remoteWire cloudprovider.ICloudWire) {
|
||||
nets, err := remoteWire.GetINetworks()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetINetworks for wire %s failed %s", remoteWire.GetId(), err)
|
||||
@@ -173,14 +172,14 @@ func syncWireNetworks(ctx context.Context, provider *models.SCloudprovider, task
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
_, _, result := models.NetworkManager.SyncNetworks(ctx, task.UserCred, localWire, nets)
|
||||
_, _, result := models.NetworkManager.SyncNetworks(ctx, task.GetUserCred(), localWire, nets)
|
||||
msg := result.Result()
|
||||
log.Infof("SyncNetworks for wire %s result: %s", localWire.Name, msg)
|
||||
if result.IsError() {
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.GetUserCred())
|
||||
}
|
||||
|
||||
func syncZoneStorages(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localZone *models.SZone, remoteZone cloudprovider.ICloudZone) {
|
||||
@@ -286,7 +285,7 @@ func syncHostStorages(ctx context.Context, provider *models.SCloudprovider, task
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
|
||||
}
|
||||
|
||||
func syncHostWires(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localHost *models.SHost, remoteHost cloudprovider.ICloudHost) {
|
||||
func syncHostWires(ctx context.Context, provider *models.SCloudprovider, task taskman.ITask, localHost *models.SHost, remoteHost cloudprovider.ICloudHost) {
|
||||
wires, err := remoteHost.GetIWires()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetIWires for host %s failed %s", remoteHost.GetName(), err)
|
||||
@@ -294,14 +293,14 @@ func syncHostWires(ctx context.Context, provider *models.SCloudprovider, task *C
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
result := localHost.SyncHostWires(ctx, task.UserCred, wires)
|
||||
result := localHost.SyncHostWires(ctx, task.GetUserCred(), wires)
|
||||
msg := result.Result()
|
||||
log.Infof("SyncHostWires for host %s result: %s", localHost.Name, msg)
|
||||
if result.IsError() {
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.GetUserCred())
|
||||
}
|
||||
|
||||
func syncHostVMs(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localHost *models.SHost, remoteHost cloudprovider.ICloudHost) {
|
||||
|
||||
@@ -3,10 +3,11 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
)
|
||||
|
||||
type DiskDeleteTask struct {
|
||||
@@ -18,6 +19,54 @@ func init() {
|
||||
}
|
||||
|
||||
func (self *DiskDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
// TODO
|
||||
disk := obj.(*models.SDisk)
|
||||
|
||||
if disk.GetGuestDiskCount() > 0 {
|
||||
reason := "Disk has been attached to server"
|
||||
self.SetStageFailed(ctx, reason)
|
||||
db.OpsLog.LogEvent(disk, db.ACT_DELOCATE_FAIL, reason, self.UserCred)
|
||||
return
|
||||
}
|
||||
if options.Options.EnablePendingDelete && ! disk.PendingDeleted && ! jsonutils.QueryBoolean(self.Params, "purge", false) && ! jsonutils.QueryBoolean(self.Params, "override_pending_delete", false) {
|
||||
self.startPendingDeleteDisk(ctx, disk)
|
||||
} else {
|
||||
self.startDeleteDisk(ctx, disk)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *DiskDeleteTask) startDeleteDisk(ctx context.Context, disk *models.SDisk) {
|
||||
db.OpsLog.LogEvent(disk, db.ACT_DELOCATING, disk.GetShortDesc(), self.UserCred)
|
||||
if disk.Status == models.DISK_INIT {
|
||||
self.OnGuestDiskDeleteSucc(ctx, disk, nil)
|
||||
return
|
||||
}
|
||||
storage := disk.GetStorage()
|
||||
host := storage.GetMasterHost()
|
||||
isPurge := false
|
||||
if (host == nil || ! host.Enabled) && jsonutils.QueryBoolean(self.Params, "purge", false) {
|
||||
isPurge = true
|
||||
}
|
||||
disk.SetStatus(self.UserCred, models.DISK_DEALLOC, "")
|
||||
if isPurge {
|
||||
self.OnGuestDiskDeleteSucc(ctx, disk, nil)
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
func (self *DiskDeleteTask) startPendingDeleteDisk(ctx context.Context, disk *models.SDisk) {
|
||||
disk.DoPendingDelete(ctx, self.UserCred)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *DiskDeleteTask) OnGuestDiskDeleteSucc(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
if obj == nil {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
return
|
||||
}
|
||||
disk := obj.(*models.SDisk)
|
||||
// self.clean_host_sched_cache(disk)
|
||||
db.OpsLog.LogEvent(disk, db.ACT_DELOCATE, disk.GetShortDesc(), self.UserCred)
|
||||
disk.RealDelete(ctx, self.UserCred)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -4,17 +4,16 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient/auth"
|
||||
"github.com/yunionio/mcclient/modules"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/notifyclient"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient/auth"
|
||||
"github.com/yunionio/mcclient/modules"
|
||||
)
|
||||
|
||||
type GuestBatchCreateTask struct {
|
||||
|
||||
@@ -5,13 +5,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/notifyclient"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type GuestCreateTask struct {
|
||||
|
||||
@@ -3,14 +3,13 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/notifyclient"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
type GuestDeleteTask struct {
|
||||
@@ -103,6 +102,7 @@ func (self *GuestDeleteTask) OnGuestDeleteComplete(ctx context.Context, obj db.I
|
||||
func (self *GuestDeleteTask) DeleteGuest(ctx context.Context, guest *models.SGuest) {
|
||||
// host := guest.GetHost()
|
||||
guest.RealDelete(ctx, self.UserCred)
|
||||
guest.RemoveAllMetadata(ctx, self.UserCred)
|
||||
db.OpsLog.LogEvent(guest, db.ACT_DELOCATE, nil, self.UserCred)
|
||||
if !guest.IsSystem && !guest.PendingDeleted {
|
||||
self.NotifyServerDeleted(ctx, guest)
|
||||
|
||||
@@ -4,12 +4,11 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type GuestDeployTask struct {
|
||||
|
||||
@@ -3,11 +3,10 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
)
|
||||
|
||||
type GuestDetachAllDisksTask struct {
|
||||
|
||||
@@ -3,10 +3,9 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/jsonutils"
|
||||
)
|
||||
|
||||
type GuestDetachDiskTask struct {
|
||||
|
||||
@@ -3,10 +3,9 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/jsonutils"
|
||||
)
|
||||
|
||||
type GuestInsertIsoTask struct {
|
||||
|
||||
@@ -3,11 +3,10 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
)
|
||||
|
||||
type GuestStartTask struct {
|
||||
@@ -27,7 +26,7 @@ func (self *GuestStartTask) checkTemplate(ctx context.Context, guest *models.SGu
|
||||
diskCat := guest.CategorizeDisks()
|
||||
if diskCat.Root != nil && len(diskCat.Root.GetTemplateId()) > 0 {
|
||||
self.SetStage("on_start_template_ready", nil)
|
||||
guest.GetDriver().CheckDiskTemplateOnStorage(ctx, self.UserCred, diskCat.Root.GetTemplateId(), diskCat.Root.StorageId, self.GetTaskId())
|
||||
guest.GetDriver().CheckDiskTemplateOnStorage(ctx, self.UserCred, diskCat.Root.GetTemplateId(), diskCat.Root.StorageId, self)
|
||||
} else {
|
||||
self.startStart(ctx, guest)
|
||||
}
|
||||
|
||||
@@ -4,12 +4,11 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type GuestStopTask struct {
|
||||
@@ -55,7 +54,7 @@ func (self *GuestStopTask) OnGuestStopTaskComplete(ctx context.Context, obj db.I
|
||||
db.OpsLog.LogEvent(guest, db.ACT_STOP, nil, self.UserCred)
|
||||
models.HostManager.ClearSchedDescCache(guest.HostId)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
if guest.Status == models.VM_READY && !guest.DisableDelete && guest.ShutdownBehavior == models.SHUTDOWN_TERMINATE {
|
||||
if guest.Status == models.VM_READY && guest.DisableDelete.IsFalse() && guest.ShutdownBehavior == models.SHUTDOWN_TERMINATE {
|
||||
guest.StartAutoDeleteGuestTask(ctx, self.UserCred, "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,12 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type GuestSyncstatusTask struct {
|
||||
|
||||
@@ -3,12 +3,11 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/pkg/util/httputils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/pkg/util/httputils"
|
||||
)
|
||||
|
||||
type GuestUndeployTask struct {
|
||||
|
||||
75
pkg/compute/tasks/network_create_task.go
Normal file
75
pkg/compute/tasks/network_create_task.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type NetworkCreateTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(NetworkCreateTask{})
|
||||
}
|
||||
|
||||
func (self *NetworkCreateTask) taskFailed(ctx context.Context, network *models.SNetwork, event string, err error) {
|
||||
log.Errorf("network create task fail on %s: %s", event, err)
|
||||
network.SetStatus(self.UserCred, models.NETWORK_STATUS_FAILED, err.Error())
|
||||
db.OpsLog.LogEvent(network, db.ACT_ALLOCATE_FAIL, err.Error(), self.UserCred)
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
}
|
||||
|
||||
func (self *NetworkCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
network := obj.(*models.SNetwork)
|
||||
|
||||
network.SetStatus(self.UserCred, models.NETWORK_STATUS_PENDING, "")
|
||||
|
||||
wire := network.GetWire()
|
||||
if wire == nil {
|
||||
self.taskFailed(ctx, network, "getwire", fmt.Errorf("no vpc"))
|
||||
return
|
||||
}
|
||||
|
||||
iwire, err := wire.GetIWire()
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, network, "getiwire", err)
|
||||
return
|
||||
}
|
||||
|
||||
prefix, err := network.GetPrefix()
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, network, "getprefix", err)
|
||||
return
|
||||
}
|
||||
|
||||
inet, err := iwire.CreateINetwork(network.Name, prefix.String(), network.Description)
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, network, "createinetwork", err)
|
||||
return
|
||||
}
|
||||
network.SetExternalId(inet.GetGlobalId())
|
||||
|
||||
err = cloudprovider.WaitStatus(inet, models.NETWORK_STATUS_AVAILABLE, 10*time.Second, 300*time.Second)
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, network, "waitstatu", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = network.SyncWithCloudNetwork(self.UserCred, inet)
|
||||
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, network, "SyncWithCloudNetwork", err)
|
||||
return
|
||||
}
|
||||
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
52
pkg/compute/tasks/network_delete_task.go
Normal file
52
pkg/compute/tasks/network_delete_task.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type NetworkDeleteTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(NetworkDeleteTask{})
|
||||
}
|
||||
|
||||
func (self *NetworkDeleteTask) taskFailed(ctx context.Context, network *models.SNetwork, err error) {
|
||||
log.Errorf("network create task fail: %s", err)
|
||||
network.SetStatus(self.UserCred, models.NETWORK_STATUS_DELETE_FAILED, err.Error())
|
||||
db.OpsLog.LogEvent(network, db.ACT_ALLOCATE_FAIL, err.Error(), self.UserCred)
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
}
|
||||
|
||||
func (self *NetworkDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
network := obj.(*models.SNetwork)
|
||||
|
||||
network.SetStatus(self.UserCred, models.NETWORK_STATUS_DELETING, "")
|
||||
db.OpsLog.LogEvent(network, db.ACT_DELOCATING, network.GetShortDesc(), self.UserCred)
|
||||
|
||||
inet, err := network.GetINetwork()
|
||||
if inet != nil {
|
||||
err = inet.Delete()
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, network, err)
|
||||
return
|
||||
}
|
||||
} else if err == cloudprovider.ErrNotFound {
|
||||
// already deleted, do nothing
|
||||
} else {
|
||||
self.taskFailed(ctx, network, err)
|
||||
return
|
||||
}
|
||||
|
||||
network.RealDelete(ctx, self.UserCred)
|
||||
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
@@ -4,11 +4,10 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
)
|
||||
|
||||
type StorageCacheImageTask struct {
|
||||
|
||||
@@ -3,10 +3,10 @@ package tasks
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type StorageUncacheImageTask struct {
|
||||
@@ -18,5 +18,20 @@ func init() {
|
||||
}
|
||||
|
||||
func (self *StorageUncacheImageTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
isForce := jsonutils.QueryBoolean(self.Params, "is_force", false)
|
||||
|
||||
storageCache := obj.(*models.SStoragecache)
|
||||
|
||||
scimg := models.StoragecachedimageManager.Register(ctx, self.UserCred, storageCache.Id, imageId)
|
||||
|
||||
db.OpsLog.LogEvent(storageCache, db.ACT_UNCACHED_IMAGE, imageId, self.UserCred)
|
||||
|
||||
if isForce {
|
||||
scimg.Detach(ctx, self.UserCred)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
76
pkg/compute/tasks/vpc_create_task.go
Normal file
76
pkg/compute/tasks/vpc_create_task.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"time"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type VpcCreateTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(VpcCreateTask{})
|
||||
}
|
||||
|
||||
func (self *VpcCreateTask) TaskFailed(ctx context.Context, vpc *models.SVpc, err error) {
|
||||
log.Errorf("vpc create task fail: %s", err)
|
||||
vpc.SetStatus(self.UserCred, models.VPC_STATUS_FAILED, err.Error())
|
||||
db.OpsLog.LogEvent(vpc, db.ACT_ALLOCATE_FAIL, err.Error(), self.UserCred)
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
}
|
||||
|
||||
func (self *VpcCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
vpc := obj.(*models.SVpc)
|
||||
vpc.SetStatus(self.UserCred, models.VPC_STATUS_PENDING, "")
|
||||
|
||||
iregion, err := vpc.GetIRegion()
|
||||
if err != nil {
|
||||
self.TaskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
ivpc, err := iregion.CreateIVpc(vpc.Name, vpc.Description, vpc.CidrBlock)
|
||||
if err != nil {
|
||||
self.TaskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
vpc.SetExternalId(ivpc.GetGlobalId())
|
||||
|
||||
err = cloudprovider.WaitStatus(ivpc, models.VPC_STATUS_AVAILABLE, 10*time.Second, 300*time.Second)
|
||||
if err != nil {
|
||||
self.TaskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = vpc.SyncWithCloudVpc(ivpc)
|
||||
if err != nil {
|
||||
log.Errorf("SyncWithCloudVpc fail: %s", err)
|
||||
self.TaskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
|
||||
provider := models.CloudproviderManager.FetchCloudproviderById(vpc.ManagerId)
|
||||
syncVpcWires(ctx, provider, self, vpc, ivpc)
|
||||
|
||||
hosts := models.HostManager.GetHostsByManagerAndRegion(provider.Id, vpc.CloudregionId)
|
||||
if hosts != nil {
|
||||
for i := 0; i < len(hosts); i += 1 {
|
||||
ihost, err := hosts[i].GetIHost()
|
||||
if err != nil {
|
||||
log.Errorf("getiHost fail %s", err)
|
||||
self.TaskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
syncHostWires(ctx, provider, self, &hosts[i], ihost)
|
||||
}
|
||||
}
|
||||
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
70
pkg/compute/tasks/vpc_delete_task.go
Normal file
70
pkg/compute/tasks/vpc_delete_task.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"time"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type VpcDeleteTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(VpcDeleteTask{})
|
||||
}
|
||||
|
||||
func (self *VpcDeleteTask) taskFailed(ctx context.Context, vpc *models.SVpc, err error) {
|
||||
log.Errorf("vpc delete task fail: %s", err)
|
||||
vpc.SetStatus(self.UserCred, models.VPC_STATUS_DELETE_FAILED, err.Error())
|
||||
db.OpsLog.LogEvent(vpc, db.ACT_DELOCATE_FAIL, err.Error(), self.UserCred)
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
}
|
||||
|
||||
func (self *VpcDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
vpc := obj.(*models.SVpc)
|
||||
|
||||
vpc.SetStatus(self.UserCred, models.VPC_STATUS_DELETING, "")
|
||||
db.OpsLog.LogEvent(vpc, db.ACT_DELOCATING, vpc.GetShortDesc(), self.UserCred)
|
||||
|
||||
region, err := vpc.GetIRegion()
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
ivpc, err := region.GetIVpcById(vpc.GetExternalId())
|
||||
if ivpc != nil {
|
||||
err = ivpc.Delete()
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
err = cloudprovider.WaitDeleted(ivpc, 10*time.Second, 300*time.Second)
|
||||
if err != nil {
|
||||
self.taskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
} else if err == cloudprovider.ErrNotFound {
|
||||
// already deleted, do nothing
|
||||
} else {
|
||||
self.taskFailed(ctx, vpc, err)
|
||||
return
|
||||
}
|
||||
|
||||
wires := vpc.GetWires()
|
||||
if wires != nil {
|
||||
for i := 0; i < len(wires); i += 1 {
|
||||
wires[i].Delete(ctx, self.UserCred)
|
||||
}
|
||||
}
|
||||
|
||||
vpc.RealDelete(ctx, self.UserCred)
|
||||
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
@@ -5,18 +5,17 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/yunionio/pkg/appctx"
|
||||
"github.com/yunionio/pkg/appsrv"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
json "github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/mcclient"
|
||||
"github.com/yunionio/mcclient/auth"
|
||||
"github.com/yunionio/pkg/appctx"
|
||||
"github.com/yunionio/pkg/appsrv"
|
||||
"github.com/yunionio/pkg/httperrors"
|
||||
"github.com/yunionio/pkg/tristate"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type Usage map[string]interface{}
|
||||
|
||||
@@ -3,10 +3,9 @@ package aliyun
|
||||
import (
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -17,15 +16,15 @@ const (
|
||||
)
|
||||
|
||||
type SAliyunClient struct {
|
||||
providerId string
|
||||
accessKey string
|
||||
secret string
|
||||
regions []SRegion
|
||||
iregions []cloudprovider.ICloudRegion
|
||||
providerId string
|
||||
providerName string
|
||||
accessKey string
|
||||
secret string
|
||||
iregions []cloudprovider.ICloudRegion
|
||||
}
|
||||
|
||||
func NewAliyunClient(providerId string, accessKey string, secret string) (*SAliyunClient, error) {
|
||||
client := SAliyunClient{providerId: providerId, accessKey: accessKey, secret: secret}
|
||||
func NewAliyunClient(providerId string, providerName string, accessKey string, secret string) (*SAliyunClient, error) {
|
||||
client := SAliyunClient{providerId: providerId, providerName: providerName, accessKey: accessKey, secret: secret}
|
||||
err := client.fetchRegions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -75,23 +74,23 @@ func (self *SAliyunClient) fetchRegions() error {
|
||||
return err
|
||||
}
|
||||
|
||||
self.regions = make([]SRegion, 0)
|
||||
err = body.Unmarshal(&self.regions, "Regions", "Region")
|
||||
regions := make([]SRegion, 0)
|
||||
err = body.Unmarshal(®ions, "Regions", "Region")
|
||||
if err != nil {
|
||||
log.Errorf("unmarshal json error %s", err)
|
||||
return err
|
||||
}
|
||||
self.iregions = make([]cloudprovider.ICloudRegion, len(self.regions))
|
||||
for i := 0; i < len(self.regions); i += 1 {
|
||||
self.regions[i].client = self
|
||||
self.iregions[i] = &self.regions[i]
|
||||
self.iregions = make([]cloudprovider.ICloudRegion, len(regions))
|
||||
for i := 0; i < len(regions); i += 1 {
|
||||
regions[i].client = self
|
||||
self.iregions[i] = ®ions[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAliyunClient) GetRegions() []SRegion {
|
||||
/*func (self *SAliyunClient) GetRegions() []SRegion {
|
||||
return self.regions
|
||||
}
|
||||
}*/
|
||||
|
||||
func (self *SAliyunClient) GetIRegions() []cloudprovider.ICloudRegion {
|
||||
return self.iregions
|
||||
@@ -110,10 +109,58 @@ func (self *SAliyunClient) GetRegion(regionId string) *SRegion {
|
||||
if len(regionId) == 0 {
|
||||
regionId = ALIYUN_DEFAULT_REGION
|
||||
}
|
||||
for i := 0; i < len(self.regions); i += 1 {
|
||||
if self.regions[i].RegionId == regionId {
|
||||
return &self.regions[i]
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
if self.iregions[i].GetId() == regionId {
|
||||
return self.iregions[i].(*SRegion)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAliyunClient) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
ihost, err := self.iregions[i].GetIHostById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SAliyunClient) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
ihost, err := self.iregions[i].GetIVpcById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SAliyunClient) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
ihost, err := self.iregions[i].GetIStorageById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SAliyunClient) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
|
||||
for i := 0; i < len(self.iregions); i += 1 {
|
||||
ihost, err := self.iregions[i].GetIStoragecacheById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@ package aliyun
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
type SMountInstances struct {
|
||||
@@ -53,7 +53,7 @@ type SDisk struct {
|
||||
ZoneId string
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDisks(instanceId string, zoneId string, category string, offset int, limit int) ([]SDisk, int, error) {
|
||||
func (self *SRegion) GetDisks(instanceId string, zoneId string, category string, diskIds []string, offset int, limit int) ([]SDisk, int, error) {
|
||||
if limit > 50 || limit <= 0 {
|
||||
limit = 50
|
||||
}
|
||||
@@ -71,6 +71,9 @@ func (self *SRegion) GetDisks(instanceId string, zoneId string, category string,
|
||||
if len(category) > 0 {
|
||||
params["Category"] = category
|
||||
}
|
||||
if diskIds != nil && len(diskIds) > 0 {
|
||||
params["DiskIds"] = jsonutils.Marshal(diskIds).String()
|
||||
}
|
||||
|
||||
body, err := self.ecsRequest("DescribeDisks", params)
|
||||
if err != nil {
|
||||
@@ -100,6 +103,10 @@ func (self *SDisk) GetGlobalId() string {
|
||||
return self.DiskId
|
||||
}
|
||||
|
||||
func (self *SDisk) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIStorge() cloudprovider.ICloudStorage {
|
||||
return self.storage
|
||||
}
|
||||
@@ -114,6 +121,14 @@ func (self *SDisk) GetStatus() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SDisk) Refresh() error {
|
||||
new, err := self.storage.zone.region.getDisk(self.DiskId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
func (self *SDisk) GetDiskFormat() string {
|
||||
return "vhd"
|
||||
}
|
||||
@@ -160,3 +175,41 @@ func (self *SDisk) GetCacheMode() string {
|
||||
func (self *SDisk) GetMountpoint() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SRegion) createDisk(zoneId string, category string, name string, sizeGb int, desc string) (string, error) {
|
||||
params := make(map[string]string)
|
||||
params["ZoneId"] = zoneId
|
||||
params["DiskName"] = name
|
||||
if len(desc) > 0 {
|
||||
params["Description"] = desc
|
||||
}
|
||||
params["Encrypted"] = "false"
|
||||
params["DiskCategory"] = category
|
||||
params["Size"] = fmt.Sprintf("%d", sizeGb)
|
||||
params["ClientToken"] = utils.GenRequestId(20)
|
||||
|
||||
body, err := self.ecsRequest("CreateDisk", params)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return body.GetString("DiskId")
|
||||
}
|
||||
|
||||
func (self *SRegion) getDisk(diskId string) (*SDisk, error) {
|
||||
disks, total, err := self.GetDisks("", "", "", []string{diskId}, 0, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if total != 1 {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
return &disks[0], nil
|
||||
}
|
||||
|
||||
func (self *SRegion) deleteDisk(diskId string) error {
|
||||
params := make(map[string]string)
|
||||
params["DiskId"] = diskId
|
||||
|
||||
_, err := self.ecsRequest("DeleteDisk", params)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,13 +2,17 @@ package aliyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/aokoli/goutils"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type SHost struct {
|
||||
@@ -23,6 +27,10 @@ func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
return self.zone.GetIStorages()
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
return self.zone.GetIStorageById(id)
|
||||
}
|
||||
|
||||
func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
|
||||
vms := make([]SInstance, 0)
|
||||
for {
|
||||
@@ -64,21 +72,29 @@ func (self *SHost) GetIVMById(gid string) (cloudprovider.ICloudVM, error) {
|
||||
}
|
||||
|
||||
func (self *SHost) GetId() string {
|
||||
return self.zone.GetId()
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
|
||||
}
|
||||
|
||||
func (self *SHost) GetName() string {
|
||||
return self.GetId()
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.zone.GetId())
|
||||
}
|
||||
|
||||
func (self *SHost) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.GetId())
|
||||
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
|
||||
}
|
||||
|
||||
func (self *SHost) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SHost) GetStatus() string {
|
||||
return models.HOST_STATUS_RUNNING
|
||||
}
|
||||
|
||||
func (self *SHost) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SHost) GetHostStatus() string {
|
||||
return models.HOST_ONLINE
|
||||
}
|
||||
@@ -150,8 +166,8 @@ func (self *SHost) getInstanceById(instanceId string) (*SInstance, error) {
|
||||
return inst, nil
|
||||
}
|
||||
|
||||
func (self *SHost) CreateVM(name string, imgId string, cpu int, memMB int, vswitchId string, ipAddr string, desc string, passwd string, storageType string, diskSizes []int) (cloudprovider.ICloudVM, error) {
|
||||
vmId, err := self._createVM(name, imgId, cpu, memMB, vswitchId, ipAddr, desc, passwd, storageType, diskSizes)
|
||||
func (self *SHost) CreateVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, vswitchId string, ipAddr string, desc string, passwd string, storageType string, diskSizes []int, publicKey string) (cloudprovider.ICloudVM, error) {
|
||||
vmId, err := self._createVM(name, imgId, sysDiskSize, cpu, memMB, vswitchId, ipAddr, desc, passwd, storageType, diskSizes, publicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -159,11 +175,40 @@ func (self *SHost) CreateVM(name string, imgId string, cpu int, memMB int, vswit
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = vm.waitStatus(InstanceStatusStopped, time.Second*10, time.Second*1800)
|
||||
// err = vm.waitStatus(InstanceStatusStopped, time.Second*10, time.Second*1800)
|
||||
return vm, err
|
||||
}
|
||||
|
||||
func (self *SHost) _createVM(name string, imgId string, cpu int, memMB int, vswitchId string, ipAddr string, desc string, passwd string, storageType string, diskSizes []int) (string, error) {
|
||||
func (self *SHost) lookUpAliyunKeypair(publicKey string) (string, error) {
|
||||
pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(publicKey))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("publicKey error %s", err)
|
||||
}
|
||||
|
||||
fingerprint := strings.Replace(ssh.FingerprintLegacyMD5(pk), ":", "", -1)
|
||||
ks, total, err := self.zone.region.GetKeypairs(fingerprint, "*", 0, 1)
|
||||
if total < 1 {
|
||||
return "", fmt.Errorf("keypair not found %s", err)
|
||||
} else {
|
||||
return ks[0].KeyPairName, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SHost) importAliyunKeypair(publicKey string) (string, error) {
|
||||
prefix, e := goutils.RandomAlphabetic(6)
|
||||
if e != nil {
|
||||
return "", fmt.Errorf("publicKey error %s", e)
|
||||
}
|
||||
|
||||
name := prefix + strconv.FormatInt(time.Now().Unix(), 10)
|
||||
if k, e := self.zone.region.ImportKeypair(name, publicKey); e != nil {
|
||||
return "", fmt.Errorf("keypair import error %s", e)
|
||||
} else {
|
||||
return k.KeyPairName, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SHost) _createVM(name string, imgId string, sysDiskSize int, cpu int, memMB int, vswitchId string, ipAddr string, desc string, passwd string, storageType string, diskSizes []int, publicKey string) (string, error) {
|
||||
net := self.zone.getNetworkById(vswitchId)
|
||||
if net == nil {
|
||||
return "", fmt.Errorf("invalid switch ID %s", vswitchId)
|
||||
@@ -182,11 +227,30 @@ func (self *SHost) _createVM(name string, imgId string, cpu int, memMB int, vswi
|
||||
return "", fmt.Errorf("get security group error %s", err)
|
||||
}
|
||||
|
||||
var secgroupId string
|
||||
if len(secgroups) == 0 {
|
||||
return "", fmt.Errorf("no secgroup for vpc!!")
|
||||
secId, err := self.zone.region.createDefaultSecurityGroup(net.wire.vpc.VpcId)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("no secgroup for vpc and failed to create a default One!!")
|
||||
} else {
|
||||
secgroupId = secId
|
||||
}
|
||||
} else {
|
||||
secgroupId = secgroups[0].SecurityGroupId
|
||||
}
|
||||
|
||||
secgroupId := secgroups[0].SecurityGroupId
|
||||
keypair := ""
|
||||
if len(publicKey) > 0 {
|
||||
if name, e := self.lookUpAliyunKeypair(publicKey); e != nil {
|
||||
if newName, err := self.importAliyunKeypair(publicKey); e != nil {
|
||||
keypair = newName
|
||||
} else {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
keypair = name
|
||||
}
|
||||
}
|
||||
|
||||
img, err := self.zone.region.GetImage(imgId)
|
||||
if err != nil {
|
||||
@@ -205,6 +269,9 @@ func (self *SHost) _createVM(name string, imgId string, cpu int, memMB int, vswi
|
||||
|
||||
disks := make([]SDisk, len(diskSizes)+1)
|
||||
disks[0].Size = img.Size
|
||||
if sysDiskSize > 0 && sysDiskSize > img.Size {
|
||||
disks[0].Size = sysDiskSize
|
||||
}
|
||||
disks[0].Category = storageType
|
||||
|
||||
for i, sz := range diskSizes {
|
||||
@@ -223,7 +290,7 @@ func (self *SHost) _createVM(name string, imgId string, cpu int, memMB int, vswi
|
||||
for _, instType := range instanceTypes {
|
||||
instanceTypeId := instType.InstanceTypeId
|
||||
log.Debugf("Try instancetype : %s", instanceTypeId)
|
||||
vmId, err := self.zone.region.CreateInstance(name, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, "")
|
||||
vmId, err := self.zone.region.CreateInstance(name, imgId, instanceTypeId, secgroupId, self.zone.ZoneId, desc, passwd, disks, vswitchId, ipAddr, keypair)
|
||||
if err != nil {
|
||||
log.Errorf("Failed for %s: %s", instanceTypeId, err)
|
||||
} else {
|
||||
|
||||
@@ -4,11 +4,10 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
type ImageStatusType string
|
||||
@@ -63,6 +62,10 @@ func (self *SImage) GetName() string {
|
||||
return self.ImageName
|
||||
}
|
||||
|
||||
func (self *SImage) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SImage) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s-%s")
|
||||
}
|
||||
@@ -86,6 +89,14 @@ func (self *SImage) GetStatus() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SImage) Refresh() error {
|
||||
new, err := self.storageCache.region.GetImage(self.ImageId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
// {"ImageId":"m-j6c1qlpa7oebbg1n2k60","RegionId":"cn-hongkong","RequestId":"F8B2F6A1-F6AA-4C92-A54C-C4A309CF811F","TaskId":"t-j6c1qlpa7oebbg1rcl9t"}
|
||||
|
||||
type ImageImportTask struct {
|
||||
|
||||
@@ -2,15 +2,14 @@ package aliyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/pkg/util/osprofile"
|
||||
"github.com/yunionio/pkg/util/seclib"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -180,14 +179,18 @@ func (self *SInstance) GetGlobalId() string {
|
||||
return self.InstanceId
|
||||
}
|
||||
|
||||
func (self *SInstance) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstance) fetchDisks() error {
|
||||
disks, total, err := self.host.zone.region.GetDisks(self.InstanceId, "", "", 0, 50)
|
||||
disks, total, err := self.host.zone.region.GetDisks(self.InstanceId, "", "", nil, 0, 50)
|
||||
if err != nil {
|
||||
log.Errorf("fetchDisks fail %s", err)
|
||||
return err
|
||||
}
|
||||
if total > len(disks) {
|
||||
disks, _, err = self.host.zone.region.GetDisks(self.InstanceId, "", "", 0, total)
|
||||
disks, _, err = self.host.zone.region.GetDisks(self.InstanceId, "", "", nil, 0, total)
|
||||
}
|
||||
self.idisks = make([]cloudprovider.ICloudDisk, len(disks))
|
||||
for i := 0; i < len(disks); i += 1 {
|
||||
@@ -279,6 +282,14 @@ func (self *SInstance) GetStatus() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SInstance) Refresh() error {
|
||||
new, err := self.host.zone.region.GetInstance(self.InstanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetRemoteStatus() string {
|
||||
// Running:运行中
|
||||
//Starting:启动中
|
||||
@@ -351,7 +362,7 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st
|
||||
if len(keypair) > 0 {
|
||||
params["KeyPairName"] = keypair
|
||||
}
|
||||
params["ClientToken"] = utils.GenRequestId(12)
|
||||
params["ClientToken"] = utils.GenRequestId(20)
|
||||
|
||||
body, err := self.ecsRequest("CreateInstance", params)
|
||||
if err != nil {
|
||||
@@ -381,7 +392,7 @@ func (self *SRegion) doDeleteVM(instanceId string) error {
|
||||
return self.instanceOperation(instanceId, "DeleteInstance", nil)
|
||||
}
|
||||
|
||||
func (self *SRegion) waitInstanceStatus(instanceId string, target string, interval time.Duration, timeout time.Duration) error {
|
||||
/*func (self *SRegion) waitInstanceStatus(instanceId string, target string, interval time.Duration, timeout time.Duration) error {
|
||||
startTime := time.Now()
|
||||
for time.Now().Sub(startTime) < timeout {
|
||||
status, err := self.GetInstanceStatus(instanceId)
|
||||
@@ -398,66 +409,78 @@ func (self *SRegion) waitInstanceStatus(instanceId string, target string, interv
|
||||
|
||||
func (self *SInstance) waitStatus(target string, interval time.Duration, timeout time.Duration) error {
|
||||
return self.host.zone.region.waitInstanceStatus(self.InstanceId, target, interval, timeout)
|
||||
}
|
||||
}*/
|
||||
|
||||
func (self *SRegion) StartVM(instanceId string) error {
|
||||
status, err := self.GetInstanceStatus(instanceId)
|
||||
status, _ := self.GetInstanceStatus(instanceId)
|
||||
if status != InstanceStatusStopped {
|
||||
return cloudprovider.ErrInvalidStatus
|
||||
}
|
||||
err = self.doStartVM(instanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return self.waitInstanceStatus(instanceId, InstanceStatusRunning, time.Second*5, time.Second*180) // 3 minutes to timeout
|
||||
return self.doStartVM(instanceId)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return self.waitInstanceStatus(instanceId, InstanceStatusRunning, time.Second*5, time.Second*180) // 3 minutes to timeout
|
||||
}
|
||||
|
||||
func (self *SRegion) StopVM(instanceId string, isForce bool) error {
|
||||
status, err := self.GetInstanceStatus(instanceId)
|
||||
status, _ := self.GetInstanceStatus(instanceId)
|
||||
if status != InstanceStatusRunning {
|
||||
return cloudprovider.ErrInvalidStatus
|
||||
}
|
||||
err = self.doStopVM(instanceId, isForce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return self.waitInstanceStatus(instanceId, InstanceStatusStopped, time.Second*10, time.Second*300) // 5 minutes to timeout
|
||||
return self.doStopVM(instanceId, isForce)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return self.waitInstanceStatus(instanceId, InstanceStatusStopped, time.Second*10, time.Second*300) // 5 minutes to timeout
|
||||
}
|
||||
|
||||
func (self *SRegion) DeleteVM(instanceId string) error {
|
||||
status, err := self.GetInstanceStatus(instanceId)
|
||||
if status == InstanceStatusRunning {
|
||||
err := self.StopVM(instanceId, true)
|
||||
err = self.StopVM(instanceId, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if status != InstanceStatusStopped {
|
||||
return cloudprovider.ErrInvalidStatus
|
||||
}
|
||||
err = self.doDeleteVM(instanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = self.waitInstanceStatus(instanceId, InstanceStatusRunning, time.Second*10, time.Second*300) // 5 minutes to timeout
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
return nil
|
||||
} else if err == nil {
|
||||
return cloudprovider.ErrTimeout
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return self.doDeleteVM(instanceId)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// err = self.waitInstanceStatus(instanceId, InstanceStatusRunning, time.Second*10, time.Second*300) // 5 minutes to timeout
|
||||
// if err == cloudprovider.ErrNotFound {
|
||||
// return nil
|
||||
// } else if err == nil {
|
||||
// return cloudprovider.ErrTimeout
|
||||
// } else {
|
||||
// return err
|
||||
// }
|
||||
}
|
||||
|
||||
func (self *SInstance) StartVM() error {
|
||||
return self.host.zone.region.StartVM(self.InstanceId)
|
||||
err := self.host.zone.region.StartVM(self.InstanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cloudprovider.WaitStatus(self, models.VM_RUNNING, 5*time.Second, 180*time.Second) // 3minutes
|
||||
}
|
||||
|
||||
func (self *SInstance) StopVM(isForce bool) error {
|
||||
return self.host.zone.region.StopVM(self.InstanceId, isForce)
|
||||
err := self.host.zone.region.StopVM(self.InstanceId, isForce)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cloudprovider.WaitStatus(self, models.VM_READY, 10*time.Second, 300*time.Second) // 5mintues
|
||||
}
|
||||
|
||||
func (self *SInstance) DeleteVM() error {
|
||||
return self.host.zone.region.DeleteVM(self.InstanceId)
|
||||
err := self.host.zone.region.DeleteVM(self.InstanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cloudprovider.WaitDeleted(self, 10*time.Second, 300*time.Second) // 5minutes
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
|
||||
|
||||
@@ -2,7 +2,7 @@ package aliyun
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/yunioncloud/pkg/util/netutils"
|
||||
"github.com/yunionio/pkg/util/netutils"
|
||||
)
|
||||
|
||||
type SInstanceNic struct {
|
||||
|
||||
@@ -2,7 +2,6 @@ package aliyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/jsonutils"
|
||||
// "github.com/yunionio/log"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
)
|
||||
|
||||
@@ -16,12 +15,12 @@ func (self *SAliyunProviderFactory) GetId() string {
|
||||
return aliyun.CLOUD_PROVIDER_ALIYUN
|
||||
}
|
||||
|
||||
func (self *SAliyunProviderFactory) GetProvider(providerId, url, account, secret string) (cloudprovider.ICloudProvider, error) {
|
||||
func (self *SAliyunProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
|
||||
provider, ok := self.providerTable[providerId]
|
||||
if ok {
|
||||
return provider, nil
|
||||
}
|
||||
client, err := aliyun.NewAliyunClient(providerId, account, secret)
|
||||
client, err := aliyun.NewAliyunClient(providerId, providerName, account, secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -53,7 +52,7 @@ func (self *SAliyunProvider) GetName() string {
|
||||
}
|
||||
|
||||
func (self *SAliyunProvider) GetSysInfo() (jsonutils.JSONObject, error) {
|
||||
regions := self.client.GetRegions()
|
||||
regions := self.client.GetIRegions()
|
||||
info := jsonutils.NewDict()
|
||||
info.Add(jsonutils.NewInt(int64(len(regions))), "region_count")
|
||||
return info, nil
|
||||
@@ -66,3 +65,19 @@ func (self *SAliyunProvider) GetIRegions() []cloudprovider.ICloudRegion {
|
||||
func (self *SAliyunProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) {
|
||||
return self.client.GetIRegionById(id)
|
||||
}
|
||||
|
||||
func (self *SAliyunProvider) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
return self.client.GetIHostById(id)
|
||||
}
|
||||
|
||||
func (self *SAliyunProvider) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
return self.client.GetIVpcById(id)
|
||||
}
|
||||
|
||||
func (self *SAliyunProvider) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
return self.client.GetIStorageById(id)
|
||||
}
|
||||
|
||||
func (self *SAliyunProvider) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
|
||||
return self.client.GetIStoragecacheById(id)
|
||||
}
|
||||
@@ -2,16 +2,14 @@ package aliyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
"strings"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/jsonutils"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
"strings"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type SRegion struct {
|
||||
@@ -22,9 +20,9 @@ type SRegion struct {
|
||||
RegionId string
|
||||
LocalName string
|
||||
|
||||
izones []cloudprovider.ICloudZone
|
||||
_izones []cloudprovider.ICloudZone
|
||||
|
||||
ivpcs []cloudprovider.ICloudVpc
|
||||
_ivpcs []cloudprovider.ICloudVpc
|
||||
|
||||
storageCache *SStoragecache
|
||||
|
||||
@@ -90,6 +88,14 @@ func (self *SRegion) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s/%s", CLOUD_PROVIDER_ALIYUN, self.RegionId)
|
||||
}
|
||||
|
||||
func (self *SRegion) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SRegion) GetProvider() string {
|
||||
return CLOUD_PROVIDER_ALIYUN
|
||||
}
|
||||
|
||||
func (self *SRegion) GetLatitude() float32 {
|
||||
return 0.0
|
||||
}
|
||||
@@ -102,26 +108,30 @@ func (self *SRegion) GetStatus() string {
|
||||
return models.CLOUD_REGION_STATUS_INSERVER
|
||||
}
|
||||
|
||||
func (self *SRegion) Refresh() error {
|
||||
// do nothing
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) {
|
||||
if self.izones == nil {
|
||||
err := self.fetchInfrastructure()
|
||||
if self._izones == nil {
|
||||
var err error
|
||||
err = self.fetchInfrastructure()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.izones, nil
|
||||
return self._izones, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
|
||||
if self.izones == nil {
|
||||
err := self.fetchInfrastructure()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(self.izones); i += 1 {
|
||||
if self.izones[i].GetGlobalId() == id {
|
||||
return self.izones[i], nil
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
if izones[i].GetGlobalId() == id {
|
||||
return izones[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
@@ -154,25 +164,23 @@ func (self *SRegion) _fetchZones(chargeType InstanceChargeType, spotStrategy Spo
|
||||
return err
|
||||
}
|
||||
|
||||
self.izones = make([]cloudprovider.ICloudZone, len(zones))
|
||||
self._izones = make([]cloudprovider.ICloudZone, len(zones))
|
||||
|
||||
for i := 0; i < len(zones); i += 1 {
|
||||
zones[i].region = self
|
||||
self.izones[i] = &zones[i]
|
||||
self._izones[i] = &zones[i]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getZoneById(id string) (*SZone, error) {
|
||||
if self.izones == nil {
|
||||
err := self.fetchInfrastructure()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(self.izones); i += 1 {
|
||||
zone := self.izones[i].(*SZone)
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
zone := izones[i].(*SZone)
|
||||
if zone.ZoneId == id {
|
||||
return zone, nil
|
||||
}
|
||||
@@ -181,25 +189,23 @@ func (self *SRegion) getZoneById(id string) (*SZone, error) {
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) {
|
||||
if self.ivpcs == nil {
|
||||
if self._ivpcs == nil {
|
||||
err := self.fetchInfrastructure()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.ivpcs, nil
|
||||
return self._ivpcs, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
if self.ivpcs == nil {
|
||||
err := self.fetchInfrastructure()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ivpcs, err := self.GetIVpcs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(self.ivpcs); i += 1 {
|
||||
if self.ivpcs[i].GetGlobalId() == id {
|
||||
return self.ivpcs[i], nil
|
||||
for i := 0; i < len(ivpcs); i += 1 {
|
||||
if ivpcs[i].GetGlobalId() == id {
|
||||
return ivpcs[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
@@ -208,7 +214,7 @@ func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
func (self *SRegion) fetchIVpcs() error {
|
||||
vpcs := make([]SVpc, 0)
|
||||
for {
|
||||
part, total, err := self.GetVpcs(len(vpcs), 50)
|
||||
part, total, err := self.GetVpcs(nil, len(vpcs), 50)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -217,10 +223,10 @@ func (self *SRegion) fetchIVpcs() error {
|
||||
break
|
||||
}
|
||||
}
|
||||
self.ivpcs = make([]cloudprovider.ICloudVpc, len(vpcs))
|
||||
self._ivpcs = make([]cloudprovider.ICloudVpc, len(vpcs))
|
||||
for i := 0; i < len(vpcs); i += 1 {
|
||||
vpcs[i].region = self
|
||||
self.ivpcs[i] = &vpcs[i]
|
||||
self._ivpcs[i] = &vpcs[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -234,10 +240,10 @@ func (self *SRegion) fetchInfrastructure() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < len(self.ivpcs); i += 1 {
|
||||
for j := 0; j < len(self.izones); j += 1 {
|
||||
zone := self.izones[j].(*SZone)
|
||||
vpc := self.ivpcs[i].(*SVpc)
|
||||
for i := 0; i < len(self._ivpcs); i += 1 {
|
||||
for j := 0; j < len(self._izones); j += 1 {
|
||||
zone := self._izones[j].(*SZone)
|
||||
vpc := self._ivpcs[i].(*SVpc)
|
||||
wire := SWire{zone: zone, vpc: vpc}
|
||||
zone.addWire(&wire)
|
||||
vpc.addWire(&wire)
|
||||
@@ -246,7 +252,7 @@ func (self *SRegion) fetchInfrastructure() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVpcs(offset int, limit int) ([]SVpc, int, error) {
|
||||
func (self *SRegion) GetVpcs(vpcId []string, offset int, limit int) ([]SVpc, int, error) {
|
||||
if limit > 50 || limit <= 0 {
|
||||
limit = 50
|
||||
}
|
||||
@@ -255,6 +261,10 @@ func (self *SRegion) GetVpcs(offset int, limit int) ([]SVpc, int, error) {
|
||||
params["PageSize"] = fmt.Sprintf("%d", limit)
|
||||
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
|
||||
|
||||
if vpcId != nil && len(vpcId) > 0 {
|
||||
params["VpcId"] = strings.Join(vpcId, ",")
|
||||
}
|
||||
|
||||
body, err := self.ecsRequest("DescribeVpcs", params)
|
||||
if err != nil {
|
||||
log.Errorf("GetVpcs fail %s", err)
|
||||
@@ -271,6 +281,17 @@ func (self *SRegion) GetVpcs(offset int, limit int) ([]SVpc, int, error) {
|
||||
return vpcs, int(total), nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getVpc(vpcId string) (*SVpc, error) {
|
||||
vpcs, total, err := self.GetVpcs([]string{vpcId}, 0, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if total != 1 {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
return &vpcs[0], nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVRouters(offset int, limit int) ([]SVRouter, int, error) {
|
||||
if limit > 50 || limit <= 0 {
|
||||
limit = 50
|
||||
@@ -324,7 +345,7 @@ func (self *SRegion) GetRouteTables(ids []string, offset int, limit int) ([]SRou
|
||||
return routetables, int(total), nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetVSwitches(ids []string, offset int, limit int) ([]SVSwitch, int, error) {
|
||||
func (self *SRegion) GetVSwitches(ids []string, vpcId string, offset int, limit int) ([]SVSwitch, int, error) {
|
||||
if limit > 50 || limit <= 0 {
|
||||
limit = 50
|
||||
}
|
||||
@@ -333,7 +354,10 @@ func (self *SRegion) GetVSwitches(ids []string, offset int, limit int) ([]SVSwit
|
||||
params["PageSize"] = fmt.Sprintf("%d", limit)
|
||||
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
|
||||
if ids != nil && len(ids) > 0 {
|
||||
params["RouteTableId"] = strings.Join(ids, ",")
|
||||
params["VSwitchId"] = strings.Join(ids, ",")
|
||||
}
|
||||
if len(vpcId) > 0 {
|
||||
params["VpcId"] = vpcId
|
||||
}
|
||||
|
||||
body, err := self.ecsRequest("DescribeVSwitches", params)
|
||||
@@ -380,14 +404,18 @@ func (self *SRegion) GetMatchInstanceTypes(cpu int, memMB int, gpu int, zoneId s
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateInstanceSimple(name string, imgId string, cpu int, memGB int, storageType string, dataDiskSizesGB []int, vswitchId string, passwd string) (*SInstance, error) {
|
||||
self.fetchInfrastructure()
|
||||
for i := 0; i < len(self.izones); i += 1 {
|
||||
z := self.izones[i].(*SZone)
|
||||
|
||||
func (self *SRegion) CreateInstanceSimple(name string, imgId string, cpu int, memGB int, storageType string, dataDiskSizesGB []int, vswitchId string, passwd string, publicKey string) (*SInstance, error) {
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
z := izones[i].(*SZone)
|
||||
log.Debugf("Search in zone %s", z.LocalName)
|
||||
net := z.getNetworkById(vswitchId)
|
||||
if net != nil {
|
||||
inst, err := z.getHost().CreateVM(name, imgId, cpu, memGB*1024, vswitchId, "", "", passwd, storageType, dataDiskSizesGB)
|
||||
inst, err := z.getHost().CreateVM(name, imgId, 0, cpu, memGB*1024, vswitchId, "", "", passwd, storageType, dataDiskSizesGB, publicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -437,3 +465,77 @@ func (self *SRegion) ModifyInstanceVNCUrlPassword(instanceId string, passwd stri
|
||||
_, err := self.ecsRequest("ModifyInstanceVncPasswd", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateIVpc(name string, desc string, cidr string) (cloudprovider.ICloudVpc, error) {
|
||||
params := make(map[string]string)
|
||||
if len(cidr) > 0 {
|
||||
params["CidrBlock"] = cidr
|
||||
}
|
||||
if len(name) > 0 {
|
||||
params["VpcName"] = name
|
||||
}
|
||||
if len(desc) > 0 {
|
||||
params["Description"] = desc
|
||||
}
|
||||
params["ClientToken"] = utils.GenRequestId(20)
|
||||
body, err := self.ecsRequest("CreateVpc", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vpcId, err := body.GetString("VpcId")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = self.fetchInfrastructure()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return self.GetIVpcById(vpcId)
|
||||
}
|
||||
|
||||
func (self *SRegion) DeleteVpc(vpcId string) error {
|
||||
params := make(map[string]string)
|
||||
params["VpcId"] = vpcId
|
||||
|
||||
_, err := self.ecsRequest("DeleteVpc", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
ihost, err := izones[i].GetIHostById(id)
|
||||
if err == nil {
|
||||
return ihost, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) {
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(izones); i += 1 {
|
||||
istore, err := izones[i].GetIStorageById(id)
|
||||
if err == nil {
|
||||
return istore, nil
|
||||
} else if err != cloudprovider.ErrNotFound {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStoragecache, error) {
|
||||
if self.storageCache.GetGlobalId() == id {
|
||||
return self.storageCache, nil
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
@@ -3,8 +3,9 @@ package aliyun
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/pkg/util/secrules"
|
||||
"github.com/yunionio/pkg/utils"
|
||||
)
|
||||
|
||||
// {"CreationTime":"2017-03-19T13:37:48Z","Description":"System created security group.","SecurityGroupId":"sg-j6cannq0xxj2r9z0yxwl","SecurityGroupName":"sg-j6cannq0xxj2r9z0yxwl","Tags":{"Tag":[]},"VpcId":"vpc-j6c86z3sh8ufhgsxwme0q"}
|
||||
@@ -99,3 +100,91 @@ func (self *SRegion) GetSecurityGroupDetails(secGroupId string) (*SSecurityGroup
|
||||
}
|
||||
return &secgrp, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) createSecurityGroup(vpcId string, name string, desc string) (string, error) {
|
||||
params := make(map[string]string)
|
||||
if len(vpcId) > 0 {
|
||||
params["VpcId"] = vpcId
|
||||
}
|
||||
if len(name) > 0 {
|
||||
params["SecurityGroupName"] = name
|
||||
}
|
||||
if len(desc) > 0 {
|
||||
params["Description"] = desc
|
||||
}
|
||||
params["ClientToken"] = utils.GenRequestId(20)
|
||||
|
||||
body, err := self.ecsRequest("CreateSecurityGroup", params)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return body.GetString("SecurityGroupId")
|
||||
}
|
||||
|
||||
func (self *SRegion) addSecurityGroupRule(secGrpId string, rule *secrules.SecurityRule) error {
|
||||
params := make(map[string]string)
|
||||
params["SecurityGroupId"] = secGrpId
|
||||
protocol := rule.Protocol
|
||||
if len(rule.Protocol) == 0 {
|
||||
protocol = "all"
|
||||
}
|
||||
params["IpProtocol"] = protocol
|
||||
params["PortRange"] = fmt.Sprintf("%d/%d", rule.PortStart, rule.PortEnd)
|
||||
if rule.Action == secrules.SecurityRuleAllow {
|
||||
params["Policy"] = "accept"
|
||||
} else {
|
||||
params["Policy"] = "drop"
|
||||
}
|
||||
params["Priority"] = fmt.Sprintf("%d", rule.Priority)
|
||||
if rule.Direction == secrules.SecurityRuleIngress {
|
||||
if rule.IPNet != nil {
|
||||
params["SourceCidrIp"] = rule.IPNet.String()
|
||||
} else {
|
||||
params["SourceCidrIp"] = "0.0.0.0/0"
|
||||
}
|
||||
params["DestCidrIp"] = "0.0.0.0/0"
|
||||
_, err := self.ecsRequest("AuthorizeSecurityGroup", params)
|
||||
return err
|
||||
} else { // rule.Direction == secrules.SecurityRuleEgress {
|
||||
if rule.IPNet != nil {
|
||||
params["DestCidrIp"] = rule.IPNet.String()
|
||||
} else {
|
||||
params["DestCidrIp"] = "0.0.0.0/0"
|
||||
}
|
||||
params["SourceCidrIp"] = "0.0.0.0/0"
|
||||
_, err := self.ecsRequest("AuthorizeSecurityGroupEgress", params)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SRegion) createDefaultSecurityGroup(vpcId string) (string, error) {
|
||||
secId, err := self.createSecurityGroup(vpcId, "", "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
inRule := secrules.SecurityRule{
|
||||
Priority: 1,
|
||||
Action: secrules.SecurityRuleAllow,
|
||||
Protocol: "",
|
||||
Direction: secrules.SecurityRuleIngress,
|
||||
PortStart: -1,
|
||||
PortEnd: -1,
|
||||
}
|
||||
err = self.addSecurityGroupRule(secId, &inRule)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
outRule := secrules.SecurityRule{
|
||||
Priority: 1,
|
||||
Action: secrules.SecurityRuleAllow,
|
||||
Protocol: "",
|
||||
Direction: secrules.SecurityRuleEgress,
|
||||
PortStart: -1,
|
||||
PortEnd: -1,
|
||||
}
|
||||
err = self.addSecurityGroupRule(secId, &outRule)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return secId, nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/yunioncloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -13,7 +13,7 @@ func init() {
|
||||
Limit int `help:"List limit"`
|
||||
}
|
||||
R(&DiskListOptions{}, "disk-list", "List disks", func(cli *aliyun.SRegion, args *DiskListOptions) error {
|
||||
disks, total, e := cli.GetDisks(args.Instance, args.Zone, args.Category, args.Offset, args.Limit)
|
||||
disks, total, e := cli.GetDisks(args.Instance, args.Zone, args.Category, nil, args.Offset, args.Limit)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/yunioncloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/yunioncloud/pkg/util/aliyun"
|
||||
"fmt"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -30,9 +30,10 @@ func init() {
|
||||
STORAGE string `help:"Storage type"`
|
||||
VSWITCH string `help:"Vswitch ID"`
|
||||
PASSWD string `help:"password"`
|
||||
PublicKey string `help:"PublicKey"`
|
||||
}
|
||||
R(&InstanceCrateOptions{}, "instance-create", "Create a instance", func(cli *aliyun.SRegion, args *InstanceCrateOptions) error {
|
||||
instance, e := cli.CreateInstanceSimple(args.NAME, args.IMAGE, args.CPU, args.MEMORYGB, args.STORAGE, args.Disk, args.VSWITCH, args.PASSWD)
|
||||
instance, e := cli.CreateInstanceSimple(args.NAME, args.IMAGE, args.CPU, args.MEMORYGB, args.STORAGE, args.Disk, args.VSWITCH, args.PASSWD, args.PublicKey)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/yunioncloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/yunioncloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,9 +1,42 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/yunioncloud/pkg/util/aliyun"
|
||||
"fmt"
|
||||
|
||||
osslib "github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
)
|
||||
|
||||
type progressListener struct {
|
||||
}
|
||||
|
||||
func (this *progressListener) ProgressChanged(event *osslib.ProgressEvent) {
|
||||
switch event.EventType {
|
||||
case osslib.TransferStartedEvent:
|
||||
fmt.Printf("\n")
|
||||
case osslib.TransferDataEvent:
|
||||
fmt.Printf("Progess: %f%%\r", (float64(event.ConsumedBytes) * 100.0 / float64(event.TotalBytes)))
|
||||
case osslib.TransferCompletedEvent:
|
||||
fmt.Printf("Transfer complete!\n")
|
||||
case osslib.TransferFailedEvent:
|
||||
fmt.Printf("Transfer failed!\n")
|
||||
default:
|
||||
fmt.Printf("Unknonw event type %d\n", event.EventType)
|
||||
}
|
||||
}
|
||||
|
||||
func str2AclType(aclStr string) osslib.ACLType {
|
||||
switch aclStr {
|
||||
case "public-rw":
|
||||
return osslib.ACLPublicReadWrite
|
||||
case "public-read":
|
||||
return osslib.ACLPublicRead
|
||||
default:
|
||||
return osslib.ACLPrivate
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
type OssListOptions struct {
|
||||
}
|
||||
@@ -54,9 +87,11 @@ func init() {
|
||||
})
|
||||
|
||||
type OssUploadOptions struct {
|
||||
BUCKET string `help:"bucket name"`
|
||||
KEY string `help:"Object key"`
|
||||
FILE string `help:"Local file path"`
|
||||
BUCKET string `help:"bucket name"`
|
||||
KEY string `help:"Object key"`
|
||||
FILE string `help:"Local file path"`
|
||||
Progress bool `help:"show progress"`
|
||||
Acl string `help:"Object ACL" choices:"private|public-read|public-rw"`
|
||||
}
|
||||
R(&OssUploadOptions{}, "oss-upload", "Upload a file to a OSS bucket", func(cli *aliyun.SRegion, args *OssUploadOptions) error {
|
||||
oss, err := cli.GetOssClient()
|
||||
@@ -67,7 +102,34 @@ func init() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = bucket.UploadFile(args.KEY, args.FILE, 1024*1024)
|
||||
|
||||
options := make([]osslib.Option, 0)
|
||||
if args.Progress {
|
||||
listener := progressListener{}
|
||||
options = append(options, osslib.Progress(&listener))
|
||||
}
|
||||
if len(args.Acl) > 0 {
|
||||
options = append(options, osslib.ACL(str2AclType(args.Acl)))
|
||||
}
|
||||
err = bucket.UploadFile(args.KEY, args.FILE, 1024*1024, options...)
|
||||
return err
|
||||
})
|
||||
|
||||
type OssObjectAclOptions struct {
|
||||
BUCKET string `help:"bucket name"`
|
||||
KEY string `help:"object key"`
|
||||
ACL string `help:"ACL" choices:"private|public-read|public-rw"`
|
||||
}
|
||||
R(&OssObjectAclOptions{}, "oss-set-acl", "Set acl for a object", func(cli *aliyun.SRegion, args *OssObjectAclOptions) error {
|
||||
oss, err := cli.GetOssClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bucket, err := oss.Bucket(args.BUCKET)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = bucket.SetObjectACL(args.KEY, str2AclType(args.ACL))
|
||||
return err
|
||||
})
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/yunioncloud/pkg/util/aliyun"
|
||||
"github.com/yunionio/onecloud/pkg/util/aliyun"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user