Add region service.

This commit is contained in:
Zexi Li
2018-07-30 12:27:27 +08:00
parent 270298fae2
commit 37624f11e2
115 changed files with 3408 additions and 627 deletions

View File

@@ -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) {

View File

@@ -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"
)

View File

@@ -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
}

View File

@@ -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

View File

@@ -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 {

View File

@@ -0,0 +1,9 @@
package db
/// Global virtual resource namespace
var globalVirtualResourceNamespace = false
func EnableGlobalVirtualResourceNamespace() {
globalVirtualResourceNamespace = true
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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())

View File

@@ -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
}
}

View File

@@ -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) {

View File

@@ -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")
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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
}

View 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
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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)
}

View 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
}

View File

@@ -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
}

View 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))
}

View File

@@ -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())
}

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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(&region)
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)
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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)

View File

@@ -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()
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -2,7 +2,6 @@ package models
import (
"context"
"github.com/yunionio/jsonutils"
"github.com/yunionio/mcclient"
)

View File

@@ -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 {

View File

@@ -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")

View File

@@ -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 {

View 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
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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 (

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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"
)

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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()

View File

@@ -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 (

View File

@@ -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) {

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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, "")
}
}

View File

@@ -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 {

View File

@@ -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 {

View 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)
}

View 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)
}

View File

@@ -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 {

View File

@@ -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
}

View 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)
}

View 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)
}

View File

@@ -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{}

View File

@@ -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(&regions, "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] = &regions[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
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -2,7 +2,6 @@ package aliyun
import (
"fmt"
"github.com/yunionio/log"
)

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -1,7 +1,7 @@
package shell
import (
"yunion.io/yunioncloud/pkg/util/aliyun"
"github.com/yunionio/onecloud/pkg/util/aliyun"
)
func init() {

View File

@@ -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
}

View File

@@ -1,7 +1,7 @@
package shell
import (
"yunion.io/yunioncloud/pkg/util/aliyun"
"github.com/yunionio/onecloud/pkg/util/aliyun"
)
func init() {

View File

@@ -1,7 +1,7 @@
package shell
import (
"yunion.io/yunioncloud/pkg/util/aliyun"
"github.com/yunionio/onecloud/pkg/util/aliyun"
)
func init() {

View File

@@ -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
})

View File

@@ -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