fix(region): refactor snapshot policy (#19006)

This commit is contained in:
屈轩
2023-12-15 17:08:01 +08:00
committed by GitHub
parent 0e5a31c41e
commit 644b2a20ab
76 changed files with 1646 additions and 3826 deletions
+9 -103
View File
@@ -15,112 +15,18 @@
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/cmd/climc/shell"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
type SnapshotPolicyListOptions struct {
options.BaseListOptions
OrderByBindDiskCount string
}
R(&SnapshotPolicyListOptions{}, "snapshot-policy-list", "List snapshot policy", func(s *mcclient.ClientSession, args *SnapshotPolicyListOptions) error {
params, err := options.ListStructToParams(args)
if err != nil {
return err
}
result, err := modules.SnapshotPoliciy.List(s, params)
if err != nil {
return err
}
printList(result, modules.SnapshotPoliciy.GetColumns(s))
return nil
})
type SnapshotPolicyDeleteOptions struct {
ID string `help:"Delete snapshot id"`
}
R(&SnapshotPolicyDeleteOptions{}, "snapshot-policy-delete", "Delete snapshot policy", func(s *mcclient.ClientSession, args *SnapshotPolicyDeleteOptions) error {
result, err := modules.SnapshotPoliciy.Delete(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type SnapshotPolicyCreateOptions struct {
NAME string
RetentionDays int `help:"snapshot retention days"`
RepeatWeekdays []int `help:"snapshot create days on week"`
TimePoints []int `help:"snapshot create time points on one day"`
}
R(&SnapshotPolicyCreateOptions{}, "snapshot-policy-create", "Create snapshot policy", func(s *mcclient.ClientSession, args *SnapshotPolicyCreateOptions) error {
params := jsonutils.Marshal(args).(*jsonutils.JSONDict)
snapshot, err := modules.SnapshotPoliciy.Create(s, params)
if err != nil {
return err
}
printObject(snapshot)
return nil
})
type SnapshotPolicyBindDisksOptions struct {
ID string `help:"ID"`
Disk []string `help:"ids of disk"`
}
R(&SnapshotPolicyBindDisksOptions{}, "snapshot-policy-bind-disk", "bind snapshotpolicy to disks",
func(s *mcclient.ClientSession, opts *SnapshotPolicyBindDisksOptions) error {
params, err := options.StructToParams(opts)
if err != nil {
return err
}
sp, err := modules.SnapshotPoliciy.PerformAction(s, opts.ID, "bind-disks", params)
if err != nil {
return err
}
printObject(sp)
return nil
})
R(&SnapshotPolicyBindDisksOptions{}, "snapshot-policy-unbind-disk", "bind snapshotpolicy to disks",
func(s *mcclient.ClientSession, opts *SnapshotPolicyBindDisksOptions) error {
params, err := options.StructToParams(opts)
if err != nil {
return err
}
sp, err := modules.SnapshotPoliciy.PerformAction(s, opts.ID, "unbind-disks", params)
if err != nil {
return err
}
printObject(sp)
return nil
})
type SnapshotPolicyCacheOptions struct {
ID string `help:"SnasphotPolicy ID"`
REGIONID string `help:"Region ID"`
PROVIDER string `help:"Provider ID"`
}
R(&SnapshotPolicyCacheOptions{}, "snapshot-policy-cache", "upload local snapshotpolicy to cloud",
func(s *mcclient.ClientSession, opts *SnapshotPolicyCacheOptions) error {
params, err := options.StructToParams(opts)
if err != nil {
return err
}
sp, err := modules.SnapshotPoliciy.PerformAction(s, opts.ID, "cache", params)
if err != nil {
return err
}
printObject(sp)
return nil
},
)
cmd := shell.NewResourceCmd(&modules.SnapshotPoliciy).WithKeyword("snapshot-policy")
cmd.List(&compute.SnapshotPolicyListOptions{})
cmd.Delete(&options.BaseIdOptions{})
cmd.Create(&compute.SnapshotPolicyCreateOptions{})
cmd.Perform("bind-disks", &compute.SnapshotPolicyDisksOptions{})
cmd.Perform("unbind-disks", &compute.SnapshotPolicyDisksOptions{})
cmd.Perform("syncstatus", &options.BaseIdOptions{})
}
@@ -1,80 +0,0 @@
// 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"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
)
func init() {
type SSnapshotpolicyDiskListOfDiskOption struct {
DISKID string `help:"disk id"`
}
R(&SSnapshotpolicyDiskListOfDiskOption{}, "disk-snapshot-policy-list", "List snapshot policy attached",
func(s *mcclient.ClientSession, opts *SSnapshotpolicyDiskListOfDiskOption) error {
result, err := modules.SnapshotPolicyDisk.ListDescendent(s, opts.DISKID, jsonutils.NewDict())
if err != nil {
return err
}
printList(result, modules.SnapshotPolicyDisk.GetColumns(s))
return nil
},
)
type SSnapshotpolicyDiskListOfSnapshotpolicyOption struct {
SNAPSHOTPOLICYID string `help:"snapshot policy id"`
}
R(&SSnapshotpolicyDiskListOfSnapshotpolicyOption{}, "snapshot-policy-disk-list", "List disk attached",
func(s *mcclient.ClientSession, opts *SSnapshotpolicyDiskListOfSnapshotpolicyOption) error {
result, err := modules.SnapshotPolicyDisk.ListDescendent2(s, opts.SNAPSHOTPOLICYID, jsonutils.NewDict())
if err != nil {
return err
}
printList(result, modules.SnapshotPolicyDisk.GetColumns(s))
return nil
},
)
type SSnapshotpolicyDiskAttachOption struct {
DISKID string `help:"disk id"`
SNAPSHOTPOLICYID string `help:"snapshot policy id"`
}
R(&SSnapshotpolicyDiskAttachOption{}, "disk-snapshot-policy-attach", "attach snapshot policy to disk",
func(s *mcclient.ClientSession, opts *SSnapshotpolicyDiskAttachOption) error {
_, err := modules.SnapshotPolicyDisk.Attach(s, opts.DISKID, opts.SNAPSHOTPOLICYID, jsonutils.NewDict())
if err != nil {
return err
}
return nil
},
)
type SSnapshotpolicyDiskDetachOption struct {
DISKID string `help:"disk id"`
SNAPSHOTPOLICYID string `help:"snapshot policy id"`
}
R(&SSnapshotpolicyDiskDetachOption{}, "disk-snapshot-policy-detach", "detach snapshot policy to disk",
func(s *mcclient.ClientSession, opts *SSnapshotpolicyDiskDetachOption) error {
_, err := modules.SnapshotPolicyDisk.Detach(s, opts.DISKID, opts.SNAPSHOTPOLICYID, jsonutils.NewDict())
if err != nil {
return err
}
return nil
},
)
}
+1 -1
View File
@@ -88,7 +88,7 @@ require (
k8s.io/client-go v0.19.3
k8s.io/cluster-bootstrap v0.19.3
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231214030214-0b69ef4c4315
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231215084758-720b4cd7bf3e
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32
yunion.io/x/jsonutils v1.0.1-0.20230613121553-0f3b41e2ef19
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361
+2 -2
View File
@@ -1201,8 +1201,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231214030214-0b69ef4c4315 h1:t0Et8SHWCT3FRC1TvGFK52t7ChsbfLySqXiqJj1z1I8=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231214030214-0b69ef4c4315/go.mod h1:aj1gR9PPb6eqqKOwvANe26CoZFY8ydmXy0fuvgKYXH0=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231215084758-720b4cd7bf3e h1:u7STaGPLvoc98IShtsHoWv2xJVDpUJC/Y5QVmA+qN3c=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231215084758-720b4cd7bf3e/go.mod h1:aj1gR9PPb6eqqKOwvANe26CoZFY8ydmXy0fuvgKYXH0=
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug=
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
+4
View File
@@ -325,3 +325,7 @@ type DiskResetInput struct {
SnapshotId string `json:"snapshot_id"`
AutoStart bool `json:"auto_start"`
}
type DiskSnapshotpolicyInput struct {
SnapshotpolicyId string `json:"snapshotpolicy_id"`
}
+3 -2
View File
@@ -158,12 +158,13 @@ type ServiceCatalogListInput struct {
type SnapshotPolicyListInput struct {
apis.VirtualResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
// 按绑定的磁盘数量排序
// pattern:asc|desc
OrderByBindDiskCount string `json:"order_by_bind_disk_count"`
// 是否启用?
IsActivated *bool `json:"is_activated"`
}
type HostnameInput struct {
+3 -23
View File
@@ -14,7 +14,9 @@
package compute
import "yunion.io/x/cloudmux/pkg/apis/compute"
import (
"yunion.io/x/cloudmux/pkg/apis/compute"
)
const (
// create by
@@ -29,24 +31,6 @@ const (
SNAPSHOT_DELETING = compute.SNAPSHOT_DELETING
SNAPSHOT_UNKNOWN = compute.SNAPSHOT_UNKNOWN
SNAPSHOT_POLICY_CREATING = compute.SNAPSHOT_POLICY_CREATING
SNAPSHOT_POLICY_READY = compute.SNAPSHOT_POLICY_READY
SNAPSHOT_POLICY_UPDATING = "updating"
SNAPSHOT_POLICY_UNKNOWN = compute.SNAPSHOT_POLICY_UNKNOWN
SNAPSHOT_POLICY_DELETING = "deleting"
SNAPSHOT_POLICY_DELETE_FAILED = "delete_failed"
SNAPSHOT_POLICY_APPLY = "applying"
SNAPSHOT_POLICY_APPLY_FAILED = "apply_failed"
SNAPSHOT_POLICY_CANCEL = "canceling"
SNAPSHOT_POLICY_CANCEL_FAILED = "cancel_failed"
SNAPSHOT_POLICY_DISK_INIT = "init"
SNAPSHOT_POLICY_DISK_READY = "ready"
SNAPSHOT_POLICY_DISK_DELETING = "deleting"
SNAPSHOT_POLICY_DISK_DELETE_FAILED = "delete_failed"
INSTANCE_SNAPSHOT_READY = compute.INSTANCE_SNAPSHOT_READY
INSTANCE_SNAPSHOT_UNKNOWN = "unknown"
INSTANCE_SNAPSHOT_FAILED = "instance_snapshot_create_failed"
@@ -54,10 +38,6 @@ const (
INSTANCE_SNAPSHOT_DELETE_FAILED = "instance_snapshot_delete_failed"
INSTANCE_SNAPSHOT_RESET = "instance_snapshot_reset"
SNAPSHOT_POLICY_CACHE_STATUS_READY = "ready"
SNAPSHOT_POLICY_CACHE_STATUS_DELETING = "deleting"
SNAPSHOT_POLICY_CACHE_STATUS_DELETE_FAILED = "delete_failed"
SNAPSHOT_EXIST = "exist"
SNAPSHOT_NOT_EXIST = "not_exist"
)
+104 -96
View File
@@ -15,92 +15,77 @@
package compute
import (
"fmt"
"sort"
"reflect"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/util/bitmap"
)
const (
SNAPSHOT_POLICY_APPLY = "applying"
SNAPSHOT_POLICY_APPLY_FAILED = "apply_failed"
SNAPSHOT_POLICY_CANCEL = "canceling"
SNAPSHOT_POLICY_CANCEL_FAILED = "cancel_failed"
)
type SnapshotPolicyDetails struct {
apis.VirtualResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
SSnapshotPolicy
RetentionDays int `json:"retention_days"`
RepeatWeekdaysDisplay []int `json:"repeat_weekdays_display"`
TimePointsDisplay []int `json:"time_points_display"`
IsActivated *bool `json:"is_activated,omitempty"`
RetentionDays int `json:"retention_days"`
BindingDiskCount int `json:"binding_disk_count"`
}
type SnapshotPolicyResourceInfo struct {
// 快照策略名称
Snapshotpolicy string `json:"snapshotpolicy"`
}
type SSnapshotPolicyCreateInput struct {
apis.VirtualResourceCreateInput
CloudproviderResourceInput
CloudregionResourceInput
RetentionDays int `json:"retention_days"`
RepeatWeekdays string `json:"repeat_weekdays"`
TimePoints string `json:"time_points"`
RetentionDays int `json:"retention_days"`
RepeatWeekdays []int `json:"repeat_weekdays"`
TimePoints []int `json:"time_points"`
}
func (self SSnapshotPolicyCreateInput) GetRepeatWeekdays(limit int) (uint32, error) {
days, err := jsonutils.ParseString(self.RepeatWeekdays)
if err != nil {
return 0, errors.Wrapf(err, "ParseString %s", self.RepeatWeekdays)
}
repeatWeekdays := []int{}
days.Unmarshal(&repeatWeekdays)
err = daysCheck(repeatWeekdays, 1, 7)
if err != nil {
return 0, err
}
if len(repeatWeekdays) > limit {
return 0, httperrors.NewInputParameterError("repeat_weekdays only contains %d days at most", limit)
}
return bitmap.IntArray2Uint(repeatWeekdays), nil
}
func (self SSnapshotPolicyCreateInput) GetTimePoints(limit int) (uint32, error) {
points, err := jsonutils.ParseString(self.TimePoints)
if err != nil {
return 0, errors.Wrapf(err, "ParseString %s", self.TimePoints)
}
timepoints := []int{}
points.Unmarshal(&timepoints)
err = daysCheck(timepoints, 0, 23)
if err != nil {
return 0, err
}
if len(timepoints) > limit {
return 0, httperrors.NewInputParameterError("time_points only contains %d points at most", limit)
}
return bitmap.IntArray2Uint(timepoints), nil
}
func daysCheck(days []int, min, max int) error {
if len(days) == 0 {
return nil
}
sort.Ints(days)
if days[0] < min || days[len(days)-1] > max {
return fmt.Errorf("Out of range")
func (self *SSnapshotPolicyCreateInput) Validate() error {
if len(self.RepeatWeekdays) == 0 {
return httperrors.NewMissingParameterError("repeat_weekdays")
}
for i := 1; i < len(days); i++ {
if days[i] == days[i-1] {
return fmt.Errorf("Has repeat day %v", days)
repeatDays := []int{}
for _, day := range self.RepeatWeekdays {
if day < 1 || day > 7 {
return httperrors.NewOutOfRangeError("repeat_weekdays out of range 1-7")
}
if !utils.IsInArray(day, repeatDays) {
repeatDays = append(repeatDays, day)
}
}
self.RepeatWeekdays = repeatDays
if len(self.TimePoints) == 0 {
return httperrors.NewMissingParameterError("time_points")
}
points := []int{}
for _, point := range self.TimePoints {
if point < 0 || point > 23 {
return httperrors.NewOutOfRangeError("time_points out of range 0-23")
}
if !utils.IsInArray(point, points) {
points = append(points, point)
}
}
self.TimePoints = points
return nil
}
@@ -109,46 +94,69 @@ type SSnapshotPolicyUpdateInput struct {
RetentionDays *int
RepeatWeekdays *string `json:"repeat_weekdays"`
TimePoints *string `json:"time_points"`
RepeatWeekdays *[]int `json:"repeat_weekdays"`
TimePoints *[]int `json:"time_points"`
}
func (self SSnapshotPolicyUpdateInput) GetRepeatWeekdays(limit int) (uint32, error) {
func (self *SSnapshotPolicyUpdateInput) Validate() error {
if self.RepeatWeekdays != nil {
days, err := jsonutils.ParseString(*self.RepeatWeekdays)
if err != nil {
return 0, errors.Wrapf(err, "ParseString %s", *self.RepeatWeekdays)
repeatDays := []int{}
for _, day := range *self.RepeatWeekdays {
if day < 1 || day > 7 {
return httperrors.NewOutOfRangeError("repeat_weekdays out of range 1-7")
}
if !utils.IsInArray(day, repeatDays) {
repeatDays = append(repeatDays, day)
}
}
repeatWeekdays := []int{}
days.Unmarshal(&repeatWeekdays)
err = daysCheck(repeatWeekdays, 1, 7)
if err != nil {
return 0, err
}
if len(repeatWeekdays) > limit {
return 0, httperrors.NewInputParameterError("repeat_weekdays only contains %d days at most", limit)
}
return bitmap.IntArray2Uint(repeatWeekdays), nil
self.RepeatWeekdays = &repeatDays
}
return 0, nil
if self.TimePoints != nil {
points := []int{}
for _, point := range *self.TimePoints {
if point < 0 || point > 23 {
return httperrors.NewOutOfRangeError("time_points out of range 0-23")
}
if !utils.IsInArray(point, points) {
points = append(points, point)
}
}
self.TimePoints = &points
}
return nil
}
func (self SSnapshotPolicyUpdateInput) GetTimePoints(limit int) (uint32, error) {
if self.TimePoints != nil {
points, err := jsonutils.ParseString(*self.TimePoints)
if err != nil {
return 0, errors.Wrapf(err, "ParseString %s", *self.TimePoints)
}
timepoints := []int{}
points.Unmarshal(&timepoints)
err = daysCheck(timepoints, 0, 23)
if err != nil {
return 0, err
}
if len(timepoints) > limit {
return 0, httperrors.NewInputParameterError("time_points only contains %d points at most", limit)
}
return bitmap.IntArray2Uint(timepoints), nil
}
return 0, nil
type SnapshotPolicyDisksInput struct {
Disks []string `json:"disk"`
}
type RepeatWeekdays []int
func (days RepeatWeekdays) String() string {
return jsonutils.Marshal(days).String()
}
func (days RepeatWeekdays) IsZero() bool {
return len(days) == 0
}
type TimePoints []int
func (points TimePoints) String() string {
return jsonutils.Marshal(points).String()
}
func (points TimePoints) IsZero() bool {
return len(points) == 0
}
func init() {
gotypes.RegisterSerializable(reflect.TypeOf(&RepeatWeekdays{}), func() gotypes.ISerializable {
return &RepeatWeekdays{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&TimePoints{}), func() gotypes.ISerializable {
return &TimePoints{}
})
}
-25
View File
@@ -1,25 +0,0 @@
// 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/pkg/apis"
type SnapshotPolicyCacheDetails struct {
apis.StatusStandaloneResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
SnapshotPolicyResourceInfo
SSnapshotPolicyCache
}
-36
View File
@@ -1,36 +0,0 @@
// 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/pkg/apis"
)
type SnapshotPolicyDiskDetails struct {
apis.VirtualJointResourceBaseDetails
// 快照策略名称
Snapshotpolicy string `json:"snapshotpolicy"`
Disk DiskDetails `json:"disk"`
}
type SnapshotPolicyDiskListInput struct {
apis.VirtualJointResourceBaseListInput
SnapshotPolicyFilterListInput
DiskFilterListInput
// 状态
Status []string `json:"status"`
}
+1 -2
View File
@@ -2641,8 +2641,7 @@ type SSnapshotPolicy struct {
// 1~7, 1 is Monday
RepeatWeekdays byte `json:"repeat_weekdays"`
// 0~23
TimePoints uint32 `json:"time_points"`
IsActivated *bool `json:"is_activated,omitempty"`
TimePoints uint32 `json:"time_points"`
}
// SSnapshotPolicyCache is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SSnapshotPolicyCache.
+9
View File
@@ -80,6 +80,9 @@ type SCapabilities struct {
SecurityGroupBrands []string `json:",allowempty"`
DisabledSecurityGroupBrands []string `json:",allowempty"`
SnapshotPolicyBrands []string `json:",allowempty"`
DisabledSnapshotPolicyBrands []string `json:",allowempty"`
ReadOnlyBrands []string `json:",allowempty"`
ReadOnlyDisabledBrands []string `json:",allowempty"`
ReadOnlyComputeEngineBrands []string `json:",allowempty"`
@@ -119,6 +122,9 @@ type SCapabilities struct {
ReadOnlySecurityGroupBrands []string `json:",allowempty"`
ReadOnlyDisabledSecurityGroupBrands []string `json:",allowempty"`
ReadOnlySnapshotPolicyBrands []string `json:",allowempty"`
ReadOnlyDisabledSnapshotPolicyBrands []string `json:",allowempty"`
ResourceTypes []string `json:",allowempty"`
StorageTypes []string `json:",allowempty"` // going to remove on 2.14
DataStorageTypes []string `json:",allowempty"` // going to remove on 2.14
@@ -374,6 +380,7 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
capa.Brands = append(capa.Brands, api.ONECLOUD_BRAND_ONECLOUD)
capa.SecurityGroupBrands = append(capa.SecurityGroupBrands, api.ONECLOUD_BRAND_ONECLOUD)
capa.ComputeEngineBrands = append(capa.ComputeEngineBrands, api.ONECLOUD_BRAND_ONECLOUD)
capa.SnapshotPolicyBrands = append(capa.SnapshotPolicyBrands, api.ONECLOUD_BRAND_ONECLOUD)
}
if count, _ := LoadbalancerClusterManager.Query().Limit(1).CountWithError(); count > 0 {
@@ -463,6 +470,8 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
appendBrand(&capa.VpcPeerBrands, &capa.DisabledVpcPeerBrands, &capa.ReadOnlyVpcPeerBrands, &capa.ReadOnlyDisabledVpcPeerBrands, brand, capability, enabled, readOnly)
case cloudprovider.CLOUD_CAPABILITY_SECURITY_GROUP:
appendBrand(&capa.SecurityGroupBrands, &capa.DisabledSecurityGroupBrands, &capa.ReadOnlySecurityGroupBrands, &capa.ReadOnlyDisabledSecurityGroupBrands, brand, capability, enabled, readOnly)
case cloudprovider.CLOUD_CAPABILITY_SNAPSHOT_POLICY:
appendBrand(&capa.SnapshotPolicyBrands, &capa.DisabledSnapshotPolicyBrands, &capa.ReadOnlySnapshotPolicyBrands, &capa.ReadOnlyDisabledSnapshotPolicyBrands, brand, capability, enabled, readOnly)
default:
}
}
+6 -5
View File
@@ -2018,7 +2018,7 @@ func syncRegionSnapshotPolicies(
result := func() compare.SyncResult {
defer syncResults.AddSqlCost(SnapshotPolicyManager)()
return SnapshotPolicyManager.SyncSnapshotPolicies(ctx, userCred, provider, localRegion, snapshotPolicies, provider.GetOwnerId(), syncRange.Xor)
return localRegion.SyncSnapshotPolicies(ctx, userCred, provider, snapshotPolicies, provider.GetOwnerId(), syncRange.Xor)
}()
syncResults.Add(SnapshotPolicyManager, result)
msg := result.Result()
@@ -2172,10 +2172,6 @@ func syncPublicCloudProviderInfo(
}
if syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_COMPUTE) {
if syncRange.IsNotSkipSyncResource(SnapshotPolicyManager) {
// sync snapshot policies before sync disks
syncRegionSnapshotPolicies(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
for j := 0; j < len(localZones); j += 1 {
@@ -2194,6 +2190,11 @@ func syncPublicCloudProviderInfo(
}
}
if syncRange.IsNotSkipSyncResource(SnapshotPolicyManager) {
// sync snapshot policies after sync disks
syncRegionSnapshotPolicies(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
// sync snapshots after sync disks
if syncRange.IsNotSkipSyncResource(SnapshotManager) {
syncRegionSnapshots(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
+154 -186
View File
@@ -31,7 +31,6 @@ import (
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/pinyinutils"
"yunion.io/x/pkg/util/rand"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
@@ -1702,20 +1701,11 @@ func (self *SDisk) syncWithCloudDisk(ctx context.Context, userCred mcclient.Toke
if err != nil {
return errors.Wrapf(err, "db.UpdateWithLock")
}
// sync disk's snapshotpolicy
snapshotpolicies, err := extDisk.GetExtSnapshotPolicyIds()
if err != nil {
return errors.Wrapf(err, "Get snapshot policies of ICloudDisk %s.", extDisk.GetId())
}
storage, err := self.GetStorage()
if err != nil {
return errors.Wrapf(err, "GetStorage")
}
err = SnapshotPolicyDiskManager.SyncByDisk(ctx, userCred, snapshotpolicies, syncOwnerId, self, storage)
if err != nil {
return err
}
db.OpsLog.LogSyncUpdate(self, diff, userCred)
if len(diff) > 0 {
@@ -1794,16 +1784,6 @@ func (manager *SDiskManager) newFromCloudDisk(ctx context.Context, userCred mccl
return nil, errors.Wrapf(err, "newFromCloudDisk")
}
// create new joint model aboutsnapshotpolicy and disk
snapshotpolicies, err := extDisk.GetExtSnapshotPolicyIds()
if err != nil {
log.Warningln("GetExtSnapshotPolicyIds:", errors.Wrapf(err, "Get snapshot policies of ICloudDisk %s.", extDisk.GetId()))
}
err = SnapshotPolicyDiskManager.SyncAttachDiskExt(ctx, userCred, snapshotpolicies, syncOwnerId, &disk, storage)
if err != nil {
log.Warningln("SyncAttachDiskExt:", err)
}
syncVirtualResourceMetadata(ctx, userCred, &disk, extDisk, false)
SyncCloudProject(ctx, userCred, &disk, syncOwnerId, extDisk, storage.ManagerId)
@@ -2373,8 +2353,8 @@ func (manager *SDiskManager) FetchCustomizeColumns(
Id string
Name string
Status string
TimePoints uint32
RepeatWeekdays uint8
TimePoints []int
RepeatWeekdays []int
DiskId string
}{}
err = q.All(&policyInfo)
@@ -2392,8 +2372,8 @@ func (manager *SDiskManager) FetchCustomizeColumns(
policies[policy.DiskId] = append(policies[policy.DiskId], api.SimpleSnapshotPolicy{
Id: policy.Id,
Name: policy.Name,
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysToIntArray(policy.RepeatWeekdays),
TimePoints: SnapshotPolicyManager.TimePointsToIntArray(policy.TimePoints),
RepeatWeekdays: policy.RepeatWeekdays,
TimePoints: policy.TimePoints,
})
}
@@ -2674,7 +2654,7 @@ func (manager *SDiskManager) CleanPendingDeleteDisks(ctx context.Context, userCr
}
}
func (manager *SDiskManager) getAutoSnapshotDisksId(isExternal bool) ([]SSnapshotPolicyDisk, error) {
func (manager *SDiskManager) GetNeedAutoSnapshotDisks() ([]SSnapshotPolicyDisk, error) {
tz, _ := time.LoadLocation(options.Options.TimeZone)
t := time.Now().In(tz)
week := t.Weekday()
@@ -2683,39 +2663,26 @@ func (manager *SDiskManager) getAutoSnapshotDisksId(isExternal bool) ([]SSnapsho
}
timePoint := t.Hour()
sps, err := SnapshotPolicyManager.GetSnapshotPoliciesAt(uint32(week), uint32(timePoint))
policy := SnapshotPolicyManager.Query().Equals("cloudregion_id", api.DEFAULT_REGION_ID)
policy = policy.Filter(sqlchemy.Contains(policy.Field("repeat_weekdays"), fmt.Sprintf("%d", week)))
sq := policy.Filter(
sqlchemy.OR(
sqlchemy.Contains(policy.Field("time_points"), fmt.Sprintf(",%d,", timePoint)),
sqlchemy.Startswith(policy.Field("time_points"), fmt.Sprintf("[%d,", timePoint)),
sqlchemy.Endswith(policy.Field("time_points"), fmt.Sprintf(",%d]", timePoint)),
sqlchemy.Equals(policy.Field("time_points"), fmt.Sprintf("[%d]", timePoint)),
),
).SubQuery()
disks := DiskManager.Query().SubQuery()
q := SnapshotPolicyDiskManager.Query()
q = q.Join(sq, sqlchemy.Equals(q.Field("snapshotpolicy_id"), sq.Field("id")))
q = q.Join(disks, sqlchemy.Equals(q.Field("disk_id"), disks.Field("id")))
ret := []SSnapshotPolicyDisk{}
err := db.FetchModelObjects(SnapshotPolicyDiskManager, q, &ret)
if err != nil {
return nil, err
}
if len(sps) == 0 {
return nil, nil
}
spds := make([]SSnapshotPolicyDisk, 0)
spdq := SnapshotPolicyDiskManager.Query()
spdq.NotEquals("status", api.SNAPSHOT_POLICY_DISK_INIT)
spdq.Filter(sqlchemy.In(spdq.Field("snapshotpolicy_id"), sps))
diskQ := DiskManager.Query().SubQuery()
spdq.Join(diskQ, sqlchemy.Equals(spdq.Field("disk_id"), diskQ.Field("id")))
if !isExternal {
spdq.Filter(sqlchemy.IsNullOrEmpty(diskQ.Field("external_id")))
} else {
spdq.Filter(sqlchemy.IsNotEmpty(diskQ.Field("external_id")))
}
err = spdq.All(&spds)
if err != nil {
return nil, err
}
return spds, nil
}
func generateAutoSnapshotName() string {
name := "Auto-" + rand.String(8)
for SnapshotManager.Query().Equals("name", name).Count() > 0 {
name = "Auto-" + rand.String(8)
}
return name
return ret, nil
}
func (disk *SDisk) validateDiskAutoCreateSnapshot() error {
@@ -2723,9 +2690,9 @@ func (disk *SDisk) validateDiskAutoCreateSnapshot() error {
if len(guests) == 0 {
return fmt.Errorf("Disks %s not attach guest, can't create snapshot", disk.GetName())
}
storage, _ := disk.GetStorage()
if storage == nil {
return fmt.Errorf("no valid storage")
storage, err := disk.GetStorage()
if err != nil {
return errors.Wrapf(err, "GetStorage")
}
if len(guests) == 1 && utils.IsInStringArray(storage.StorageType, api.FIEL_STORAGE) {
if !utils.IsInStringArray(guests[0].Status, []string{api.VM_RUNNING, api.VM_READY}) {
@@ -2736,86 +2703,124 @@ func (disk *SDisk) validateDiskAutoCreateSnapshot() error {
}
func (manager *SDiskManager) AutoDiskSnapshot(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
spds, err := manager.getAutoSnapshotDisksId(false)
disks, err := manager.GetNeedAutoSnapshotDisks()
if err != nil {
log.Errorf("Get auto snapshot disks id failed: %s", err)
return
}
if len(spds) == 0 {
log.Infof("CronJob AutoDiskSnapshot: No disk need create snapshot")
return
}
log.Debugf("auto snapshot %d disks", len(disks))
now := time.Now()
for i := 0; i < len(spds); i++ {
var (
disk = manager.FetchDiskById(spds[i].DiskId)
snapshotPolicy, _ = SnapshotPolicyManager.FetchSnapshotPolicyById(spds[i].SnapshotpolicyId)
snapshotName = generateAutoSnapshotName()
autoSnapshotCount = options.Options.DefaultMaxSnapshotCount - options.Options.DefaultMaxManualSnapshotCount
err error
snapCount int
cleanOverdueSnapshots bool
)
if err = disk.validateDiskAutoCreateSnapshot(); err != nil {
goto onFail
}
if err = disk.CreateSnapshotAuto(ctx, userCred, snapshotName, snapshotPolicy); err != nil {
goto onFail
}
snapCount, err = SnapshotManager.Query().Equals("fake_deleted", false).
Equals("disk_id", disk.Id).Equals("created_by", api.SNAPSHOT_AUTO).
CountWithError()
for i := 0; i < len(disks); i++ {
disk, err := disks[i].GetDisk()
if err != nil {
err = errors.Wrap(err, "get snapshot count")
goto onFail
log.Errorf("get disk error: %v", err)
continue
}
// if auto snapshot count gt max auto snapshot count, do clean overdued snapshots
cleanOverdueSnapshots = snapCount > autoSnapshotCount
if cleanOverdueSnapshots {
disk.CleanOverdueSnapshots(ctx, userCred, snapshotPolicy, now)
autoSnapshotCount := options.Options.DefaultMaxSnapshotCount - options.Options.DefaultMaxManualSnapshotCount
err = func() error {
policy, err := disks[i].GetSnapshotPolicy()
if err != nil {
return errors.Wrapf(err, "GetSnapshotPolicy")
}
if len(disk.ExternalId) == 0 {
err = disk.validateDiskAutoCreateSnapshot()
if err != nil {
return errors.Wrapf(err, "validateDiskAutoCreateSnapshot")
}
}
snapshot, err := disk.CreateSnapshotAuto(ctx, userCred, policy)
if err != nil {
return errors.Wrapf(err, "CreateSnapshotAuto")
}
snapCount, err := SnapshotManager.Query().Equals("fake_deleted", false).
Equals("disk_id", disk.Id).Equals("created_by", api.SNAPSHOT_AUTO).
CountWithError()
if err != nil {
return errors.Wrap(err, "get snapshot count")
}
// if auto snapshot count gt max auto snapshot count, do clean overdued snapshots
cleanOverdueSnapshots := snapCount > autoSnapshotCount
if cleanOverdueSnapshots {
disk.CleanOverdueSnapshots(ctx, userCred, policy, now)
}
db.OpsLog.LogEvent(disk, db.ACT_DISK_AUTO_SNAPSHOT, snapshot.Name, userCred)
policy.ExecuteNotify(ctx, userCred, disk.GetName())
return nil
}()
if err != nil {
log.Errorf("auto snapshot %s error: %v", disk.Name, err)
db.OpsLog.LogEvent(disk, db.ACT_DISK_AUTO_SNAPSHOT_FAIL, err.Error(), userCred)
notifyclient.NotifySystemErrorWithCtx(ctx, disk.Id, disk.Name, db.ACT_DISK_AUTO_SNAPSHOT_FAIL, errors.Wrapf(err, "Disk auto create snapshot").Error())
}
db.OpsLog.LogEvent(disk, db.ACT_DISK_AUTO_SNAPSHOT, "disk auto snapshot "+snapshotName, userCred)
snapshotPolicy.ExecuteNotify(ctx, userCred, disk.GetName())
continue
onFail:
db.OpsLog.LogEvent(disk, db.ACT_DISK_AUTO_SNAPSHOT_FAIL, err.Error(), userCred)
reason := fmt.Sprintf("Disk auto create snapshot failed: %s", err.Error())
notifyclient.NotifySystemErrorWithCtx(ctx, disk.Id, disk.Name, db.ACT_DISK_AUTO_SNAPSHOT_FAIL, reason)
}
}
func (self *SDisk) CreateSnapshotAuto(
ctx context.Context, userCred mcclient.TokenCredential,
snapshotName string, snapshotPolicy *SSnapshotPolicy,
) error {
snap, err := SnapshotManager.CreateSnapshot(ctx, self.GetOwnerId(), api.SNAPSHOT_AUTO,
self.Id, "", "", snapshotName, snapshotPolicy.RetentionDays, false)
policy *SSnapshotPolicy,
) (*SSnapshot, error) {
storage, err := self.GetStorage()
if err != nil {
return errors.Wrap(err, "disk create snapshot auto")
return nil, errors.Wrapf(err, "GetStorage")
}
snapshot := &SSnapshot{}
snapshot.SetModelManager(SnapshotManager, snapshot)
snapshot.ProjectId = self.ProjectId
snapshot.DomainId = self.DomainId
snapshot.DiskId = self.Id
if len(self.ExternalId) == 0 {
snapshot.StorageId = self.StorageId
}
db.OpsLog.LogEvent(snap, db.ACT_CREATE, "disk create snapshot auto", userCred)
err = snap.StartSnapshotCreateTask(ctx, userCred, nil, "")
// inherit encrypt_key_id
snapshot.EncryptKeyId = self.EncryptKeyId
driver, err := storage.GetRegionDriver()
if err != nil {
return errors.Wrap(err, "disk auto snapshot start snapshot task")
return nil, errors.Wrapf(err, "GetRegionDriver")
}
return nil
snapshot.OutOfChain = driver.SnapshotIsOutOfChain(self)
snapshot.Size = self.DiskSize
snapshot.DiskType = self.DiskType
snapshot.Location = ""
snapshot.CreatedBy = api.SNAPSHOT_AUTO
snapshot.ManagerId = storage.ManagerId
if cloudregion, _ := storage.GetRegion(); cloudregion != nil {
snapshot.CloudregionId = cloudregion.GetId()
}
snapshot.Name = fmt.Sprintf("%s-auto-snapshot-%d", self.Name, time.Now().Unix())
snapshot.Status = api.SNAPSHOT_CREATING
if policy.RetentionDays > 0 {
snapshot.ExpiredAt = time.Now().AddDate(0, 0, policy.RetentionDays)
}
snapshot.IsSystem = self.IsSystem
err = SnapshotManager.TableSpec().Insert(ctx, snapshot)
if err != nil {
return nil, errors.Wrapf(err, "Insert")
}
db.OpsLog.LogEvent(snapshot, db.ACT_CREATE, "disk create snapshot auto", userCred)
err = snapshot.StartSnapshotCreateTask(ctx, userCred, nil, "")
if err != nil {
return nil, errors.Wrap(err, "disk auto snapshot start snapshot task")
}
return snapshot, nil
}
func (self *SDisk) CleanOverdueSnapshots(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, now time.Time) error {
kwargs := jsonutils.NewDict()
kwargs.Set("snapshotpolicy_id", jsonutils.NewString(sp.Id))
kwargs.Set("retention_day", jsonutils.NewInt(int64(sp.RetentionDays)))
kwargs.Set("start_time", jsonutils.NewTimeString(now))
if task, err := taskman.TaskManager.NewTask(ctx, "DiskCleanOverduedSnapshots", self, userCred, kwargs, "", "", nil); err != nil {
log.Errorln(err)
return err
} else {
task.ScheduleRun(nil)
task, err := taskman.TaskManager.NewTask(ctx, "DiskCleanOverduedSnapshots", self, userCred, kwargs, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
return nil
return task.ScheduleRun(nil)
}
func (self *SDisk) StartCreateBackupTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
@@ -3003,85 +3008,48 @@ func (disk *SDisk) GetUsages() []db.IUsage {
}
}
func (disk *SDisk) PerformBindSnapshotpolicy(ctx context.Context, userCred mcclient.TokenCredential,
query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
spIden, err := data.GetString("snapshotpolicy")
func (disk *SDisk) PerformBindSnapshotpolicy(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input *api.DiskSnapshotpolicyInput,
) (jsonutils.JSONObject, error) {
spObj, err := validators.ValidateModel(userCred, SnapshotPolicyManager, &input.SnapshotpolicyId)
if err != nil {
return nil, httperrors.NewMissingParameterError("miss snapshotpolicy")
return nil, err
}
// check snapshotpolicy
imodel, err := db.FetchByIdOrName(SnapshotPolicyManager, userCred, spIden)
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewInputParameterError("no such snapshotpolicy %s", spIden)
}
if err != nil {
return nil, errors.Wrap(err, "db.FetchByIdOrName")
}
snapshotpolicy := imodel.(*SSnapshotPolicy)
// try to bind
spd, err := SnapshotPolicyDiskManager.newSnapshotpolicyDisk(ctx, userCred, snapshotpolicy, disk)
if errors.Cause(err) == ErrExistSD {
if spd.Status != api.SNAPSHOT_POLICY_DISK_INIT {
return nil, nil
sp := spObj.(*SSnapshotPolicy)
if len(sp.ManagerId) > 0 {
storage, err := disk.GetStorage()
if err != nil {
return nil, errors.Wrapf(err, "GetStorage")
}
if storage.ManagerId != sp.ManagerId {
return nil, httperrors.NewConflictError("The snapshot policy %s and disk account are different", sp.Name)
}
zone, err := storage.GetZone()
if err != nil {
return nil, errors.Wrapf(err, "GetZone")
}
if sp.CloudregionId != zone.CloudregionId {
return nil, httperrors.NewConflictError("The snapshot policy %s and the disk are in different region", sp.Name)
}
} else if err != nil {
return nil, errors.Wrap(err, "SnapshotPolicyDiskManager.newSnapshotpolicyDisk")
}
// start up SnapshotPolicyApplyTask
taskData := jsonutils.NewDict()
taskData.Add(jsonutils.Marshal(spd), "snapshotPolicyDisk")
taskData.Add(jsonutils.Marshal(snapshotpolicy), "snapshotPolicy")
if task, err := taskman.TaskManager.NewTask(ctx, "SnapshotPolicyApplyTask", disk, userCred, nil, "", "",
nil); err != nil {
return nil, errors.Wrap(err, "fail to start up SnapshotPolicyApplyTask")
} else {
task.ScheduleRun(taskData)
}
return nil, nil
return nil, sp.StartBindDisksTask(ctx, userCred, []string{disk.Id})
}
func (disk *SDisk) PerformUnbindSnapshotpolicy(ctx context.Context, userCred mcclient.TokenCredential,
query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
spIden, err := data.GetString("snapshotpolicy")
func (disk *SDisk) PerformUnbindSnapshotpolicy(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input *api.DiskSnapshotpolicyInput,
) (jsonutils.JSONObject, error) {
spObj, err := validators.ValidateModel(userCred, SnapshotPolicyManager, &input.SnapshotpolicyId)
if err != nil {
return nil, httperrors.NewMissingParameterError("miss snapshotpolicy")
return nil, err
}
// check snapshotpolicy
imodel, err := db.FetchByIdOrName(SnapshotPolicyManager, userCred, spIden)
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewInputParameterError("no such snapshotpolicy %s", spIden)
}
if err != nil {
return nil, errors.Wrap(err, "db.FetchByIdOrName")
}
snapshotpolicy := imodel.(*SSnapshotPolicy)
spd, err := SnapshotPolicyDiskManager.FetchBySnapshotPolicyDisk(snapshotpolicy.GetId(), disk.GetId())
if err != nil {
return nil, errors.Wrap(err, "SnapshotPolicyDiskManager.FetchBySnapshotPolicyDisk")
}
if spd == nil {
// has been detach
return nil, nil
}
// start up SnapshotPolicyCancelTask
taskdata := jsonutils.NewDict()
taskdata.Add(jsonutils.NewString(snapshotpolicy.Id), "snapshot_policy_id")
taskdata.Add(jsonutils.Marshal(spd), "snapshotPolicyDisk")
if task, err := taskman.TaskManager.NewTask(ctx, "SnapshotPolicyCancelTask", disk, userCred, nil, "", "",
nil); err != nil {
return nil, errors.Wrap(err, "fail to start up SnapshotPolicyCancelTask")
} else {
spd.SetStatus(userCred, api.SNAPSHOT_POLICY_DISK_DELETING, "")
task.ScheduleRun(taskdata)
}
return nil, nil
sp := spObj.(*SSnapshotPolicy)
return nil, sp.StartUnbindDisksTask(ctx, userCred, []string{disk.Id})
}
func (manager *SDiskManager) ListItemExportKeys(ctx context.Context,
+2 -2
View File
@@ -278,7 +278,7 @@ func (self *SCloudregion) purgeResources(ctx context.Context, managerId string)
nicips := NetworkinterfacenetworkManager.Query("row_id").In("networkinterface_id", nics.SubQuery())
secgroups := SecurityGroupManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
rules := SecurityGroupRuleManager.Query("id").In("secgroup_id", secgroups.SubQuery())
policycaches := SnapshotPolicyCacheManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
policies := SnapshotPolicyManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
snapshots := SnapshotManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
tables := TablestoreManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
wafs := WafInstanceManager.Query("id").Equals("manager_id", managerId).Equals("cloudregion_id", self.Id)
@@ -295,7 +295,7 @@ func (self *SCloudregion) purgeResources(ctx context.Context, managerId string)
{manager: WafInstanceManager, key: "id", q: wafs},
{manager: TablestoreManager, key: "id", q: tables},
{manager: SnapshotManager, key: "id", q: snapshots},
{manager: SnapshotPolicyCacheManager, key: "id", q: policycaches},
{manager: SnapshotPolicyManager, key: "id", q: policies},
{manager: SecurityGroupRuleManager, key: "id", q: rules},
{manager: SecurityGroupManager, key: "id", q: secgroups},
{manager: NetworkinterfacenetworkManager, key: "row_id", q: nicips},
+5 -7
View File
@@ -82,13 +82,11 @@ type IRegionDriver interface {
type ISnapshotDriver interface {
// Region Driver Snapshot Policy Apis
RequestUpdateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, input cloudprovider.SnapshotPolicyInput, task taskman.ITask) error
RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
RequestPreSnapshotPolicyApply(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *SDisk, sp *SSnapshotPolicy, data jsonutils.JSONObject) error
// Region Driver Snapshot Policy joint Disk Apis
ValidateCreateSnapshopolicyDiskData(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshotPolicy *SSnapshotPolicy) error
ValidateCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, input *api.SSnapshotPolicyCreateInput) (*api.SSnapshotPolicyCreateInput, error)
RequestCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, sp *SSnapshotPolicy, task taskman.ITask) error
RequestSnapshotPolicyBindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, diskIds []string, task taskman.ITask) error
RequestSnapshotPolicyUnbindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *SSnapshotPolicy, diskIds []string, task taskman.ITask) error
RequestDeleteSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *SCloudregion, sp *SSnapshotPolicy, task taskman.ITask) error
// Region Driver Snapshot Apis
ValidateSnapshotDelete(ctx context.Context, snapshot *SSnapshot) error
File diff suppressed because it is too large Load Diff
-208
View File
@@ -1,208 +0,0 @@
// 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 (
"testing"
"time"
"yunion.io/x/log"
"yunion.io/x/pkg/tristate"
)
func TestSSnapshotPolicy_Key(t *testing.T) {
cases := []struct {
in *SSnapshotPolicy
want uint64
}{
{
&SSnapshotPolicy{
RepeatWeekdays: 0,
TimePoints: 0,
RetentionDays: 7,
IsActivated: tristate.True,
},
15 + 2,
},
{
&SSnapshotPolicy{
RepeatWeekdays: 11,
},
11<<56 + 2,
},
{
&SSnapshotPolicy{
TimePoints: 234,
},
234<<24 + 2,
},
{
&SSnapshotPolicy{
RetentionDays: -1,
},
0,
},
{
&SSnapshotPolicy{
RepeatWeekdays: 13,
TimePoints: 123,
RetentionDays: 7,
},
936748724556660752,
},
}
for i, c := range cases {
g := c.in.Key()
if c.want != g {
log.Errorf("the %d case, want %d, get %d", i, c.want, g)
}
}
}
func TestSSnapshotPolicy_ComputeNextSyncTime(t *testing.T) {
timeStr := "2006-01-02 15:04:05"
t.Run("base test", func(t *testing.T) {
cases := []struct {
in *SSnapshotPolicy
base string
want string
}{
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{2}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{4}),
},
base: "2020-10-31 00:00:00",
want: "2020-11-03 04:00:00",
},
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{5, 7}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{2, 6}),
},
base: "2020-10-31 00:00:00",
want: "2020-11-01 02:00:00",
},
}
for _, c := range cases {
base, _ := time.Parse(timeStr, c.base)
want, _ := time.Parse(timeStr, c.want)
real := c.in.ComputeNextSyncTime(base)
if want != real {
t.Fatalf("want: %s, real: %s", want, real)
}
}
})
t.Run("same day", func(t *testing.T) {
cases := []struct {
in *SSnapshotPolicy
base string
want string
}{
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{6, 7}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{2}),
},
base: "2020-10-31 00:00:00",
want: "2020-10-31 02:00:00",
},
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{6, 7}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{2}),
},
base: "2020-10-31 02:00:00",
want: "2020-11-01 02:00:00",
},
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{6, 7}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{2}),
},
base: "2020-10-31 01:00:00",
want: "2020-10-31 02:00:00",
},
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{6}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{2, 4}),
},
base: "2020-10-31 05:00:00",
want: "2020-11-07 02:00:00",
},
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{1, 2, 3, 4, 5, 6, 7}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{0}),
},
base: "2020-10-31 05:00:00",
want: "2020-11-01 00:00:00",
},
}
for _, c := range cases {
base, _ := time.Parse(timeStr, c.base)
want, _ := time.Parse(timeStr, c.want)
real := c.in.ComputeNextSyncTime(base)
if want != real {
t.Fatalf("want: %s, real: %s", want, real)
}
}
})
t.Run("retentionday", func(t *testing.T) {
cases := []struct {
in *SSnapshotPolicy
base string
want string
}{
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{5}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{4}),
RetentionDays: 2,
},
base: "2020-10-31 04:00:00",
want: "2020-11-01 04:00:00",
},
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{6}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{4}),
RetentionDays: 8,
},
base: "2020-10-31 04:00:00",
want: "2020-11-01 04:00:00",
},
{
in: &SSnapshotPolicy{
RepeatWeekdays: SnapshotPolicyManager.RepeatWeekdaysParseIntArray([]int{1, 6}),
TimePoints: SnapshotPolicyManager.TimePointsParseIntArray([]int{4}),
RetentionDays: 4,
},
base: "2020-10-31 04:00:00",
want: "2020-11-02 04:00:00",
},
}
for _, c := range cases {
base, _ := time.Parse(timeStr, c.base)
want, _ := time.Parse(timeStr, c.want)
real := c.in.ComputeNextSyncTime(base)
if want != real {
t.Fatalf("want: %s, real: %s", want, real)
}
}
})
}
-566
View File
@@ -1,566 +0,0 @@
// 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"
"fmt"
"strings"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/appsrv"
"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/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SSnapshotPolicyCacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SCloudregionResourceBaseManager
SManagedResourceBaseManager
SSnapshotPolicyResourceBaseManager
}
type SSnapshotPolicyCache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SCloudregionResourceBase
SManagedResourceBase
SSnapshotPolicyResourceBase `width:"128" charset:"ascii" create:"required"`
// SnapshotpolicyId string `width:"128" charset:"ascii" create:"required"`
}
var SnapshotPolicyCacheManager *SSnapshotPolicyCacheManager
func init() {
SnapshotPolicyCacheManager = &SSnapshotPolicyCacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SSnapshotPolicyCache{},
"snapshotpolicycache_tbl",
"snapshotpolicycache",
"snapshotpolicycaches",
),
}
SnapshotPolicyCacheManager.SetVirtualObject(SnapshotPolicyCacheManager)
}
func NewSSnapshotPolicyCache(snapshotpolicyId, cloudregionId, externalId string) *SSnapshotPolicyCache {
cache := SSnapshotPolicyCache{
// SnapshotpolicyId: snapshotpolicyId,
SCloudregionResourceBase: SCloudregionResourceBase{
CloudregionId: cloudregionId,
},
SExternalizedResourceBase: db.SExternalizedResourceBase{
ExternalId: externalId,
},
}
cache.SnapshotpolicyId = snapshotpolicyId
cache.SetModelManager(SnapshotPolicyCacheManager, &cache)
return &cache
}
// 快照策略缓存列表
func (spcm *SSnapshotPolicyCacheManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.SnapshotPolicyCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = spcm.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemFilter")
}
q, err = spcm.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = spcm.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
q, err = spcm.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
q, err = spcm.SSnapshotPolicyResourceBaseManager.ListItemFilter(ctx, q, userCred, query.SnapshotPolicyFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SSnapshotPolicyResourceBaseManager.ListItemFilter")
}
/*if snapshotpolicyIden := query.Snapshotpolicy; len(snapshotpolicyIden) > 0 {
snapshotpolicy, err := SnapshotPolicyManager.FetchByIdOrName(userCred, snapshotpolicyIden)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2(SnapshotPolicyManager.Keyword(), snapshotpolicyIden)
} else {
return nil, err
}
}
q = q.Equals("snapshotpolicy_id", snapshotpolicy.GetId())
}*/
return q, nil
}
func (spcm *SSnapshotPolicyCacheManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.SnapshotPolicyCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = spcm.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = spcm.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = spcm.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
q, err = spcm.SSnapshotPolicyResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.SnapshotPolicyFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SSnapshotPolicyResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (spcm *SSnapshotPolicyCacheManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = spcm.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = spcm.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = spcm.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = spcm.SSnapshotPolicyResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (spc *SSnapshotPolicyCache) GetIRegion(ctx context.Context) (cloudprovider.ICloudRegion, error) {
provider, err := spc.GetDriver(ctx)
if err != nil {
return nil, err
}
if region := CloudregionManager.FetchRegionById(spc.CloudregionId); region != nil {
return provider.GetIRegionById(region.ExternalId)
}
return nil, fmt.Errorf("failed to find iregion for snapshotpolicycache %s: cloudregion %s manager %s", spc.Id,
spc.CloudregionId, spc.ManagerId)
}
func (spc *SSnapshotPolicyCache) GetSnapshotPolicy() (*SSnapshotPolicy, error) {
model, err := SnapshotPolicyManager.FetchById(spc.SnapshotpolicyId)
if err != nil {
return nil, fmt.Errorf("failed to fetchsnapshotpolicy by %s", spc.SnapshotpolicyId)
}
return model.(*SSnapshotPolicy), nil
}
func (spcm *SSnapshotPolicyCacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.SnapshotPolicyCacheDetails {
rows := make([]api.SnapshotPolicyCacheDetails, len(objs))
stdRows := spcm.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
manRows := spcm.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := spcm.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
snapshotPolicyRows := spcm.SSnapshotPolicyResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.SnapshotPolicyCacheDetails{
StatusStandaloneResourceDetails: stdRows[i],
ManagedResourceInfo: manRows[i],
CloudregionResourceInfo: regionRows[i],
SnapshotPolicyResourceInfo: snapshotPolicyRows[i],
}
}
return rows
}
// =============================================== detach and delete ===================================================
func (spc *SSnapshotPolicyCache) RealDetele(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, spc)
}
func (spc *SSnapshotPolicyCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (spc *SSnapshotPolicyCache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential,
query jsonutils.JSONObject, data jsonutils.JSONObject) error {
spc.SetStatus(userCred, api.SNAPSHOT_POLICY_CACHE_STATUS_DELETING, "")
task, err := taskman.TaskManager.NewTask(ctx, "SnapshotPolicyCacheDeleteTask", spc, userCred, nil, "", "", nil)
if err != nil {
return err
}
task.ScheduleRun(nil)
return nil
}
// ================================================= new and regist ====================================================
func (spcm *SSnapshotPolicyCacheManager) NewCache(ctx context.Context, userCred mcclient.TokenCredential,
snapshotPolicyId, regionId, providerId string) (*SSnapshotPolicyCache, error) {
snapshotPolicyCache := NewSSnapshotPolicyCache(snapshotPolicyId, regionId, "")
snapshotPolicyCache.ManagerId = providerId
err := snapshotPolicyCache.CreateCloudSnapshotPolicy(ctx)
if err != nil {
return nil, err
}
snapshotPolicyCache.Status = api.SNAPSHOT_POLICY_CACHE_STATUS_READY
// should have lock
if err := spcm.TableSpec().Insert(ctx, snapshotPolicyCache); err != nil {
return nil, errors.Wrapf(err, "insert snapshotpolicycache failed")
}
return snapshotPolicyCache, nil
}
func (spcm *SSnapshotPolicyCacheManager) NewCacheWithExternalId(ctx context.Context, userCred mcclient.TokenCredential,
snapshotPolicyId, externalId, regionId, providerId string, name string) (*SSnapshotPolicyCache, error) {
snapshotPolicyCache := NewSSnapshotPolicyCache(snapshotPolicyId, regionId, externalId)
snapshotPolicyCache.ManagerId = providerId
snapshotPolicyCache.Status = api.SNAPSHOT_POLICY_CACHE_STATUS_READY
snapshotPolicyCache.Name = name
// should have lock
if err := spcm.TableSpec().Insert(ctx, snapshotPolicyCache); err != nil {
return nil, errors.Wrapf(err, "insert snapshotpolicycache failed")
}
return snapshotPolicyCache, nil
}
func (spcm *SSnapshotPolicyCacheManager) Register(ctx context.Context, userCred mcclient.TokenCredential, snapshotPolicyId,
regionId string, providerId string) (*SSnapshotPolicyCache, error) {
// Many request about same snapshot policy with same region and provider coming will cause many same cache
// building without lock, so we must Lock.
lockman.LockRawObject(ctx, snapshotPolicyId, regionId+providerId)
defer lockman.ReleaseRawObject(ctx, snapshotPolicyId, regionId+providerId)
snapshotPolicyCache, err := spcm.FetchSnapshotPolicyCache(snapshotPolicyId, regionId, providerId)
// error
if err != nil {
return nil, err
}
// no cache
if snapshotPolicyCache != nil {
return snapshotPolicyCache, nil
}
return spcm.NewCache(ctx, userCred, snapshotPolicyId, regionId, providerId)
}
// ==================================================== fetch =========================================================
func (spcm *SSnapshotPolicyCacheManager) FetchSnapshotpolicyCaheById(cacheId string) (*SSnapshotPolicyCache, error) {
q := spcm.FilterById(spcm.Query(), cacheId)
return spcm.fetchByQuery(q)
}
func (spcm *SSnapshotPolicyCacheManager) FetchSnapshotPolicyCache(snapshotPolicyId, regionId, providerId string) (*SSnapshotPolicyCache, error) {
q := spcm.Query()
q.Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("snapshotpolicy_id"), snapshotPolicyId),
sqlchemy.Equals(q.Field("cloudregion_id"), regionId),
sqlchemy.Equals(q.Field("manager_id"), providerId)))
return spcm.fetchByQuery(q)
}
func (spcm *SSnapshotPolicyCacheManager) FetchSnapshotPolicyCacheByExtId(externalId, regionId,
providerId string) (*SSnapshotPolicyCache, error) {
q := spcm.Query()
q.Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("external_id"), externalId),
sqlchemy.Equals(q.Field("cloudregion_id"), regionId),
sqlchemy.Equals(q.Field("manager_id"), providerId)))
return spcm.fetchByQuery(q)
}
func (spcm *SSnapshotPolicyCacheManager) FetchAllByExtIds(externalIds []string, regionId,
providerId string) ([]SSnapshotPolicyCache, error) {
q := spcm.Query().In("external_id", externalIds).Equals("cloudregion_id", regionId).Equals("manager_id", providerId)
return spcm.fetchAllByQuery(q)
}
func (spcm *SSnapshotPolicyCacheManager) FetchAllBySnpId(snapshotPolicyId string) ([]SSnapshotPolicyCache, error) {
q := spcm.Query().Equals("snapshotpolicy_id", snapshotPolicyId)
return spcm.fetchAllByQuery(q)
}
func (spcm *SSnapshotPolicyCacheManager) FetchAllByRegionProvider(cloudregionId,
managerId string) ([]SSnapshotPolicyCache, error) {
q := spcm.Query().Equals("cloudregion_id", cloudregionId).Equals("manager_id", managerId)
return spcm.fetchAllByQuery(q)
}
func (spcm *SSnapshotPolicyCacheManager) fetchAllByQuery(q *sqlchemy.SQuery) ([]SSnapshotPolicyCache, error) {
caches := make([]SSnapshotPolicyCache, 0, 1)
if err := db.FetchModelObjects(spcm, q, &caches); err != nil {
return nil, err
}
return caches, nil
}
func (spcm *SSnapshotPolicyCacheManager) fetchByQuery(q *sqlchemy.SQuery) (*SSnapshotPolicyCache, error) {
count, err := q.CountWithError()
if err != nil {
return nil, err
}
if count == 0 {
return nil, nil
}
snapshotPolicyCache := SSnapshotPolicyCache{}
// if exist, only one
q.First(&snapshotPolicyCache)
snapshotPolicyCache.SetModelManager(spcm, &snapshotPolicyCache)
return &snapshotPolicyCache, nil
}
// ============================================== cloud operation ======================================================
// This function should call in the task.
type sOperaResult struct {
err error
snapshotPolicyId string
}
func (spcm *SSnapshotPolicyCacheManager) UpdateCloudSnapshotPolicy(snapshotPolicyId string,
input *cloudprovider.SnapshotPolicyInput) error {
//todo maybe
return fmt.Errorf("Not implement")
}
type snapshotPolicyTask struct {
ctx context.Context
userCred mcclient.TokenCredential
spc SSnapshotPolicyCache
retChan chan sOperaResult
}
func (t *snapshotPolicyTask) Run() {
err := t.spc.DeleteCloudSnapshotPolicy(t.ctx)
if err != nil {
t.retChan <- sOperaResult{err, t.spc.GetId()}
return
}
err = t.spc.RealDetele(t.ctx, t.userCred)
if err != nil {
t.retChan <- sOperaResult{errors.Wrap(err, "delete cache in database failed"), t.spc.GetId()}
return
}
t.retChan <- sOperaResult{nil, t.spc.GetId()}
}
func (t *snapshotPolicyTask) Dump() string {
return ""
}
func (spcm *SSnapshotPolicyCacheManager) DeleteCloudSnapshotPolices(ctx context.Context,
userCred mcclient.TokenCredential, snapshotPolicyId string) error {
spCaches, err := spcm.FetchAllBySnpId(snapshotPolicyId)
if err != nil {
return errors.Wrapf(err, "fetch all snapshotPolicyCaches ofsnapshotpolicy %s failed", snapshotPolicyId)
}
if len(spCaches) == 0 {
return nil
}
wm := appsrv.NewWorkerManager("delete-cloud-snapshotpolices", len(spCaches), 1, false)
task := &snapshotPolicyTask{
ctx: ctx,
userCred: userCred,
retChan: make(chan sOperaResult),
}
for i := range spCaches {
task.spc = spCaches[i]
wm.Run(task, nil, func(e error) {
task.retChan <- sOperaResult{e, task.spc.GetId()}
})
}
failedRecord := make([]string, 0)
for i := 0; i < len(spCaches); i++ {
ret := <-task.retChan
if ret.err != nil {
failedRecord = append(failedRecord, fmt.Sprintf("%s failed because that %s", ret.snapshotPolicyId,
ret.err.Error()))
}
}
if len(failedRecord) != 0 {
return fmt.Errorf("delete: " + strings.Join(failedRecord, "; "))
}
return nil
}
func (spc *SSnapshotPolicyCache) CreateCloudSnapshotPolicy(ctx context.Context) error {
// create correspondingsnapshotpolicy in cloud
iregion, err := spc.GetIRegion(ctx)
if err != nil {
return err
}
snapshotPolicy, err := spc.GetSnapshotPolicy()
if err != nil {
return err
}
externalId, err := iregion.CreateSnapshotPolicy(snapshotPolicy.GenerateCreateSpParams())
if err != nil {
return errors.Wrap(err, "createsnapshotpolicy failed")
}
spc.ExternalId = externalId
spc.Name = snapshotPolicy.Name
iPolicy, err := iregion.GetISnapshotPolicyById(externalId)
if err != nil {
return err
}
err = cloudprovider.WaitStatus(iPolicy, api.SNAPSHOT_POLICY_READY, 10*time.Second, 300*time.Second)
if err != nil {
return err
}
return nil
}
func (spc *SSnapshotPolicyCache) DeleteCloudSnapshotPolicy(ctx context.Context) error {
if len(spc.ExternalId) > 0 {
iregion, err := spc.GetIRegion(ctx)
if err != nil {
return err
}
cloudSp, err := iregion.GetISnapshotPolicyById(spc.ExternalId)
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil
}
if err != nil {
return errors.Wrap(err, "fetch snapshotpolicy from cloud before deleting failed")
}
if cloudSp == nil {
return nil
}
return iregion.DeleteSnapshotPolicy(spc.ExternalId)
}
return nil
}
func (spc *SSnapshotPolicyCache) UpdateCloudSnapshotPolicy(ctx context.Context, input *cloudprovider.SnapshotPolicyInput) error {
iregion, err := spc.GetIRegion(ctx)
if err != nil {
return err
}
err = iregion.UpdateSnapshotPolicy(input, spc.ExternalId)
if err != nil {
return errors.Wrap(err, "createsnapshotpolicy failed")
}
return nil
}
func (manager *SSnapshotPolicyCacheManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.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 (manager *SSnapshotPolicyCacheManager) ResourceScope() rbacscope.TRbacScope {
return rbacscope.ScopeProject
}
func (spc *SSnapshotPolicyCache) GetOwnerId() mcclient.IIdentityProvider {
p, err := spc.GetSnapshotPolicy()
if err != nil {
log.Errorf("unable to get snapshotpolicy of snapshotpolicycache %s: %v", spc.GetId(), err)
return nil
}
return p.GetOwnerId()
}
+29 -586
View File
@@ -15,31 +15,16 @@
package models
import (
"bytes"
"context"
"database/sql"
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/sets"
"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/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SSnapshotPolicyDiskManager struct {
db.SVirtualJointResourceBaseManager
SSnapshotPolicyResourceBaseManager
SDiskResourceBaseManager
}
@@ -58,9 +43,9 @@ func init() {
SnapshotPolicyDiskManager = &SSnapshotPolicyDiskManager{
SVirtualJointResourceBaseManager: db.NewVirtualJointResourceBaseManager(
SSnapshotPolicyDisk{},
"snapshotpolicydisks_tbl",
"snapshotpolicydisk",
"snapshotpolicydisks",
"snapshot_policy_disks_tbl",
"snapshot_policy_disk",
"snapshot_policy_disks",
DiskManager,
SnapshotPolicyManager,
),
@@ -73,584 +58,42 @@ func init() {
type SSnapshotPolicyDisk struct {
db.SVirtualJointResourceBase
SSnapshotPolicyResourceBase `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
SDiskResourceBase `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
Status string `width:"36" charset:"ascii" nullable:"false" default:"init" list:"user" create:"optional"`
NextSyncTime time.Time
SnapshotpolicyId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
SDiskResourceBase `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
}
func (sd *SSnapshotPolicyDisk) SetStatus(userCred mcclient.TokenCredential, status string, reason string) error {
if sd.Status == status {
return nil
}
oldStatus := sd.Status
_, err := db.Update(sd, func() error {
sd.Status = status
return nil
})
func (self *SSnapshotPolicyDisk) GetDisk() (*SDisk, error) {
disk, err := DiskManager.FetchById(self.DiskId)
if err != nil {
return err
return nil, errors.Wrapf(err, "FetchById(%s)", self.DiskId)
}
if userCred != nil {
notes := fmt.Sprintf("%s=>%s", oldStatus, status)
if len(reason) > 0 {
notes = fmt.Sprintf("%s: %s", notes, reason)
}
db.OpsLog.LogEvent(sd, db.ACT_UPDATE_STATUS, notes, userCred)
}
return nil
return disk.(*SDisk), nil
}
func (manager *SSnapshotPolicyDiskManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.SnapshotPolicyDiskDetails {
rows := make([]api.SnapshotPolicyDiskDetails, len(objs))
virtRows := manager.SVirtualJointResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
snapIds := make([]string, len(rows))
diskIds := make([]string, len(rows))
for i := range rows {
rows[i] = api.SnapshotPolicyDiskDetails{
VirtualJointResourceBaseDetails: virtRows[i],
}
snapIds[i] = objs[i].(*SSnapshotPolicyDisk).SnapshotpolicyId
diskIds[i] = objs[i].(*SSnapshotPolicyDisk).DiskId
}
snapIdMaps, err := db.FetchIdNameMap2(SnapshotPolicyManager, snapIds)
func (self *SSnapshotPolicyDisk) GetSnapshotPolicy() (*SSnapshotPolicy, error) {
policy, err := SnapshotPolicyManager.FetchById(self.SnapshotpolicyId)
if err != nil {
log.Errorf("FetchIdNameMap2 fail for snapshot Ids %s", err)
return rows
return nil, errors.Wrapf(err, "FetchById(%s)", self.SnapshotpolicyId)
}
disks := make(map[string]SDisk)
err = db.FetchStandaloneObjectsByIds(DiskManager, diskIds, &disks)
if err != nil {
log.Errorf("FetchStandaloneObjectsByIds for disks fail %s", err)
return rows
}
for i := range rows {
if name, ok := snapIdMaps[snapIds[i]]; ok {
rows[i].Snapshotpolicy = name
}
if disk, ok := disks[diskIds[i]]; ok {
rows[i].Disk = api.DiskDetails{}
jsonutils.Update(&rows[i].Disk, disk)
}
}
return rows
return policy.(*SSnapshotPolicy), nil
}
// ==================================================== fetch ==========================================================
func (m *SSnapshotPolicyDiskManager) FetchBySnapshotPolicyDisk(spId, diskId string) (*SSnapshotPolicyDisk, error) {
q := m.Query().Equals("snapshotpolicy_id", spId).Equals("disk_id", diskId)
ret := make([]SSnapshotPolicyDisk, 0, 1)
err := db.FetchModelObjects(m, q, &ret)
if err != nil {
return nil, err
}
if len(ret) == 0 {
return nil, nil
}
return &ret[0], nil
func (man *SSnapshotPolicyDiskManager) RemoveByDisk(id string) error {
_, err := sqlchemy.GetDB().Exec(
fmt.Sprintf(
"delete from %s where disk_id = ?",
man.TableSpec().Name(),
), id,
)
return err
}
func (sdm *SSnapshotPolicyDiskManager) InitializeData() error {
diskQ := DiskManager.Query("id").SubQuery()
sdQ := sdm.Query().NotIn("disk_id", diskQ)
var sds []SSnapshotPolicyDisk
err := db.FetchModelObjects(sdm, sdQ, &sds)
if err != nil {
return errors.Wrap(err, "unable to FetchModelObjects")
}
for i := range sds {
sd := &sds[i]
_, err := db.Update(sd, func() error {
return sd.MarkDelete()
})
if err != nil {
return err
}
}
sds = make([]SSnapshotPolicyDisk, 0)
q := sdm.Query().IsNullOrEmpty("next_sync_time")
err = db.FetchModelObjects(sdm, q, &sds)
if err != nil {
return err
}
// fetch all snapshotpolicy
spIdSet := sets.NewString()
for i := range sds {
spIdSet.Insert(sds[i].SnapshotpolicyId)
}
sps, err := SnapshotPolicyManager.FetchAllByIds(spIdSet.UnsortedList())
if err != nil {
return errors.Wrap(err, "FetchAllByIds")
}
spMap := make(map[string]*SSnapshotPolicy, len(sps))
for i := range sps {
spMap[sps[i].GetId()] = &sps[i]
}
now := time.Now()
for i := range sds {
sd := &sds[i]
_, err := db.Update(sd, func() error {
sd.NextSyncTime = spMap[sd.SnapshotpolicyId].ComputeNextSyncTime(now)
return nil
})
if err != nil {
return errors.Wrap(err, "db.Update")
}
}
return nil
}
func (m *SSnapshotPolicyDiskManager) FetchAllByDiskID(ctx context.Context, userCred mcclient.TokenCredential,
diskID string) ([]SSnapshotPolicyDisk, error) {
return m.fetchAll(ctx, userCred, m.GetMasterFieldName(), diskID)
}
func (m *SSnapshotPolicyDiskManager) FetchAllBySnapshotpolicyID(ctx context.Context, userCred mcclient.TokenCredential,
snapshotPolicyID string) ([]SSnapshotPolicyDisk, error) {
return m.fetchAll(ctx, userCred, m.GetSlaveFieldName(), snapshotPolicyID)
}
func (m *SSnapshotPolicyDiskManager) FetchDiskCountBySPID(snapshotpolicyID string) (int, error) {
disksq := DiskManager.Query("id").IsFalse("pending_deleted").SubQuery()
sdsq := m.Query().SubQuery()
q := sdsq.Query().Join(disksq, sqlchemy.Equals(disksq.Field("id"),
sdsq.Field("disk_id"))).Equals("snapshotpolicy_id", snapshotpolicyID)
return q.CountWithError()
}
func (m *SSnapshotPolicyDiskManager) fetchAll(ctx context.Context, userCred mcclient.TokenCredential,
fieldName string, fieldValue string) ([]SSnapshotPolicyDisk, error) {
q := m.Query()
q.Equals(fieldName, fieldValue)
ret := make([]SSnapshotPolicyDisk, 0)
err := db.FetchModelObjects(m, q, &ret)
if err != nil {
return nil, err
}
return ret, nil
}
// ==================================================== sync ===========================================================
// SyncDetachByDisk will detach all snapshot policies fo cloudRelations
// if cloudRelations is nil, it will detach all shapshot policies which has been attached to disk.
func (m *SSnapshotPolicyDiskManager) SyncDetachByDisk(ctx context.Context, userCred mcclient.TokenCredential,
cloudRelations []SSnapshotPolicyDisk, disk *SDisk) error {
snapshotPolicyDisks := cloudRelations
var err error
if snapshotPolicyDisks == nil {
snapshotPolicyDisks, err = m.FetchAllByDiskID(ctx, userCred, disk.GetId())
if err != nil {
return errors.Wrapf(err, "Fetach allsnapshotpolicy of disk %s in database", disk.GetId())
}
}
failResult := make([]string, 0, 1)
for i := range snapshotPolicyDisks {
err = snapshotPolicyDisks[i].DetachByDisk(ctx, userCred, disk)
if err != nil {
failResult = append(failResult, snapshotPolicyDisks[i].GetId())
}
}
if len(failResult) != 0 {
errInfo := "detach failed which IDs are: "
return errors.Error(errInfo + strings.Join(failResult, ", "))
}
return nil
}
// SyncDetachBySnapshotpolicy detach all sn
func (m *SSnapshotPolicyDiskManager) SyncDetachBySnapshotpolicy(ctx context.Context,
userCred mcclient.TokenCredential, cloudRelations []SSnapshotPolicyDisk, snapshotPolicy *SSnapshotPolicy) error {
snapshotPolicyDisks := cloudRelations
var err error
if snapshotPolicyDisks == nil {
snapshotPolicyDisks, err = m.FetchAllBySnapshotpolicyID(ctx, userCred, snapshotPolicy.GetId())
if err != nil {
return errors.Wrapf(err, "Fetach all bysnapshotpolicy %s in database", snapshotPolicy.GetId())
}
}
failResult := make([]string, 0, 1)
for i := range snapshotPolicyDisks {
err = snapshotPolicyDisks[i].DetachBySnapshotpolicy(ctx, userCred, snapshotPolicy)
if err != nil {
failResult = append(failResult, snapshotPolicyDisks[i].GetId())
}
}
if len(failResult) != 0 {
errInfo := "detach failed which IDs are "
return errors.Error(errInfo + strings.Join(failResult, ", "))
}
return nil
}
func (m *SSnapshotPolicyDiskManager) SyncByDisk(ctx context.Context, userCred mcclient.TokenCredential,
extSnapshotpolicies []string, syncOwnerID mcclient.IIdentityProvider, disk *SDisk, storage *SStorage) error {
sds, err := m.FetchAllByDiskID(ctx, userCred, disk.GetId())
if err != nil {
return errors.Wrapf(err, "Fetach allsnapshotpolicy of disk %s in database", disk.GetId())
}
//fetch snapshotPolicy Cache to find the snapshotpolicyID corresponding to extSnapshotpolicyID
region, _ := storage.GetRegion()
spCaches, err := SnapshotPolicyCacheManager.FetchAllByExtIds(extSnapshotpolicies, region.GetId(),
storage.ManagerId)
if err != nil {
return errors.Wrapf(err, "fetachsnapshotpolicy caches failed")
}
cloudRelationsSet := make(map[string]struct{})
for i := range spCaches {
cloudRelationsSet[spCaches[i].SnapshotpolicyId] = struct{}{}
}
removed := make([]SSnapshotPolicyDisk, 0, 1)
added := make([]string, 0, 1)
for i := range sds {
if _, ok := cloudRelationsSet[sds[i].SnapshotpolicyId]; !ok {
removed = append(removed, sds[i])
}
delete(cloudRelationsSet, sds[i].SnapshotpolicyId)
}
for k := range cloudRelationsSet {
added = append(added, k)
}
err = m.SyncDetachByDisk(ctx, userCred, removed, disk)
if err != nil {
return err
}
err = m.SyncAttachDisk(ctx, userCred, added, syncOwnerID, disk)
if err != nil {
return err
}
return nil
}
func (m *SSnapshotPolicyDiskManager) SyncAttachDisk(ctx context.Context, userCred mcclient.TokenCredential,
Snapshotpolicies []string, syncOwnerID mcclient.IIdentityProvider, disk *SDisk) error {
lockman.LockRawObject(ctx, "snapshot-policies", disk.Id)
defer lockman.ReleaseRawObject(ctx, "snapshot-policies", disk.Id)
failRecord := make([]string, 0, 1)
for _, spId := range Snapshotpolicies {
snapshotpolicyDisk, err := db.FetchJointByIds(m, disk.GetId(), spId, jsonutils.JSONNull)
if err != nil && err != sql.ErrNoRows {
failRecord = append(failRecord,
fmt.Sprintf("Get SnapshotpolicyDisk whose diskid %s snapshotpolicyid %s failed",
disk.GetId(), spId))
continue
}
if snapshotpolicyDisk != nil {
continue
}
sd := SSnapshotPolicyDisk{}
sd.DiskId = disk.GetId()
sd.SnapshotpolicyId = spId
sd.Status = api.SNAPSHOT_POLICY_DISK_READY
err = m.TableSpec().Insert(ctx, &sd)
if err != nil {
failRecord = append(failRecord, fmt.Sprintf("attachsnapshotpolicy %s to disk %s failed",
spId, disk.GetId()))
continue
}
}
if len(failRecord) == 0 {
return nil
}
buf := bytes.NewBufferString("sync attach extSnapshotpolicies to disk ")
buf.WriteString(disk.GetId())
buf.WriteString("failed because that ")
for i := range failRecord {
buf.WriteString(failRecord[i])
buf.WriteString(", ")
}
buf.Truncate(buf.Len() - 2)
return errors.Error(buf.String())
}
func (m *SSnapshotPolicyDiskManager) SyncAttachDiskExt(ctx context.Context, userCred mcclient.TokenCredential,
extSnapshotpolicies []string, syncOwnerID mcclient.IIdentityProvider, disk *SDisk, storage *SStorage) error {
//fetch snapshotPolicy Cache to find the snapshotpolicyID corresponding to extSnapshotpolicyID
region, _ := storage.GetRegion()
spCaches, err := SnapshotPolicyCacheManager.FetchAllByExtIds(extSnapshotpolicies, region.GetId(),
storage.ManagerId)
if err != nil {
return errors.Wrapf(err, "fetachsnapshotpolicy caches failed")
}
snapshotPolicie := make([]string, 0, 1)
for i := range spCaches {
snapshotPolicie = append(snapshotPolicie, spCaches[i].SnapshotpolicyId)
}
return m.SyncAttachDisk(ctx, userCred, snapshotPolicie, syncOwnerID, disk)
}
// ==================================================== detach =========================================================
func (sd *SSnapshotPolicyDisk) RealDetach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, sd)
}
func (sd *SSnapshotPolicyDisk) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (sd *SSnapshotPolicyDisk) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
// syncDetach should lock before
func (sd *SSnapshotPolicyDisk) DetachByDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk) error {
snapshotPolicy := SSnapshotPolicy{}
snapshotPolicy.Id = sd.SnapshotpolicyId
snapshotPolicy.SetModelManager(SnapshotPolicyManager, &snapshotPolicy)
lockman.LockJointObject(ctx, disk, &snapshotPolicy)
defer lockman.ReleaseJointObject(ctx, disk, &snapshotPolicy)
// todo call real Detach
return sd.RealDetach(ctx, userCred)
}
func (sd *SSnapshotPolicyDisk) DetachBySnapshotpolicy(ctx context.Context, userCred mcclient.TokenCredential,
snapshotPolicy *SSnapshotPolicy) error {
disk := SDisk{}
disk.Id = sd.DiskId
disk.SetModelManager(DiskManager, &disk)
lockman.LockJointObject(ctx, &disk, snapshotPolicy)
defer lockman.ReleaseJointObject(ctx, &disk, snapshotPolicy)
return sd.RealDetach(ctx, userCred)
}
// ==================================================== create =========================================================
const ErrExistSD = errors.Error("snapshotpolicy disk has been exist")
func (self *SSnapshotPolicyDiskManager) newSnapshotpolicyDisk(ctx context.Context, userCred mcclient.TokenCredential,
sp *SSnapshotPolicy, disk *SDisk) (*SSnapshotPolicyDisk, error) {
q := self.Query().Equals("snapshotpolicy_id", sp.GetId()).Equals("disk_id", disk.GetId())
count, err := q.CountWithError()
if err != nil {
return nil, nil
}
if count > 0 {
spd := SSnapshotPolicyDisk{}
q.First(&spd)
spd.SetModelManager(self, &spd)
return &spd, ErrExistSD
}
spd := SSnapshotPolicyDisk{}
spd.SnapshotpolicyId = sp.GetId()
spd.DiskId = disk.GetId()
now := time.Now()
spd.NextSyncTime = sp.ComputeNextSyncTime(now)
spd.SetModelManager(self, &spd)
lockman.LockJointObject(ctx, disk, sp)
defer lockman.ReleaseJointObject(ctx, disk, sp)
return &spd, self.TableSpec().Insert(ctx, &spd)
}
func (self *SSnapshotPolicyDiskManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
diskId, _ := data.GetString(self.GetMasterFieldName())
snapshotPolicyId, _ := data.GetString(self.GetSlaveFieldName())
disk := DiskManager.FetchDiskById(diskId)
snapshotPolicy, err := SnapshotPolicyManager.FetchSnapshotPolicyById(snapshotPolicyId)
if err != nil {
return nil, err
}
storage, _ := disk.GetStorage()
region, _ := storage.GetRegion()
err = region.GetDriver().ValidateCreateSnapshopolicyDiskData(ctx, userCred, disk, snapshotPolicy)
if err != nil {
return nil, err
}
//to control that one disk should only bind one snapshot policy
spds, err := SnapshotPolicyDiskManager.FetchAllByDiskID(ctx, userCred, diskId)
if err != nil {
return nil, err
}
if len(spds) > 1 {
return nil, httperrors.NewInputParameterError("disk %s has too many snapshot policy attached", diskId)
}
if len(spds) == 1 {
data.Add(jsonutils.NewString(spds[0].SnapshotpolicyId), "need_detach")
}
// I don't want to request to database again behind
data.Add(jsonutils.Marshal(snapshotPolicy), "snapshotPolicy")
data.Add(jsonutils.Marshal(disk), "disk")
return data, nil
}
func (sd *SSnapshotPolicyDisk) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
sp, err := SnapshotPolicyManager.FetchSnapshotPolicyById(sd.SnapshotpolicyId)
if err != nil {
return err
}
now := time.Now()
sd.NextSyncTime = sp.ComputeNextSyncTime(now)
return nil
}
func (sd *SSnapshotPolicyDisk) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.
IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
taskdata := data.(*jsonutils.JSONDict)
taskdata.Add(jsonutils.Marshal(sd), "snapshotPolicyDisk")
disk := &SDisk{}
data.Unmarshal(disk, "disk")
disk.SetModelManager(DiskManager, disk)
task, err := taskman.TaskManager.NewTask(ctx, "SnapshotPolicyApplyTask", disk, userCred, nil, "", "", nil)
if err != nil {
log.Errorf("SnapshotPolicyApplyTask newTask error %s", err)
} else {
task.ScheduleRun(taskdata)
}
}
// ==================================================== delete =========================================================
func (sd *SSnapshotPolicyDisk) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject,
data jsonutils.JSONObject) error {
diskID := sd.DiskId
model, err := DiskManager.FetchById(diskID)
if err != nil {
return errors.Wrapf(err, "Fetch disk by ID %s failed", diskID)
}
disk := model.(*SDisk)
snapshotPolicyID := sd.SnapshotpolicyId
taskData := jsonutils.NewDict()
taskData.Add(jsonutils.NewString(snapshotPolicyID), "snapshot_policy_id")
taskData.Add(jsonutils.Marshal(sd), "snapshotPolicyDisk")
sd.SetStatus(userCred, api.SNAPSHOT_POLICY_DISK_DELETING, "")
task, err := taskman.TaskManager.NewTask(ctx, "SnapshotPolicyCancelTask", disk, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrapf(err, "SnapshotPolicyCancelTask newTask error %s", err)
} else {
task.ScheduleRun(taskData)
}
return nil
}
func (manager *SSnapshotPolicyDiskManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.SnapshotPolicyDiskListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SVirtualJointResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualJointResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SVirtualJointResourceBaseManager.ListItemFilter")
}
q, err = manager.SSnapshotPolicyResourceBaseManager.ListItemFilter(ctx, q, userCred, query.SnapshotPolicyFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SSnapshotPolicyResourceBaseManager.ListItemFilter")
}
q, err = manager.SDiskResourceBaseManager.ListItemFilter(ctx, q, userCred, query.DiskFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SDiskResourceBaseManager.ListItemFilter")
}
if len(query.Status) > 0 {
q = q.In("status", query.Status)
}
return q, nil
}
func (manager *SSnapshotPolicyDiskManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.SnapshotPolicyDiskListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SVirtualJointResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualJointResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SVirtualJointResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SSnapshotPolicyResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.SnapshotPolicyFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SSnapshotPolicyResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SDiskResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.DiskFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SDiskResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SSnapshotPolicyDiskManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SVirtualJointResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SSnapshotPolicyResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SDiskResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SSnapshotPolicyDiskManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SVirtualJointResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SVirtualJointResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SSnapshotPolicyResourceBaseManager.GetExportKeys()...) {
q, err = manager.SSnapshotPolicyResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SSnapshotPolicyResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SDiskResourceBaseManager.GetExportKeys()...) {
q, err = manager.SDiskResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SDiskResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
func (man *SSnapshotPolicyDiskManager) RemoveBySnapshotpolicy(id string) error {
_, err := sqlchemy.GetDB().Exec(
fmt.Sprintf(
"delete from %s where snapshotpolicy_id = ?",
man.TableSpec().Name(),
), id,
)
return err
}
@@ -1,180 +0,0 @@
// 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"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/reflectutils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SSnapshotPolicyResourceBase struct {
// 本地快照策略ID
SnapshotpolicyId string `width:"36" charset:"ascii" nullable:"false" create:"required" index:"true" list:"user" json:"snapshotpolicy_id"`
}
type SSnapshotPolicyResourceBaseManager struct{}
func ValidateSnapshotPolicyResourceInput(userCred mcclient.TokenCredential, query api.SnapshotPolicyResourceInput) (*SSnapshotPolicy, api.SnapshotPolicyResourceInput, error) {
snapPolicyObj, err := SnapshotPolicyManager.FetchByIdOrName(userCred, query.SnapshotpolicyId)
if err != nil {
if err == sql.ErrNoRows {
return nil, query, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", SnapshotPolicyManager.Keyword(), query.SnapshotpolicyId)
} else {
return nil, query, errors.Wrap(err, "SnapshotPolicyManager.FetchByIdOrName")
}
}
query.SnapshotpolicyId = snapPolicyObj.GetId()
return snapPolicyObj.(*SSnapshotPolicy), query, nil
}
func (self *SSnapshotPolicyResourceBase) GetSnapshotPolicy() *SSnapshotPolicy {
spObj, err := SnapshotPolicyManager.FetchById(self.SnapshotpolicyId)
if err != nil {
log.Errorf("failed to find snapshot policy %s error: %v", self.SnapshotpolicyId, err)
return nil
}
return spObj.(*SSnapshotPolicy)
}
func (manager *SSnapshotPolicyResourceBaseManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.SnapshotPolicyResourceInfo {
rows := make([]api.SnapshotPolicyResourceInfo, len(objs))
snapshotPolicyIds := make([]string, len(objs))
for i := range objs {
var base *SSnapshotPolicyResourceBase
err := reflectutils.FindAnonymouStructPointer(objs[i], &base)
if err != nil {
log.Errorf("Cannot find SSnapshotPolicyResourceBase in object %s", objs[i])
continue
}
snapshotPolicyIds[i] = base.SnapshotpolicyId
}
snapshotPolicyNames, err := db.FetchIdNameMap2(SnapshotPolicyManager, snapshotPolicyIds)
if err != nil {
log.Errorf("FetchIdNameMap2 fail %s", err)
return rows
}
for i := range rows {
if name, ok := snapshotPolicyNames[snapshotPolicyIds[i]]; ok {
rows[i].Snapshotpolicy = name
}
}
return rows
}
func (manager *SSnapshotPolicyResourceBaseManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.SnapshotPolicyFilterListInput,
) (*sqlchemy.SQuery, error) {
if len(query.SnapshotpolicyId) > 0 {
snapPObj, _, err := ValidateSnapshotPolicyResourceInput(userCred, query.SnapshotPolicyResourceInput)
if err != nil {
return nil, errors.Wrap(err, "ValidateSnapshotPolicyResourceInput")
}
q = q.Equals("snapshotpolicy_id", snapPObj.GetId())
}
return q, nil
}
func (manager *SSnapshotPolicyResourceBaseManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.SnapshotPolicyFilterListInput,
) (*sqlchemy.SQuery, error) {
if !db.NeedOrderQuery(manager.GetOrderByFields(query)) {
return q, nil
}
orderQ := SnapshotPolicyManager.Query("id")
orderSubQ := orderQ.SubQuery()
orderQ, orders, fields := manager.GetOrderBySubQuery(orderQ, orderSubQ, orderQ.Field("id"), userCred, query, nil, nil)
q = q.LeftJoin(orderSubQ, sqlchemy.Equals(q.Field("snapshotpolicy_id"), orderSubQ.Field("id")))
q = db.OrderByFields(q, orders, fields)
return q, nil
}
func (manager *SSnapshotPolicyResourceBaseManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
if field == "snapshotpolicy" {
snapPolicyQuery := SnapshotPolicyManager.Query("name", "id").Distinct().SubQuery()
q.AppendField(snapPolicyQuery.Field("name", field))
q = q.Join(snapPolicyQuery, sqlchemy.Equals(q.Field("snapshotpolicy_id"), snapPolicyQuery.Field("id")))
q.GroupBy(snapPolicyQuery.Field("name"))
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SSnapshotPolicyResourceBaseManager) GetOrderBySubQuery(
q *sqlchemy.SQuery,
subq *sqlchemy.SSubQuery,
joinField sqlchemy.IQueryField,
userCred mcclient.TokenCredential,
query api.SnapshotPolicyFilterListInput,
orders []string,
fields []sqlchemy.IQueryField,
) (*sqlchemy.SQuery, []string, []sqlchemy.IQueryField) {
if !db.NeedOrderQuery(manager.GetOrderByFields(query)) {
return q, orders, fields
}
snapQ := SnapshotPolicyManager.Query().SubQuery()
q = q.LeftJoin(snapQ, sqlchemy.Equals(joinField, snapQ.Field("id")))
q = q.AppendField(snapQ.Field("name").Label("snapshotpolicy"))
orders = append(orders, query.OrderBySnapshotpolicy)
fields = append(fields, subq.Field("snapshotpolicy"))
return q, orders, fields
}
func (manager *SSnapshotPolicyResourceBaseManager) GetOrderByFields(query api.SnapshotPolicyFilterListInput) []string {
return []string{query.OrderBySnapshotpolicy}
}
func (manager *SSnapshotPolicyResourceBaseManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
if keys.ContainsAny(manager.GetExportKeys()...) {
subq := SnapshotPolicyManager.Query("id", "name").SubQuery()
q = q.LeftJoin(subq, sqlchemy.Equals(q.Field("snapshotpolicy_id"), subq.Field("id")))
if keys.Contains("snapshotpolicy") {
q = q.AppendField(subq.Field("name", "snapshotpolicy"))
}
}
return q, nil
}
func (manager *SSnapshotPolicyResourceBaseManager) GetExportKeys() []string {
return []string{"snapshotpolicy"}
}
+2 -3
View File
@@ -537,10 +537,9 @@ func (manager *SSnapshotManager) OnCreateComplete(ctx context.Context, items []d
func (self *SSnapshot) StartSnapshotCreateTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "SnapshotCreateTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return err
return errors.Wrapf(err, "NewTask")
}
task.ScheduleRun(nil)
return nil
return task.ScheduleRun(nil)
}
func (self *SSnapshot) GetGuest() (*SGuest, error) {
+2 -3
View File
@@ -106,9 +106,8 @@ type ComputeOptions struct {
DefaultMaxManualSnapshotCount int `default:"2" help:"Per Disk max manual snapshot count, default 2"`
//snapshot policy options
RetentionDaysLimit int `default:"49" help:"Days of snapshot retention, default 49 days"`
TimePointsLimit int `default:"1" help:"time point of every days, default 1 point"`
RepeatWeekdaysLimit int `default:"7" help:"day point of every weekday, default 7 points"`
RetentionDaysLimit int `default:"49" help:"Days of snapshot retention, default 49 days"`
TimePointsLimit int `default:"1" help:"time point of every days, default 1 point"`
ServerStatusSyncIntervalMinutes int `default:"5" help:"Interval to sync server status, defualt is 5 minutes"`
-18
View File
@@ -194,24 +194,6 @@ func (self *SAliyunRegionDriver) ValidateUpdateLoadbalancerListenerData(ctx cont
return input, nil
}
func (self *SAliyunRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context.Context,
userCred mcclient.TokenCredential, disk *models.SDisk, snapshotPolicy *models.SSnapshotPolicy) error {
//err := self.SManagedVirtualizationRegionDriver.ValidateCreateSnapshopolicyDiskData(ctx, userCred, disk, snapshotPolicy)
//if err != nil {
// return nil
//}
//// In Aliyun, One disk only apply one snapshot policy
//ret, err := models.SnapshotPolicyDiskManager.FetchAllByDiskID(ctx, userCred, disk.GetId())
//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
return nil
}
func (self *SAliyunRegionDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, storage *models.SStorage, input *api.SnapshotCreateInput) error {
if strings.HasPrefix(input.Name, "auto") || strings.HasPrefix(input.Name, "http://") || strings.HasPrefix(input.Name, "https://") {
return httperrors.NewBadRequestError(
+20 -24
View File
@@ -155,18 +155,6 @@ func (self *SBaseRegionDriver) RequestDeleteLoadbalancerListenerRule(ctx context
return fmt.Errorf("Not Implement RequestDeleteLoadbalancerListenerRule")
}
func (self *SBaseRegionDriver) RequestUpdateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, input cloudprovider.SnapshotPolicyInput, task taskman.ITask) error {
return fmt.Errorf("Not Implement RequestUpdateSnapshotPolicy")
}
func (self *SBaseRegionDriver) RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) error {
return fmt.Errorf("Not Implement RequestApplySnapshotPolicy")
}
func (self *SBaseRegionDriver) RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) error {
return fmt.Errorf("Not Implement RequestCancelSnapshotPolicy")
}
func (self *SBaseRegionDriver) ValidateSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot) error {
return fmt.Errorf("Not Implement ValidateSnapshotDelete")
}
@@ -195,18 +183,6 @@ func (self *SBaseRegionDriver) OnDiskReset(ctx context.Context, userCred mcclien
return fmt.Errorf("Not Implement OnDiskReset")
}
func (self *SBaseRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context.Context,
userCred mcclient.TokenCredential, disk *models.SDisk, snapshotPolicy *models.SSnapshotPolicy) error {
if disk.DomainId != snapshotPolicy.DomainId {
return httperrors.NewBadRequestError("disk and snapshotpolicy should have same domain")
}
if disk.ProjectId != snapshotPolicy.ProjectId {
return httperrors.NewBadRequestError("disk and snapshotpolicy should have same project")
}
return nil
}
func (self *SBaseRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error {
return fmt.Errorf("Not implement OnSnapshotDelete")
}
@@ -509,3 +485,23 @@ func (drv *SBaseRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *
func (self *SBaseRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateUpdateSecurityGroupInput")
}
func (self *SBaseRegionDriver) ValidateCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, input *api.SSnapshotPolicyCreateInput) (*api.SSnapshotPolicyCreateInput, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateSnapshotPolicy")
}
func (self *SBaseRegionDriver) RequestCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, sp *models.SSnapshotPolicy, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestCreateSnapshotPolicy")
}
func (self *SBaseRegionDriver) RequestDeleteSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, sp *models.SSnapshotPolicy, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestDeleteSnapshotPolicy")
}
func (self *SBaseRegionDriver) RequestSnapshotPolicyBindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, diskIds []string, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSnapshotPolicyBindDisks")
}
func (self *SBaseRegionDriver) RequestSnapshotPolicyUnbindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, diskIds []string, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSnapshotPolicyUnbindDisks")
}
+36 -62
View File
@@ -32,6 +32,7 @@ import (
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/compute"
hostapi "yunion.io/x/onecloud/pkg/apis/host"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -40,7 +41,6 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
@@ -846,57 +846,6 @@ func (self *SKVMRegionDriver) OnDiskReset(ctx context.Context, userCred mcclient
return models.GetStorageDriver(storage.StorageType).OnDiskReset(ctx, userCred, disk, snapshot, data)
}
func (self *SKVMRegionDriver) RequestUpdateSnapshotPolicy(ctx context.Context,
userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, input cloudprovider.SnapshotPolicyInput,
task taskman.ITask) error {
return nil
}
func (self *SKVMRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context.Context,
userCred mcclient.TokenCredential, disk *models.SDisk, snapshotPolicy *models.SSnapshotPolicy) error {
err := self.SBaseRegionDriver.ValidateCreateSnapshopolicyDiskData(ctx, userCred, disk, snapshotPolicy)
if err != nil {
return err
}
if snapshotPolicy.RetentionDays < -1 || snapshotPolicy.RetentionDays == 0 || snapshotPolicy.RetentionDays > options.Options.RetentionDaysLimit {
return httperrors.NewInputParameterError("Retention days must in 1~%d or -1", options.Options.RetentionDaysLimit)
}
repeatWeekdays := models.SnapshotPolicyManager.RepeatWeekdaysToIntArray(snapshotPolicy.RepeatWeekdays)
timePoints := models.SnapshotPolicyManager.TimePointsToIntArray(snapshotPolicy.TimePoints)
if len(repeatWeekdays) > options.Options.RepeatWeekdaysLimit {
return httperrors.NewInputParameterError("repeat_weekdays only contains %d days at most",
options.Options.RepeatWeekdaysLimit)
}
if len(timePoints) > options.Options.TimePointsLimit {
return httperrors.NewInputParameterError("time_points only contains %d points at most", options.Options.TimePointsLimit)
}
return nil
}
func (self *SKVMRegionDriver) RequestApplySnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
data := jsonutils.NewDict()
data.Add(jsonutils.NewString(sp.GetId()), "snapshotpolicy_id")
return data, nil
})
return nil
}
func (self *SKVMRegionDriver) RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
data := jsonutils.NewDict()
data.Add(jsonutils.NewString(sp.GetId()), "snapshotpolicy_id")
return data, nil
})
return nil
}
func (self *SKVMRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error {
task.SetStage("OnKvmSnapshotDelete", nil)
task.ScheduleRun(data)
@@ -1197,16 +1146,6 @@ func (self *SKVMRegionDriver) RequestAssociateEipForNAT(ctx context.Context, use
return errors.Wrapf(cloudprovider.ErrNotSupported, "RequestAssociateEipForNAT")
}
func (self *SKVMRegionDriver) RequestPreSnapshotPolicyApply(ctx context.Context, userCred mcclient.
TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return data, nil
})
return nil
}
func (self *SKVMRegionDriver) ValidateCacheSecgroup(ctx context.Context, userCred mcclient.TokenCredential, secgroup *models.SSecurityGroup, vpc *models.SVpc, classic bool) error {
return errors.Wrap(httperrors.ErrNotSupported, "No need to cache secgroup for onecloud region")
}
@@ -1642,3 +1581,38 @@ func (self *SKVMRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.C
return input, nil
}
func (self *SKVMRegionDriver) ValidateCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, input *api.SSnapshotPolicyCreateInput) (*api.SSnapshotPolicyCreateInput, error) {
return input, nil
}
func (self *SKVMRegionDriver) RequestCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, sp *models.SSnapshotPolicy, task taskman.ITask) error {
sp.SetStatus(userCred, apis.STATUS_AVAILABLE, "")
return task.ScheduleRun(nil)
}
func (self *SKVMRegionDriver) RequestDeleteSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, sp *models.SSnapshotPolicy, task taskman.ITask) error {
return task.ScheduleRun(nil)
}
func (self *SKVMRegionDriver) RequestSnapshotPolicyBindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, diskIds []string, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
disks, err := sp.GetUnbindDisks(diskIds)
if err != nil {
return nil, errors.Wrapf(err, "GetUnbindDisks")
}
ids := []string{}
for _, disk := range disks {
ids = append(ids, disk.Id)
}
return nil, sp.BindDisks(ctx, disks)
})
return nil
}
func (self *SKVMRegionDriver) RequestSnapshotPolicyUnbindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, diskIds []string, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return nil, sp.UnbindDisks(diskIds)
})
return nil
}
+122 -108
View File
@@ -33,6 +33,7 @@ import (
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -1038,90 +1039,6 @@ func (self *SManagedVirtualizationRegionDriver) RequestDeleteVpc(ctx context.Con
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestUpdateSnapshotPolicy(ctx context.Context, userCred mcclient.
TokenCredential, sp *models.SSnapshotPolicy, input cloudprovider.SnapshotPolicyInput, task taskman.ITask) error {
// it's too cumbersome to pass parameters in taskman, so change a simple way for the moment
//spcache, err := models.SnapshotPolicyCacheManager.FetchSnapshotPolicyCache(sp.GetId(), sp.CloudregionId, sp.ManagerId)
//if err != nil {
// return errors.Wrapf(err, "Fetch cache ofsnapshotpolicy %s", sp.GetId())
//}
//return spcache.UpdateCloudSnapshotPolicy(&input)
return nil
}
// RequestApplySnapshotPolicy apply snapshotpolicy for public cloud.
// In our system, one disk only can hava one snapshot policy attached.
// Default, some public cloud such as Aliyun is same with us and this function shoule be used for these public cloud.
// But in Some public cloud such as Qcloud different with us,
// we should wirte a new function in corressponding regiondriver which detach all snapshotpolicy of disk after
// attache new one.
// You can refer to the implementations of function SQcloudRegionDriver.RequestApplySnapshotPolicy().
func (self *SManagedVirtualizationRegionDriver) RequestApplySnapshotPolicy(ctx context.Context,
userCred mcclient.TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy,
data jsonutils.JSONObject) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
storage, _ := disk.GetStorage()
region, _ := storage.GetRegion()
regionId := region.GetId()
providerId := storage.ManagerId
spcache, err := models.SnapshotPolicyCacheManager.Register(ctx, userCred, sp.GetId(), regionId, providerId)
if err != nil {
return nil, errors.Wrap(err, "registersnapshotpolicy cache failed")
}
iRegion, err := disk.GetIRegion(ctx)
if err != nil {
return nil, err
}
err = iRegion.ApplySnapshotPolicyToDisks(spcache.GetExternalId(), disk.GetExternalId())
if err != nil {
return nil, err
}
data := jsonutils.NewDict()
data.Add(jsonutils.NewString(sp.GetId()), "snapshotpolicy_id")
return data, nil
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCancelSnapshotPolicy(ctx context.Context, userCred mcclient.
TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
storage, _ := disk.GetStorage()
region, _ := storage.GetRegion()
regionId := region.GetId()
providerId := storage.ManagerId
spcache, err := models.SnapshotPolicyCacheManager.FetchSnapshotPolicyCache(sp.GetId(), regionId, providerId)
if err != nil {
return nil, errors.Wrap(err, "registersnapshotpolicy cache failed")
}
iRegion, err := spcache.GetIRegion(ctx)
if err != nil {
return nil, err
}
data := jsonutils.NewDict()
data.Add(jsonutils.NewString(sp.GetId()), "snapshotpolicy_id")
err = iRegion.CancelSnapshotPolicyToDisks(spcache.GetExternalId(), disk.GetExternalId())
if errors.Cause(err) == cloudprovider.ErrNotFound {
return data, nil
}
if err != nil {
return nil, err
}
return data, nil
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) ValidateSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot) error {
return nil
}
@@ -1210,20 +1127,6 @@ func (self *SManagedVirtualizationRegionDriver) OnDiskReset(ctx context.Context,
return nil
}
func (self *SManagedVirtualizationRegionDriver) ValidateCreateSnapshopolicyDiskData(ctx context.Context,
userCred mcclient.TokenCredential, disk *models.SDisk, snapshotPolicy *models.SSnapshotPolicy) error {
err := self.SBaseRegionDriver.ValidateCreateSnapshopolicyDiskData(ctx, userCred, disk, snapshotPolicy)
if err != nil {
return err
}
if snapshotPolicy.RetentionDays < -1 || snapshotPolicy.RetentionDays == 0 || snapshotPolicy.RetentionDays > 65535 {
return httperrors.NewInputParameterError("Retention days must in 1~65535 or -1")
}
return nil
}
func (self *SManagedVirtualizationRegionDriver) OnSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot, task taskman.ITask, data jsonutils.JSONObject) error {
task.SetStage("OnManagedSnapshotDelete", nil)
task.ScheduleRun(data)
@@ -1238,16 +1141,6 @@ func (self *SManagedVirtualizationRegionDriver) RequestAssociateEipForNAT(ctx co
return eip.StartEipAssociateTask(ctx, userCred, jsonutils.Marshal(opts).(*jsonutils.JSONDict), task.GetTaskId())
}
func (self *SManagedVirtualizationRegionDriver) RequestPreSnapshotPolicyApply(ctx context.Context, userCred mcclient.
TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
return data, nil
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstance(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *models.SDBInstance, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iregion, err := dbinstance.GetIRegion(ctx)
@@ -3543,3 +3436,124 @@ func (self *SManagedVirtualizationRegionDriver) CreateDefaultSecurityGroup(
}
return newGroup, nil
}
func (self *SManagedVirtualizationRegionDriver) ValidateCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, input *api.SSnapshotPolicyCreateInput) (*api.SSnapshotPolicyCreateInput, error) {
if len(input.CloudproviderId) == 0 {
return nil, httperrors.NewMissingParameterError("cloudprovider_id")
}
managerObj, err := validators.ValidateModel(userCred, models.CloudproviderManager, &input.CloudproviderId)
if err != nil {
return nil, err
}
input.ManagerId = input.CloudproviderId
manager := managerObj.(*models.SCloudprovider)
if manager.Provider != region.Provider {
return nil, httperrors.NewConflictError("manager %s is not %s cloud", manager.Name, region.Provider)
}
return input, nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCreateSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, sp *models.SSnapshotPolicy, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iRegion, err := sp.GetIRegion(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
opts := &cloudprovider.SnapshotPolicyInput{
Name: sp.Name,
Desc: sp.Description,
RetentionDays: sp.RetentionDays,
TimePoints: sp.TimePoints,
RepeatWeekdays: sp.RepeatWeekdays,
}
opts.Tags, _ = sp.GetAllUserMetadata()
id, err := iRegion.CreateSnapshotPolicy(opts)
if err != nil {
return nil, errors.Wrapf(err, "CreateSnapshotPolicy")
}
_, err = db.Update(sp, func() error {
sp.ExternalId = id
sp.Status = apis.STATUS_AVAILABLE
return nil
})
return nil, err
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestDeleteSnapshotPolicy(ctx context.Context, userCred mcclient.TokenCredential, region *models.SCloudregion, sp *models.SSnapshotPolicy, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iPolicy, err := sp.GetISnapshotPolicy(ctx)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows || errors.Cause(err) == cloudprovider.ErrNotFound {
return nil, nil
}
return nil, errors.Wrapf(err, "GetISnapshotPolicy")
}
err = iPolicy.Delete()
if err != nil {
return nil, errors.Wrapf(err, "Delete")
}
return nil, nil
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestSnapshotPolicyBindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, diskIds []string, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iPolicy, err := sp.GetISnapshotPolicy(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetISnapshotPolicy")
}
disks, err := sp.GetUnbindDisks(diskIds)
if err != nil {
return nil, errors.Wrapf(err, "GetUnbindDisks")
}
externalIds := []string{}
for _, disk := range disks {
if len(disk.ExternalId) > 0 && !utils.IsInStringArray(disk.ExternalId, externalIds) {
externalIds = append(externalIds, disk.ExternalId)
}
}
if len(externalIds) > 0 {
err = iPolicy.ApplyDisks(externalIds)
if err != nil {
return nil, errors.Wrapf(err, "ApplyDisks %s", externalIds)
}
return nil, sp.BindDisks(ctx, disks)
}
return nil, nil
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestSnapshotPolicyUnbindDisks(ctx context.Context, userCred mcclient.TokenCredential, sp *models.SSnapshotPolicy, diskIds []string, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iPolicy, err := sp.GetISnapshotPolicy(ctx)
if err != nil {
return nil, errors.Wrapf(err, "GetISnapshotPolicy")
}
disks, err := sp.GetBindDisks(diskIds)
if err != nil {
return nil, errors.Wrapf(err, "GetBindDisks")
}
externalIds := []string{}
for _, disk := range disks {
if len(disk.ExternalId) > 0 && !utils.IsInStringArray(disk.ExternalId, externalIds) {
externalIds = append(externalIds, disk.ExternalId)
}
}
if len(externalIds) > 0 {
err = iPolicy.CancelDisks(externalIds)
if err != nil {
return nil, errors.Wrapf(err, "CancelDisks %s", externalIds)
}
return nil, sp.UnbindDisks(diskIds)
}
return nil, nil
})
return nil
}
-28
View File
@@ -274,34 +274,6 @@ func (self *SQcloudRegionDriver) RequestSyncLoadbalancerBackend(ctx context.Cont
return nil
}
func (self *SQcloudRegionDriver) RequestPreSnapshotPolicyApply(ctx context.Context, userCred mcclient.
TokenCredential, task taskman.ITask, disk *models.SDisk, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
if sp == nil {
return data, nil
}
storage, _ := disk.GetStorage()
region, _ := storage.GetRegion()
spcache, err := models.SnapshotPolicyCacheManager.FetchSnapshotPolicyCache(sp.GetId(),
region.GetId(), storage.ManagerId)
if err != nil {
return nil, err
}
iRegion, err := spcache.GetIRegion(ctx)
if err != nil {
return nil, err
}
err = iRegion.CancelSnapshotPolicyToDisks(spcache.GetExternalId(), disk.GetExternalId())
if err != nil {
return nil, err
}
return data, nil
})
return nil
}
func (self *SQcloudRegionDriver) InitDBInstanceUser(ctx context.Context, instance *models.SDBInstance, task taskman.ITask, desc *cloudprovider.SManagedDBInstanceCreateConfig) error {
user := "root"
account := models.SDBInstanceAccount{}
+2 -2
View File
@@ -98,6 +98,8 @@ func InitHandlers(app *appsrv.Application) {
models.WafRuleStatementManager,
models.BillingResourceCheckManager,
models.SnapshotPolicyDiskManager,
} {
db.RegisterModelManager(manager)
}
@@ -139,7 +141,6 @@ func InitHandlers(app *appsrv.Application) {
models.InstanceSnapshotManager,
models.SnapshotManager,
models.SnapshotPolicyManager,
models.SnapshotPolicyCacheManager,
models.BaremetalagentManager,
models.LoadbalancerManager,
models.LoadbalancerListenerManager,
@@ -269,7 +270,6 @@ func InitHandlers(app *appsrv.Application) {
models.CloudproviderRegionManager,
models.DBInstanceNetworkManager,
models.NetworkinterfacenetworkManager,
models.SnapshotPolicyDiskManager,
models.InstanceSnapshotJointManager,
models.DnsZoneVpcManager,
models.DBInstanceSecgroupManager,
@@ -40,12 +40,7 @@ func init() {
func (self *DiskCleanOverduedSnapshots) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
disk := obj.(*models.SDisk)
spId, _ := self.Params.GetString("snapshotpolicy_id")
sp, _ := models.SnapshotPolicyManager.FetchSnapshotPolicyById(spId)
if sp == nil {
self.SetStageFailed(ctx, jsonutils.NewString("missing snapshot policy ???"))
return
}
retentionDays, _ := self.Params.Int("retention_days")
now, err := self.Params.GetTime("start_time")
if err != nil {
@@ -66,8 +61,8 @@ func (self *DiskCleanOverduedSnapshots) OnInit(ctx context.Context, obj db.IStan
}
cleanOverdueSnapshots = snapCount > (options.Options.DefaultMaxSnapshotCount - options.Options.DefaultMaxManualSnapshotCount)
if sp.RetentionDays > 0 && !cleanOverdueSnapshots {
t := now.AddDate(0, 0, -1*sp.RetentionDays)
if retentionDays > 0 && !cleanOverdueSnapshots {
t := now.AddDate(0, 0, -1*int(retentionDays))
snapCount, err = models.SnapshotManager.Query().Equals("fake_deleted", false).Equals("disk_id", disk.Id).
Equals("created_by", compute.SNAPSHOT_AUTO).LT("created_at", t).CountWithError()
if err != nil {
+2 -1
View File
@@ -177,12 +177,13 @@ func (self *DiskDeleteTask) startPendingDeleteDisk(ctx context.Context, disk *mo
self.OnGuestDiskDeleteCompleteFailed(ctx, disk, jsonutils.NewString("pending delete disk failed"))
return
}
err = models.SnapshotPolicyDiskManager.SyncDetachByDisk(ctx, self.UserCred, nil, disk)
err = models.SnapshotPolicyDiskManager.RemoveByDisk(disk.Id)
if err != nil {
self.OnGuestDiskDeleteCompleteFailed(ctx, disk,
jsonutils.NewString("detach all snapshotpolicies of disk failed"))
return
}
self.SetStageComplete(ctx, nil)
}
@@ -1,64 +0,0 @@
// 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"
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"
)
type SnapshotPolicyCacheDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SnapshotPolicyCacheDeleteTask{})
}
func (self *SnapshotPolicyCacheDeleteTask) taskFailed(ctx context.Context, cache *models.SSnapshotPolicyCache,
err jsonutils.JSONObject) {
cache.SetStatus(self.UserCred, api.SNAPSHOT_POLICY_CACHE_STATUS_DELETE_FAILED, err.String())
self.SetStageFailed(ctx, err)
}
func (self *SnapshotPolicyCacheDeleteTask) taskComplete(ctx context.Context, cache *models.SSnapshotPolicyCache) {
cache.RealDetele(ctx, self.UserCred)
self.SetStageComplete(ctx, nil)
}
func (self *SnapshotPolicyCacheDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel,
data jsonutils.JSONObject) {
cache := obj.(*models.SSnapshotPolicyCache)
if len(cache.ExternalId) == 0 {
self.taskComplete(ctx, cache)
return
}
err := cache.DeleteCloudSnapshotPolicy(ctx)
if err != nil {
self.taskFailed(ctx, cache, jsonutils.NewString(err.Error()))
return
}
self.taskComplete(ctx, cache)
}
@@ -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"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
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 SnapshotpolicyBindDisksTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SnapshotpolicyBindDisksTask{})
}
func (self *SnapshotpolicyBindDisksTask) taskFailed(ctx context.Context, sp *models.SSnapshotPolicy, err error) {
sp.SetStatus(self.UserCred, api.SNAPSHOT_POLICY_APPLY_FAILED, err.Error())
db.OpsLog.LogEvent(sp, db.ACT_BIND, err, self.UserCred)
logclient.AddActionLogWithStartable(self, sp, logclient.ACT_BIND, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SnapshotpolicyBindDisksTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
sp := obj.(*models.SSnapshotPolicy)
region, err := sp.GetRegion()
if err != nil {
self.taskFailed(ctx, sp, errors.Wrapf(err, "GetRegion"))
return
}
diskIds := jsonutils.GetQueryStringArray(self.Params, "disk_ids")
self.SetStage("OnSnapshotPolicyBindDisksComplete", nil)
err = region.GetDriver().RequestSnapshotPolicyBindDisks(ctx, self.UserCred, sp, diskIds, self)
if err != nil {
self.taskFailed(ctx, sp, errors.Wrapf(err, "RequestSnapshotPolicyBindDisks"))
return
}
}
func (self *SnapshotpolicyBindDisksTask) OnSnapshotPolicyBindDisksComplete(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
sp.SetStatus(self.UserCred, apis.STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}
func (self *SnapshotpolicyBindDisksTask) OnSnapshotPolicyBindDisksCompleteFailed(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
self.taskFailed(ctx, sp, errors.Errorf(data.String()))
}
@@ -0,0 +1,73 @@
// 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"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type SnapshotPolicyCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SnapshotPolicyCreateTask{})
}
func (self *SnapshotPolicyCreateTask) taskFailed(ctx context.Context, sp *models.SSnapshotPolicy, err error) {
sp.SetStatus(self.UserCred, apis.STATUS_CREATE_FAILED, err.Error())
db.OpsLog.LogEvent(sp, db.ACT_ALLOCATE_FAIL, err, self.UserCred)
logclient.AddActionLogWithStartable(self, sp, logclient.ACT_ALLOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SnapshotPolicyCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
sp := obj.(*models.SSnapshotPolicy)
region, err := sp.GetRegion()
if err != nil {
self.taskFailed(ctx, sp, errors.Wrapf(err, "GetRegion"))
return
}
self.SetStage("OnCreateSnapshotPolicyComplete", nil)
err = region.GetDriver().RequestCreateSnapshotPolicy(ctx, self.UserCred, region, sp, self)
if err != nil {
self.taskFailed(ctx, sp, errors.Wrapf(err, "RequestCreateSnapshotPolicy"))
return
}
}
func (self *SnapshotPolicyCreateTask) OnCreateSnapshotPolicyComplete(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
logclient.AddActionLogWithStartable(self, sp, logclient.ACT_ALLOCATE, nil, self.UserCred, true)
notifyclient.EventNotify(ctx, self.UserCred, notifyclient.SEventNotifyParam{
Obj: sp,
Action: notifyclient.ActionCreate,
})
self.SetStageComplete(ctx, nil)
}
func (self *SnapshotPolicyCreateTask) OnCreateSnapshotPolicyCompleteFailed(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
self.taskFailed(ctx, sp, errors.Errorf(data.String()))
}
@@ -18,8 +18,9 @@ import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
@@ -35,22 +36,29 @@ func init() {
taskman.RegisterTask(SnapshotPolicyDeleteTask{})
}
func (self *SnapshotPolicyDeleteTask) taskFail(ctx context.Context, sp *models.SSnapshotPolicy, reason jsonutils.JSONObject) {
sp.SetStatus(self.GetUserCred(), api.SNAPSHOT_POLICY_DELETE_FAILED, reason.String())
db.OpsLog.LogEvent(sp, db.ACT_DELOCATE_FAIL, reason, self.UserCred)
logclient.AddActionLogWithStartable(self, sp, logclient.ACT_DELOCATE, reason, self.UserCred, false)
notifyclient.NotifySystemErrorWithCtx(ctx, sp.Id, sp.Name, api.SNAPSHOT_POLICY_DELETE_FAILED, reason.String())
self.SetStageFailed(ctx, reason)
func (self *SnapshotPolicyDeleteTask) taskFail(ctx context.Context, sp *models.SSnapshotPolicy, err error) {
sp.SetStatus(self.GetUserCred(), apis.STATUS_DELETE_FAILED, err.Error())
db.OpsLog.LogEvent(sp, db.ACT_DELOCATE_FAIL, err, self.UserCred)
logclient.AddActionLogWithStartable(self, sp, logclient.ACT_DELOCATE, err, self.UserCred, false)
notifyclient.NotifySystemErrorWithCtx(ctx, sp.Id, sp.Name, apis.STATUS_DELETE_FAILED, err.Error())
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SnapshotPolicyDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
sp := obj.(*models.SSnapshotPolicy)
err := models.SnapshotPolicyCacheManager.DeleteCloudSnapshotPolices(ctx, self.UserCred, sp.GetId())
region, err := sp.GetRegion()
if err != nil {
self.taskFail(ctx, sp, jsonutils.NewString(err.Error()))
self.taskFail(ctx, sp, errors.Wrapf(err, "GetRegion"))
return
}
self.SetStage("OnSnapshotPolicyDeleteComplete", nil)
err = region.GetDriver().RequestDeleteSnapshotPolicy(ctx, self.UserCred, region, sp, self)
if err != nil {
self.taskFail(ctx, sp, errors.Wrapf(err, "RequestDeleteSnapshotPolicy"))
return
}
self.OnSnapshotPolicyDeleteComplete(ctx, sp, data)
}
func (self *SnapshotPolicyDeleteTask) OnSnapshotPolicyDeleteComplete(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
@@ -65,5 +73,5 @@ func (self *SnapshotPolicyDeleteTask) OnSnapshotPolicyDeleteComplete(ctx context
}
func (self *SnapshotPolicyDeleteTask) OnSnapshotPolicyDeleteCompleteFailed(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
self.taskFail(ctx, sp, data)
self.taskFail(ctx, sp, errors.Errorf(data.String()))
}
@@ -1,242 +0,0 @@
// 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"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"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/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
func init() {
taskman.RegisterTask(SnapshotPolicyApplyTask{})
taskman.RegisterTask(SnapshotPolicyCancelTask{})
}
type SnapshotPolicyApplyTask struct {
taskman.STask
}
func (self *SnapshotPolicyApplyTask) taskFail(ctx context.Context, disk *models.SDisk,
spd *models.SSnapshotPolicyDisk, reason jsonutils.JSONObject) {
if spd != nil {
err := spd.RealDetach(ctx, self.UserCred)
if err != nil {
log.Errorf("Delete snapshotpolicydisk %s failed, need to delete", spd.GetId())
}
snapshotpolicy, err := models.SnapshotPolicyManager.FetchSnapshotPolicyById(spd.SnapshotpolicyId)
if err == nil {
db.OpsLog.LogEvent(snapshotpolicy, db.ACT_SNAPSHOT_POLICY_BIND_DISK_FAIL, "", self.UserCred)
logclient.AddActionLogWithStartable(self, snapshotpolicy, logclient.ACT_BIND_DISK, "", self.UserCred, false)
}
}
disk.SetStatus(self.UserCred, compute.DISK_APPLY_SNAPSHOT_FAIL, reason.String())
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)
notifyclient.NotifySystemErrorWithCtx(ctx, disk.GetId(), disk.Name, compute.DISK_APPLY_SNAPSHOT_FAIL, reason.String())
self.SetStageFailed(ctx, reason)
}
func (self *SnapshotPolicyApplyTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
disk := obj.(*models.SDisk)
spd := models.SSnapshotPolicyDisk{}
data.Unmarshal(&spd, "snapshotPolicyDisk")
var snapshotPolicy *models.SSnapshotPolicy
if data.Contains("need_detach") {
snapshotPolicyID, _ := data.GetString("need_detach")
model, err := models.SnapshotPolicyManager.FetchById(snapshotPolicyID)
if err != nil {
self.taskFail(ctx, disk, &spd, jsonutils.NewString(err.Error()))
return
}
snapshotPolicy = model.(*models.SSnapshotPolicy)
}
self.Params.Add(jsonutils.NewString(spd.SnapshotpolicyId), "snapshotpolicy_id")
self.SetStage("OnPreSnapshotPolicyApplyComplete", nil)
// pass data to next Stage without inserting database through this way
storage, _ := disk.GetStorage()
region, _ := storage.GetRegion()
if err := region.GetDriver().RequestPreSnapshotPolicyApply(ctx, self.UserCred, self, disk, snapshotPolicy,
data); err != nil {
self.taskFail(ctx, disk, &spd, jsonutils.NewString(err.Error()))
return
}
}
func (self *SnapshotPolicyApplyTask) OnPreSnapshotPolicyApplyCompleteFailed(ctx context.Context, disk *models.SDisk,
reason jsonutils.JSONObject) {
spId, _ := self.Params.GetString("snapshotpolicy_id")
spd, err := models.SnapshotPolicyDiskManager.FetchBySnapshotPolicyDisk(spId, disk.GetId())
if err != nil {
self.taskFail(ctx, disk, nil, reason)
return
}
self.taskFail(ctx, disk, spd, reason)
}
func (self *SnapshotPolicyApplyTask) OnPreSnapshotPolicyApplyComplete(ctx context.Context, disk *models.SDisk,
data jsonutils.JSONObject) {
snapshotPolicy := models.SSnapshotPolicy{}
spd := models.SSnapshotPolicyDisk{}
data.Unmarshal(&snapshotPolicy, "snapshotPolicy")
data.Unmarshal(&spd, "snapshotPolicyDisk")
if data.Contains("need_detach") {
snapshotPolicyID, _ := data.GetString("need_detach")
spd1, err := models.SnapshotPolicyDiskManager.FetchBySnapshotPolicyDisk(snapshotPolicyID, disk.GetId())
if err != nil {
self.taskFail(ctx, disk, &spd, jsonutils.NewString(err.Error()))
return
}
if spd1 != nil {
spd1.RealDetach(ctx, self.UserCred)
}
}
self.SetStage("OnSnapshotPolicyApply", nil)
// pass data to next Stage without inserting database through this way
storage, _ := disk.GetStorage()
region, _ := storage.GetRegion()
if err := region.GetDriver().
RequestApplySnapshotPolicy(ctx, self.UserCred, self, disk, &snapshotPolicy, data); err != nil {
self.taskFail(ctx, disk, &spd, jsonutils.NewString(err.Error()))
}
}
func (self *SnapshotPolicyApplyTask) OnSnapshotPolicyApplyFailed(ctx context.Context, disk *models.SDisk,
reason jsonutils.JSONObject) {
spId, _ := self.Params.GetString("snapshotpolicy_id")
spd, err := models.SnapshotPolicyDiskManager.FetchBySnapshotPolicyDisk(spId, disk.GetId())
if err != nil {
self.taskFail(ctx, disk, nil, reason)
return
}
self.taskFail(ctx, disk, spd, reason)
}
func (self *SnapshotPolicyApplyTask) OnSnapshotPolicyApply(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
sp_id, _ := data.GetString("snapshotpolicy_id")
spd, err := models.SnapshotPolicyDiskManager.FetchBySnapshotPolicyDisk(sp_id, disk.GetId())
if err != nil {
log.Errorf("Fetch snapshotpolicy disk failed")
} else if spd != nil {
spd.SetStatus(self.UserCred, compute.SNAPSHOT_POLICY_DISK_READY, "")
snapshotpolicy, err := models.SnapshotPolicyManager.FetchSnapshotPolicyById(spd.SnapshotpolicyId)
if err == nil {
db.OpsLog.LogEvent(snapshotpolicy, db.ACT_SNAPSHOT_POLICY_BIND_DISK, "", self.UserCred)
logclient.AddActionLogWithStartable(self, snapshotpolicy, logclient.ACT_BIND_DISK, "", 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)
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
type SnapshotPolicyCancelTask struct {
taskman.STask
}
func (self *SnapshotPolicyCancelTask) taskFail(ctx context.Context, disk *models.SDisk, spd *models.SSnapshotPolicyDisk, reason jsonutils.JSONObject) {
if spd != nil {
spd.SetStatus(self.UserCred, compute.SNAPSHOT_POLICY_DISK_DELETE_FAILED, "")
snapshotpolicy, err := models.SnapshotPolicyManager.FetchSnapshotPolicyById(spd.SnapshotpolicyId)
if err == nil {
db.OpsLog.LogEvent(snapshotpolicy, db.ACT_SNAPSHOT_POLICY_UNBIND_DISK_FAIL, "", self.UserCred)
logclient.AddActionLogWithStartable(self, snapshotpolicy, logclient.ACT_UNBIND_DISK, "", self.UserCred, false)
}
}
disk.SetStatus(self.UserCred, compute.DISK_CALCEL_SNAPSHOT_FAIL, reason.String())
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)
}
func (self *SnapshotPolicyCancelTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
disk := obj.(*models.SDisk)
snapshotPolicyID, _ := data.GetString("snapshot_policy_id")
spd := models.SSnapshotPolicyDisk{}
data.Unmarshal(&spd, "snapshotPolicyDisk")
self.Params.Add(jsonutils.NewString(snapshotPolicyID), "snapshotpolicy_id")
model, err := models.SnapshotPolicyManager.FetchById(snapshotPolicyID)
if err != nil {
self.taskFail(ctx, disk, &spd, jsonutils.NewString(fmt.Sprintf("failed to fetch disk by id %s: %s", snapshotPolicyID, err.Error())))
return
}
snapshotPolicy := model.(*models.SSnapshotPolicy)
self.SetStage("OnSnapshotPolicyCancel", nil)
storage, _ := disk.GetStorage()
region, _ := storage.GetRegion()
if err := region.GetDriver().RequestCancelSnapshotPolicy(ctx, self.UserCred, self, disk, snapshotPolicy, data); err != nil {
self.taskFail(ctx, disk, &spd, jsonutils.NewString(err.Error()))
// fmt.Sprintf("faile to detach snapshot policy %s and disk %s: %s", snapshotPolicy.Id, disk.Id, err.Error()))
}
}
func (self *SnapshotPolicyCancelTask) OnSnapshotPolicyCancelFailed(ctx context.Context, disk *models.SDisk,
reason jsonutils.JSONObject) {
spId, _ := self.Params.GetString("snapshotpolicy_id")
spd, err := models.SnapshotPolicyDiskManager.FetchBySnapshotPolicyDisk(spId, disk.GetId())
if err != nil {
self.taskFail(ctx, disk, nil, reason)
return
}
self.taskFail(ctx, disk, spd, reason)
}
func (self *SnapshotPolicyCancelTask) OnSnapshotPolicyCancel(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
sp_id, _ := data.GetString("snapshotpolicy_id")
spd, err := models.SnapshotPolicyDiskManager.FetchBySnapshotPolicyDisk(sp_id, disk.GetId())
if err != nil {
log.Errorf("Fechsnapshotpolicy disk failed")
}
if spd != nil {
//real detach
spd.RealDetach(ctx, self.UserCred)
snapshotpolicy, err := models.SnapshotPolicyManager.FetchSnapshotPolicyById(spd.SnapshotpolicyId)
if err == nil {
db.OpsLog.LogEvent(snapshotpolicy, db.ACT_SNAPSHOT_POLICY_UNBIND_DISK, "", self.UserCred)
logclient.AddActionLogWithStartable(self, snapshotpolicy, logclient.ACT_UNBIND_DISK, "", self.UserCred, true)
}
}
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)
}
@@ -0,0 +1,62 @@
// 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"
"yunion.io/x/onecloud/pkg/apis"
"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 SnapshotpolicySyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SnapshotpolicySyncstatusTask{})
}
func (self *SnapshotpolicySyncstatusTask) taskFailed(ctx context.Context, sp *models.SSnapshotPolicy, err error) {
sp.SetStatus(self.UserCred, apis.STATUS_UNKNOWN, err.Error())
db.OpsLog.LogEvent(sp, db.ACT_SYNC_STATUS, err, self.UserCred)
logclient.AddActionLogWithStartable(self, sp, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SnapshotpolicySyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
sp := obj.(*models.SSnapshotPolicy)
iSp, err := sp.GetISnapshotPolicy(ctx)
if err != nil {
self.taskFailed(ctx, sp, errors.Wrapf(err, "GetISnapshotPolicy"))
return
}
provider, err := sp.GetCloudprovider()
if err != nil {
self.taskFailed(ctx, sp, errors.Wrapf(err, "GetCloudprovider"))
return
}
sp.SyncWithCloudPolicy(ctx, self.UserCred, provider, iSp)
self.SetStageComplete(ctx, nil)
}
@@ -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"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
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 SnapshotpolicyUnbindDisksTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SnapshotpolicyUnbindDisksTask{})
}
func (self *SnapshotpolicyUnbindDisksTask) taskFailed(ctx context.Context, sp *models.SSnapshotPolicy, err error) {
sp.SetStatus(self.UserCred, api.SNAPSHOT_POLICY_CANCEL_FAILED, err.Error())
db.OpsLog.LogEvent(sp, db.ACT_UNBIND, err, self.UserCred)
logclient.AddActionLogWithStartable(self, sp, logclient.ACT_UNBIND, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *SnapshotpolicyUnbindDisksTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
sp := obj.(*models.SSnapshotPolicy)
region, err := sp.GetRegion()
if err != nil {
self.taskFailed(ctx, sp, errors.Wrapf(err, "GetRegion"))
return
}
diskIds := jsonutils.GetQueryStringArray(self.Params, "disk_ids")
self.SetStage("OnSnapshotPolicyUnbindDisksComplete", nil)
err = region.GetDriver().RequestSnapshotPolicyUnbindDisks(ctx, self.UserCred, sp, diskIds, self)
if err != nil {
self.taskFailed(ctx, sp, errors.Wrapf(err, "RequestSnapshotPolicyUnbindDisks"))
return
}
}
func (self *SnapshotpolicyUnbindDisksTask) OnSnapshotPolicyUnbindDisksComplete(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
sp.SetStatus(self.UserCred, apis.STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}
func (self *SnapshotpolicyUnbindDisksTask) OnSnapshotPolicyUnbindDisksCompleteFailed(ctx context.Context, sp *models.SSnapshotPolicy, data jsonutils.JSONObject) {
self.taskFailed(ctx, sp, errors.Errorf(data.String()))
}
@@ -1,31 +0,0 @@
// 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/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var SnapshotPolicyCache modulebase.ResourceManager
func init() {
SnapshotPolicyCache = modules.NewComputeManager("snapshotpolicycache", "snapshotpolicycaches",
[]string{"Snapshotpolicy_Id", "External_Id", "Cloudregion_Id", "Manager_Id"},
[]string{},
)
modules.RegisterCompute(&SnapshotPolicyCache)
}
@@ -1,45 +0,0 @@
// 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/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
var (
SnapshotPolicyDisk modulebase.JointResourceManager
SnapshotPolicyDisk1 modulebase.JointResourceManager
)
func init() {
SnapshotPolicyDisk = modules.NewJointComputeManager(
"snapshotpolicydisk",
"snapshotpolicydisks",
[]string{"Disk_ID", "Snapshotpolicy_ID"},
[]string{},
&Disks,
&SnapshotPoliciy)
modules.RegisterCompute(&SnapshotPolicyDisk)
SnapshotPolicyDisk1 = modules.NewJointComputeManager(
"snapshotpolicydisk",
"snapshotpolicydisks",
[]string{"Disk_ID", "Snapshotpolicy_ID"},
[]string{},
&SnapshotPoliciy,
&Disks)
modules.RegisterCompute(&SnapshotPolicyDisk1)
}
@@ -0,0 +1,54 @@
// 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 SnapshotPolicyListOptions struct {
options.BaseListOptions
OrderByBindDiskCount string
}
func (opts *SnapshotPolicyListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type SnapshotPolicyCreateOptions struct {
options.BaseCreateOptions
CloudregionId string
ManagerId string
RetentionDays int `help:"snapshot retention days" default:"-1"`
RepeatWeekdays []int `help:"snapshot create days on week"`
TimePoints []int `help:"snapshot create time points on one day"`
}
func (opts *SnapshotPolicyCreateOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(opts), nil
}
type SnapshotPolicyDisksOptions struct {
options.BaseIdOptions
Disks []string `help:"ids of disk"`
}
func (opts *SnapshotPolicyDisksOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(map[string]interface{}{"disks": opts.Disks}), nil
}
+1
View File
@@ -261,6 +261,7 @@ const (
ACT_DISSOCIATE = "dissociate"
ACT_BIND = "bind"
ACT_UNBIND = "unbind"
ACT_PROGRESS = "progress"
ACT_ADD_BASTION_SERVER = "add_bastion_server"
+1 -1
View File
@@ -1465,7 +1465,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231214030214-0b69ef4c4315
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231215084758-720b4cd7bf3e
## explicit; go 1.18
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
-5
View File
@@ -23,10 +23,5 @@ const (
SNAPSHOT_DELETING = "deleting"
SNAPSHOT_UNKNOWN = "unknown"
SNAPSHOT_POLICY_CREATING = "creating"
SNAPSHOT_POLICY_READY = "ready"
SNAPSHOT_POLICY_UNKNOWN = "unknown"
INSTANCE_SNAPSHOT_READY = "ready"
)
+1
View File
@@ -20,6 +20,7 @@ const (
STATUS_CREATING = "creating"
STATUS_CREATE_FAILED = "create_failed"
STATUS_AVAILABLE = "available"
STATUS_UNKNOWN = "unknown"
USER_TAG_PREFIX = "user:"
+1
View File
@@ -32,6 +32,7 @@ const (
CLOUD_CAPABILITY_NETWORK = "network"
CLOUD_CAPABILITY_SECURITY_GROUP = "security_group"
CLOUD_CAPABILITY_EIP = "eip"
CLOUD_CAPABILITY_SNAPSHOT_POLICY = "snapshot_policy"
CLOUD_CAPABILITY_LOADBALANCER = "loadbalancer"
CLOUD_CAPABILITY_OBJECTSTORE = "objectstore"
CLOUD_CAPABILITY_RDS = "rds"
+5 -8
View File
@@ -99,12 +99,8 @@ type ICloudRegion interface {
GetISnapshotById(snapshotId string) (ICloudSnapshot, error)
CreateSnapshotPolicy(*SnapshotPolicyInput) (string, error)
UpdateSnapshotPolicy(*SnapshotPolicyInput, string) error
DeleteSnapshotPolicy(string) error
ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error
CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error
GetISnapshotPolicies() ([]ICloudSnapshotPolicy, error)
GetISnapshotPolicyById(snapshotPolicyId string) (ICloudSnapshotPolicy, error)
GetISnapshotPolicyById(id string) (ICloudSnapshotPolicy, error)
GetIHosts() ([]ICloudHost, error)
GetIHostById(id string) (ICloudHost, error)
@@ -547,8 +543,6 @@ type ICloudDisk interface {
CreateISnapshot(ctx context.Context, name string, desc string) (ICloudSnapshot, error)
GetISnapshots() ([]ICloudSnapshot, error)
GetExtSnapshotPolicyIds() ([]string, error)
Resize(ctx context.Context, newSizeMB int64) error
Reset(ctx context.Context, snapshotId string) (string, error)
@@ -576,10 +570,13 @@ type ICloudInstanceSnapshot interface {
type ICloudSnapshotPolicy interface {
IVirtualResource
IsActivated() bool
GetRetentionDays() int
GetRepeatWeekdays() ([]int, error)
GetTimePoints() ([]int, error)
Delete() error
ApplyDisks(ids []string) error
CancelDisks(ids []string) error
GetApplyDiskIds() ([]string, error)
}
type ICloudGlobalVpc interface {
+6 -3
View File
@@ -17,9 +17,12 @@ package cloudprovider
import "strconv"
type SnapshotPolicyInput struct {
RetentionDays int
RepeatWeekdays, TimePoints []int
PolicyName string
RetentionDays int
RepeatWeekdays []int
TimePoints []int
Name string
Desc string
Tags map[string]string
}
func (spi *SnapshotPolicyInput) GetStringArrayRepeatWeekdays() []string {
+1
View File
@@ -988,6 +988,7 @@ func (region *SAliyunClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_CONTAINER + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_TABLESTORE + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_CERT,
cloudprovider.CLOUD_CAPABILITY_SNAPSHOT_POLICY,
}
return caps
}
+35 -30
View File
@@ -75,14 +75,10 @@ func (self *SDisk) GetIops() int {
return self.IOPS
}
func (self *SRegion) GetDisks(instanceId string, zoneId string, category string, diskIds []string, offset int, limit int) ([]SDisk, int, error) {
if limit > 50 || limit <= 0 {
limit = 50
}
func (self *SRegion) GetDisks(instanceId string, zoneId string, category string, diskIds []string, snapshotpolicyId string) ([]SDisk, error) {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["PageSize"] = fmt.Sprintf("%d", limit)
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
params["MaxResults"] = "500"
if len(instanceId) > 0 {
params["InstanceId"] = instanceId
@@ -93,24 +89,38 @@ func (self *SRegion) GetDisks(instanceId string, zoneId string, category string,
if len(category) > 0 {
params["Category"] = category
}
if diskIds != nil && len(diskIds) > 0 {
if len(diskIds) > 0 {
params["DiskIds"] = jsonutils.Marshal(diskIds).String()
}
body, err := self.ecsRequest("DescribeDisks", params)
if err != nil {
log.Errorf("GetDisks fail %s", err)
return nil, 0, err
if len(snapshotpolicyId) > 0 {
params["AutoSnapshotPolicyId"] = snapshotpolicyId
}
disks := make([]SDisk, 0)
err = body.Unmarshal(&disks, "Disks", "Disk")
if err != nil {
log.Errorf("Unmarshal disk details fail %s", err)
return nil, 0, err
ret := []SDisk{}
for {
resp, err := self.ecsRequest("DescribeDisks", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDisks")
}
part := struct {
Disks struct {
Disk []SDisk
}
NextToken string
}{}
err = resp.Unmarshal(&part)
if err != nil {
return nil, errors.Wrapf(err, "Unmarshal")
}
ret = append(ret, part.Disks.Disk...)
if len(part.NextToken) == 0 || len(part.Disks.Disk) == 0 {
break
}
params["NextToken"] = part.NextToken
}
total, _ := body.Int("TotalCount")
return disks, int(total), nil
return ret, nil
}
func (self *SDisk) GetId() string {
@@ -278,14 +288,16 @@ func (self *SRegion) CreateDisk(zoneId string, category string, name string, siz
}
func (self *SRegion) getDisk(diskId string) (*SDisk, error) {
disks, total, err := self.GetDisks("", "", "", []string{diskId}, 0, 1)
disks, err := self.GetDisks("", "", "", []string{diskId}, "")
if err != nil {
return nil, err
}
if total != 1 {
return nil, cloudprovider.ErrNotFound
for i := range disks {
if disks[i].DiskId == diskId {
return &disks[i], nil
}
}
return &disks[0], nil
return nil, errors.Wrapf(cloudprovider.ErrNotFound, diskId)
}
func (self *SRegion) DeleteDisk(diskId string) error {
@@ -391,13 +403,6 @@ func (self *SDisk) GetCreatedAt() time.Time {
return self.CreationTime
}
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
if len(self.AutoSnapshotPolicyId) == 0 {
return []string{}, nil
}
return []string{self.AutoSnapshotPolicyId}, nil
}
func (self *SDisk) GetExpiredAt() time.Time {
return convertExpiredAt(self.ExpiredTime)
}
+3 -10
View File
@@ -243,16 +243,9 @@ func (a byAttachedTime) Less(i, j int) bool {
}
func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
disks := []SDisk{}
for {
part, total, err := self.host.zone.region.GetDisks(self.InstanceId, "", "", nil, len(disks), 50)
if err != nil {
return nil, errors.Wrapf(err, "GetDisks for %s", self.InstanceId)
}
disks = append(disks, part...)
if len(disks) >= total {
break
}
disks, err := self.host.zone.region.GetDisks(self.InstanceId, "", "", nil, "")
if err != nil {
return nil, errors.Wrapf(err, "GetDisks for %s", self.InstanceId)
}
sort.Sort(byAttachedTime(disks))
+87 -89
View File
@@ -20,8 +20,9 @@ import (
"strconv"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/apis"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
@@ -56,25 +57,27 @@ func (self *SSnapshotPolicy) GetName() string {
}
func (self *SSnapshotPolicy) GetStatus() string {
// XXX: aliyun文档与实际返回值不符
if self.Status == Normal || self.Status == Available {
return api.SNAPSHOT_POLICY_READY
} else if self.Status == Creating {
return api.SNAPSHOT_POLICY_CREATING
} else {
return api.SNAPSHOT_POLICY_UNKNOWN
switch self.Status {
case Normal, Available:
return apis.STATUS_AVAILABLE
case Creating:
return apis.STATUS_CREATING
default:
return apis.STATUS_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
policies, err := self.region.GetSnapshotPolicies(self.AutoSnapshotPolicyId)
if err != nil {
return errors.Wrapf(err, "GetSnapshotPolicies")
}
return nil
for i := range policies {
if policies[i].AutoSnapshotPolicyId == self.AutoSnapshotPolicyId {
return jsonutils.Update(self, policies[i])
}
}
return errors.Wrapf(cloudprovider.ErrNotFound, self.AutoSnapshotPolicyId)
}
func (self *SSnapshotPolicy) IsEmulated() bool {
@@ -134,57 +137,57 @@ 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)
policies, err := self.GetSnapshotPolicies("")
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]
ret := make([]cloudprovider.ICloudSnapshotPolicy, len(policies))
for i := 0; i < len(policies); i += 1 {
ret[i] = &policies[i]
}
return ret, nil
}
func (self *SRegion) GetSnapshotPolicies(policyId string, offset int, limit int) ([]SSnapshotPolicy, int, error) {
func (self *SRegion) GetSnapshotPolicies(policyId string) ([]SSnapshotPolicy, error) {
params := make(map[string]string)
params["RegionId"] = self.RegionId
if limit != 0 {
params["PageSize"] = fmt.Sprintf("%d", limit)
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
}
params["PageSize"] = "100"
pageNum := 1
params["PageNumber"] = fmt.Sprintf("%d", pageNum)
if len(policyId) > 0 {
params["AutoSnapshotPolicyId"] = policyId
}
body, err := self.ecsRequest("DescribeAutoSnapshotPolicyEx", params)
if err != nil {
return nil, 0, fmt.Errorf("GetSnapshotPolicys fail %s", err)
ret := make([]SSnapshotPolicy, 0)
for {
resp, err := self.ecsRequest("DescribeAutoSnapshotPolicyEx", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeAutoSnapshotPolicyEx")
}
part := struct {
TotalCount int
AutoSnapshotPolicies struct {
AutoSnapshotPolicy []SSnapshotPolicy
}
}{}
err = resp.Unmarshal(&part)
if err != nil {
return nil, err
}
ret = append(ret, part.AutoSnapshotPolicies.AutoSnapshotPolicy...)
if len(ret) >= part.TotalCount || len(part.AutoSnapshotPolicies.AutoSnapshotPolicy) == 0 {
break
}
pageNum++
params["PageNumber"] = fmt.Sprintf("%d", pageNum)
}
snapshotPolicies := make([]SSnapshotPolicy, 0)
if err := body.Unmarshal(&snapshotPolicies, "AutoSnapshotPolicies", "AutoSnapshotPolicy"); err != nil {
return nil, 0, fmt.Errorf("Unmarshal snapshot policies details fail %s", err)
for i := 0; i < len(ret); i += 1 {
ret[i].region = self
}
total, _ := body.Int("TotalCount")
for i := 0; i < len(snapshotPolicies); i += 1 {
snapshotPolicies[i].region = self
}
return snapshotPolicies, int(total), nil
return ret, nil
}
func (self *SSnapshotPolicy) Delete() error {
@@ -202,15 +205,17 @@ func (self *SRegion) DeleteSnapshotPolicy(snapshotPolicyId string) error {
return err
}
func (self *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
policies, _, err := self.GetSnapshotPolicies(snapshotPolicyId, 0, 1)
func (self *SRegion) GetISnapshotPolicyById(id string) (cloudprovider.ICloudSnapshotPolicy, error) {
policies, err := self.GetSnapshotPolicies(id)
if err != nil {
return nil, err
}
if len(policies) == 0 {
return nil, cloudprovider.ErrNotFound
for i := range policies {
if policies[i].AutoSnapshotPolicyId == id {
return &policies[i], nil
}
}
return &policies[0], nil
return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
}
func (self *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput) (string, error) {
@@ -225,12 +230,12 @@ func (self *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInp
params["repeatWeekdays"] = jsonutils.Marshal(input.GetStringArrayRepeatWeekdays()).String()
params["timePoints"] = jsonutils.Marshal(input.GetStringArrayTimePoints()).String()
params["retentionDays"] = strconv.Itoa(input.RetentionDays)
params["autoSnapshotPolicyName"] = input.PolicyName
if body, err := self.ecsRequest("CreateAutoSnapshotPolicy", params); err != nil {
return "", fmt.Errorf("CreateAutoSnapshotPolicy fail %s", err)
} else {
return body.GetString("AutoSnapshotPolicyId")
params["autoSnapshotPolicyName"] = input.Name
body, err := self.ecsRequest("CreateAutoSnapshotPolicy", params)
if err != nil {
return "", errors.Wrapf(err, "CreateAutoSnapshotPolicy")
}
return body.GetString("AutoSnapshotPolicyId")
}
func (self *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput, snapshotPolicyId string) error {
@@ -252,52 +257,45 @@ func (self *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInp
return nil
}
//func (self *SRegion) UpdateSnapshotPolicy(
// snapshotPolicyId string, retentionDays *int,
// repeatWeekdays, timePoints *jsonutils.JSONArray, policyName string,
//) error {
// params := make(map[string]string)
// params["RegionId"] = self.RegionId
// if len(policyName) > 0 {
// params["autoSnapshotPolicyName"] = policyName
// }
// if retentionDays != nil {
// params["retentionDays"] = strconv.Itoa(*retentionDays)
// }
// if repeatWeekdays != nil {
// params["repeatWeekdays"] = repeatWeekdays.String()
// }
// if timePoints != nil {
// params["timePoints"] = timePoints.String()
// }
// _, err := self.ecsRequest("ModifyAutoSnapshotPolicyEx", params)
// if err != nil {
// return fmt.Errorf("ModifyAutoSnapshotPolicyEx Fail %s", err)
// }
// return nil
//}
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskIds []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 {
return fmt.Errorf("ApplyAutoSnapshotPolicy Fail %s", err)
return errors.Wrapf(err, "ApplyAutoSnapshotPolicy")
}
return nil
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
func (self *SSnapshotPolicy) ApplyDisks(ids []string) error {
return self.region.ApplySnapshotPolicyToDisks(self.AutoSnapshotPolicyId, ids)
}
func (self *SSnapshotPolicy) GetApplyDiskIds() ([]string, error) {
disks, err := self.region.GetDisks("", "", "", nil, self.AutoSnapshotPolicyId)
if err != nil {
return nil, err
}
ret := []string{}
for _, disk := range disks {
ret = append(ret, disk.DiskId)
}
return ret, nil
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskIds []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 {
return fmt.Errorf("CancelAutoSnapshotPolicy Fail %s", err)
return errors.Wrapf(err, "CancelAutoSnapshotPolicy")
}
return nil
}
func (self *SSnapshotPolicy) CancelDisks(ids []string) error {
return self.region.CancelSnapshotPolicyToDisks(self.AutoSnapshotPolicyId, ids)
}
+19 -27
View File
@@ -69,39 +69,31 @@ func (self *SStorage) GetIZone() cloudprovider.ICloudZone {
func (self *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
disks := make([]SDisk, 0)
offset := 0
storageType := self.storageType
if self.storageType == api.STORAGE_CLOUD_ESSD_PL2 || self.storageType == api.STORAGE_CLOUD_ESSD_PL3 || self.storageType == api.STORAGE_CLOUD_ESSD_PL0 {
storageType = api.STORAGE_CLOUD_ESSD
}
for {
parts, total, err := self.zone.region.GetDisks("", self.zone.GetId(), storageType, nil, offset, 50)
if err != nil {
return nil, errors.Wrapf(err, "GetDisks")
}
performanceLevel := ""
switch self.storageType {
case api.STORAGE_CLOUD_ESSD_PL0:
performanceLevel = "PL0"
case api.STORAGE_CLOUD_ESSD:
performanceLevel = "PL1"
case api.STORAGE_CLOUD_ESSD_PL2:
performanceLevel = "PL2"
case api.STORAGE_CLOUD_ESSD_PL3:
performanceLevel = "PL3"
}
for _, disk := range parts {
if disk.PerformanceLevel == performanceLevel {
disks = append(disks, disk)
}
}
offset += len(parts)
if offset >= total {
break
parts, err := self.zone.region.GetDisks("", self.zone.GetId(), storageType, nil, "")
if err != nil {
return nil, errors.Wrapf(err, "GetDisks")
}
performanceLevel := ""
switch self.storageType {
case api.STORAGE_CLOUD_ESSD_PL0:
performanceLevel = "PL0"
case api.STORAGE_CLOUD_ESSD:
performanceLevel = "PL1"
case api.STORAGE_CLOUD_ESSD_PL2:
performanceLevel = "PL2"
case api.STORAGE_CLOUD_ESSD_PL3:
performanceLevel = "PL3"
}
for _, disk := range parts {
if disk.PerformanceLevel == performanceLevel {
disks = append(disks, disk)
}
}
idisks := make([]cloudprovider.ICloudDisk, len(disks))
for i := 0; i < len(disks); i += 1 {
disks[i].storage = self
+1
View File
@@ -533,6 +533,7 @@ func (region *SApsaraClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_QUOTA + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_IPV6_GATEWAY + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_TABLESTORE + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_SNAPSHOT_POLICY,
}
return caps
}
+32 -30
View File
@@ -76,14 +76,12 @@ type SDisk struct {
DepartmentInfo
}
func (self *SRegion) GetDisks(instanceId string, zoneId string, category string, diskIds []string, offset int, limit int) ([]SDisk, int, error) {
if limit > 50 || limit <= 0 {
limit = 50
}
func (self *SRegion) GetDisks(instanceId string, zoneId string, category string, diskIds []string, snapshotpolicyId string) ([]SDisk, error) {
params := make(map[string]string)
params["RegionId"] = self.RegionId
params["PageSize"] = fmt.Sprintf("%d", limit)
params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
params["PageSize"] = "50"
pageNum := 1
params["PageNumber"] = fmt.Sprintf("%d", pageNum)
if len(instanceId) > 0 {
params["InstanceId"] = instanceId
@@ -94,24 +92,33 @@ func (self *SRegion) GetDisks(instanceId string, zoneId string, category string,
if len(category) > 0 {
params["Category"] = category
}
if diskIds != nil && len(diskIds) > 0 {
if len(diskIds) > 0 {
params["DiskIds"] = jsonutils.Marshal(diskIds).String()
}
body, err := self.ecsRequest("DescribeDisks", params)
if err != nil {
log.Errorf("GetDisks fail %s", err)
return nil, 0, err
if len(snapshotpolicyId) > 0 {
params["AutoSnapshotPolicyId"] = snapshotpolicyId
}
ret := []SDisk{}
for {
body, err := self.ecsRequest("DescribeDisks", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDisks")
}
disks := make([]SDisk, 0)
err = body.Unmarshal(&disks, "Disks", "Disk")
if err != nil {
log.Errorf("Unmarshal disk details fail %s", err)
return nil, 0, err
part := make([]SDisk, 0)
err = body.Unmarshal(&part, "Disks", "Disk")
if err != nil {
return nil, errors.Wrapf(err, "Unmarshal")
}
ret = append(ret, part...)
total, _ := body.Int("TotalCount")
if len(ret) >= int(total) || len(part) == 0 {
break
}
pageNum++
params["PageNumber"] = fmt.Sprintf("%d", pageNum)
}
total, _ := body.Int("TotalCount")
return disks, int(total), nil
return ret, nil
}
func (self *SDisk) GetId() string {
@@ -272,14 +279,16 @@ func (self *SRegion) CreateDisk(zoneId string, category string, name string, siz
}
func (self *SRegion) getDisk(diskId string) (*SDisk, error) {
disks, total, err := self.GetDisks("", "", "", []string{diskId}, 0, 1)
disks, err := self.GetDisks("", "", "", []string{diskId}, "")
if err != nil {
return nil, err
}
if total != 1 {
return nil, cloudprovider.ErrNotFound
for i := range disks {
if disks[i].DiskId == diskId {
return &disks[i], nil
}
}
return &disks[0], nil
return nil, errors.Wrapf(cloudprovider.ErrNotFound, diskId)
}
func (self *SRegion) DeleteDisk(diskId string) error {
@@ -399,13 +408,6 @@ func (self *SDisk) GetCreatedAt() time.Time {
return self.CreationTime
}
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
if len(self.AutoSnapshotPolicyId) == 0 {
return []string{}, nil
}
return []string{self.AutoSnapshotPolicyId}, nil
}
func (self *SDisk) GetExpiredAt() time.Time {
return convertExpiredAt(self.ExpiredTime)
}
+3 -9
View File
@@ -238,15 +238,9 @@ func (a byAttachedTime) Less(i, j int) bool {
func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
disks := []SDisk{}
for {
part, total, err := self.host.zone.region.GetDisks(self.InstanceId, "", "", nil, len(disks), 50)
if err != nil {
return nil, errors.Wrapf(err, "GetDisks for %s", self.InstanceId)
}
disks = append(disks, part...)
if len(disks) >= total {
break
}
disks, err := self.host.zone.region.GetDisks(self.InstanceId, "", "", nil, "")
if err != nil {
return nil, errors.Wrapf(err, "GetDisks for %s", self.InstanceId)
}
sort.Sort(byAttachedTime(disks))
+32 -46
View File
@@ -19,9 +19,10 @@ import (
"sort"
"strconv"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/apis"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
@@ -57,13 +58,13 @@ func (self *SSnapshotPolicy) GetName() string {
}
func (self *SSnapshotPolicy) GetStatus() string {
// XXX: apsara文档与实际返回值不符
if self.Status == Normal || self.Status == Available {
return api.SNAPSHOT_POLICY_READY
} else if self.Status == Creating {
return api.SNAPSHOT_POLICY_CREATING
} else {
return api.SNAPSHOT_POLICY_UNKNOWN
switch self.Status {
case Normal, Available:
return apis.STATUS_AVAILABLE
case Creating:
return apis.STATUS_CREATING
default:
return apis.STATUS_UNKNOWN
}
}
@@ -131,10 +132,6 @@ 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 {
@@ -222,12 +219,12 @@ func (self *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInp
params["repeatWeekdays"] = jsonutils.Marshal(input.GetStringArrayRepeatWeekdays()).String()
params["timePoints"] = jsonutils.Marshal(input.GetStringArrayTimePoints()).String()
params["retentionDays"] = strconv.Itoa(input.RetentionDays)
params["autoSnapshotPolicyName"] = input.PolicyName
if body, err := self.ecsRequest("CreateAutoSnapshotPolicy", params); err != nil {
return "", fmt.Errorf("CreateAutoSnapshotPolicy fail %s", err)
} else {
return body.GetString("AutoSnapshotPolicyId")
params["autoSnapshotPolicyName"] = input.Name
body, err := self.ecsRequest("CreateAutoSnapshotPolicy", params)
if err != nil {
return "", errors.Wrapf(err, "CreateAutoSnapshotPolicy")
}
return body.GetString("AutoSnapshotPolicyId")
}
func (self *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput, snapshotPolicyId string) error {
@@ -249,36 +246,10 @@ func (self *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInp
return nil
}
//func (self *SRegion) UpdateSnapshotPolicy(
// snapshotPolicyId string, retentionDays *int,
// repeatWeekdays, timePoints *jsonutils.JSONArray, policyName string,
//) error {
// params := make(map[string]string)
// params["RegionId"] = self.RegionId
// if len(policyName) > 0 {
// params["autoSnapshotPolicyName"] = policyName
// }
// if retentionDays != nil {
// params["retentionDays"] = strconv.Itoa(*retentionDays)
// }
// if repeatWeekdays != nil {
// params["repeatWeekdays"] = repeatWeekdays.String()
// }
// if timePoints != nil {
// params["timePoints"] = timePoints.String()
// }
// _, err := self.ecsRequest("ModifyAutoSnapshotPolicyEx", params)
// if err != nil {
// return fmt.Errorf("ModifyAutoSnapshotPolicyEx Fail %s", err)
// }
// return nil
//}
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskIds []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 {
@@ -287,10 +258,17 @@ func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId
return nil
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
func (self *SSnapshotPolicy) ApplyDisks(ids []string) error {
return self.region.ApplySnapshotPolicyToDisks(self.AutoSnapshotPolicyId, ids)
}
func (self *SSnapshotPolicy) GetApplyDiskIds() ([]string, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskIds []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 {
@@ -298,3 +276,11 @@ func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId
}
return nil
}
func (self *SSnapshotPolicy) CancelDisks(ids []string) error {
return self.region.CancelSnapshotPolicyToDisks(self.AutoSnapshotPolicyId, ids)
}
func (self *SSnapshotPolicy) Update(opts *cloudprovider.SnapshotPolicyInput) error {
return self.region.UpdateSnapshotPolicy(opts, self.AutoSnapshotPolicyId)
}
+4 -10
View File
@@ -72,16 +72,10 @@ func (self *SStorage) getDisks() ([]SDisk, error) {
if len(self.zone.disks) > 0 {
return self.zone.disks, nil
}
self.zone.disks = []SDisk{}
for {
part, total, err := self.zone.region.GetDisks("", self.zone.GetId(), "", nil, len(self.zone.disks), 100)
if err != nil {
return nil, errors.Wrapf(err, "GetDisks")
}
self.zone.disks = append(self.zone.disks, part...)
if len(self.zone.disks) >= total || len(part) == 0 {
break
}
var err error
self.zone.disks, err = self.zone.region.GetDisks("", self.zone.GetId(), "", nil, "")
if err != nil {
return nil, errors.Wrapf(err, "GetDisks")
}
return self.zone.disks, nil
}
-4
View File
@@ -171,10 +171,6 @@ func (self *SDisk) CreateISnapshot(ctx context.Context, name string, desc string
return self.storage.cluster.region.GetISnapshotById(snapshotId)
}
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return []string{}, nil
}
func (self *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
return cloudprovider.ErrNotImplemented
}
-4
View File
@@ -197,10 +197,6 @@ func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return []cloudprovider.ICloudSnapshot{}, nil
}
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return []string{}, nil
}
func (self *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
return self.storage.zone.region.ResizeDisk(self.GetId(), newSizeMB/1024)
}
-28
View File
@@ -294,34 +294,6 @@ func (self *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSn
return nil, cloudprovider.ErrNotFound
}
func (self *SRegion) CreateSnapshotPolicy(*cloudprovider.SnapshotPolicyInput) (string, error) {
return "", cloudprovider.ErrNotImplemented
}
func (self *SRegion) UpdateSnapshotPolicy(*cloudprovider.SnapshotPolicyInput, string) error {
return cloudprovider.ErrNotImplemented
}
func (self *SRegion) DeleteSnapshotPolicy(policyId string) error {
return cloudprovider.ErrNotImplemented
}
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
return cloudprovider.ErrNotImplemented
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
return cloudprovider.ErrNotImplemented
}
func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (self *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
return nil, cloudprovider.ErrNotFound
}
func (self *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) {
iHosts := make([]cloudprovider.ICloudHost, 0)
-4
View File
@@ -23,10 +23,6 @@ type SDisk struct {
SBillingBase
}
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return []string{""}, nil
}
func (self *SDisk) GetIStorageId() string {
return ""
}
-4
View File
@@ -238,10 +238,6 @@ func (s *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return isnapshots, nil
}
func (s *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return []string{}, nil
}
func (s *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
return cloudprovider.ErrNotImplemented
}
-9
View File
@@ -191,15 +191,6 @@ func (disk *SDisk) GetISnapshot(id string) (cloudprovider.ICloudSnapshot, error)
return disk.storage.zone.region.GetSnapshot(id)
}
func (disk *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
result := []string{}
for _, policy := range disk.ResourcePolicies {
globalId := strings.TrimPrefix(policy, fmt.Sprintf("%s/%s/", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION))
result = append(result, globalId)
}
return result, nil
}
func (disk *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
return disk.storage.zone.region.ResizeDisk(disk.SelfLink, int(newSizeMB>>10))
}
+1
View File
@@ -1011,6 +1011,7 @@ func (self *SGoogleClient) GetCapabilities() []string {
// cloudprovider.CLOUD_CAPABILITY_EVENT,
cloudprovider.CLOUD_CAPABILITY_CLOUDID,
cloudprovider.CLOUD_CAPABILITY_QUOTA + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_SNAPSHOT_POLICY + cloudprovider.READ_ONLY_SUFFIX,
}
return caps
}
+20 -9
View File
@@ -21,10 +21,10 @@ import (
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/apis"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
type SDailySchedule struct {
@@ -98,10 +98,9 @@ func (region *SRegion) GetResourcePolicy(id string) (*SResourcePolicy, error) {
func (policy *SResourcePolicy) GetStatus() string {
switch policy.Status {
case "READY":
return api.SNAPSHOT_POLICY_READY
return apis.STATUS_AVAILABLE
default:
log.Errorf("unknown policy status %s", policy.Status)
return api.SNAPSHOT_POLICY_UNKNOWN
return apis.STATUS_UNKNOWN
}
}
@@ -129,6 +128,22 @@ func (policy *SResourcePolicy) GetRetentionDays() int {
return policy.SnapshotSchedulePolicy.RetentionPolicy.MaxRetentionDays
}
func (policy *SResourcePolicy) ApplyDisks(ids []string) error {
return cloudprovider.ErrNotImplemented
}
func (policy *SResourcePolicy) GetApplyDiskIds() ([]string, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (policy *SResourcePolicy) CancelDisks(ids []string) error {
return cloudprovider.ErrNotImplemented
}
func (policy *SResourcePolicy) Delete() error {
return cloudprovider.ErrNotImplemented
}
func (policy *SResourcePolicy) GetRepeatWeekdays() ([]int, error) {
result := []int{1, 2, 3, 4, 5, 6, 7}
if len(policy.SnapshotSchedulePolicy.Schedule.WeeklySchedule.DayOfWeeks) > 0 {
@@ -157,7 +172,3 @@ func (policy *SResourcePolicy) GetTimePoints() ([]int, error) {
}
return result, nil
}
func (policy *SResourcePolicy) IsActivated() bool {
return true
}
-4
View File
@@ -203,10 +203,6 @@ func (s *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return isnapshots, nil
}
func (s *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return []string{}, nil
}
func (s *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
return cloudprovider.ErrNotImplemented
}
@@ -274,10 +274,6 @@ func (cli *SObjectStoreClient) CreateSnapshotPolicy(*cloudprovider.SnapshotPolic
return "", cloudprovider.ErrNotSupported
}
func (cli *SObjectStoreClient) DeleteSnapshotPolicy(string) error {
return cloudprovider.ErrNotSupported
}
func (cli *SObjectStoreClient) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
return cloudprovider.ErrNotSupported
}
-4
View File
@@ -166,10 +166,6 @@ func (self *SBootDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (self *SBootDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (self *SBootDisk) GetTemplateId() string {
return self.ImageId
}
-4
View File
@@ -168,10 +168,6 @@ func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return nil, cloudprovider.ErrNotImplemented
}
func (self *SDisk) GetTemplateId() string {
return ""
}
-4
View File
@@ -342,10 +342,6 @@ func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return isnapshots, nil
}
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return self.storage.zone.region.GetSnapshotIdByDiskId(self.GetId())
}
func (self *SDisk) GetTemplateId() string {
//return self.ImageId
return ""
+1
View File
@@ -1005,6 +1005,7 @@ func (self *SQcloudClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_CDN + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_CONTAINER + cloudprovider.READ_ONLY_SUFFIX,
cloudprovider.CLOUD_CAPABILITY_CERT,
cloudprovider.CLOUD_CAPABILITY_SNAPSHOT_POLICY,
}
return caps
}
+31 -28
View File
@@ -21,7 +21,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/apis"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
@@ -48,6 +48,7 @@ type SSnapshotPolicy struct {
Policy []SSnapshotDatePolicy
Activated bool `json:"IsActivated"`
IsPermanent bool
DiskIdSet []string
}
func (self *SSnapshotPolicy) GetId() string {
@@ -63,10 +64,12 @@ func (self *SSnapshotPolicy) GetGlobalId() string {
}
func (self *SSnapshotPolicy) GetStatus() string {
if self.AutoSnapshotPolicyState == NORMAL {
return api.SNAPSHOT_POLICY_READY
switch self.AutoSnapshotPolicyState {
case NORMAL:
return apis.STATUS_AVAILABLE
default:
return apis.STATUS_UNKNOWN
}
return api.SNAPSHOT_POLICY_UNKNOWN
}
func (self *SSnapshotPolicy) Refresh() error {
@@ -115,10 +118,6 @@ func (self *SSnapshotPolicy) GetTimePoints() ([]int, error) {
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 {
@@ -191,14 +190,7 @@ func (self *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovi
}
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)
// In Qcloud, that IsPermanent is true means that keep snapshot forever,
// In OneCloud, that RetentionDays is -1 means that keep snapshot forever.
if input.RetentionDays == -1 {
@@ -213,8 +205,8 @@ func (self *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInp
}
params[dayOfWeekPrefix+strconv.Itoa(index)] = strconv.Itoa(day)
}
if len(input.PolicyName) > 0 {
params["AutoSnapshotPolicyName"] = input.PolicyName
if len(input.Name) > 0 {
params["AutoSnapshotPolicyName"] = input.Name
}
for index, hour := range input.TimePoints {
params[hourPrefix+strconv.Itoa(index)] = strconv.Itoa(hour)
@@ -227,33 +219,44 @@ func (self *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInp
return id, nil
}
func (self *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput, snapshotPolicyId string) error {
// not implement
return nil
}
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskIds []string) error {
params := make(map[string]string)
params["AutoSnapshotPolicyId"] = snapshotPolicyId
params["DiskIds.0"] = diskId
for i, id := range diskIds {
params[fmt.Sprintf("DiskIds.%d", i)] = id
}
_, err := self.cbsRequest("BindAutoSnapshotPolicy", params)
if err != nil {
return errors.Wrapf(err, "Bind AutoSnapshotPolicy %s to Disk failed", snapshotPolicyId)
return errors.Wrapf(err, "BindAutoSnapshotPolicy")
}
return nil
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
func (self *SSnapshotPolicy) ApplyDisks(ids []string) error {
return self.region.ApplySnapshotPolicyToDisks(self.AutoSnapshotPolicyId, ids)
}
func (self *SSnapshotPolicy) GetApplyDiskIds() ([]string, error) {
return self.DiskIdSet, nil
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskIds []string) error {
params := make(map[string]string)
params["AutoSnapshotPolicyId"] = snapshotPolicyId
params["DiskIds.0"] = diskId
for i, id := range diskIds {
params[fmt.Sprintf("DiskIds.%d", i)] = id
}
_, err := self.cbsRequest("UnbindAutoSnapshotPolicy", params)
if err != nil {
return errors.Wrapf(err, "Unbind AutoSnapshotPolicy %s of Disk failed", snapshotPolicyId)
return errors.Wrapf(err, "UnbindAutoSnapshotPolicy")
}
return nil
}
func (self *SSnapshotPolicy) CancelDisks(ids []string) error {
return self.region.CancelSnapshotPolicyToDisks(self.AutoSnapshotPolicyId, ids)
}
func (self *SRegion) GetSnapshotIdByDiskId(diskID string) ([]string, error) {
params := make(map[string]string)
params["DiskId"] = diskID
+1 -17
View File
@@ -79,10 +79,6 @@ func (r *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput)
return "", errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateSnapshotPolicy")
}
func (r *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput, snapshotPolicyId string) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "UpdateSnapshotPolicy")
}
func (r *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISnapshotPolicyById")
}
@@ -91,18 +87,6 @@ func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolic
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISnapshotPolicies")
}
func (self *SRegion) DeleteSnapshotPolicy(string) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "DeleteSnapshotPolicy")
}
func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "ApplySnapshotPolicyToDisks")
}
func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "CancelSnapshotPolicyToDisks")
}
func (self *SRegion) GetISkus() ([]cloudprovider.ICloudSku, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "GetISkus")
}
@@ -411,4 +395,4 @@ func (self *SRegion) GetIMiscResources() ([]cloudprovider.ICloudMiscResource, er
func (self *SRegion) GetISSLCertificates() ([]cloudprovider.ICloudSSLCertificate, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetISSLCertificate")
}
}
-4
View File
@@ -119,10 +119,6 @@ func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
return nil, cloudprovider.ErrNotSupported
}
func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return nil, cloudprovider.ErrNotSupported
}
func (self *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
return cloudprovider.ErrNotSupported
}
-4
View File
@@ -168,10 +168,6 @@ func (disk *SDisk) GetCreatedAt() time.Time {
return disk.CreatedAt
}
func (disk *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
return nil, errors.ErrNotImplemented
}
func (disk *SDisk) GetExpiredAt() time.Time {
return convertExpiredAt(disk.ExpiredTime)
}