Merge pull request #11966 from ioito/feat/qx-cdn

feat(region): add qcloud cdn
This commit is contained in:
Zexi Li
2021-08-20 18:43:42 +08:00
committed by GitHub
16 changed files with 764 additions and 14 deletions
+26
View File
@@ -0,0 +1,26 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.CDNDomains)
cmd.List(&compute.CDNDomainListOptions{})
}
+25 -4
View File
@@ -14,11 +14,17 @@
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
CDN_DOMAIN_STATUS_ONLINE = "online"
CDN_DOMAIN_STATUS_OFFLINE = "offline"
CDN_DOMAIN_STATUS_PROCESSING = "processing"
CDN_DOMAIN_STATUS_REJECTED = "rejected"
CDN_DOMAIN_STATUS_ONLINE = "online"
CDN_DOMAIN_STATUS_OFFLINE = "offline"
CDN_DOMAIN_STATUS_DELETING = "deleting"
CDN_DOMAIN_STATUS_DELETE_FAILED = "delete_failed"
CDN_DOMAIN_STATUS_PROCESSING = "processing"
CDN_DOMAIN_STATUS_REJECTED = "rejected"
CDN_DOMAIN_STATUS_UNKNOWN = "unknown"
CDN_DOMAIN_AREA_MAINLAND = "mainland"
CDN_DOMAIN_AREA_OVERSEAS = "overseas"
CDN_DOMAIN_AREA_GLOBAL = "global"
@@ -45,3 +51,18 @@ type CdnDomain struct {
type CdnDomains struct {
Data []CdnDomain `json:"data"`
}
type CDNDomainCreateInput struct {
}
type CDNDomainDetails struct {
apis.EnabledStatusInfrasResourceBaseDetails
ManagedResourceInfo
}
type CDNDomainListInput struct {
apis.EnabledStatusInfrasResourceBaseListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
}
+3 -2
View File
@@ -27,12 +27,13 @@ import (
// +onecloud:model-api-gen
type SExternalizedResourceBase struct {
// 外部Id, 对用公有云私有资源自身Id
// 云上Id, 对应云上资源自身Id
ExternalId string `width:"256" charset:"utf8" index:"true" list:"user" create:"domain_optional" update:"admin" json:"external_id"`
// 资源导入时间
ImportedAt time.Time `nullable:"true" created_at:"true" index:"true" get:"user" list:"user" json:"imported_at"`
Source string `width:"12" charset:"ascii" get:"user" list:"user" create:"optional" json:"source"`
// 资源来源, cloud: 从云上同步下来的资源, local: 从本地创建的资源或资源在本地更改过项目
Source string `width:"12" charset:"ascii" get:"user" list:"user" create:"optional" json:"source"`
}
func (model *SExternalizedResourceBase) BeforeInsert() {
+13
View File
@@ -294,6 +294,9 @@ type ICloudProvider interface {
GetICloudInterVpcNetworks() ([]ICloudInterVpcNetwork, error)
GetICloudInterVpcNetworkById(id string) (ICloudInterVpcNetwork, error)
CreateICloudInterVpcNetwork(opts *SInterVpcNetworkCreateOptions) (ICloudInterVpcNetwork, error)
GetICloudCDNDomains() ([]ICloudCDNDomain, error)
GetICloudCDNDomainByName(name string) (ICloudCDNDomain, error)
}
func IsSupportProject(prod ICloudProvider) bool {
@@ -521,13 +524,23 @@ func (self *SBaseProvider) GetSamlSpInitiatedLoginUrl(idpName string) string {
func (self *SBaseProvider) GetICloudInterVpcNetworks() ([]ICloudInterVpcNetwork, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetICloudInterVpcNetworkById(id string) (ICloudInterVpcNetwork, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) CreateICloudInterVpcNetwork(opts *SInterVpcNetworkCreateOptions) (ICloudInterVpcNetwork, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetICloudCDNDomains() ([]ICloudCDNDomain, error) {
return nil, errors.Wrapf(ErrNotImplemented, "GetICloudCDNDomains")
}
func (self *SBaseProvider) GetICloudCDNDomainByName(name string) (ICloudCDNDomain, error) {
return nil, errors.Wrapf(ErrNotImplemented, "GetICloudCDNDomainByName")
}
func NewBaseProvider(factory ICloudProviderFactory) SBaseProvider {
return SBaseProvider{factory: factory}
}
+2 -1
View File
@@ -60,7 +60,8 @@ const (
CLOUD_CAPABILITY_MONGO_DB = "mongodb" // MongoDB
CLOUD_CAPABILITY_ES = "es" // ElasticSearch
CLOUD_CAPABILITY_KAFKA = "kafka" // Kafka
CLOUD_CAPABILITY_APP = "app" //App
CLOUD_CAPABILITY_APP = "app" // App
CLOUD_CAPABILITY_CDN = "cdn" // CDN
)
const (
+9
View File
@@ -1497,3 +1497,12 @@ type ICloudNatSku interface {
GetPrepaidStatus() string
GetPostpaidStatus() string
}
type ICloudCDNDomain interface {
ICloudEnabledResource
GetArea() string
GetServiceType() string
Delete() error
}
+391
View File
@@ -0,0 +1,391 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCDNDomainManager struct {
db.SEnabledStatusInfrasResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SDeletePreventableResourceBaseManager
}
var CDNDomainManager *SCDNDomainManager
func init() {
CDNDomainManager = &SCDNDomainManager{
SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
SCDNDomain{},
"cdn_domains_tbl",
"cdn_domain",
"cdn_domains",
),
}
CDNDomainManager.SetVirtualObject(CDNDomainManager)
}
type SCDNDomain struct {
db.SEnabledStatusInfrasResourceBase
db.SExternalizedResourceBase
SDeletePreventableResourceBase
SManagedResourceBase
// 服务类别
ServiceType string `list:"user" width:"32" update:"admin" create:"admin_required"`
// 加速区域
Area string `list:"user" width:"32" update:"admin" create:"admin_required"`
}
func (manager *SCDNDomainManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudproviderManager},
}
}
func (manager *SCDNDomainManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CDNDomainDetails {
rows := make([]api.CDNDomainDetails, len(objs))
stdRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.CDNDomainDetails{
EnabledStatusInfrasResourceBaseDetails: stdRows[i],
ManagedResourceInfo: managerRows[i],
}
}
return rows
}
func (self *SCloudprovider) GetCDNDomains() ([]SCDNDomain, error) {
q := CDNDomainManager.Query().Equals("manager_id", self.Id)
domains := []SCDNDomain{}
err := db.FetchModelObjects(CDNDomainManager, q, &domains)
if err != nil {
return nil, err
}
return domains, nil
}
func (self *SCloudprovider) SyncCDNDomains(ctx context.Context, userCred mcclient.TokenCredential, exts []cloudprovider.ICloudCDNDomain) compare.SyncResult {
lockman.LockRawObject(ctx, CDNDomainManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, CDNDomainManager.Keyword(), self.Id)
result := compare.SyncResult{}
dbDomains, err := self.GetCDNDomains()
if err != nil {
result.Error(err)
return result
}
removed := make([]SCDNDomain, 0)
commondb := make([]SCDNDomain, 0)
commonext := make([]cloudprovider.ICloudCDNDomain, 0)
added := make([]cloudprovider.ICloudCDNDomain, 0)
err = compare.CompareSets(dbDomains, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].syncRemoveCloudCDNDomain(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].SyncWithCloudCDNDomain(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i += 1 {
_, err := self.newFromCloudCDNDomain(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SCDNDomain) syncRemoveCloudCDNDomain(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
self.DeletePreventionOff(self, userCred)
err := self.ValidateDeleteCondition(ctx)
if err != nil {
return errors.Wrapf(err, "ValidateDeleteCondition")
}
return self.RealDelete(ctx, userCred)
}
func (self *SCDNDomain) GetICloudCDNDomain() (cloudprovider.ICloudCDNDomain, error) {
manager := self.GetCloudprovider()
if manager == nil {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetCloudprovider")
}
provider, err := manager.GetProvider()
if err != nil {
return nil, errors.Wrapf(err, "GetProvider")
}
return provider.GetICloudCDNDomainByName(self.Name)
}
func (self *SCDNDomain) SyncWithCloudCDNDomain(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudCDNDomain) error {
diff, err := db.UpdateWithLock(ctx, self, func() error {
self.Name = ext.GetName()
self.Status = ext.GetStatus()
self.Area = ext.GetArea()
self.ServiceType = ext.GetServiceType()
return nil
})
if err != nil {
return err
}
db.OpsLog.LogSyncUpdate(self, diff, userCred)
syncMetadata(ctx, userCred, self, ext)
if provider := self.GetCloudprovider(); provider != nil {
SyncCloudDomain(userCred, self, provider.GetOwnerId())
self.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
}
return nil
}
func (self *SCloudprovider) newFromCloudCDNDomain(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudCDNDomain) (*SCDNDomain, error) {
domain := SCDNDomain{}
domain.SetModelManager(CDNDomainManager, &domain)
domain.ExternalId = ext.GetGlobalId()
domain.ManagerId = self.Id
domain.Name = ext.GetName()
domain.Status = ext.GetStatus()
domain.Area = ext.GetArea()
domain.ServiceType = ext.GetServiceType()
err := CDNDomainManager.TableSpec().Insert(ctx, &domain)
if err != nil {
return nil, err
}
syncMetadata(ctx, userCred, &domain, ext)
SyncCloudDomain(userCred, &domain, self.GetOwnerId())
domain.SyncShareState(ctx, userCred, self.getAccountShareInfo())
db.OpsLog.LogEvent(&domain, db.ACT_CREATE, domain.GetShortDesc(ctx), userCred)
return &domain, nil
}
func (manager *SCDNDomainManager) ValidateCreateData(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject,
input api.CDNDomainCreateInput,
) (api.CDNDomainCreateInput, error) {
return input, nil
}
func (self *SCDNDomain) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SCDNDomain) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
var err = func() error {
task, err := taskman.TaskManager.NewTask(ctx, "CDNDomainDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
return task.ScheduleRun(nil)
}()
if err != nil {
self.SetStatus(userCred, api.CDN_DOMAIN_STATUS_DELETE_FAILED, err.Error())
return nil
}
return nil
}
func (self *SCDNDomain) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
self.SetStatus(userCred, api.CDN_DOMAIN_STATUS_DELETING, "")
return nil
}
func (self *SCDNDomain) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
}
// 列出CDN域名
func (manager *SCDNDomainManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.CDNDomainListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SCDNDomainManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
switch field {
default:
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
}
return q, httperrors.ErrNotFound
}
func (manager *SCDNDomainManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.CDNDomainListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SCDNDomainManager) totalCount(
ownerId mcclient.IIdentityProvider,
scope rbacutils.TRbacScope,
rangeObjs []db.IStandaloneModel,
providers []string,
brands []string,
cloudEnv string,
) int {
q := CDNDomainManager.Query()
if scope != rbacutils.ScopeSystem && ownerId != nil {
q = q.Equals("domain_id", ownerId.GetProjectDomainId())
}
q = CloudProviderFilter(q, q.Field("manager_id"), providers, brands, cloudEnv)
q = RangeObjectsFilter(q, rangeObjs, q.Field("cloudregion_id"), nil, q.Field("manager_id"), nil, nil)
cnt, _ := q.CountWithError()
return cnt
}
func (manager *SCDNDomainManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SCDNDomain) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "syncstatus")
}
// 同步域名状态
func (self *SCDNDomain) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.NatGatewaySyncstatusInput) (jsonutils.JSONObject, error) {
var openTask = true
count, err := taskman.TaskManager.QueryTasksOfObject(self, time.Now().Add(-3*time.Minute), &openTask).CountWithError()
if err != nil {
return nil, err
}
if count > 0 {
return nil, httperrors.NewBadRequestError("CDN domain has %d task active, can't sync status", count)
}
return nil, self.StartSyncstatus(ctx, userCred, "")
}
func (self *SCDNDomain) StartSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
return StartResourceSyncStatusTask(ctx, userCred, self, "CDNDomainSyncstatusTask", parentTaskId)
}
+2
View File
@@ -234,6 +234,8 @@ func InitHandlers(app *appsrv.Application) {
models.AppManager,
models.AppEnvironmentManager,
models.CDNDomainManager,
} {
db.RegisterModelManager(manager)
handler := db.NewModelHandler(manager)
@@ -0,0 +1,72 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type CDNDomainDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(CDNDomainDeleteTask{})
}
func (self *CDNDomainDeleteTask) taskFailed(ctx context.Context, domain *models.SCDNDomain, err error) {
domain.SetStatus(self.UserCred, api.CDN_DOMAIN_STATUS_DELETE_FAILED, err.Error())
db.OpsLog.LogEvent(domain, db.ACT_DELOCATE_FAIL, err.Error(), self.UserCred)
logclient.AddActionLogWithStartable(self, domain, logclient.ACT_DELETE, err.Error(), self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *CDNDomainDeleteTask) taskComplete(ctx context.Context, domain *models.SCDNDomain) {
domain.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
func (self *CDNDomainDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
domain := obj.(*models.SCDNDomain)
iDomain, err := domain.GetICloudCDNDomain()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound || errors.Cause(err) == sql.ErrNoRows {
self.taskComplete(ctx, domain)
return
}
self.taskFailed(ctx, domain, errors.Wrapf(err, "GetICloudCDNDomain"))
return
}
err = iDomain.Delete()
if err != nil {
self.taskFailed(ctx, domain, errors.Wrapf(err, "Delete"))
return
}
self.taskComplete(ctx, domain)
}
@@ -0,0 +1,61 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type CDNDomainSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(CDNDomainSyncstatusTask{})
}
func (self *CDNDomainSyncstatusTask) taskFailed(ctx context.Context, domain *models.SCDNDomain, err error) {
domain.SetStatus(self.GetUserCred(), api.CDN_DOMAIN_STATUS_UNKNOWN, err.Error())
db.OpsLog.LogEvent(domain, db.ACT_SYNC_STATUS, domain.GetShortDesc(ctx), self.GetUserCred())
logclient.AddActionLogWithContext(ctx, domain, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *CDNDomainSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
domain := obj.(*models.SCDNDomain)
iDomain, err := domain.GetICloudCDNDomain()
if err != nil {
self.taskFailed(ctx, domain, errors.Wrapf(err, "GetICloudCDNDomain"))
return
}
err = domain.SyncWithCloudCDNDomain(ctx, self.GetUserCred(), iDomain)
if err != nil {
self.taskFailed(ctx, domain, errors.Wrapf(err, "SyncWithCloudCDNDomain"))
return
}
self.SetStageComplete(ctx, nil)
}
@@ -88,6 +88,11 @@ func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStand
notes := fmt.Sprintf("SyncQuotas for provider %s result: %s", provider.Name, msg)
log.Infof(notes)
}
domains, err := p.GetICloudCDNDomains()
if err == nil {
result := provider.SyncCDNDomains(ctx, self.GetUserCred(), domains)
log.Infof("Sync CDN for provider %s result: %s", provider.Name, result.Result())
}
return nil, nil
})
}
+36
View File
@@ -0,0 +1,36 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
)
type SCDNDomainManager struct {
modulebase.ResourceManager
}
var (
CDNDomains SCDNDomainManager
)
func init() {
CDNDomains = SCDNDomainManager{
NewComputeManager("cdn_domain", "cdn_domains",
[]string{},
[]string{}),
}
registerCompute(&CDNDomains)
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type CDNDomainListOptions struct {
options.BaseListOptions
}
func (opts *CDNDomainListOptions) Params() (jsonutils.JSONObject, error) {
return options.StructToParams(opts)
}
+81 -5
View File
@@ -18,8 +18,10 @@ import (
"fmt"
"strconv"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SCdnOrigin struct {
@@ -32,7 +34,13 @@ type SCdnOrigin struct {
BackupOriginType interface{} `json:"BackupOriginType"`
BackupServerName interface{} `json:"BackupServerName"`
}
type SCdnDomain struct {
multicloud.SResourceBase
multicloud.QcloudTags
client *SQcloudClient
Area string `json:"Area"`
Cname string `json:"Cname"`
CreateTime string `json:"CreateTime"`
@@ -46,12 +54,80 @@ type SCdnDomain struct {
Status string `json:"Status"`
UpdateTime string `json:"UpdateTime"`
}
func (self *SCdnDomain) GetName() string {
return self.Domain
}
func (self *SCdnDomain) GetGlobalId() string {
return self.Domain
}
func (self *SCdnDomain) GetId() string {
return self.Domain
}
func (self *SCdnDomain) GetStatus() string {
return self.Status
}
func (self *SCdnDomain) GetEnabled() bool {
return self.Disable == "normal"
}
func (self *SCdnDomain) GetArea() string {
return self.Area
}
func (self *SCdnDomain) GetServiceType() string {
return self.ServiceType
}
func (self *SCdnDomain) Delete() error {
return self.client.DeleteCdnDomain(self.Domain)
}
func (self *SQcloudClient) DeleteCdnDomain(domain string) error {
params := map[string]string{
"Domain": domain,
}
_, err := self.cdnRequest("DeleteCdnDomain", params)
return errors.Wrapf(err, "DeleteCdnDomain")
}
type SDomains struct {
RequestID string `json:"RequestId"`
Domains []SCdnDomain `json:"Domains"`
TotalNumber int `json:"TotalNumber"`
}
func (self *SQcloudClient) GetICloudCDNDomains() ([]cloudprovider.ICloudCDNDomain, error) {
cdns, err := self.DescribeAllCdnDomains(nil, nil, "")
if err != nil {
return nil, err
}
ret := []cloudprovider.ICloudCDNDomain{}
for i := range cdns {
cdns[i].client = self
ret = append(ret, &cdns[i])
}
return ret, nil
}
func (self *SQcloudClient) GetICloudCDNDomainByName(name string) (cloudprovider.ICloudCDNDomain, error) {
domains, _, err := self.DescribeCdnDomains([]string{name}, nil, "", 0, 1)
if err != nil {
return nil, errors.Wrapf(err, "DescribeCdnDomains")
}
for i := range domains {
if domains[i].Domain == name {
domains[i].client = self
return &domains[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, name)
}
func (client *SQcloudClient) AddCdnDomain(domain string, originType string, origins []string, cosPrivateAccess string) error {
params := map[string]string{}
params["Domain"] = domain
@@ -63,7 +139,7 @@ func (client *SQcloudClient) AddCdnDomain(domain string, originType string, orig
params["Origin.CosPrivateAccess"] = cosPrivateAccess
_, err := client.cdnRequest("AddCdnDomain", params)
if err != nil {
return errors.Wrapf(err, ` client.cdnRequest("AddCdnDomain", %s)`, jsonutils.Marshal(params).String())
return errors.Wrapf(err, `AddCdnDomain %s`, params)
}
return nil
}
@@ -96,12 +172,12 @@ func (client *SQcloudClient) DescribeCdnDomains(domains, origins []string, domai
resp, err := client.cdnRequest("DescribeDomains", params)
if err != nil {
return nil, 0, errors.Wrapf(err, "client.DescribeDomains(DescribeDomains, %s)", jsonutils.Marshal(params).String())
return nil, 0, errors.Wrapf(err, "DescribeDomains %s", params)
}
cdnDomains := []SCdnDomain{}
err = resp.Unmarshal(&cdnDomains, "Domains")
if err != nil {
return nil, 0, errors.Wrapf(err, "%s.Unmarshal(records)", jsonutils.Marshal(resp).String())
return nil, 0, errors.Wrapf(err, "resp.Unmarshal")
}
totalcount, _ := resp.Float("TotalNumber")
return cdnDomains, int(totalcount), nil
@@ -112,7 +188,7 @@ func (client *SQcloudClient) DescribeAllCdnDomains(domains, origins []string, do
for {
part, total, err := client.DescribeCdnDomains(domains, origins, domainType, len(cdnDomains), 50)
if err != nil {
return nil, errors.Wrap(err, "client.DescribeCdnDomains(domains, origins, len(cdnDomains), 50)")
return nil, errors.Wrap(err, "DescribeCdnDomains")
}
cdnDomains = append(cdnDomains, part...)
if len(cdnDomains) >= total {
@@ -441,3 +441,11 @@ func (self *SQcloudProvider) GetICloudInterVpcNetworkById(id string) (cloudprovi
func (self *SQcloudProvider) CreateICloudInterVpcNetwork(opts *cloudprovider.SInterVpcNetworkCreateOptions) (cloudprovider.ICloudInterVpcNetwork, error) {
return self.client.CreateICloudInterVpcNetwork(opts)
}
func (self *SQcloudProvider) GetICloudCDNDomains() ([]cloudprovider.ICloudCDNDomain, error) {
return self.client.GetICloudCDNDomains()
}
func (self *SQcloudProvider) GetICloudCDNDomainByName(name string) (cloudprovider.ICloudCDNDomain, error) {
return self.client.GetICloudCDNDomainByName(name)
}
+1 -2
View File
@@ -1089,8 +1089,6 @@ func (self *SQcloudClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_LOADBALANCER,
cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
cloudprovider.CLOUD_CAPABILITY_RDS,
// cloudprovider.CLOUD_CAPABILITY_CACHE,
// cloudprovider.CLOUD_CAPABILITY_RDS,
cloudprovider.CLOUD_CAPABILITY_CACHE,
cloudprovider.CLOUD_CAPABILITY_EVENT,
cloudprovider.CLOUD_CAPABILITY_CLOUDID,
@@ -1101,6 +1099,7 @@ func (self *SQcloudClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_MONGO_DB,
cloudprovider.CLOUD_CAPABILITY_ES,
cloudprovider.CLOUD_CAPABILITY_KAFKA,
cloudprovider.CLOUD_CAPABILITY_CDN,
}
return caps
}