Skip to content

Commit 218f491

Browse files
authored
fix(region): change disk billing type (#22532)
1 parent c22a181 commit 218f491

File tree

20 files changed

+220
-29
lines changed

20 files changed

+220
-29
lines changed

cmd/climc/shell/compute/disks.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func init() {
4646
cmd.Perform("rebuild", &compute_options.DiskRebuildOptions{})
4747
cmd.Perform("migrate", &compute_options.DiskMigrateOptions{})
4848
cmd.Perform("reset-template", &compute_options.DiskResetTemplateOptions{})
49+
cmd.Perform("change-billing-type", new(compute_options.DiskChangeBillingTypeOptions))
4950

5051
type DiskDetailOptions struct {
5152
ID string `help:"ID or Name of disk"`

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,14 @@ require (
9393
k8s.io/cri-api v0.22.17
9494
k8s.io/klog/v2 v2.20.0
9595
moul.io/http2curl/v2 v2.3.0
96-
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250512085204-4c8552cf788d
96+
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250515020430-3c80e4f0c134
9797
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256
9898
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
9999
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
100100
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
101-
yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281
101+
yunion.io/x/pkg v1.10.4-0.20250513085810-efeaaca81a0e
102102
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
103-
yunion.io/x/sqlchemy v1.1.3-0.20250507115529-f74b83fda63b
103+
yunion.io/x/sqlchemy v1.1.3-0.20250513031856-ce9f71063b3a
104104
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c
105105
)
106106

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,8 +1376,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
13761376
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
13771377
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
13781378
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
1379-
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250512085204-4c8552cf788d h1:3ofa2X04MnwqHnrGV6bc6nivoU7n4/fi9ckQgTWHXyQ=
1380-
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250512085204-4c8552cf788d/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ=
1379+
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250515020430-3c80e4f0c134 h1:JbyK6805VYmJg426R/4P8WHsPARBhgWCcrnF/bZYIeg=
1380+
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250515020430-3c80e4f0c134/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ=
13811381
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256 h1:kLKQ6zbgPDQflRwoHFAjxNChcbhXIFgsUVLkJwiXu/8=
13821382
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
13831383
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
@@ -1391,11 +1391,11 @@ yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 h1:Hu/4ERvoWaN6aiFs4h4/yvVB
13911391
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc=
13921392
yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
13931393
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
1394-
yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281 h1:P22/MaBc9bqE9DyHvS3oQjc4XsaIEbIVGMLdTSroDew=
1395-
yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM=
1394+
yunion.io/x/pkg v1.10.4-0.20250513085810-efeaaca81a0e h1:OiBxJR18bq5fFK/IZWYRX+5HTMs2KgQJe0a3BZfdIVU=
1395+
yunion.io/x/pkg v1.10.4-0.20250513085810-efeaaca81a0e/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM=
13961396
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 h1:1KJ3YYinydPHpDEQRXdr/T8SYcKZ5Er+m489H+PnaQ4=
13971397
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
1398-
yunion.io/x/sqlchemy v1.1.3-0.20250507115529-f74b83fda63b h1:VDSvBxXEcrac4pw9+fHP17XXPZNgHzkUPxtGDNx518M=
1399-
yunion.io/x/sqlchemy v1.1.3-0.20250507115529-f74b83fda63b/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A=
1398+
yunion.io/x/sqlchemy v1.1.3-0.20250513031856-ce9f71063b3a h1:mDW1VyYJxZ4ORITZGDWacUiBNyqX6rMObnQk77NvUOg=
1399+
yunion.io/x/sqlchemy v1.1.3-0.20250513031856-ce9f71063b3a/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A=
14001400
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c h1:QuLab2kSRECZRxo4Lo2KcYn6XjQFDGaZ1+x0pYDVVwQ=
14011401
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=

pkg/apis/compute/disk.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,11 @@ func (d *DiskFsFeatures) IsZero() bool {
376376
}
377377
return false
378378
}
379+
380+
type DiskChangeBillingTypeInput struct {
381+
// 仅在磁盘挂载在虚拟机上时调用
382+
// 目前支持阿里云
383+
// enmu: [postpaid, prepaid]
384+
// required: true
385+
BillingType string `json:"billing_type"`
386+
}

pkg/apis/compute/guest_const.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,6 @@ const (
180180
VM_QGA_SET_NETWORK = "qga_set_network"
181181
VM_QGA_SET_NETWORK_FAILED = "qga_set_network_failed"
182182

183-
// 更改计费模式
184-
VM_CHANGE_BILLING_TYPE = "change_billing_type"
185-
VM_CHANGE_BILLING_TYPE_FAILED = "change_billing_type_failed"
186-
187183
SHUTDOWN_STOP = "stop"
188184
SHUTDOWN_TERMINATE = "terminate"
189185
SHUTDOWN_STOP_RELEASE_GPU = "stop_release_gpu"

pkg/apis/const.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ const (
5858
STATUS_AVAILABLE = "available"
5959
STATUS_CREATE_FAILED = "create_failed"
6060

61+
// 更改计费模式
62+
STATUS_CHANGE_BILLING_TYPE = "change_billing_type"
63+
STATUS_CHANGE_BILLING_TYPE_FAILED = "change_billing_type_failed"
64+
6165
CLOUD_TAG_PREFIX = "ext:"
6266
USER_TAG_PREFIX = "user:"
6367
SYS_CLOUD_TAG_PREFIX = "sys:"

pkg/compute/guestdrivers/managedvirtual.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ func (drv *SManagedVirtualizedGuestDriver) RequestStartOnHost(ctx context.Contex
484484
if guest.BillingType == billing_api.BILLING_TYPE_POSTPAID && jsonutils.QueryBoolean(task.GetParams(), "auto_prepaid", false) {
485485
err = ivm.ChangeBillingType(billing_api.BILLING_TYPE_PREPAID)
486486
if err != nil && errors.Cause(err) != cloudprovider.ErrNotImplemented {
487-
logclient.AddSimpleActionLog(guest, logclient.ACT_VM_CHANGE_BILLING_TYPE, errors.Wrapf(err, billing_api.BILLING_TYPE_PREPAID), userCred, false)
487+
logclient.AddSimpleActionLog(guest, logclient.ACT_CHANGE_BILLING_TYPE, errors.Wrapf(err, billing_api.BILLING_TYPE_PREPAID), userCred, false)
488488
}
489489
}
490490

@@ -985,7 +985,7 @@ func (drv *SManagedVirtualizedGuestDriver) RequestStopOnHost(ctx context.Context
985985
if opts.StopCharging && guest.BillingType == billing_api.BILLING_TYPE_PREPAID {
986986
err = ivm.ChangeBillingType(billing_api.BILLING_TYPE_POSTPAID)
987987
if err != nil && errors.Cause(err) != cloudprovider.ErrNotImplemented {
988-
logclient.AddSimpleActionLog(guest, logclient.ACT_VM_CHANGE_BILLING_TYPE, errors.Wrapf(err, billing_api.BILLING_TYPE_POSTPAID), task.GetUserCred(), false)
988+
logclient.AddSimpleActionLog(guest, logclient.ACT_CHANGE_BILLING_TYPE, errors.Wrapf(err, billing_api.BILLING_TYPE_POSTPAID), task.GetUserCred(), false)
989989
}
990990
}
991991

pkg/compute/models/disks.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3339,3 +3339,29 @@ func (disk *SDisk) resetDiskinfo(
33393339
db.OpsLog.LogEvent(disk, db.ACT_UPDATE, notes, userCred)
33403340
return nil
33413341
}
3342+
3343+
func (disk *SDisk) PerformChangeBillingType(ctx context.Context, userCred mcclient.TokenCredential, _ jsonutils.JSONObject, input *api.DiskChangeBillingTypeInput) (jsonutils.JSONObject, error) {
3344+
if !utils.IsInStringArray(disk.Status, []string{api.DISK_READY}) {
3345+
return nil, httperrors.NewServerStatusError("Cannot change disk billing type in status %s", disk.Status)
3346+
}
3347+
if len(input.BillingType) == 0 {
3348+
return nil, httperrors.NewMissingParameterError("billing_type")
3349+
}
3350+
if !utils.IsInStringArray(input.BillingType, []string{billing_api.BILLING_TYPE_POSTPAID, billing_api.BILLING_TYPE_PREPAID}) {
3351+
return nil, httperrors.NewInputParameterError("invalid billing_type %s", input.BillingType)
3352+
}
3353+
if disk.BillingType == input.BillingType {
3354+
return nil, nil
3355+
}
3356+
return nil, disk.StartChangeBillingTypeTask(ctx, userCred, "")
3357+
}
3358+
3359+
func (disk *SDisk) StartChangeBillingTypeTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
3360+
disk.SetStatus(ctx, userCred, apis.STATUS_CHANGE_BILLING_TYPE, "")
3361+
kwargs := jsonutils.NewDict()
3362+
task, err := taskman.TaskManager.NewTask(ctx, "DiskChangeBillingTypeTask", disk, userCred, kwargs, parentTaskId, "", nil)
3363+
if err != nil {
3364+
return err
3365+
}
3366+
return task.ScheduleRun(nil)
3367+
}

pkg/compute/models/guest_actions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6757,7 +6757,7 @@ func (g *SGuest) PerformChangeBillingType(ctx context.Context, userCred mcclient
67576757
}
67586758

67596759
func (self *SGuest) StartChangeBillingTypeTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
6760-
self.SetStatus(ctx, userCred, api.VM_CHANGE_BILLING_TYPE, "")
6760+
self.SetStatus(ctx, userCred, apis.STATUS_CHANGE_BILLING_TYPE, "")
67616761
kwargs := jsonutils.NewDict()
67626762
task, err := taskman.TaskManager.NewTask(ctx, "GuestChangeBillingTypeTask", self, userCred, kwargs, parentTaskId, "", nil)
67636763
if err != nil {
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2019 Yunion
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package disk
16+
17+
import (
18+
"context"
19+
"time"
20+
21+
"yunion.io/x/cloudmux/pkg/cloudprovider"
22+
"yunion.io/x/jsonutils"
23+
"yunion.io/x/pkg/errors"
24+
25+
"yunion.io/x/onecloud/pkg/apis"
26+
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
27+
api "yunion.io/x/onecloud/pkg/apis/compute"
28+
"yunion.io/x/onecloud/pkg/cloudcommon/db"
29+
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
30+
"yunion.io/x/onecloud/pkg/compute/models"
31+
"yunion.io/x/onecloud/pkg/util/logclient"
32+
)
33+
34+
type DiskChangeBillingTypeTask struct {
35+
SDiskBaseTask
36+
}
37+
38+
func init() {
39+
taskman.RegisterTask(DiskChangeBillingTypeTask{})
40+
}
41+
42+
func (self *DiskChangeBillingTypeTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
43+
disk := obj.(*models.SDisk)
44+
45+
idisk, err := disk.GetIDisk(ctx)
46+
if err != nil {
47+
self.taskFail(ctx, disk, errors.Wrapf(err, "GetIDisk"))
48+
return
49+
}
50+
51+
billType := ""
52+
switch disk.BillingType {
53+
case billing_api.BILLING_TYPE_POSTPAID:
54+
billType = billing_api.BILLING_TYPE_PREPAID
55+
case billing_api.BILLING_TYPE_PREPAID:
56+
billType = billing_api.BILLING_TYPE_POSTPAID
57+
}
58+
59+
err = idisk.ChangeBillingType(billType)
60+
if err != nil {
61+
if errors.Cause(err) == cloudprovider.ErrNotImplemented {
62+
disk.SetStatus(ctx, self.GetUserCred(), api.DISK_READY, "")
63+
self.SetStageComplete(ctx, nil)
64+
return
65+
}
66+
self.taskFail(ctx, disk, errors.Wrapf(err, "ChangeBillingType"))
67+
return
68+
}
69+
70+
idisk.Refresh()
71+
72+
db.Update(disk, func() error {
73+
disk.BillingType = billType
74+
disk.ExpiredAt = time.Time{}
75+
if disk.BillingType == billing_api.BILLING_TYPE_PREPAID {
76+
disk.AutoRenew = idisk.IsAutoRenew()
77+
disk.ExpiredAt = idisk.GetExpiredAt()
78+
}
79+
return nil
80+
})
81+
82+
self.taskComplete(ctx, disk)
83+
}
84+
85+
func (self *DiskChangeBillingTypeTask) taskComplete(ctx context.Context, disk *models.SDisk) {
86+
disk.SetStatus(ctx, self.GetUserCred(), api.DISK_READY, "")
87+
logclient.AddActionLogWithStartable(self, disk, logclient.ACT_CHANGE_BILLING_TYPE, disk.BillingType, self.UserCred, true)
88+
self.SetStageComplete(ctx, nil)
89+
}
90+
91+
func (self *DiskChangeBillingTypeTask) taskFail(ctx context.Context, disk *models.SDisk, err error) {
92+
disk.SetStatus(ctx, self.GetUserCred(), apis.STATUS_CHANGE_BILLING_TYPE_FAILED, "")
93+
logclient.AddActionLogWithStartable(self, disk, logclient.ACT_CHANGE_BILLING_TYPE, err, self.UserCred, false)
94+
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
95+
}

0 commit comments

Comments
 (0)