mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
snapshotpolicy list create delete apply cancel finish except that disk sync snapshot policy
add copyright fix some imprefection fix test file
This commit is contained in:
@@ -42,8 +42,10 @@ const (
|
||||
DISK_POST_MIGRATE = "post_migrate"
|
||||
DISK_MIGRATING = "migrating"
|
||||
|
||||
DISK_START_SNAPSHOT = "start_snapshot"
|
||||
DISK_SNAPSHOTING = "snapshoting"
|
||||
DISK_START_SNAPSHOT = "start_snapshot"
|
||||
DISK_SNAPSHOTING = "snapshoting"
|
||||
DISK_APPLY_SNAPSHOT_FAIL = "apply_snapshot_failed"
|
||||
DISK_CALCEL_SNAPSHOT_FAIL = "cancel_snapshot_failed"
|
||||
|
||||
DISK_TYPE_SYS = "sys"
|
||||
DISK_TYPE_SWAP = "swap"
|
||||
|
||||
@@ -48,3 +48,18 @@ type SSnapshotPolicyCreateInput struct {
|
||||
RepeatWeekdays []int `json:"repeat_weekdays"`
|
||||
TimePoints []int `json:"time_points"`
|
||||
}
|
||||
|
||||
type SSnapshotPolicyCreateInternalInput struct {
|
||||
apis.Meta
|
||||
|
||||
Name string
|
||||
ProjectId string
|
||||
DomainId string
|
||||
|
||||
ManagerId string
|
||||
CloudregionId string
|
||||
|
||||
RetentionDays int
|
||||
RepeatWeekdays uint8
|
||||
TimePoints uint32
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
|
||||
@@ -80,8 +80,8 @@ type ICloudRegion interface {
|
||||
|
||||
CreateSnapshotPolicy(*SnapshotPolicyInput) (string, error)
|
||||
DeleteSnapshotPolicy(string) error
|
||||
ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskIds []string) error
|
||||
CancelSnapshotPolicyToDisks(diskIds []string) error
|
||||
ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error
|
||||
CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error
|
||||
GetISnapshotPolicies() ([]ICloudSnapshotPolicy, error)
|
||||
GetISnapshotPolicyById(snapshotPolicyId string) (ICloudSnapshotPolicy, error)
|
||||
|
||||
@@ -373,7 +373,7 @@ type ICloudDisk interface {
|
||||
GetISnapshot(idStr string) (ICloudSnapshot, error)
|
||||
GetISnapshots() ([]ICloudSnapshot, error)
|
||||
|
||||
GetExtSnapshotPolicyId() string
|
||||
GetExtSnapshotPolicyIds() []string
|
||||
|
||||
Resize(ctx context.Context, newSizeMB int64) error
|
||||
Reset(ctx context.Context, snapshotId string) (string, error)
|
||||
@@ -393,6 +393,7 @@ type ICloudSnapshot interface {
|
||||
type ICloudSnapshotPolicy interface {
|
||||
IVirtualResource
|
||||
|
||||
IsActivated() bool
|
||||
GetRetentionDays() int
|
||||
GetRepeatWeekdays() ([]int, error)
|
||||
GetTimePoints() ([]int, error)
|
||||
|
||||
@@ -40,7 +40,6 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/options"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
@@ -95,9 +94,6 @@ type SDisk struct {
|
||||
DiskType string `width:"32" charset:"ascii" nullable:"true" list:"user" update:"admin"` // Column(VARCHAR(32, charset='ascii'), nullable=True)
|
||||
// # is persistent
|
||||
Nonpersistent bool `default:"false" list:"user"` // Column(Boolean, default=False)
|
||||
|
||||
AutoSnapshot bool `default:"false" nullable:"true" get:"user" update:"user"`
|
||||
SnapshotPolicyId string `width:"128" charset:"ascii" nullable:"true" get:"user" list:"user" update:"user" create:"optional"`
|
||||
}
|
||||
|
||||
func (manager *SDiskManager) GetContextManagers() [][]db.IModelManager {
|
||||
@@ -759,51 +755,6 @@ func (self *SDisk) PerformResize(ctx context.Context, userCred mcclient.TokenCre
|
||||
return nil, self.StartDiskResizeTask(ctx, userCred, int64(sizeMb), "", &pendingUsage, guest)
|
||||
}
|
||||
|
||||
func (self *SDisk) AllowPerformApplySnapshotPolicy(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject) bool {
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "apply-snapshot-policy")
|
||||
}
|
||||
|
||||
func (self *SDisk) PerformApplySnapshotPolicy(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject, data jsonutils.JSONObject,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
spv := validators.NewModelIdOrNameValidator("snapshotpolicy", "snapshotpolicy", userCred)
|
||||
if err := spv.Validate(data.(*jsonutils.JSONDict)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp := spv.Model.(*SSnapshotPolicy)
|
||||
return nil, sp.StartApplySnapshotPolicyToDisks(ctx, userCred, []string{self.Id})
|
||||
}
|
||||
|
||||
func (self *SDisk) AllowPerformCancelSnapshotPolicy(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject) bool {
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "cancel-snapshot-policy")
|
||||
}
|
||||
|
||||
func (self *SDisk) PerformCancelSnapshotPolicy(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject, data jsonutils.JSONObject,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
if len(self.SnapshotPolicyId) == 0 {
|
||||
return nil, httperrors.NewBadRequestError("Disk dosen't apply any snapshot policy")
|
||||
}
|
||||
return nil, self.StartCancelSnapshotPolicyToDisks(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SDisk) StartCancelSnapshotPolicyToDisks(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
if task, err := taskman.TaskManager.NewTask(ctx, "SnapshotPolicyCancelTask", self, userCred, nil, "", "", nil); err != nil {
|
||||
return err
|
||||
} else {
|
||||
task.ScheduleRun(nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
|
||||
storage := self.GetStorage()
|
||||
if storage == nil {
|
||||
@@ -1210,6 +1161,7 @@ func (self *SDisk) syncRemoveCloudDisk(ctx context.Context, userCred mcclient.To
|
||||
self.SetStatus(userCred, api.DISK_UNKNOWN, "missing original disk after sync")
|
||||
return err
|
||||
}
|
||||
// todo detach joint modle about snapshotpolicy and disk
|
||||
return self.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
@@ -1256,13 +1208,7 @@ func (self *SDisk) syncWithCloudDisk(ctx context.Context, userCred mcclient.Toke
|
||||
self.CreatedAt = createdAt
|
||||
}
|
||||
|
||||
extPolicyId := extDisk.GetExtSnapshotPolicyId()
|
||||
if len(extPolicyId) > 0 {
|
||||
isp, _ := db.FetchByExternalId(SnapshotPolicyManager, extPolicyId)
|
||||
if isp != nil {
|
||||
self.SnapshotPolicyId = isp.GetId()
|
||||
}
|
||||
}
|
||||
// todo sync disk's snapshotpolicy
|
||||
|
||||
return nil
|
||||
})
|
||||
@@ -1311,13 +1257,7 @@ func (manager *SDiskManager) newFromCloudDisk(ctx context.Context, userCred mccl
|
||||
disk.CreatedAt = createAt
|
||||
}
|
||||
|
||||
extPolicyId := extDisk.GetExtSnapshotPolicyId()
|
||||
if len(extPolicyId) > 0 {
|
||||
isp, _ := db.FetchByExternalId(SnapshotPolicyManager, extPolicyId)
|
||||
if isp != nil {
|
||||
disk.SnapshotPolicyId = isp.GetId()
|
||||
}
|
||||
}
|
||||
// todo create new joint model about snapshotpolicy and disk
|
||||
|
||||
err = manager.TableSpec().Insert(&disk)
|
||||
if err != nil {
|
||||
@@ -1717,14 +1657,6 @@ func (self *SDisk) GetAttachedGuests() []SGuest {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SDisk) SetSnapshotPolicy(policyId string) error {
|
||||
_, err := db.Update(self, func() error {
|
||||
self.SnapshotPolicyId = policyId
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SDisk) SetDiskReady(ctx context.Context, userCred mcclient.TokenCredential, reason string) {
|
||||
self.SetStatus(userCred, api.DISK_READY, reason)
|
||||
guests := self.GetAttachedGuests()
|
||||
|
||||
@@ -82,8 +82,9 @@ type IRegionDriver interface {
|
||||
ValidateCreateSnapshotPolicyData(ctx context.Context, userCred mcclient.TokenCredential, data *compute.SSnapshotPolicyCreateInput) error
|
||||
RequestCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, task taskman.ITask) error
|
||||
RequestDeleteSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, task taskman.ITask) error
|
||||
RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, task taskman.ITask, diskIds []string) error
|
||||
RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region cloudprovider.ICloudRegion, task taskman.ITask, diskIds []string) error
|
||||
|
||||
// Region Driver Snapshot Policy joint Disk Apis
|
||||
ValidateCreateSnapshopolicyDiskData(ctx context.Context, userCred mcclient.TokenCredential, diskID string) error
|
||||
|
||||
// Region Driver Snapshot Apis
|
||||
ValidateSnapshotDelete(ctx context.Context, snapshot *SSnapshot) error
|
||||
@@ -93,6 +94,8 @@ type IRegionDriver interface {
|
||||
SnapshotIsOutOfChain(disk *SDisk) bool
|
||||
GetDiskResetParams(snapshot *SSnapshot) *jsonutils.JSONDict
|
||||
OnDiskReset(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshot *SSnapshot, data jsonutils.JSONObject) error
|
||||
RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, task taskman.ITask, diskId string) error
|
||||
RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, task taskman.ITask, diskId string) error
|
||||
}
|
||||
|
||||
var regionDrivers map[string]IRegionDriver
|
||||
|
||||
@@ -17,7 +17,6 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
@@ -31,6 +30,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/bitmap"
|
||||
)
|
||||
|
||||
type SSnapshotPolicyManager struct {
|
||||
@@ -46,9 +46,9 @@ type SSnapshotPolicy struct {
|
||||
|
||||
RetentionDays int `nullable:"false" list:"user" get:"user" create:"required"`
|
||||
|
||||
// {repeat_weekdays: [1,2,3,4,5,6,7], time_points: [0...23]}
|
||||
RepeatWeekdays string `charset:"utf8" list:"user" get:"user" create:"required"`
|
||||
TimePoints string `charset:"utf8" list:"user" get:"user" create:"required"`
|
||||
RepeatWeekdays uint8 `charset:"utf8" create:"required"`
|
||||
TimePoints uint32 `charset:"utf8" create:"required"`
|
||||
IsActivated bool `list:"user" get:"user" create:"optional" default:"true"`
|
||||
}
|
||||
|
||||
var SnapshotPolicyManager *SSnapshotPolicyManager
|
||||
@@ -97,10 +97,31 @@ func (manager *SSnapshotPolicyManager) ValidateCreateData(ctx context.Context, u
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = input.JSON(input)
|
||||
internalInput := manager.sSnapshotPolicyCreateInputToInternal(input)
|
||||
data = internalInput.JSON(internalInput)
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (manager *SSnapshotPolicyManager) sSnapshotPolicyCreateInputToInternal(input *api.SSnapshotPolicyCreateInput) *api.SSnapshotPolicyCreateInternalInput {
|
||||
ret := api.SSnapshotPolicyCreateInternalInput{
|
||||
Meta: input.Meta,
|
||||
Name: input.Name,
|
||||
ProjectId: input.ProjectId,
|
||||
DomainId: input.DomainId,
|
||||
ManagerId: input.ManagerId,
|
||||
CloudregionId: input.CloudregionId,
|
||||
RetentionDays: input.RetentionDays,
|
||||
}
|
||||
|
||||
ret.RepeatWeekdays = manager.RepeatWeekdaysParseIntArray(input.RepeatWeekdays)
|
||||
ret.TimePoints = manager.TimePointsParseIntArray(input.TimePoints)
|
||||
return &ret
|
||||
}
|
||||
|
||||
func (manager *SSnapshotPolicyManager) sSnapshotPolicyCreateInputFromInternal(input *api.SSnapshotPolicyCreateInternalInput) *api.SSnapshotPolicyCreateInput {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
self.StartCreateSnapshotPolicy(ctx, userCred, ownerId, query, data)
|
||||
}
|
||||
@@ -131,9 +152,26 @@ func (self *SSnapshotPolicy) StartSnapshotPolicyDeleteTask(ctx context.Context,
|
||||
func (self *SSnapshotPolicy) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
ret := self.SCloudregionResourceBase.GetCustomizeColumns(ctx, userCred, query)
|
||||
ret.Update(self.SVirtualResourceBase.GetCustomizeColumns(ctx, userCred, query))
|
||||
|
||||
// more
|
||||
weekdays := SnapshotPolicyManager.RepeatWeekdaysToIntArray(self.RepeatWeekdays)
|
||||
timePoints := SnapshotPolicyManager.TimePointsToIntArray(self.TimePoints)
|
||||
ret.Add(jsonutils.Marshal(weekdays), "repeat_weekdays")
|
||||
ret.Add(jsonutils.Marshal(timePoints), "time_points")
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*jsonutils.JSONDict, error) {
|
||||
ret := jsonutils.NewDict()
|
||||
|
||||
// more
|
||||
weekdays := SnapshotPolicyManager.RepeatWeekdaysToIntArray(self.RepeatWeekdays)
|
||||
timePoints := SnapshotPolicyManager.TimePointsToIntArray(self.TimePoints)
|
||||
ret.Add(jsonutils.Marshal(weekdays), "repeat_weekdays")
|
||||
ret.Add(jsonutils.Marshal(timePoints), "time_points")
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetIRegion() (cloudprovider.ICloudRegion, error) {
|
||||
provider, err := self.GetDriver()
|
||||
if err != nil {
|
||||
@@ -146,34 +184,25 @@ func (self *SSnapshotPolicy) GetIRegion() (cloudprovider.ICloudRegion, error) {
|
||||
return provider.GetIRegionById(region.ExternalId)
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GenerateCreateSpParams() (*cloudprovider.SnapshotPolicyInput, error) {
|
||||
idays, err := jsonutils.ParseString(self.RepeatWeekdays)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("SnapshotPolicy %s Parse repeat weekdays error %s", self.Name, err)
|
||||
}
|
||||
weekdays := idays.(*jsonutils.JSONArray)
|
||||
intWeekdays := make([]int, weekdays.Length())
|
||||
for i, v := range weekdays.Value() {
|
||||
t, err := v.Int()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse weekdays error %s", weekdays)
|
||||
}
|
||||
intWeekdays[i] = int(t)
|
||||
}
|
||||
func (self *SSnapshotPolicyManager) RepeatWeekdaysParseIntArray(nums []int) uint8 {
|
||||
return uint8(bitmap.IntArray2Uint(nums))
|
||||
}
|
||||
|
||||
idays, err = jsonutils.ParseString(self.TimePoints)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("SnapshotPolicy %s Parse time points error %s", self.Name, err)
|
||||
}
|
||||
timePoints := idays.(*jsonutils.JSONArray)
|
||||
intTimePoints := make([]int, timePoints.Length())
|
||||
for i, v := range timePoints.Value() {
|
||||
t, err := v.Int()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse weekdays error %s", timePoints)
|
||||
}
|
||||
intTimePoints[i] = int(t)
|
||||
}
|
||||
func (self *SSnapshotPolicyManager) RepeatWeekdaysToIntArray(n uint8) []int {
|
||||
return bitmap.Uint2IntArray(uint32(n))
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicyManager) TimePointsParseIntArray(nums []int) uint32 {
|
||||
return bitmap.IntArray2Uint(nums)
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicyManager) TimePointsToIntArray(n uint32) []int {
|
||||
return bitmap.Uint2IntArray(n)
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GenerateCreateSpParams() (*cloudprovider.SnapshotPolicyInput, error) {
|
||||
intWeekdays := SnapshotPolicyManager.RepeatWeekdaysToIntArray(self.RepeatWeekdays)
|
||||
intTimePoints := SnapshotPolicyManager.TimePointsToIntArray(self.TimePoints)
|
||||
|
||||
return &cloudprovider.SnapshotPolicyInput{
|
||||
RetentionDays: self.RetentionDays,
|
||||
@@ -271,19 +300,20 @@ func (self *SSnapshotPolicy) SyncWithCloudSnapshotPolicy(ctx context.Context, us
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
self.RepeatWeekdays = jsonutils.Marshal(arw).String()
|
||||
self.RepeatWeekdays = SnapshotPolicyManager.RepeatWeekdaysParseIntArray(arw)
|
||||
|
||||
atp, err := ext.GetTimePoints()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
self.TimePoints = jsonutils.Marshal(atp).String()
|
||||
self.TimePoints = SnapshotPolicyManager.TimePointsParseIntArray(atp)
|
||||
return nil
|
||||
})
|
||||
db.OpsLog.LogSyncUpdate(self, diff, userCred)
|
||||
SyncCloudProject(userCred, self, ownerId, ext, self.ManagerId)
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SSnapshotPolicyManager) newFromCloudSnapshotPolicy(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
ext cloudprovider.ICloudSnapshotPolicy, region *SCloudregion,
|
||||
@@ -307,12 +337,12 @@ func (manager *SSnapshotPolicyManager) newFromCloudSnapshotPolicy(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
snapshotPolicy.RepeatWeekdays = jsonutils.Marshal(arw).String()
|
||||
snapshotPolicy.RepeatWeekdays = SnapshotPolicyManager.RepeatWeekdaysParseIntArray(arw)
|
||||
atp, err := ext.GetTimePoints()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
snapshotPolicy.TimePoints = jsonutils.Marshal(atp).String()
|
||||
snapshotPolicy.TimePoints = SnapshotPolicyManager.TimePointsParseIntArray(atp)
|
||||
|
||||
err = manager.TableSpec().Insert(&snapshotPolicy)
|
||||
if err != nil {
|
||||
@@ -354,24 +384,6 @@ func (self *SSnapshotPolicy) StartApplySnapshotPolicyToDisks(ctx context.Context
|
||||
return nil
|
||||
}
|
||||
|
||||
// func (self *SSnapshotPolicy) AllowPerformCancelToDisks(ctx context.Context,
|
||||
// userCred mcclient.TokenCredential,
|
||||
// query jsonutils.JSONObject,
|
||||
// data jsonutils.JSONObject) bool {
|
||||
// return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "apply-to-disks")
|
||||
// }
|
||||
|
||||
// func (self *SSnapshotPolicy) PerformCancelToDisks(
|
||||
// ctx context.Context, userCred mcclient.TokenCredential,
|
||||
// query jsonutils.JSONObject, data jsonutils.JSONObject,
|
||||
// ) (jsonutils.JSONObject, error) {
|
||||
// diskIds, err := self.preCheck(ctx, userCred, query, data)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return nil, self.StartCancelSnapshotPolicyToDisks(ctx, userCred, diskIds)
|
||||
// }
|
||||
|
||||
func (self *SSnapshotPolicy) preCheck(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject, data jsonutils.JSONObject,
|
||||
@@ -404,4 +416,4 @@ func (self *SSnapshotPolicy) preCheck(
|
||||
return nil, httperrors.NewNotFoundError("Disks %v not found", notFoundDisks)
|
||||
}
|
||||
return diskIds, nil
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// 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"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SSnapshotPolicyDiskManager struct {
|
||||
db.SVirtualJointResourceBaseManager
|
||||
}
|
||||
|
||||
func (manager *SSnapshotPolicyDiskManager) GetMasterFieldName() string {
|
||||
return "disk_id"
|
||||
}
|
||||
|
||||
func (manager *SSnapshotPolicyDiskManager) GetSlaveFieldName() string {
|
||||
return "snapshotpolicy_id"
|
||||
}
|
||||
|
||||
var SnapshotPolicyDiskManager *SSnapshotPolicyDiskManager
|
||||
|
||||
func init() {
|
||||
db.InitManager(func() {
|
||||
SnapshotPolicyDiskManager = &SSnapshotPolicyDiskManager{
|
||||
SVirtualJointResourceBaseManager: db.NewVirtualJointResourceBaseManager(
|
||||
SSnapshotPolicyDisk{},
|
||||
"snapshotpolicydisks_tbl",
|
||||
"snapshotpolicydisk",
|
||||
"snapshotpolicydisks",
|
||||
DiskManager,
|
||||
SnapshotPolicyManager,
|
||||
),
|
||||
}
|
||||
SnapshotPolicyDiskManager.SetVirtualObject(SnapshotPolicyDiskManager)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
type SSnapshotPolicyDisk struct {
|
||||
db.SVirtualJointResourceBase
|
||||
|
||||
SnapshotpolicyId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
|
||||
DiskId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicyDisk) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return db.DetachJoint(ctx, userCred, self)
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicyDiskManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
cloudregionV := validators.NewModelIdOrNameValidator("cloudregion", "cloudregion", ownerId)
|
||||
err := cloudregionV.Validate(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cloudregion := cloudregionV.Model.(*SCloudregion)
|
||||
diskId, _ := data.GetString(self.GetMasterManager().Keyword())
|
||||
err = cloudregion.GetDriver().ValidateCreateSnapshopolicyDiskData(ctx, userCred, diskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicyDiskManager) FetchAllSnapshotPolicyOfDisk(ctx context.Context, userCred mcclient.TokenCredential, diskID string) ([]SSnapshotPolicyDisk, error) {
|
||||
q := self.Query()
|
||||
q.Equals(self.GetMasterFieldName(), diskID)
|
||||
ret := make([]SSnapshotPolicyDisk, 0)
|
||||
err := db.FetchModelObjects(self, q, &ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicyDisk) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
diskID := self.DiskId
|
||||
model, err := DiskManager.FetchById(diskID)
|
||||
if err != nil {
|
||||
log.Errorf("Fetch disk by ID %s failed", diskID)
|
||||
}
|
||||
disk := model.(*SDisk)
|
||||
snapshotPolicyID := self.SnapshotpolicyId
|
||||
taskData := jsonutils.NewDict()
|
||||
taskData.Add(jsonutils.NewString(snapshotPolicyID), "snapshot_policy_id")
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "SnapshotPolicyApplyTask", disk, userCred, taskData, "", "", nil)
|
||||
if err != nil {
|
||||
log.Errorf("SnapshotPolicyApplyTask newTask error %s", err)
|
||||
} else {
|
||||
task.ScheduleRun(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicyDisk) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
diskID := self.DiskId
|
||||
model, err := DiskManager.FetchById(diskID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Fetch disk by ID %s failed", diskID)
|
||||
}
|
||||
disk := model.(*SDisk)
|
||||
snapshotPolicyID := self.SnapshotpolicyId
|
||||
taskData := jsonutils.NewDict()
|
||||
taskData.Add(jsonutils.NewString(snapshotPolicyID), "snapshot_policy_id")
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "SnapshotPolicyCancelTask", disk, userCred, taskData, "", "", nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "SnapshotPolicyCancelTask newTask error %s", err)
|
||||
} else {
|
||||
task.ScheduleRun(nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -823,27 +823,25 @@ func daysValidate(days []int, min, max int) ([]int, error) {
|
||||
return days, nil
|
||||
}
|
||||
|
||||
func (self *SAliyunRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context.Context, userCred mcclient.TokenCredential, diskID string) error {
|
||||
ret, err := models.SnapshotPolicyDiskManager.FetchAllSnapshotPolicyOfDisk(ctx, userCred, diskID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(ret) != 0 {
|
||||
return httperrors.NewBadRequestError("One disk could't attach two snapshot policy in aliyun; please detach last one first.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAliyunRegionDriver) ValidateCreateSnapshotPolicyData(ctx context.Context, userCred mcclient.TokenCredential, data *compute.SSnapshotPolicyCreateInput) error {
|
||||
var err error
|
||||
err := self.SManagedVirtualizationRegionDriver.ValidateCreateSnapshotPolicyData(ctx, userCred, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if data.RetentionDays < -1 || data.RetentionDays == 0 || data.RetentionDays > 65535 {
|
||||
return httperrors.NewInputParameterError("Retention days must in 1~65535 or -1")
|
||||
}
|
||||
|
||||
if len(data.RepeatWeekdays) == 0 {
|
||||
return httperrors.NewMissingParameterError("repeat_weekdays")
|
||||
}
|
||||
data.RepeatWeekdays, err = daysValidate(data.RepeatWeekdays, 1, 7)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
|
||||
if len(data.TimePoints) == 0 {
|
||||
return httperrors.NewInputParameterError("time_points")
|
||||
}
|
||||
data.TimePoints, err = daysValidate(data.TimePoints, 0, 23)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -138,11 +138,11 @@ func (self *SBaseRegionDriver) RequestDeleteSnapshotPolicy(ctx context.Context,
|
||||
return fmt.Errorf("Not Implement RequestDeleteSnapshotPolicy")
|
||||
}
|
||||
|
||||
func (self *SBaseRegionDriver) RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, task taskman.ITask, diskIds []string) error {
|
||||
func (self *SBaseRegionDriver) RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, task taskman.ITask, diskId string) error {
|
||||
return fmt.Errorf("Not Implement RequestApplySnapshotPolicy")
|
||||
}
|
||||
|
||||
func (self *SBaseRegionDriver) RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region cloudprovider.ICloudRegion, task taskman.ITask, diskIds []string) error {
|
||||
func (self *SBaseRegionDriver) RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, task taskman.ITask, diskId string) error {
|
||||
return fmt.Errorf("Not Implement RequestApplySnapshotPolicy")
|
||||
}
|
||||
|
||||
@@ -173,3 +173,7 @@ func (self *SBaseRegionDriver) GetDiskResetParams(snapshot *models.SSnapshot) *j
|
||||
func (self *SBaseRegionDriver) OnDiskReset(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, data *jsonutils.JSONObject) error {
|
||||
return fmt.Errorf("Not Implement OnDiskReset")
|
||||
}
|
||||
|
||||
func (self *SBaseRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context.Context, userCred mcclient.TokenCredential, diskID string) error {
|
||||
return fmt.Errorf("Not Implement ValidateCreateSnapshotpolicyDiskData")
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
@@ -1087,13 +1088,13 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteSnapshotPolicy(ctx
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizationRegionDriver) RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, task taskman.ITask, diskIds []string) error {
|
||||
func (self *SManagedVirtualizationRegionDriver) RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, task taskman.ITask, diskId string) error {
|
||||
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
|
||||
iRegion, err := sp.GetIRegion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = iRegion.ApplySnapshotPolicyToDisks(sp.GetExternalId(), diskIds)
|
||||
err = iRegion.ApplySnapshotPolicyToDisks(sp.GetExternalId(), diskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1102,9 +1103,13 @@ func (self *SManagedVirtualizationRegionDriver) RequestApplySnapshotPolicy(ctx c
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizationRegionDriver) RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region cloudprovider.ICloudRegion, task taskman.ITask, diskIds []string) error {
|
||||
func (self *SManagedVirtualizationRegionDriver) RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, task taskman.ITask, diskId string) error {
|
||||
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
|
||||
err := region.CancelSnapshotPolicyToDisks(diskIds)
|
||||
iRegion, err := sp.GetIRegion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = iRegion.CancelSnapshotPolicyToDisks(sp.GetExternalId(), diskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1183,3 +1188,28 @@ func (self *SManagedVirtualizationRegionDriver) OnDiskReset(ctx context.Context,
|
||||
}
|
||||
return iDisk.Refresh()
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizationRegionDriver) ValidateCreateSnapshotPolicyData(ctx context.Context, userCred mcclient.TokenCredential, data *compute.SSnapshotPolicyCreateInput) error {
|
||||
var err error
|
||||
|
||||
if len(data.RepeatWeekdays) == 0 {
|
||||
return httperrors.NewMissingParameterError("repeat_weekdays")
|
||||
}
|
||||
data.RepeatWeekdays, err = daysValidate(data.RepeatWeekdays, 1, 7)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
|
||||
if len(data.TimePoints) == 0 {
|
||||
return httperrors.NewInputParameterError("time_points")
|
||||
}
|
||||
data.TimePoints, err = daysValidate(data.TimePoints, 0, 23)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizationRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context.Context, userCred mcclient.TokenCredential, diskID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,16 +20,17 @@ import (
|
||||
"regexp"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
|
||||
"yunion.io/x/onecloud/pkg/util/rand"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
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/cloudcommon/validators"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/rand"
|
||||
)
|
||||
|
||||
type SQcloudRegionDriver struct {
|
||||
@@ -743,3 +744,14 @@ func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerBackendData(ctx conte
|
||||
data.Set("cloudregion_id", jsonutils.NewString(lb.CloudregionId))
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SQcloudRegionDriver) ValidateCreateSnapshotPolicyData(ctx context.Context, userCred mcclient.TokenCredential, data *compute.SSnapshotPolicyCreateInput) error {
|
||||
err := self.SManagedVirtualizationRegionDriver.ValidateCreateSnapshotPolicyData(ctx, userCred, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if data.RetentionDays < -1 || data.RetentionDays == 0 || data.RetentionDays > 65535 {
|
||||
return httperrors.NewInputParameterError("Retention days must in 1~65535 or -1")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -153,6 +153,7 @@ func InitHandlers(app *appsrv.Application) {
|
||||
models.CloudproviderRegionManager,
|
||||
models.DBInstanceNetworkManager,
|
||||
models.NetworkinterfacenetworkManager,
|
||||
models.SnapshotPolicyDiskManager,
|
||||
} {
|
||||
db.RegisterModelManager(manager)
|
||||
handler := db.NewJointModelHandler(manager)
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -81,86 +82,51 @@ type SnapshotPolicyApplyTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func (self *SnapshotPolicyApplyTask) taskFail(ctx context.Context, sp *models.SSnapshotPolicy, reason string) {
|
||||
stringIds, _ := getDiskIds(self)
|
||||
disks := make([]models.SDisk, 0)
|
||||
q := models.DiskManager.Query().In("id", stringIds)
|
||||
err := db.FetchModelObjects(models.DiskManager, q, &disks)
|
||||
if err == nil {
|
||||
for i := 0; i < len(disks); i++ {
|
||||
db.OpsLog.LogEvent(&disks[i], db.ACT_APPLY_SNAPSHOT_POLICY_FAILED, reason, self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, &disks[i], logclient.ACT_APPLY_SNAPSHOT_POLICY, reason, self.UserCred, false)
|
||||
}
|
||||
func (self *SnapshotPolicyApplyTask) taskFail(ctx context.Context, disk *models.SDisk, snapshotPolicyId, reason string) {
|
||||
jointModel, err := db.FetchJointByIds(models.SnapshotPolicyDiskManager, self.Id, snapshotPolicyId, jsonutils.JSONNull)
|
||||
if err != nil {
|
||||
log.Errorf("Fetch SnapshotPolicy %s Disk %s joint model failed, need to delete", self.Id, snapshotPolicyId)
|
||||
return
|
||||
}
|
||||
snapshotPolicyDisk := jointModel.(*models.SSnapshotPolicyDisk)
|
||||
err = snapshotPolicyDisk.Detach(ctx, self.UserCred)
|
||||
if err != nil {
|
||||
log.Errorf("Delete SnapshotPolicy %s Disk %s joint model failed, need to delete", self.Id, snapshotPolicyId)
|
||||
}
|
||||
|
||||
disk.SetStatus(self.UserCred, compute.DISK_APPLY_SNAPSHOT_FAIL, reason)
|
||||
db.OpsLog.LogEvent(disk, db.ACT_APPLY_SNAPSHOT_POLICY_FAILED, reason, self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, disk, logclient.ACT_APPLY_SNAPSHOT_POLICY, reason, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, reason)
|
||||
}
|
||||
|
||||
func getDiskIds(task *SnapshotPolicyApplyTask) ([]string, error) {
|
||||
diskIds, err := task.Params.GetArray("disk_ids")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Missing parasm disk_ids")
|
||||
}
|
||||
stringIds := make([]string, len(diskIds))
|
||||
for i := 0; i < len(diskIds); i++ {
|
||||
stringIds[i], _ = diskIds[i].GetString()
|
||||
}
|
||||
return stringIds, nil
|
||||
}
|
||||
|
||||
func (self *SnapshotPolicyApplyTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
snapshotPolicy := obj.(*models.SSnapshotPolicy)
|
||||
disk := obj.(*models.SDisk)
|
||||
snapshotPolicyID, _ := self.Params.GetString("snapshot_policy_id")
|
||||
|
||||
region := snapshotPolicy.GetRegion()
|
||||
if region == nil {
|
||||
self.taskFail(ctx, snapshotPolicy, fmt.Sprintf("failed to find region for snapshot policy %s", snapshotPolicy.Name))
|
||||
return
|
||||
}
|
||||
|
||||
stringIds, err := getDiskIds(self)
|
||||
iregion, err := disk.GetIRegion()
|
||||
if err != nil {
|
||||
self.taskFail(ctx, snapshotPolicy, err.Error())
|
||||
self.taskFail(ctx, disk, snapshotPolicyID, fmt.Sprintf("failed to find iregion for snapshot policy %s: %s", disk.Id, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
diskExt, err := models.DiskManager.Query("external_id").In("id", stringIds).AllStringMap()
|
||||
// fetch disk model by diksID
|
||||
model, err := models.SnapshotPolicyManager.FetchById(snapshotPolicyID)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, snapshotPolicy, fmt.Sprintf("Fetch disks external_id failed %s", err))
|
||||
self.taskFail(ctx, disk, snapshotPolicyID, fmt.Sprintf("failed to fetch disk by id %s: %s", snapshotPolicyID, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
diskExtIds := make([]string, 0)
|
||||
for i := 0; i < len(diskExt); i++ {
|
||||
val, ok := diskExt[i]["external_id"]
|
||||
if ok {
|
||||
diskExtIds = append(diskExtIds, val)
|
||||
}
|
||||
}
|
||||
|
||||
snapshotPolicy := model.(*models.SSnapshotPolicy)
|
||||
self.SetStage("OnSnapshotPolicyApply", nil)
|
||||
if err := region.GetDriver().RequestApplySnapshotPolicy(ctx, self.GetUserCred(), snapshotPolicy, self, diskExtIds); err != nil {
|
||||
self.taskFail(ctx, snapshotPolicy, err.Error())
|
||||
if err := iregion.ApplySnapshotPolicyToDisks(snapshotPolicy.ExternalId, disk.ExternalId); err != nil {
|
||||
self.taskFail(ctx, disk, snapshotPolicyID, fmt.Sprintf("faile to attach snapshot policy %s and disk %s: %s", snapshotPolicy.Id, disk.Id, err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SnapshotPolicyApplyTask) OnSnapshotPolicyApply(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
|
||||
stringIds, _ := getDiskIds(self)
|
||||
disks := make([]models.SDisk, 0)
|
||||
q := models.DiskManager.Query().In("id", stringIds)
|
||||
err := db.FetchModelObjects(models.DiskManager, q, &disks)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, sp, fmt.Sprintf("Fetch disks failed %s", err))
|
||||
return
|
||||
}
|
||||
for i := 0; i < len(disks); i++ {
|
||||
disks[i].SetSnapshotPolicy(sp.Id)
|
||||
db.OpsLog.LogEvent(&disks[i], db.ACT_APPLY_SNAPSHOT_POLICY, nil, self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, &disks[i], logclient.ACT_APPLY_SNAPSHOT_POLICY, nil, self.UserCred, true)
|
||||
}
|
||||
db.OpsLog.LogEvent(disk, db.ACT_APPLY_SNAPSHOT_POLICY, "", self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, disk, logclient.ACT_APPLY_SNAPSHOT_POLICY, "", self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *SnapshotPolicyApplyTask) OnSnapshotPolicyApplyFailed(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
|
||||
self.taskFail(ctx, sp, data.String())
|
||||
}
|
||||
|
||||
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
@@ -169,7 +135,18 @@ type SnapshotPolicyCancelTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func (self *SnapshotPolicyCancelTask) taskFail(ctx context.Context, disk *models.SDisk, reason string) {
|
||||
func (self *SnapshotPolicyCancelTask) taskFail(ctx context.Context, disk *models.SDisk, snapshotPolicyId, reason string) {
|
||||
jointModel, err := db.FetchJointByIds(models.SnapshotPolicyDiskManager, self.Id, snapshotPolicyId, jsonutils.JSONNull)
|
||||
if err != nil {
|
||||
log.Errorf("Fetch SnapshotPolicy %s Disk %s joint model failed, need to mark undelete", self.Id, snapshotPolicyId)
|
||||
return
|
||||
}
|
||||
snapshotPolicyDisk := jointModel.(*models.SSnapshotPolicyDisk)
|
||||
err = snapshotPolicyDisk.MarkUnDelete()
|
||||
if err != nil {
|
||||
log.Errorf("Mark undelete joint model snapshotPolicy %s and disk %s failes", snapshotPolicyId, disk.Id)
|
||||
}
|
||||
disk.SetStatus(self.UserCred, compute.DISK_CALCEL_SNAPSHOT_FAIL, reason)
|
||||
db.OpsLog.LogEvent(disk, db.ACT_CANCEL_SNAPSHOT_POLICY_FAILED, reason, self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, disk, logclient.ACT_CANCEL_SNAPSHOT_POLICY, reason, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, reason)
|
||||
@@ -177,42 +154,28 @@ func (self *SnapshotPolicyCancelTask) taskFail(ctx context.Context, disk *models
|
||||
|
||||
func (self *SnapshotPolicyCancelTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
disk := obj.(*models.SDisk)
|
||||
storage := disk.GetStorage()
|
||||
if storage == nil {
|
||||
self.taskFail(ctx, disk, fmt.Sprintf("failed to find storage for disk %s", disk.Name))
|
||||
return
|
||||
}
|
||||
region := storage.GetRegion()
|
||||
if region == nil {
|
||||
self.taskFail(ctx, disk, fmt.Sprintf("failed to find region for disk %s", disk.Name))
|
||||
snapshotPolicyID, _ := self.GetParams().GetString("snapshot_policy_id")
|
||||
|
||||
// get region
|
||||
iregion, err := disk.GetIRegion()
|
||||
if err != nil {
|
||||
self.taskFail(ctx, disk, snapshotPolicyID, fmt.Sprintf("failed to find iregion for disk %s: %s", disk.Name, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
iSnapshotPolicy, err := models.SnapshotPolicyManager.FetchById(disk.SnapshotPolicyId)
|
||||
model, err := models.SnapshotPolicyManager.FetchById(snapshotPolicyID)
|
||||
if err != nil {
|
||||
self.taskFail(ctx, disk, fmt.Sprintf("failed to find snapshot policy for disk %s, %s", disk.Name, err))
|
||||
self.taskFail(ctx, disk, snapshotPolicyID, fmt.Sprintf("failed to fetch disk by id %s: %s", snapshotPolicyID, err.Error()))
|
||||
return
|
||||
}
|
||||
snapshotPolicy := iSnapshotPolicy.(*models.SSnapshotPolicy)
|
||||
iRegion, err := snapshotPolicy.GetIRegion()
|
||||
if err != nil {
|
||||
self.taskFail(ctx, disk, fmt.Sprintf("failed to find region for snapshot policy %s", snapshotPolicy.Name))
|
||||
return
|
||||
}
|
||||
self.SetStage("OnSnapshotPolicyCancel", nil)
|
||||
if err := region.GetDriver().RequestCancelSnapshotPolicy(
|
||||
ctx, self.GetUserCred(), iRegion, self, []string{disk.ExternalId}); err != nil {
|
||||
self.taskFail(ctx, disk, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SnapshotPolicyCancelTask) OnSnapshotPolicyCancel(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
|
||||
disk.SetSnapshotPolicy("")
|
||||
snapshotPolicy := model.(*models.SSnapshotPolicy)
|
||||
self.SetStage("OnSnapshotPolicyApply", nil)
|
||||
if err := iregion.CancelSnapshotPolicyToDisks(snapshotPolicy.ExternalId, disk.ExternalId); err != nil {
|
||||
self.taskFail(ctx, disk, snapshotPolicyID, fmt.Sprintf("faile to detach snapshot policy %s and disk %s: %s", snapshotPolicy.Id, disk.Id, err.Error()))
|
||||
}
|
||||
|
||||
db.OpsLog.LogEvent(disk, db.ACT_CANCEL_SNAPSHOT_POLICY, "", self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, disk, logclient.ACT_CANCEL_SNAPSHOT_POLICY, "", self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *SnapshotPolicyCancelTask) OnSnapshotPolicyCancelFailed(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
|
||||
self.taskFail(ctx, disk, data.String())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// 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
|
||||
|
||||
var (
|
||||
SnapshotPolicyDisk JointResourceManager
|
||||
)
|
||||
|
||||
func init() {
|
||||
SnapshotPolicyDisk = NewJointComputeManager(
|
||||
"snapshotpolicydisk",
|
||||
"snapshotpolicydisks",
|
||||
[]string{"Disk_ID", "Snapshotpolicy_ID"},
|
||||
[]string{},
|
||||
&Disks,
|
||||
&SnapshotPoliciy)
|
||||
registerCompute(&SnapshotPolicyDisk)
|
||||
}
|
||||
@@ -405,8 +405,8 @@ func (self *SDisk) GetCreatedAt() time.Time {
|
||||
return self.CreationTime
|
||||
}
|
||||
|
||||
func (self *SDisk) GetExtSnapshotPolicyId() string {
|
||||
return self.AutoSnapshotPolicyId
|
||||
func (self *SDisk) GetExtSnapshotPolicyIds() []string {
|
||||
return []string{self.AutoSnapshotPolicyId}
|
||||
}
|
||||
|
||||
func (self *SDisk) GetExpiredAt() time.Time {
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/aliyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type SSnapshotPolicyListOptions struct {
|
||||
PolicyId string `help:"snapshot policy id"`
|
||||
Offset int `help:"offset"`
|
||||
Limit int `help:"limit"`
|
||||
}
|
||||
|
||||
shellutils.R(&SSnapshotPolicyListOptions{}, "snapshot-policy-list", "list snapshot policy",
|
||||
func(cli *aliyun.SRegion, args *SSnapshotPolicyListOptions) error {
|
||||
snapshotPolicis, num, err := cli.GetSnapshotPolicies(args.PolicyId, args.Offset, args.Limit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(snapshotPolicis, num, args.Offset, args.Limit, []string{})
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
type SSnapshotPolicyDeleteOptions struct {
|
||||
ID string `help:"snapshot id"`
|
||||
}
|
||||
shellutils.R(&SSnapshotPolicyDeleteOptions{}, "snapshot-policy-delete", "delete snapshot policy",
|
||||
func(cli *aliyun.SRegion, args *SSnapshotPolicyDeleteOptions) error {
|
||||
err := cli.DeleteSnapshotPolicy(args.ID)
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
type SSnapshotPolicyCreateOptions struct {
|
||||
Name string `help:"snapshot name"`
|
||||
|
||||
RetentionDays int `help:"retention days"`
|
||||
RepeatWeekdays []int `help:"auto snapshot which days of the week"`
|
||||
TimePoints []int `help:"auto snapshot which hours of the day"`
|
||||
}
|
||||
shellutils.R(&SSnapshotPolicyCreateOptions{}, "snapshot-policy-create", "create snapshot policy",
|
||||
func(cli *aliyun.SRegion, args *SSnapshotPolicyCreateOptions) error {
|
||||
input := cloudprovider.SnapshotPolicyInput{
|
||||
RetentionDays: args.RetentionDays,
|
||||
RepeatWeekdays: args.RepeatWeekdays,
|
||||
TimePoints: args.TimePoints,
|
||||
PolicyName: args.Name,
|
||||
}
|
||||
_, err := cli.CreateSnapshotPolicy(&input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
type SSnapshotPolicyApplyOptions struct {
|
||||
SNAPSHOTPOLICYID string `help:"snapshot policy id"`
|
||||
DISKID string `help:"disk id"`
|
||||
}
|
||||
shellutils.R(&SSnapshotPolicyApplyOptions{}, "snapshot-policy-apply", "apply snapshot policy",
|
||||
func(cli *aliyun.SRegion, args *SSnapshotPolicyApplyOptions) error {
|
||||
err := cli.ApplySnapshotPolicyToDisks(args.SNAPSHOTPOLICYID, args.DISKID)
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
type SSnapshotPolicyCancelOptions struct {
|
||||
SNAPSHOTPOLICYID string `help:"snapshot policy id"`
|
||||
DISKID string `help":disk id"`
|
||||
}
|
||||
shellutils.R(&SSnapshotPolicyCancelOptions{}, "snapshot-policy-cancel", "cancel snapshot policy",
|
||||
func(cli *aliyun.SRegion, args *SSnapshotPolicyCancelOptions) error {
|
||||
err := cli.CancelSnapshotPolicyToDisks(args.SNAPSHOTPOLICYID, args.DISKID)
|
||||
return err
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -135,6 +135,10 @@ func (self *SSnapshotPolicy) GetTimePoints() ([]int, error) {
|
||||
return parsePolicy(self.TimePoints)
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) IsActivated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
|
||||
snapshotPolicies, total, err := self.GetSnapshotPolicies("", 0, 50)
|
||||
if err != nil {
|
||||
@@ -159,8 +163,10 @@ func (self *SRegion) GetSnapshotPolicies(policyId string, offset int, limit int)
|
||||
params := make(map[string]string)
|
||||
|
||||
params["RegionId"] = self.RegionId
|
||||
params["PageSize"] = fmt.Sprintf("%d", limit)
|
||||
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
|
||||
if limit != 0 {
|
||||
params["PageSize"] = fmt.Sprintf("%d", limit)
|
||||
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
|
||||
}
|
||||
|
||||
if len(policyId) > 0 {
|
||||
params["AutoSnapshotPolicyId"] = policyId
|
||||
@@ -253,10 +259,11 @@ func (self *SRegion) UpdateSnapshotPolicy(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskIds []string) error {
|
||||
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
params := make(map[string]string)
|
||||
params["RegionId"] = self.RegionId
|
||||
params["autoSnapshotPolicyId"] = snapshotPolicyId
|
||||
diskIds := []string{diskId}
|
||||
params["diskIds"] = jsonutils.Marshal(diskIds).String()
|
||||
_, err := self.ecsRequest("ApplyAutoSnapshotPolicy", params)
|
||||
if err != nil {
|
||||
@@ -265,9 +272,10 @@ func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskIds
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CancelSnapshotPolicyToDisks(diskIds []string) error {
|
||||
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
params := make(map[string]string)
|
||||
params["RegionId"] = self.RegionId
|
||||
diskIds := []string{diskId}
|
||||
params["diskIds"] = jsonutils.Marshal(diskIds).String()
|
||||
_, err := self.ecsRequest("CancelAutoSnapshotPolicy", params)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// 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 aws
|
||||
@@ -16,8 +16,8 @@ package multicloud
|
||||
|
||||
type SDisk struct{}
|
||||
|
||||
func (self *SDisk) GetExtSnapshotPolicyId() string {
|
||||
return ""
|
||||
func (self *SDisk) GetExtSnapshotPolicyIds() []string {
|
||||
return []string{""}
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIStorageId() string {
|
||||
|
||||
@@ -186,11 +186,11 @@ func (cli *SObjectStoreClient) DeleteSnapshotPolicy(string) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (cli *SObjectStoreClient) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskIds []string) error {
|
||||
func (cli *SObjectStoreClient) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (cli *SObjectStoreClient) CancelSnapshotPolicyToDisks(diskIds []string) error {
|
||||
func (cli *SObjectStoreClient) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/qcloud"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type SSnapshotPolicyListOptions struct {
|
||||
PolicyId string `help:"snapshot policy id"`
|
||||
Offset int `help:"offset"`
|
||||
Limit int `help:"limit"`
|
||||
}
|
||||
|
||||
shellutils.R(&SSnapshotPolicyListOptions{}, "snapshot-policy-list", "list snapshot policy",
|
||||
func(cli *qcloud.SRegion, args *SSnapshotPolicyListOptions) error {
|
||||
snapshotPolicis, num, err := cli.GetSnapshotPolicies(args.PolicyId, args.Offset, args.Limit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printList(snapshotPolicis, num, args.Offset, args.Limit, []string{})
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
type SSnapshotPolicyDeleteOptions struct {
|
||||
ID string `help:"snapshot id"`
|
||||
}
|
||||
shellutils.R(&SSnapshotPolicyDeleteOptions{}, "snapshot-policy-delete", "delete snapshot policy",
|
||||
func(cli *qcloud.SRegion, args *SSnapshotPolicyDeleteOptions) error {
|
||||
err := cli.DeleteSnapshotPolicy(args.ID)
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
type SSnapshotPolicyCreateOptions struct {
|
||||
Name string `help:"snapshot name"`
|
||||
|
||||
RetentionDays int `help:"retention days"`
|
||||
RepeatWeekdays []int `help:"auto snapshot which days of the week"`
|
||||
TimePoints []int `help:"auto snapshot which hours of the day"`
|
||||
}
|
||||
shellutils.R(&SSnapshotPolicyCreateOptions{}, "snapshot-policy-create", "create snapshot policy",
|
||||
func(cli *qcloud.SRegion, args *SSnapshotPolicyCreateOptions) error {
|
||||
input := cloudprovider.SnapshotPolicyInput{
|
||||
RetentionDays: args.RetentionDays,
|
||||
RepeatWeekdays: args.RepeatWeekdays,
|
||||
TimePoints: args.TimePoints,
|
||||
PolicyName: args.Name,
|
||||
}
|
||||
_, err := cli.CreateSnapshotPolicy(&input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
type SSnapshotPolicyApplyOptions struct {
|
||||
SNAPSHOTPOLICYID string `help:"snapshot policy id"`
|
||||
DISKID string `help:"disk id"`
|
||||
}
|
||||
shellutils.R(&SSnapshotPolicyApplyOptions{}, "snapshot-policy-apply", "apply snapshot policy",
|
||||
func(cli *qcloud.SRegion, args *SSnapshotPolicyApplyOptions) error {
|
||||
err := cli.ApplySnapshotPolicyToDisks(args.SNAPSHOTPOLICYID, args.DISKID)
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
type SSnapshotPolicyCancelOptions struct {
|
||||
SNAPSHOTPOLICYID string `help:"snapshot policy id"`
|
||||
DISKID string `help:"disk id"`
|
||||
}
|
||||
shellutils.R(&SSnapshotPolicyCancelOptions{}, "snapshot-policy-cancel", "cancel snapshot policy",
|
||||
func(cli *qcloud.SRegion, args *SSnapshotPolicyCancelOptions) error {
|
||||
err := cli.CancelSnapshotPolicyToDisks(args.SNAPSHOTPOLICYID, args.DISKID)
|
||||
return err
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
// 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 qcloud
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
const (
|
||||
NORMAL = "NORMAL"
|
||||
UNKOWN = "ISOLATED"
|
||||
)
|
||||
|
||||
type SPolicy struct {
|
||||
DayOfWeek []int
|
||||
Hour []int
|
||||
}
|
||||
|
||||
type SSnapshotPolicy struct {
|
||||
region *SRegion
|
||||
|
||||
AutoSnapshotPolicyName string
|
||||
AutoSnapshotPolicyId string
|
||||
AutoSnapshotPolicyState string
|
||||
RetentionDays int
|
||||
Policy []SPolicy
|
||||
Activated bool `json:"is_activated"`
|
||||
IsPermanent bool
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetId() string {
|
||||
return self.AutoSnapshotPolicyId
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetName() string {
|
||||
return self.AutoSnapshotPolicyName
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetStatus() string {
|
||||
if self.AutoSnapshotPolicyState == NORMAL {
|
||||
return api.SNAPSHOT_POLICY_READY
|
||||
}
|
||||
return api.SNAPSHOT_POLICY_UNKNOWN
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) Refresh() error {
|
||||
if snapshotPolicies, total, err := self.region.GetSnapshotPolicies(self.AutoSnapshotPolicyId, 0, 1); err != nil {
|
||||
return err
|
||||
} else if total != 1 {
|
||||
return cloudprovider.ErrNotFound
|
||||
} else if err := jsonutils.Update(self, snapshotPolicies[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetRetentionDays() int {
|
||||
return self.RetentionDays
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetRepeatWeekdays() ([]int, error) {
|
||||
if len(self.Policy) == 0 {
|
||||
return nil, errors.Error("Policy Set Empty")
|
||||
}
|
||||
return self.Policy[0].DayOfWeek, nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) GetTimePoints() ([]int, error) {
|
||||
if len(self.Policy) == 0 {
|
||||
return nil, errors.Error("Policy Set Empty")
|
||||
}
|
||||
return self.Policy[0].Hour, nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) IsActivated() bool {
|
||||
return self.Activated
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
|
||||
snapshotPolicies, total, err := self.GetSnapshotPolicies("", 0, 50)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for len(snapshotPolicies) < total {
|
||||
var parts []SSnapshotPolicy
|
||||
parts, total, err = self.GetSnapshotPolicies("", len(snapshotPolicies), 50)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
snapshotPolicies = append(snapshotPolicies, parts...)
|
||||
}
|
||||
ret := make([]cloudprovider.ICloudSnapshotPolicy, len(snapshotPolicies))
|
||||
for i := 0; i < len(snapshotPolicies); i += 1 {
|
||||
ret[i] = &snapshotPolicies[i]
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetSnapshotPolicies(policyId string, offset int, limit int) ([]SSnapshotPolicy, int, error) {
|
||||
params := make(map[string]string)
|
||||
if len(policyId) > 0 {
|
||||
params["AutoSnapshotPolicyIds.0"] = policyId
|
||||
}
|
||||
if limit != 0 {
|
||||
params["Limit"] = strconv.Itoa(limit)
|
||||
params["Offset"] = strconv.Itoa(offset)
|
||||
}
|
||||
body, err := self.cbsRequest("DescribeAutoSnapshotPolicies", params)
|
||||
if err != nil {
|
||||
return nil, 0, errors.Wrap(err, "Get Snapshot Policies failed")
|
||||
}
|
||||
snapshotPolicies := make([]SSnapshotPolicy, 0, 1)
|
||||
if err := body.Unmarshal(&snapshotPolicies, "AutoSnapshotPolicySet"); err != nil {
|
||||
return nil, 0, errors.Wrap(err, "Unmarshal snapshot policies detail failed")
|
||||
}
|
||||
return snapshotPolicies, len(snapshotPolicies), nil
|
||||
}
|
||||
|
||||
func (self *SSnapshotPolicy) Delete() error {
|
||||
if self.region == nil {
|
||||
return fmt.Errorf("Not init region for snapshotPolicy %s", self.GetId())
|
||||
}
|
||||
return self.region.DeleteSnapshotPolicy(self.GetId())
|
||||
}
|
||||
|
||||
func (self *SRegion) DeleteSnapshotPolicy(snapshotPolicyId string) error {
|
||||
params := make(map[string]string)
|
||||
params["AutoSnapshotPolicyIds.0"] = snapshotPolicyId
|
||||
_, err := self.cbsRequest("DeleteAutoSnapshotPolicies", params)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "delete auto snapshot policy %s failed", snapshotPolicyId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
|
||||
policies, _, err := self.GetSnapshotPolicies(snapshotPolicyId, 0, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(policies) == 0 {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
return &policies[0], nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput) (string, error) {
|
||||
if input.RepeatWeekdays == nil {
|
||||
return "", fmt.Errorf("Can't create snapshot policy with nil repeatWeekdays")
|
||||
}
|
||||
if input.TimePoints == nil {
|
||||
return "", fmt.Errorf("Can't create snapshot policy with nil timePoints")
|
||||
}
|
||||
params := make(map[string]string)
|
||||
params["RetentionDays"] = strconv.Itoa(input.RetentionDays)
|
||||
dayOfWeekPrefix, hourPrefix := "Policy.0.DayOfWeek.", "Policy.0.Hour."
|
||||
for index, day := range input.RepeatWeekdays {
|
||||
if day == 0 {
|
||||
day = 7
|
||||
}
|
||||
params[dayOfWeekPrefix+strconv.Itoa(index)] = strconv.Itoa(day)
|
||||
}
|
||||
if len(input.PolicyName) > 0 {
|
||||
params["AutoSnapshotPolicyName"] = input.PolicyName
|
||||
}
|
||||
for index, hour := range input.TimePoints {
|
||||
params[hourPrefix+strconv.Itoa(index)] = strconv.Itoa(hour)
|
||||
}
|
||||
body, err := self.cbsRequest("CreateAutoSnapshotPolicy", params)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "create auto snapshot policy failed")
|
||||
}
|
||||
id, _ := body.GetString("AutoSnapshotPolicyId")
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) UpdateSnapshotPolicy(
|
||||
snapshotPolicyId string, retentionDays *int,
|
||||
repeatWeekdays, timePoints *jsonutils.JSONArray, policyName string,
|
||||
) error {
|
||||
// not implement
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
params := make(map[string]string)
|
||||
params["AutoSnapshotPolicyId"] = snapshotPolicyId
|
||||
params["DiskIds.0"] = diskId
|
||||
_, err := self.cbsRequest("BindAutoSnapshotPolicy", params)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Bind AutoSnapshotPolicy %s to Disk failed", snapshotPolicyId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
params := make(map[string]string)
|
||||
params["AutoSnapshotPolicyId"] = snapshotPolicyId
|
||||
params["DiskIds.0"] = diskId
|
||||
_, err := self.cbsRequest("UnbindAutoSnapshotPolicy", params)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Unbind AutoSnapshotPolicy %s of Disk failed", snapshotPolicyId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -38,11 +38,11 @@ func (self *SRegion) DeleteSnapshotPolicy(string) error {
|
||||
return fmt.Errorf("DeleteSnapshotPolicy not implement")
|
||||
}
|
||||
|
||||
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskIds []string) error {
|
||||
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
return fmt.Errorf("ApplySnapshotPolicyToDisks not implement")
|
||||
}
|
||||
|
||||
func (self *SRegion) CancelSnapshotPolicyToDisks(diskIds []string) error {
|
||||
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
|
||||
return fmt.Errorf("ApplySnapshotPolicyToDisks not implement")
|
||||
}
|
||||
|
||||
|
||||
@@ -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 bitmap
|
||||
|
||||
func Uint2IntArray(n uint32) []int {
|
||||
ret := make([]int, 0, 2)
|
||||
var i uint = 0
|
||||
for n != 0 {
|
||||
if n&(1<<i) != 0 {
|
||||
n &= uint32(^(1 << i))
|
||||
ret = append(ret, int(i))
|
||||
}
|
||||
i++
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func IntArray2Uint(nums []int) uint32 {
|
||||
var ret uint32 = 0
|
||||
for _, i := range nums {
|
||||
ret |= (1 << uint(i))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// 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 bitmap
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUint2IntArray(t *testing.T) {
|
||||
oneCase := make([]int, 32)
|
||||
for i := range oneCase {
|
||||
oneCase[i] = i
|
||||
}
|
||||
testCase := []struct {
|
||||
input uint32
|
||||
want []int
|
||||
}{
|
||||
{24, []int{3, 4}},
|
||||
{0, []int{}},
|
||||
{math.MaxUint32, oneCase},
|
||||
}
|
||||
|
||||
for _, tc := range testCase {
|
||||
real := Uint2IntArray(tc.input)
|
||||
if !sliceEqual(real, tc.want) {
|
||||
t.Fatalf("want %v, but %v\n", tc.want, real)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sliceEqual(a, b []int) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(a); i++ {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func TestIntArray2Uint(t *testing.T) {
|
||||
oneCase := make([]int, 32)
|
||||
for i := range oneCase {
|
||||
oneCase[i] = i
|
||||
}
|
||||
testCase := []struct {
|
||||
want uint32
|
||||
input []int
|
||||
}{
|
||||
{24, []int{3, 4}},
|
||||
{0, []int{}},
|
||||
{math.MaxUint32, oneCase},
|
||||
}
|
||||
|
||||
for _, tc := range testCase {
|
||||
real := IntArray2Uint(tc.input)
|
||||
if tc.want != real {
|
||||
t.Fatalf("want %d, but %d\n", tc.want, real)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user