mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge branch 'master' of https://github.com/yunionio/onecloud into bugfix/zxc-commonalert
This commit is contained in:
@@ -314,7 +314,7 @@ VERSION ?= $(shell git describe --exact-match 2> /dev/null || \
|
||||
git describe --match=$(git rev-parse --short=8 HEAD) --always --dirty --abbrev=8)
|
||||
|
||||
image:
|
||||
TAG=$(VERSION) REGISTRY=$(REGISTRY) $(ROOT_DIR)/scripts/docker_push.sh $(filter-out $@,$(MAKECMDGOALS))
|
||||
DEBUG=$(DEBUG) ARCH=$(ARCH) TAG=$(VERSION) REGISTRY=$(REGISTRY) $(ROOT_DIR)/scripts/docker_push.sh $(filter-out $@,$(MAKECMDGOALS))
|
||||
|
||||
.PHONY: image
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ COPY . /root/go/src/yunion.io/x/onecloud
|
||||
WORKDIR /root/go/src/yunion.io/x/onecloud
|
||||
RUN make cmd/esxi-agent
|
||||
|
||||
FROM FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.2
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.2
|
||||
|
||||
MAINTAINER "Yaoqi Wan wanyaoqi@yunionyun.com"
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ func init() {
|
||||
NoObjectStorage bool `help:"filter cloudproviders that has no object storage"`
|
||||
Capability []string `help:"capability filter" choices:"project|compute|network|loadbalancer|objectstore|rds|cache|event"`
|
||||
Cloudregion string `help:"filter cloudproviders by cloudregion"`
|
||||
|
||||
HostSchedtagId string `help:"filter by host schedtag"`
|
||||
}
|
||||
R(&CloudproviderListOptions{}, "cloud-provider-list", "List cloud providers", func(s *mcclient.ClientSession, args *CloudproviderListOptions) error {
|
||||
var params *jsonutils.JSONDict
|
||||
@@ -62,6 +64,10 @@ func init() {
|
||||
if len(args.Cloudregion) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Cloudregion), "cloudregion")
|
||||
}
|
||||
|
||||
if len(args.HostSchedtagId) > 0 {
|
||||
params.Add(jsonutils.NewString(args.HostSchedtagId), "host_schedtag_id")
|
||||
}
|
||||
}
|
||||
result, err := modules.Cloudproviders.List(s, params)
|
||||
if err != nil {
|
||||
|
||||
@@ -153,4 +153,17 @@ func init() {
|
||||
printBatchResults(ret, modules.Schedtags.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&options.ResourceMetadataOptions{}, "schedtag-set-user-metadata", "Set metadata of a server", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
|
||||
params, err := opts.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Schedtags.PerformAction(s, opts.ID, "user-metadata", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -70,13 +70,15 @@ func init() {
|
||||
|
||||
type HostsQueryOptions struct {
|
||||
options.BaseListOptions
|
||||
HostType string `help:"Host type filter" choices:"baremetal|hypervisor|esxi|kubelet|hyperv"`
|
||||
Ncpu int64 `help:"#CPU count of host" metavar:"<CPU_COUNT>"`
|
||||
MemSize int64 `help:"Memory MB size"`
|
||||
DiskSpec []string `help:"Disk spec string, like 'Linux_adapter0_HDD_111Gx4'"`
|
||||
Nic int64 `help:"#Nics count of host" metavar:"<NIC_COUNT>"`
|
||||
GpuModel []string `help:"GPU model, like 'GeForce GTX 1050 Ti'"`
|
||||
Occupied bool `help:"show occupid host" json:"-"`
|
||||
HostType string `help:"Host type filter" choices:"baremetal|hypervisor|esxi|kubelet|hyperv"`
|
||||
Ncpu int64 `help:"#CPU count of host" metavar:"<CPU_COUNT>"`
|
||||
MemSize int64 `help:"Memory MB size"`
|
||||
DiskSpec []string `help:"Disk spec string, like 'Linux_adapter0_HDD_111Gx4'"`
|
||||
Nic int64 `help:"#Nics count of host" metavar:"<NIC_COUNT>"`
|
||||
GpuModel []string `help:"GPU model, like 'GeForce GTX 1050 Ti'"`
|
||||
Occupied bool `help:"Show occupid host" json:"-"`
|
||||
Manufacture string `help:"Manufacture of host"`
|
||||
Model string `help:"Model of host"`
|
||||
}
|
||||
R(&HostsQueryOptions{}, "spec-hosts-list", "List hosts according by specs", func(s *mcclient.ClientSession, args *HostsQueryOptions) error {
|
||||
newHostSpecKeys := func() []string {
|
||||
@@ -90,6 +92,12 @@ func init() {
|
||||
if args.Nic > 0 {
|
||||
keys = append(keys, fmt.Sprintf("nic:%d", args.Nic))
|
||||
}
|
||||
if args.Manufacture != "" {
|
||||
keys = append(keys, fmt.Sprintf("manufacture:%s", args.Manufacture))
|
||||
}
|
||||
if args.Model != "" {
|
||||
keys = append(keys, fmt.Sprintf("model:%s", args.Model))
|
||||
}
|
||||
for _, gm := range args.GpuModel {
|
||||
keys = append(keys, fmt.Sprintf("gpu_model:%s", gm))
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
)
|
||||
@@ -35,4 +36,17 @@ func init() {
|
||||
cmd.Perform("public", &options.BasePublicOptions{})
|
||||
cmd.Perform("change-owner", &options.VpcChangeOwnerOptions{})
|
||||
cmd.Get("vpc-change-owner-candidate-domains", &options.VpcIdOptions{})
|
||||
|
||||
R(&options.ResourceMetadataOptions{}, "vpc-set-user-metadata", "Set metadata of a vpc", func(s *mcclient.ClientSession, opts *options.ResourceMetadataOptions) error {
|
||||
params, err := opts.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Vpcs.PerformAction(s, opts.ID, "user-metadata", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
)
|
||||
|
||||
type BaseEventListOptions struct {
|
||||
@@ -54,23 +53,19 @@ type TypeEventListOptions struct {
|
||||
ID string `help:"" metavar:"OBJ_ID"`
|
||||
}
|
||||
|
||||
func doK8sEventList(s *mcclient.ClientSession, args *EventListOptions) error {
|
||||
return doEventList(*k8s.Logs.ResourceManager, s, args)
|
||||
}
|
||||
|
||||
func doComputeEventList(s *mcclient.ClientSession, args *EventListOptions) error {
|
||||
return doEventList(modules.Logs, s, args)
|
||||
return DoEventList(modules.Logs, s, args)
|
||||
}
|
||||
|
||||
func doImageEventList(s *mcclient.ClientSession, args *EventListOptions) error {
|
||||
return doEventList(modules.ImageLogs, s, args)
|
||||
return DoEventList(modules.ImageLogs, s, args)
|
||||
}
|
||||
|
||||
func doIdentityEventList(s *mcclient.ClientSession, args *EventListOptions) error {
|
||||
return doEventList(modules.IdentityLogs, s, args)
|
||||
return DoEventList(modules.IdentityLogs, s, args)
|
||||
}
|
||||
|
||||
func doEventList(man modulebase.ResourceManager, s *mcclient.ClientSession, args *EventListOptions) error {
|
||||
func DoEventList(man modulebase.ResourceManager, s *mcclient.ClientSession, args *EventListOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
if len(args.Type) > 0 {
|
||||
params.Add(jsonutils.NewStringArray(args.Type), "obj_type")
|
||||
@@ -190,16 +185,6 @@ func init() {
|
||||
return doComputeEventList(s, &nargs)
|
||||
})
|
||||
|
||||
R(&TypeEventListOptions{}, "kubecluster-event", "Show operation event logs of kubernetes cluster", func(s *mcclient.ClientSession, args *TypeEventListOptions) error {
|
||||
nargs := EventListOptions{BaseEventListOptions: args.BaseEventListOptions, Id: args.ID, Type: []string{"kubecluster"}}
|
||||
return doK8sEventList(s, &nargs)
|
||||
})
|
||||
|
||||
R(&TypeEventListOptions{}, "kubemachine-event", "Show operation event logs of kubernetes machine", func(s *mcclient.ClientSession, args *TypeEventListOptions) error {
|
||||
nargs := EventListOptions{BaseEventListOptions: args.BaseEventListOptions, Id: args.ID, Type: []string{"kubemachine"}}
|
||||
return doK8sEventList(s, &nargs)
|
||||
})
|
||||
|
||||
R(&TypeEventListOptions{}, "image-event", "Show operation event logs of glance images", func(s *mcclient.ClientSession, args *TypeEventListOptions) error {
|
||||
nargs := EventListOptions{BaseEventListOptions: args.BaseEventListOptions, Id: args.ID, Type: []string{"image"}}
|
||||
return doImageEventList(s, &nargs)
|
||||
|
||||
+20
-20
@@ -78,7 +78,7 @@ type ICreateOpt interface {
|
||||
IOpt
|
||||
}
|
||||
|
||||
func (cmd ResourceCmd) runWithDesc(action, desc string, args interface{}, callback interface{}) {
|
||||
func (cmd ResourceCmd) RunWithDesc(action, desc string, args interface{}, callback interface{}) {
|
||||
man := cmd.manager
|
||||
prefix := cmd.prefix
|
||||
if prefix != "" {
|
||||
@@ -98,8 +98,8 @@ func (cmd ResourceCmd) runWithDesc(action, desc string, args interface{}, callba
|
||||
R(args, fmt.Sprintf("%s%s-%s", prefix, cmd.keyword, action), desc, callback)
|
||||
}
|
||||
|
||||
func (cmd ResourceCmd) run(action string, args interface{}, callback interface{}) {
|
||||
cmd.runWithDesc(action, "", args, callback)
|
||||
func (cmd ResourceCmd) Run(action string, args interface{}, callback interface{}) {
|
||||
cmd.RunWithDesc(action, "", args, callback)
|
||||
}
|
||||
|
||||
func (cmd ResourceCmd) List(args IListOpt) {
|
||||
@@ -130,7 +130,7 @@ func (cmd ResourceCmd) List(args IListOpt) {
|
||||
printList(result, man.GetColumns(s))
|
||||
return nil
|
||||
}
|
||||
cmd.run("list", args, callback)
|
||||
cmd.Run("list", args, callback)
|
||||
}
|
||||
|
||||
func (cmd ResourceCmd) Create(args ICreateOpt) {
|
||||
@@ -147,7 +147,7 @@ func (cmd ResourceCmd) Create(args ICreateOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.run("create", args, callback)
|
||||
cmd.Run("create", args, callback)
|
||||
}
|
||||
|
||||
type IIdOpt interface {
|
||||
@@ -177,7 +177,7 @@ func (cmd ResourceCmd) Show(args IShowOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.runWithDesc("show", fmt.Sprintf("Show details of a %s", man.GetKeyword()), args, callback)
|
||||
cmd.RunWithDesc("show", fmt.Sprintf("Show details of a %s", man.GetKeyword()), args, callback)
|
||||
}
|
||||
|
||||
func (cmd ResourceCmd) ClassShow(args IShowOpt) {
|
||||
@@ -194,7 +194,7 @@ func (cmd ResourceCmd) ClassShow(args IShowOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.runWithDesc(args.GetId(), fmt.Sprintf("Show %s of a %s", args.GetId(), man.GetKeyword()), args, callback)
|
||||
cmd.RunWithDesc(args.GetId(), fmt.Sprintf("Show %s of a %s", args.GetId(), man.GetKeyword()), args, callback)
|
||||
}
|
||||
|
||||
type IGetActionOpt interface {
|
||||
@@ -247,7 +247,7 @@ func (cmd ResourceCmd) Custom(action TCustomAction, funcname string, args IGetAc
|
||||
}
|
||||
return nil
|
||||
}
|
||||
cmd.runWithDesc(funcname, fmt.Sprintf("Get %s of a %s", funcname, man.GetKeyword()), args, callback)
|
||||
cmd.RunWithDesc(funcname, fmt.Sprintf("Get %s of a %s", funcname, man.GetKeyword()), args, callback)
|
||||
}
|
||||
|
||||
type IDeleteOpt interface {
|
||||
@@ -269,7 +269,7 @@ func (cmd ResourceCmd) Delete(args IDeleteOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.runWithDesc("delete", fmt.Sprintf("Delete %s", man.GetKeyword()), args, callback)
|
||||
cmd.RunWithDesc("delete", fmt.Sprintf("Delete %s", man.GetKeyword()), args, callback)
|
||||
}
|
||||
|
||||
type IWithDescOpt interface {
|
||||
@@ -295,7 +295,7 @@ func (cmd ResourceCmd) Perform(action string, args IPerformOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.run(action, args, callback)
|
||||
cmd.Run(action, args, callback)
|
||||
}
|
||||
|
||||
func (cmd ResourceCmd) PerformClass(action string, args IOpt) {
|
||||
@@ -312,7 +312,7 @@ func (cmd ResourceCmd) PerformClass(action string, args IOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.run(action, args, callback)
|
||||
cmd.Run(action, args, callback)
|
||||
}
|
||||
|
||||
type IBatchPerformOpt interface {
|
||||
@@ -331,7 +331,7 @@ func (cmd ResourceCmd) BatchPerform(action string, args IBatchPerformOpt) {
|
||||
printBatchResults(ret, man.GetColumns(s))
|
||||
return nil
|
||||
}
|
||||
cmd.run(action, args, callback)
|
||||
cmd.Run(action, args, callback)
|
||||
}
|
||||
|
||||
type IGetOpt interface {
|
||||
@@ -353,7 +353,7 @@ func (cmd ResourceCmd) Get(specific string, args IGetOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.runWithDesc(specific, fmt.Sprintf("Get %s of a %s", specific, man.GetKeyword()), args, callback)
|
||||
cmd.RunWithDesc(specific, fmt.Sprintf("Get %s of a %s", specific, man.GetKeyword()), args, callback)
|
||||
}
|
||||
|
||||
type IUpdateOpt interface {
|
||||
@@ -375,7 +375,7 @@ func (cmd ResourceCmd) Update(args IUpdateOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.run("update", args, callback)
|
||||
cmd.Run("update", args, callback)
|
||||
}
|
||||
|
||||
type IMetadataOpt interface {
|
||||
@@ -397,7 +397,7 @@ func (cmd ResourceCmd) GetMetadata(args IMetadataOpt) {
|
||||
printObject(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.runWithDesc("metadata", fmt.Sprintf("Show metadata of a %s", man.GetKeyword()), args, callback)
|
||||
cmd.RunWithDesc("metadata", fmt.Sprintf("Show metadata of a %s", man.GetKeyword()), args, callback)
|
||||
}
|
||||
|
||||
type IBatchDeleteOpt interface {
|
||||
@@ -416,7 +416,7 @@ func (cmd ResourceCmd) BatchDelete(args IBatchDeleteOpt) {
|
||||
printBatchResults(ret, man.GetColumns(s))
|
||||
return nil
|
||||
}
|
||||
cmd.run("delete", args, callback)
|
||||
cmd.Run("delete", args, callback)
|
||||
}
|
||||
|
||||
type IBatchDeleteWithParamOpt interface {
|
||||
@@ -439,7 +439,7 @@ func (cmd ResourceCmd) BatchDeleteWithParam(args IBatchDeleteWithParamOpt) {
|
||||
printBatchResults(ret, man.GetColumns(s))
|
||||
return nil
|
||||
}
|
||||
cmd.run("delete", args, callback)
|
||||
cmd.Run("delete", args, callback)
|
||||
}
|
||||
|
||||
type IBatchPutOpt interface {
|
||||
@@ -458,7 +458,7 @@ func (cmd ResourceCmd) BatchPut(args IBatchPutOpt) {
|
||||
printBatchResults(ret, man.GetColumns(s))
|
||||
return nil
|
||||
}
|
||||
cmd.run("update", args, callback)
|
||||
cmd.Run("update", args, callback)
|
||||
}
|
||||
|
||||
type JointCmd struct {
|
||||
@@ -498,7 +498,7 @@ func (cmd JointCmd) List(args IJointListOpt) {
|
||||
printList(result, man.GetColumns(s))
|
||||
return nil
|
||||
}
|
||||
cmd.runWithDesc("list", fmt.Sprintf("list %s %s pairs", man.MasterManager().KeyString(), man.SlaveManager().KeyString()), args, callback)
|
||||
cmd.RunWithDesc("list", fmt.Sprintf("list %s %s pairs", man.MasterManager().KeyString(), man.SlaveManager().KeyString()), args, callback)
|
||||
}
|
||||
|
||||
type IJointShowOpt interface {
|
||||
@@ -521,5 +521,5 @@ func (cmd JointCmd) Show(args IJointShowOpt) {
|
||||
printObject(result)
|
||||
return nil
|
||||
}
|
||||
cmd.run("show", args, callback)
|
||||
cmd.Run("show", args, callback)
|
||||
}
|
||||
|
||||
@@ -15,27 +15,11 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initKubeCerts() {
|
||||
cmdN := func(action string) string {
|
||||
return fmt.Sprintf("kubecert-%s", action)
|
||||
}
|
||||
R(&o.CertListOptions{}, cmdN("list"), "List k8s cluster certificates key pairs", func(s *mcclient.ClientSession, args *o.CertListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.KubeCerts.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(ret, k8s.KubeCerts.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
cmd := NewK8sResourceCmd(k8s.KubeCerts)
|
||||
cmd.List(new(o.CertListOptions))
|
||||
}
|
||||
|
||||
@@ -28,13 +28,22 @@ func initKubeCluster() {
|
||||
cmdN := func(action string) string {
|
||||
return fmt.Sprintf("k8s-cluster-%s", action)
|
||||
}
|
||||
cmd := NewK8sResourceCmd(k8s.KubeClusters).SetKeyword("cluster")
|
||||
cmd := NewK8sResourceCmd(k8s.KubeClusters)
|
||||
cmd.SetKeyword("cluster")
|
||||
cmd.ShowEvent()
|
||||
cmd.List(new(o.ClusterListOptions))
|
||||
cmd.Show(new(o.IdentOptions))
|
||||
cmd.Create(new(o.KubeClusterCreateOptions))
|
||||
cmd.Perform("sync", new(o.ClusterSyncOptions))
|
||||
cmd.Perform("syncstatus", new(o.IdentOptions))
|
||||
cmd.Get("components-status", new(o.IdentOptions))
|
||||
cmd.Get("api-resources", new(o.IdentOptions))
|
||||
cmd.Get("cluster-users", new(o.IdentOptions))
|
||||
cmd.Get("cluster-user-groups", new(o.IdentOptions))
|
||||
cmd.Perform("purge", new(o.ClusterPurgeOptions))
|
||||
cmd.Perform("delete-machines", new(o.KubeClusterDeleteMachinesOptions))
|
||||
cmd.Perform("add-machines", new(o.KubeClusterAddMachinesOptions))
|
||||
cmd.PerformClass("gc", new(o.ClusterGCOpts))
|
||||
|
||||
R(&o.KubeClusterImportOptions{}, cmdN("import"), "Import k8s cluster", func(s *mcclient.ClientSession, args *o.KubeClusterImportOptions) error {
|
||||
params, err := args.Params()
|
||||
@@ -55,41 +64,6 @@ func initKubeCluster() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.KubeClusterAddMachinesOptions{}, cmdN("add-machines"), "Add machines to cluster", func(s *mcclient.ClientSession, args *o.KubeClusterAddMachinesOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "add-machines", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.KubeClusterDeleteMachinesOptions{}, cmdN("delete-machines"), "Delete machines in cluster", func(s *mcclient.ClientSession, args *o.KubeClusterDeleteMachinesOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "delete-machines", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.IdentOptions{}, cmdN("terminate"), "Terminate cluster", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
|
||||
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "terminate", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.IdentOptions{}, cmdN("kubeconfig"), "Generate kubeconfig of a cluster", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
|
||||
ret, err := k8s.KubeClusters.GetSpecific(s, args.ID, "kubeconfig", nil)
|
||||
if err != nil {
|
||||
@@ -156,37 +130,6 @@ func initKubeCluster() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.IdentOptions{}, cmdN("syncstatus"), "Sync cluster status", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
|
||||
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "syncstatus", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.ClusterSyncOptions{}, cmdN("sync"), "Sync cluster k8s resources", func(s *mcclient.ClientSession, args *o.ClusterSyncOptions) error {
|
||||
param, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.KubeClusters.PerformAction(s, args.ID, "sync", param)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.IdentOptions{}, cmdN("components-status"), "Get cluster component status", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
|
||||
ret, err := k8s.KubeClusters.GetSpecific(s, args.ID, "components-status", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.ClusterComponentTypeOptions{}, cmdN("component-setting"), "Get cluster component setting", func(s *mcclient.ClientSession, args *o.ClusterComponentTypeOptions) error {
|
||||
q := jsonutils.NewDict()
|
||||
q.Add(jsonutils.NewString(args.TYPE), "type")
|
||||
|
||||
@@ -15,30 +15,11 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initCronJob() {
|
||||
cmd := initK8sNamespaceResource("cronjob", k8s.CronJobs)
|
||||
cmdN := cmd.CommandNameFactory
|
||||
createCmd := NewCommand(
|
||||
&o.CronJobCreateOptions{},
|
||||
cmdN("create"),
|
||||
"Create cronjob resource",
|
||||
func(s *mcclient.ClientSession, args *o.CronJobCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.CronJobs.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
cmd.AddR(createCmd)
|
||||
cmd.Create(new(o.CronJobCreateOptions))
|
||||
}
|
||||
|
||||
@@ -15,48 +15,12 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initDeployment() {
|
||||
cmd := initK8sNamespaceResource("deployment", k8s.Deployments)
|
||||
cmdN := cmd.CommandNameFactory
|
||||
|
||||
createCmd := NewCommand(
|
||||
&o.DeploymentCreateOptions{},
|
||||
cmdN("create"),
|
||||
"Create deployment resource",
|
||||
func(s *mcclient.ClientSession, args *o.DeploymentCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Deployments.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
updateCmd := NewCommand(
|
||||
&o.DeploymentUpdateOptions{},
|
||||
cmdN("update"),
|
||||
"Update deployment resource",
|
||||
func(s *mcclient.ClientSession, args *o.DeploymentUpdateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Deployments.Update(s, args.NAME, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObjectYAML(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
cmd.AddR(createCmd, updateCmd)
|
||||
cmd.Create(new(o.DeploymentCreateOptions))
|
||||
cmd.Update(new(o.DeploymentUpdateOptions))
|
||||
}
|
||||
|
||||
@@ -27,7 +27,9 @@ func init() {
|
||||
Delete(new(options.IdentOptions)).
|
||||
AttachCluster(new(options.FedResourceJointClusterAttachOptions)).
|
||||
DetachCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions))
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
Sync(new(options.FedResourceIdOptions)).
|
||||
ShowEvent()
|
||||
|
||||
cmd.ClassShow(new(options.FedApiResourecesOptions))
|
||||
cmd.ClassShow(new(options.FedClusterUsersOptions))
|
||||
|
||||
@@ -27,5 +27,7 @@ func init() {
|
||||
Delete(new(options.IdentOptions)).
|
||||
AttachCluster(new(options.FedResourceJointClusterAttachOptions)).
|
||||
DetachCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions))
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
Sync(new(options.FedResourceIdOptions)).
|
||||
ShowEvent()
|
||||
}
|
||||
|
||||
@@ -20,47 +20,52 @@ import (
|
||||
)
|
||||
|
||||
type fedResourceCmd struct {
|
||||
*shell.ResourceCmd
|
||||
*K8sResourceCmd
|
||||
}
|
||||
|
||||
func newFedResourceCmd(manager modulebase.IBaseManager) *fedResourceCmd {
|
||||
cmd := NewK8sResourceCmd(manager)
|
||||
return &fedResourceCmd{
|
||||
ResourceCmd: cmd,
|
||||
K8sResourceCmd: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *fedResourceCmd) List(args shell.IListOpt) *fedResourceCmd {
|
||||
c.ResourceCmd.List(args)
|
||||
c.K8sResourceCmd.List(args)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *fedResourceCmd) Show(args shell.IShowOpt) *fedResourceCmd {
|
||||
c.ResourceCmd.Show(args)
|
||||
c.K8sResourceCmd.Show(args)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *fedResourceCmd) Create(args shell.ICreateOpt) *fedResourceCmd {
|
||||
c.ResourceCmd.Create(args)
|
||||
c.K8sResourceCmd.Create(args)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *fedResourceCmd) Delete(args shell.IDeleteOpt) *fedResourceCmd {
|
||||
c.ResourceCmd.Delete(args)
|
||||
c.K8sResourceCmd.Delete(args)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *fedResourceCmd) AttachCluster(args shell.IPerformOpt) *fedResourceCmd {
|
||||
c.ResourceCmd.Perform("attach-cluster", args)
|
||||
c.K8sResourceCmd.Perform("attach-cluster", args)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *fedResourceCmd) DetachCluster(args shell.IPerformOpt) *fedResourceCmd {
|
||||
c.ResourceCmd.Perform("detach-cluster", args)
|
||||
c.K8sResourceCmd.Perform("detach-cluster", args)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *fedResourceCmd) SyncCluster(args shell.IPerformOpt) *fedResourceCmd {
|
||||
c.ResourceCmd.Perform("sync-cluster", args)
|
||||
c.K8sResourceCmd.Perform("sync-cluster", args)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *fedResourceCmd) Sync(args shell.IPerformOpt) *fedResourceCmd {
|
||||
c.K8sResourceCmd.Perform("sync", args)
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -28,5 +28,7 @@ func init() {
|
||||
Delete(new(options.IdentOptions)).
|
||||
AttachCluster(new(options.FedResourceJointClusterAttachOptions)).
|
||||
DetachCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions))
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
Sync(new(options.IdentOptions)).
|
||||
ShowEvent()
|
||||
}
|
||||
|
||||
@@ -27,7 +27,9 @@ func init() {
|
||||
Delete(new(options.IdentOptions)).
|
||||
AttachCluster(new(options.FedResourceJointClusterAttachOptions)).
|
||||
DetachCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions))
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
Sync(new(options.IdentOptions)).
|
||||
ShowEvent()
|
||||
|
||||
cmd.ClassShow(new(options.FedApiResourecesOptions))
|
||||
cmd.ClassShow(new(options.FedClusterUsersOptions))
|
||||
|
||||
@@ -28,5 +28,7 @@ func init() {
|
||||
Delete(new(options.IdentOptions)).
|
||||
AttachCluster(new(options.FedResourceJointClusterAttachOptions)).
|
||||
DetachCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions))
|
||||
SyncCluster(new(options.FedResourceJointClusterDetachOptions)).
|
||||
Sync(new(options.IdentOptions)).
|
||||
ShowEvent()
|
||||
}
|
||||
|
||||
@@ -15,12 +15,118 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/cmd/climc/shell/events"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
)
|
||||
|
||||
func NewK8sResourceCmd(manager modulebase.IBaseManager) *shell.ResourceCmd {
|
||||
return shell.NewResourceCmd(manager).SetPrefix("k8s")
|
||||
type K8sResourceCmd struct {
|
||||
*shell.ResourceCmd
|
||||
manager modulebase.IBaseManager
|
||||
}
|
||||
|
||||
func NewK8sResourceCmd(manager modulebase.IBaseManager) *K8sResourceCmd {
|
||||
cmd := new(K8sResourceCmd)
|
||||
cmd.ResourceCmd = shell.NewResourceCmd(manager).SetPrefix("k8s")
|
||||
cmd.manager = manager
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (cmd *K8sResourceCmd) GetClusterResManager() k8s.IClusterResourceManager {
|
||||
return cmd.manager.(k8s.IClusterResourceManager)
|
||||
}
|
||||
|
||||
func (cmd *K8sResourceCmd) ShowEvent() *K8sResourceCmd {
|
||||
callback := func(s *mcclient.ClientSession, opt *events.TypeEventListOptions) error {
|
||||
args := &events.EventListOptions{BaseEventListOptions: opt.BaseEventListOptions, Id: opt.ID, Type: []string{cmd.manager.GetKeyword()}}
|
||||
return events.DoEventList(*k8s.Logs.ResourceManager, s, args)
|
||||
}
|
||||
cmd.RunWithDesc("event", fmt.Sprintf("Show operation event logs of k8s %s", cmd.manager.GetKeyword()), new(events.TypeEventListOptions), callback)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (cmd *K8sResourceCmd) EditRaw(opt shell.IGetOpt) *K8sResourceCmd {
|
||||
man := cmd.GetClusterResManager()
|
||||
callback := func(s *mcclient.ClientSession, args shell.IGetOpt) error {
|
||||
params, err := opt.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawData, err := man.GetRaw(s, args.GetId(), params.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
yamlBytes := rawData.YAMLString()
|
||||
tempfile, err := ioutil.TempFile("", fmt.Sprintf("k8s-%s*.yaml", args.GetId()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(tempfile.Name())
|
||||
if _, err := tempfile.Write([]byte(yamlBytes)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tempfile.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command("vim", tempfile.Name())
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
content, err := ioutil.ReadFile(tempfile.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonBytes, err := yaml.YAMLToJSON(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body, err := jsonutils.Parse(jsonBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params, err = args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := man.UpdateRaw(s, args.GetId(), params.(*jsonutils.JSONDict), body.(*jsonutils.JSONDict)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
cmd.RunWithDesc("edit-raw", fmt.Sprintf("Edit and update k8s %s by raw data", man.GetKeyword()), opt, callback)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (cmd *K8sResourceCmd) ShowRaw(args shell.IGetOpt) *K8sResourceCmd {
|
||||
man := cmd.GetClusterResManager()
|
||||
callback := func(s *mcclient.ClientSession, args shell.IGetOpt) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := man.GetRaw(s, args.GetId(), params.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObjectYAML(ret)
|
||||
return nil
|
||||
}
|
||||
cmd.RunWithDesc("show-raw", fmt.Sprintf("Show k8s %s raw data", man.GetKeyword()), args, callback)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewK8sJointCmd(manager modulebase.JointManager) *shell.JointCmd {
|
||||
|
||||
@@ -15,25 +15,11 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initIngress() {
|
||||
cmdN := initK8sNamespaceResource("ingress", k8s.Ingresses)
|
||||
createCmd := NewCommand(
|
||||
&o.IngressCreateOptions{},
|
||||
cmdN.CommandNameFactory("create"),
|
||||
"Create ingress rules to service",
|
||||
func(s *mcclient.ClientSession, args *o.IngressCreateOptions) error {
|
||||
spec := args.Params()
|
||||
ret, err := k8s.Ingresses.Create(s, spec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
cmdN.AddR(createCmd)
|
||||
cmd := initK8sNamespaceResource("ingress", k8s.Ingresses)
|
||||
cmd.Create(new(o.IngressCreateOptions))
|
||||
}
|
||||
|
||||
@@ -15,31 +15,12 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initJob() {
|
||||
cmd := initK8sNamespaceResource("job", k8s.Jobs)
|
||||
cmdN := cmd.CommandNameFactory
|
||||
|
||||
createCmd := NewCommand(
|
||||
&o.JobCreateOptions{},
|
||||
cmdN("create"),
|
||||
"Create job resource",
|
||||
func(s *mcclient.ClientSession, args *o.JobCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Jobs.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
cmd.AddR(createCmd)
|
||||
cmd.Create(new(o.JobCreateOptions))
|
||||
}
|
||||
|
||||
+18
-265
@@ -16,16 +16,10 @@ package k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
@@ -78,10 +72,6 @@ func resourceCmdN(prefix, suffix string) string {
|
||||
return fmt.Sprintf("k8s-%s-%s", prefix, suffix)
|
||||
}
|
||||
|
||||
func kubeResourceCmdN(prefix, suffix string) string {
|
||||
return fmt.Sprintf("kube-%s-%s", prefix, suffix)
|
||||
}
|
||||
|
||||
func clusterContext(clusterId string) modulebase.ManagerContext {
|
||||
return modulebase.ManagerContext{
|
||||
InstanceManager: k8s.KubeClusters,
|
||||
@@ -93,261 +83,24 @@ func printObjectYAML(obj jsonutils.JSONObject) {
|
||||
fmt.Println(obj.YAMLString())
|
||||
}
|
||||
|
||||
type Cmd struct {
|
||||
Options interface{}
|
||||
Command string
|
||||
Desc string
|
||||
Callback interface{}
|
||||
func initK8sClusterResource(kind string, manager modulebase.Manager) *K8sResourceCmd {
|
||||
cmd := NewK8sResourceCmd(manager)
|
||||
cmd.SetKeyword(kind)
|
||||
cmd.List(new(o.ResourceListOptions))
|
||||
cmd.Show(new(o.ResourceGetOptions))
|
||||
cmd.BatchDeleteWithParam(new(o.ResourceDeleteOptions))
|
||||
cmd.ShowEvent()
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCommand(options interface{}, command string, desc string, callback interface{}) *Cmd {
|
||||
return &Cmd{
|
||||
Options: options,
|
||||
Command: command,
|
||||
Desc: desc,
|
||||
Callback: callback,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Cmd) R() {
|
||||
R(c.Options, c.Command, c.Desc, c.Callback)
|
||||
}
|
||||
|
||||
type ShellCommands struct {
|
||||
Commands []*Cmd
|
||||
CommandNameFactory func(suffix string) string
|
||||
}
|
||||
|
||||
func NewShellCommands(cmdN func(suffix string) string) *ShellCommands {
|
||||
c := &ShellCommands{
|
||||
CommandNameFactory: cmdN,
|
||||
}
|
||||
c.Commands = make([]*Cmd, 0)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *ShellCommands) AddR(rs ...*Cmd) *ShellCommands {
|
||||
for _, r := range rs {
|
||||
r.R()
|
||||
c.Commands = append(c.Commands, r)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func initK8sClusterResource(kind string, manager modulebase.Manager) *ShellCommands {
|
||||
cmdN := NewCmdNameFactory(kind)
|
||||
return NewShellCommands(cmdN.Do).AddR(
|
||||
NewK8sResourceListCmd(cmdN, manager),
|
||||
NewK8sResourceGetCmd(cmdN, manager),
|
||||
NewK8sResourceDeleteCmd(cmdN, manager),
|
||||
)
|
||||
}
|
||||
|
||||
func NewK8sResourceListCmd(cmdN CmdNameFactory, manager modulebase.Manager) *Cmd {
|
||||
return NewCommand(
|
||||
&o.ResourceListOptions{},
|
||||
cmdN.Do("list"),
|
||||
fmt.Sprintf("List k8s %s", cmdN.Kind),
|
||||
func(s *mcclient.ClientSession, args *o.ResourceListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := manager.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
PrintListResultTable(ret, manager.(k8s.ListPrinter), s)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type CmdNameFactory struct {
|
||||
Kind string
|
||||
Do func(string) string
|
||||
}
|
||||
|
||||
func NewCmdNameFactory(kind string) CmdNameFactory {
|
||||
return CmdNameFactory{
|
||||
Kind: kind,
|
||||
Do: func(suffix string) string {
|
||||
return resourceCmdN(kind, suffix)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewK8sNsResourceListCmd(cmdN CmdNameFactory, manager modulebase.Manager) *Cmd {
|
||||
return NewCommand(
|
||||
&o.NamespaceResourceListOptions{},
|
||||
cmdN.Do("list"),
|
||||
fmt.Sprintf("List k8s %s", cmdN.Kind),
|
||||
func(s *mcclient.ClientSession, args *o.NamespaceResourceListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := manager.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
PrintListResultTable(ret, manager.(k8s.ListPrinter), s)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func NewK8sResourceGetCmd(cmdN CmdNameFactory, manager modulebase.Manager) *Cmd {
|
||||
return NewCommand(
|
||||
&o.ResourceGetOptions{},
|
||||
cmdN.Do("show"),
|
||||
fmt.Sprintf("Show k8s %s", cmdN.Kind),
|
||||
func(s *mcclient.ClientSession, args *o.ResourceGetOptions) error {
|
||||
ret, err := manager.Get(s, args.NAME, args.Params())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObjectYAML(ret)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func NewK8sNsResourceGetCmd(cmdN CmdNameFactory, manager modulebase.Manager) *Cmd {
|
||||
return NewCommand(
|
||||
&o.NamespaceResourceGetOptions{},
|
||||
cmdN.Do("show"),
|
||||
fmt.Sprintf("Show k8s %s", cmdN.Kind),
|
||||
func(s *mcclient.ClientSession, args *o.NamespaceResourceGetOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := manager.Get(s, args.NAME, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObjectYAML(ret)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func NewK8sNsResourceGetRawCmd(cmdN CmdNameFactory, manager k8s.IClusterResourceManager) *Cmd {
|
||||
return NewCommand(
|
||||
&o.NamespaceResourceGetOptions{},
|
||||
cmdN.Do("show-raw"),
|
||||
fmt.Sprintf("Show k8s %s raw data", cmdN.Kind),
|
||||
func(s *mcclient.ClientSession, args *o.NamespaceResourceGetOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := manager.GetRaw(s, args.NAME, params.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObjectYAML(ret)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func NewK8sResourceEditRawCmd(cmdN CmdNameFactory, manager k8s.IClusterResourceManager) *Cmd {
|
||||
return NewCommand(
|
||||
&o.NamespaceResourceGetOptions{},
|
||||
cmdN.Do("edit-raw"),
|
||||
fmt.Sprintf("Edit and update k8s %s raw data", cmdN.Kind),
|
||||
func(s *mcclient.ClientSession, args *o.NamespaceResourceGetOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawData, err := manager.GetRaw(s, args.NAME, params.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
yamlBytes := rawData.YAMLString()
|
||||
tempfile, err := ioutil.TempFile("", fmt.Sprintf("k8s-%s-%s*.yaml", cmdN.Kind, args.NAME))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(tempfile.Name())
|
||||
if _, err := tempfile.Write([]byte(yamlBytes)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tempfile.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command("vim", tempfile.Name())
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
content, err := ioutil.ReadFile(tempfile.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonBytes, err := yaml.YAMLToJSON(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body, err := jsonutils.Parse(jsonBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params, err = args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := manager.UpdateRaw(s, args.NAME, params.(*jsonutils.JSONDict), body.(*jsonutils.JSONDict)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func NewK8sResourceDeleteCmd(cmdN CmdNameFactory, manager modulebase.Manager) *Cmd {
|
||||
return NewCommand(
|
||||
&o.ResourceDeleteOptions{},
|
||||
cmdN.Do("delete"),
|
||||
fmt.Sprintf("Delete k8s %s", cmdN.Kind),
|
||||
func(s *mcclient.ClientSession, args *o.ResourceDeleteOptions) error {
|
||||
ret := manager.BatchDelete(s, args.NAME, args.Params())
|
||||
printBatchResults(ret, manager.GetColumns(s))
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func NewK8sNsResourceDeleteCmd(cmdN CmdNameFactory, manager modulebase.Manager) *Cmd {
|
||||
deleteCmd := NewCommand(
|
||||
&o.NamespaceResourceDeleteOptions{},
|
||||
cmdN.Do("delete"),
|
||||
fmt.Sprintf("Delete k8s %s", cmdN.Kind),
|
||||
func(s *mcclient.ClientSession, args *o.NamespaceResourceDeleteOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret := manager.BatchDelete(s, args.NAME, params)
|
||||
printBatchResults(ret, manager.GetColumns(s))
|
||||
return nil
|
||||
},
|
||||
)
|
||||
return deleteCmd
|
||||
}
|
||||
|
||||
func initK8sNamespaceResource(kind string, manager k8s.IClusterResourceManager) *ShellCommands {
|
||||
cmdN := NewCmdNameFactory(kind)
|
||||
return NewShellCommands(cmdN.Do).AddR(
|
||||
NewK8sNsResourceListCmd(cmdN, manager),
|
||||
NewK8sNsResourceGetCmd(cmdN, manager),
|
||||
NewK8sNsResourceDeleteCmd(cmdN, manager),
|
||||
NewK8sNsResourceGetRawCmd(cmdN, manager),
|
||||
NewK8sResourceEditRawCmd(cmdN, manager),
|
||||
)
|
||||
func initK8sNamespaceResource(kind string, manager k8s.IClusterResourceManager) *K8sResourceCmd {
|
||||
cmd := NewK8sResourceCmd(manager)
|
||||
cmd.SetKeyword(kind)
|
||||
cmd.List(new(o.NamespaceResourceListOptions))
|
||||
cmd.Show(new(o.NamespaceResourceGetOptions))
|
||||
cmd.BatchDeleteWithParam(new(o.NamespaceResourceDeleteOptions))
|
||||
cmd.ShowRaw(new(o.NamespaceResourceGetOptions))
|
||||
cmd.EditRaw(new(o.NamespaceResourceGetOptions))
|
||||
cmd.ShowEvent()
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -15,73 +15,18 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initKubeMachine() {
|
||||
cmdN := func(action string) string {
|
||||
return fmt.Sprintf("kubemachine-%s", action)
|
||||
}
|
||||
R(&o.MachineListOptions{}, cmdN("list"), "List k8s node machines", func(s *mcclient.ClientSession, args *o.MachineListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := k8s.KubeMachines.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(result, k8s.KubeMachines.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.MachineCreateOptions{}, cmdN("create"), "Create k8s machine", func(s *mcclient.ClientSession, args *o.MachineCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
node, err := k8s.KubeMachines.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(node)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.IdentOptions{}, cmdN("show"), "Show details of a machine", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
|
||||
result, err := k8s.KubeMachines.Get(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.IdentsOptions{}, cmdN("delete"), "Delete machine", func(s *mcclient.ClientSession, args *o.IdentsOptions) error {
|
||||
ret := k8s.KubeMachines.BatchDelete(s, args.ID, nil)
|
||||
printBatchResults(ret, k8s.KubeMachines.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.IdentOptions{}, cmdN("recreate"), "Re-Create machine when create fail", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
|
||||
ret, err := k8s.KubeMachines.PerformAction(s, args.ID, "recreate", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.IdentOptions{}, cmdN("terminate"), "Terminate a machine", func(s *mcclient.ClientSession, args *o.IdentOptions) error {
|
||||
ret, err := k8s.KubeMachines.PerformAction(s, args.ID, "terminate", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
cmd := NewK8sResourceCmd(k8s.KubeMachines)
|
||||
cmd.SetKeyword("machine")
|
||||
cmd.ShowEvent()
|
||||
cmd.List(new(o.MachineListOptions))
|
||||
cmd.Create(new(o.MachineCreateOptions))
|
||||
cmd.Show(new(o.IdentOptions))
|
||||
cmd.BatchDelete(new(o.IdentsOptions))
|
||||
cmd.Perform("recreate", new(o.IdentOptions))
|
||||
cmd.Perform("terminate", new(o.IdentOptions))
|
||||
}
|
||||
|
||||
@@ -16,8 +16,12 @@ package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initPod() {
|
||||
initK8sNamespaceResource("pod", k8s.Pods)
|
||||
cmd := NewK8sResourceCmd(k8s.Pods)
|
||||
cmd.List(new(o.NamespaceResourceListOptions))
|
||||
cmd.Show(new(o.NamespaceResourceGetOptions))
|
||||
}
|
||||
|
||||
@@ -15,46 +15,14 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initPVC() {
|
||||
cmdN := NewCmdNameFactory("pvc")
|
||||
pvcCmd := NewShellCommands(cmdN.Do).AddR(
|
||||
NewK8sNsResourceGetCmd(cmdN, k8s.PersistentVolumeClaims),
|
||||
NewK8sNsResourceDeleteCmd(cmdN, k8s.PersistentVolumeClaims),
|
||||
)
|
||||
listCmd := NewCommand(
|
||||
&o.PVCListOptions{},
|
||||
cmdN.Do("list"),
|
||||
"List PersistentVolumeClaims resource",
|
||||
func(s *mcclient.ClientSession, args *o.PVCListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.PersistentVolumeClaims.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
PrintListResultTable(ret, k8s.PersistentVolumeClaims, s)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
createCmd := NewCommand(
|
||||
&o.PVCCreateOptions{},
|
||||
cmdN.Do("create"),
|
||||
"Create PersistentVolumeClaims resource",
|
||||
func(s *mcclient.ClientSession, args *o.PVCCreateOptions) error {
|
||||
ret, err := k8s.PersistentVolumeClaims.Create(s, args.Params())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
pvcCmd.AddR(listCmd, createCmd)
|
||||
cmd := NewK8sResourceCmd(k8s.PersistentVolumeClaims)
|
||||
cmd.Create(new(o.PVCCreateOptions))
|
||||
cmd.Show(new(o.NamespaceResourceGetOptions))
|
||||
cmd.BatchDeleteWithParam(new(o.NamespaceResourceDeleteOptions))
|
||||
cmd.List(new(o.PVCListOptions))
|
||||
}
|
||||
|
||||
@@ -15,17 +15,12 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
//"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
//o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initRbac() {
|
||||
//cmdRole := initK8sNamespaceResource("rbacrole", k8s.RbacRoles)
|
||||
initK8sNamespaceResource("rbac-role", k8s.RbacRoles)
|
||||
initK8sNamespaceResource("rbac-rolebinding", k8s.RbacRoleBindings)
|
||||
initK8sClusterResource("rbac-clusterrole", k8s.RbacClusterRoles)
|
||||
initK8sClusterResource("rbac-clusterrolebinding", k8s.RbacClusterRoleBindings)
|
||||
initK8sNamespaceResource("serviceaccount", k8s.ServiceAccounts)
|
||||
//cmdRoleN := cmdRole.CommandNameFactory
|
||||
}
|
||||
|
||||
@@ -21,22 +21,15 @@ import (
|
||||
)
|
||||
|
||||
func initRelease() {
|
||||
cmd := NewK8sResourceCmd(k8s.Releases)
|
||||
cmd.List(new(o.ReleaseListOptions))
|
||||
cmd.Create(new(o.ReleaseCreateOptions))
|
||||
cmd.Delete(new(o.ReleaseDeleteOptions))
|
||||
cmd.ShowEvent()
|
||||
|
||||
cmdN := func(suffix string) string {
|
||||
return resourceCmdN("release", suffix)
|
||||
}
|
||||
R(&o.ReleaseListOptions{}, cmdN("list"), "List k8s cluster helm releases", func(s *mcclient.ClientSession, args *o.ReleaseListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Releases.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(ret, k8s.Releases.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.NamespaceResourceGetOptions{}, cmdN("show"), "Get helm release details", func(s *mcclient.ClientSession, args *o.NamespaceResourceGetOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
@@ -54,19 +47,6 @@ func initRelease() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.ReleaseCreateOptions{}, cmdN("create"), "Create release with specified helm chart", func(s *mcclient.ClientSession, args *o.ReleaseCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Releases.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.ReleaseUpgradeOptions{}, cmdN("upgrade"), "Upgrade release", func(s *mcclient.ClientSession, args *o.ReleaseUpgradeOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
@@ -81,11 +61,6 @@ func initRelease() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.ReleaseDeleteOptions{}, cmdN("delete"), "Delete release", func(s *mcclient.ClientSession, args *o.ReleaseDeleteOptions) error {
|
||||
_, err := k8s.Releases.Delete(s, args.NAME, args.Params())
|
||||
return err
|
||||
})
|
||||
|
||||
R(&o.ReleaseHistoryOptions{}, cmdN("history"), "Get release history", func(s *mcclient.ClientSession, args *o.ReleaseHistoryOptions) error {
|
||||
ret, err := k8s.Releases.GetSpecific(s, args.NAME, "history", args.Params())
|
||||
if err != nil {
|
||||
|
||||
@@ -15,88 +15,18 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initRepo() {
|
||||
cmdN := func(suffix string) string {
|
||||
return resourceCmdN("repo", suffix)
|
||||
}
|
||||
R(&o.RepoListOptions{}, cmdN("list"), "List k8s global helm repos", func(s *mcclient.ClientSession, args *o.RepoListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := k8s.Repos.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(result, k8s.Repos.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.RepoGetOptions{}, cmdN("show"), "Show details of a repo", func(s *mcclient.ClientSession, args *o.RepoGetOptions) error {
|
||||
repo, err := k8s.Repos.Get(s, args.NAME, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(repo)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.RepoCreateOptions{}, cmdN("create"), "Add repository", func(s *mcclient.ClientSession, args *o.RepoCreateOptions) error {
|
||||
repo, err := k8s.Repos.Create(s, args.Params())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(repo)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.RepoUpdateOptions{}, cmdN("update"), "Update helm repository", func(s *mcclient.ClientSession, args *o.RepoUpdateOptions) error {
|
||||
repo, err := k8s.Repos.Update(s, args.NAME, args.Params())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(repo)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.RepoGetOptions{}, cmdN("delete"), "Delete a repository", func(s *mcclient.ClientSession, args *o.RepoGetOptions) error {
|
||||
repo, err := k8s.Repos.Delete(s, args.NAME, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(repo)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.RepoGetOptions{}, cmdN("sync"), "Sync a repository", func(s *mcclient.ClientSession, args *o.RepoGetOptions) error {
|
||||
repo, err := k8s.Repos.PerformAction(s, args.NAME, "sync", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(repo)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.RepoGetOptions{}, cmdN("public"), "Make repository public", func(s *mcclient.ClientSession, args *o.RepoGetOptions) error {
|
||||
repo, err := k8s.Repos.PerformAction(s, args.NAME, "public", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(repo)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&o.RepoGetOptions{}, cmdN("private"), "Make repository private", func(s *mcclient.ClientSession, args *o.RepoGetOptions) error {
|
||||
repo, err := k8s.Repos.PerformAction(s, args.NAME, "private", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(repo)
|
||||
return nil
|
||||
})
|
||||
cmd := NewK8sResourceCmd(k8s.Repos)
|
||||
cmd.List(new(o.RepoListOptions))
|
||||
cmd.Show(new(o.RepoGetOptions))
|
||||
cmd.Create(new(o.RepoCreateOptions))
|
||||
cmd.Update(new(o.RepoUpdateOptions))
|
||||
cmd.Delete(new(o.RepoGetOptions))
|
||||
cmd.Perform("sync", new(o.RepoGetOptions))
|
||||
cmd.Perform("public", new(o.RepoPublicOptions))
|
||||
cmd.Perform("private", new(o.RepoGetOptions))
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
func init() {
|
||||
cmd := NewK8sResourceCmd(k8s.RbacRoles).SetKeyword("role")
|
||||
cmd.Create(new(options.RoleCreateOpt))
|
||||
cmd.Update(new(options.RoleUpdateOpt))
|
||||
cmd.List(new(options.NamespaceResourceListOptions))
|
||||
cmd.Show(new(options.NamespaceResourceGetOptions))
|
||||
cmd.BatchDelete(new(options.ResourceIdsOptions))
|
||||
|
||||
@@ -15,69 +15,20 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initSecret() {
|
||||
cmdN := NewCmdNameFactory("secret")
|
||||
secretCmd := NewShellCommands(cmdN.Do).AddR(
|
||||
NewK8sNsResourceGetCmd(cmdN, k8s.Secrets),
|
||||
NewK8sNsResourceDeleteCmd(cmdN, k8s.Secrets),
|
||||
)
|
||||
listCmd := NewCommand(
|
||||
&o.SecretListOptions{},
|
||||
cmdN.Do("list"),
|
||||
"List secret resource",
|
||||
func(s *mcclient.ClientSession, args *o.SecretListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Secrets.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
PrintListResultTable(ret, k8s.Secrets, s)
|
||||
return nil
|
||||
})
|
||||
secretCmd.AddR(listCmd)
|
||||
cmd := NewK8sResourceCmd(k8s.Secrets)
|
||||
cmd.Show(new(o.NamespaceResourceGetOptions))
|
||||
cmd.BatchDeleteWithParam(new(o.NamespaceResourceDeleteOptions))
|
||||
cmd.List(new(o.SecretListOptions))
|
||||
cmd.ShowEvent()
|
||||
|
||||
registryCmd := NewCmdNameFactory("secret-registry")
|
||||
registryCreateCmd := NewCommand(
|
||||
&o.RegistrySecretCreateOptions{},
|
||||
registryCmd.Do("create"),
|
||||
"Create docker registry secret secret",
|
||||
func(s *mcclient.ClientSession, args *o.RegistrySecretCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Secrets.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
registryCmd := NewK8sResourceCmd(k8s.Secrets).WithKeyword("secret-registry")
|
||||
registryCmd.Create(new(o.RegistrySecretCreateOptions))
|
||||
|
||||
cephCSICmd := NewCmdNameFactory("secret-ceph-csi")
|
||||
cephCSICreateCmd := NewCommand(
|
||||
&o.CephCSISecretCreateOptions{},
|
||||
cephCSICmd.Do("create"),
|
||||
"Create ceph csi user secret",
|
||||
func(s *mcclient.ClientSession, args *o.CephCSISecretCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Secrets.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
secretCmd.AddR(cephCSICreateCmd, registryCreateCmd)
|
||||
cephCSICmd := NewK8sResourceCmd(k8s.Secrets).WithKeyword("secret-ceph-csi")
|
||||
cephCSICmd.Create(new(o.CephCSISecretCreateOptions))
|
||||
}
|
||||
|
||||
@@ -15,51 +15,16 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initService() {
|
||||
cmdN := NewCmdNameFactory("service")
|
||||
svcCmd := NewShellCommands(cmdN.Do).AddR(
|
||||
NewK8sNsResourceGetCmd(cmdN, k8s.Services),
|
||||
NewK8sNsResourceDeleteCmd(cmdN, k8s.Services),
|
||||
)
|
||||
|
||||
listCmd := NewCommand(
|
||||
&o.ServiceListOptions{},
|
||||
cmdN.Do("list"),
|
||||
"List Services resource",
|
||||
func(s *mcclient.ClientSession, args *o.ServiceListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Services.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
PrintListResultTable(ret, k8s.Services, s)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
createCmd := NewCommand(
|
||||
&o.ServiceCreateOptions{},
|
||||
cmdN.Do("create"),
|
||||
"Create service resource",
|
||||
func(s *mcclient.ClientSession, args *o.ServiceCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Services.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
svcCmd.AddR(listCmd, createCmd)
|
||||
cmd := NewK8sResourceCmd(k8s.Services)
|
||||
cmd.SetKeyword("service")
|
||||
cmd.Show(new(o.NamespaceResourceGetOptions))
|
||||
cmd.BatchDeleteWithParam(new(o.NamespaceResourceDeleteOptions))
|
||||
cmd.List(new(o.ServiceListOptions))
|
||||
cmd.Create(new(o.ServiceCreateOptions))
|
||||
cmd.ShowEvent()
|
||||
}
|
||||
|
||||
@@ -15,31 +15,11 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initStatefulset() {
|
||||
cmd := initK8sNamespaceResource("statefulset", k8s.StatefulSets)
|
||||
cmdN := cmd.CommandNameFactory
|
||||
|
||||
createCmd := NewCommand(
|
||||
&o.StatefulSetCreateOptions{},
|
||||
cmdN("create"),
|
||||
"Create statefulset resource",
|
||||
func(s *mcclient.ClientSession, args *o.StatefulSetCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.StatefulSets.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
})
|
||||
|
||||
cmd.AddR(createCmd)
|
||||
cmd.Create(new(o.StatefulSetCreateOptions))
|
||||
}
|
||||
|
||||
@@ -15,70 +15,15 @@
|
||||
package k8s
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
o "yunion.io/x/onecloud/pkg/mcclient/options/k8s"
|
||||
)
|
||||
|
||||
func initStorageClass() {
|
||||
cmdN := NewCmdNameFactory("storageclass")
|
||||
scCmd := initK8sClusterResource("storageclass", k8s.Storageclass)
|
||||
scCmd.Perform("set-default", new(o.ClusterResourceBaseOptions))
|
||||
|
||||
setDefaultCmd := NewCommand(
|
||||
&o.ClusterResourceBaseOptions{},
|
||||
cmdN.Do("set-default"),
|
||||
"Set storageclass as default",
|
||||
func(s *mcclient.ClientSession, args *o.ClusterResourceBaseOptions) error {
|
||||
ret, err := k8s.Storageclass.PerformAction(s, args.NAME, "set-default", args.Params())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
scCmd.AddR(setDefaultCmd)
|
||||
|
||||
addStorageClassCephCSI(scCmd)
|
||||
}
|
||||
|
||||
func addStorageClassCephCSI(cmd *ShellCommands) {
|
||||
rbdN := NewCmdNameFactory("storageclass-ceph-csi-rbd")
|
||||
rbdCreateCmd := NewCommand(
|
||||
&o.StorageClassCephCSIRBDCreateOptions{},
|
||||
rbdN.Do("create"),
|
||||
"Create ceph csi rbd",
|
||||
func(s *mcclient.ClientSession, args *o.StorageClassCephCSIRBDCreateOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Storageclass.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
testConnCmd := NewCommand(
|
||||
&o.StorageClassCephCSIRBDTestOptions{},
|
||||
rbdN.Do("connection-test"),
|
||||
"Test storageclass connection",
|
||||
func(s *mcclient.ClientSession, args *o.StorageClassCephCSIRBDTestOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := k8s.Storageclass.PerformClassAction(s, "connection-test", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(ret)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
cmd.AddR(rbdCreateCmd, testConnCmd)
|
||||
rbdCmd := NewK8sResourceCmd(k8s.Storageclass).SetKeyword("storageclass-ceph-csi-rbd")
|
||||
rbdCmd.Create(new(o.StorageClassCephCSIRBDCreateOptions))
|
||||
rbdCmd.PerformClass("connection-test", new(o.StorageClassCephCSIRBDTestOptions))
|
||||
}
|
||||
|
||||
+2285
-2166
File diff suppressed because it is too large
Load Diff
@@ -149,121 +149,121 @@
|
||||
"id": "No context manager",
|
||||
"message": "No context manager",
|
||||
"translation": "找不到上下文管理器",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:493:48"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:500:48"
|
||||
},
|
||||
{
|
||||
"id": "No such context %s(%s)",
|
||||
"message": "No such context %s(%s)",
|
||||
"translation": "没有此上下文%s(%s)",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:510:47"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:517:47"
|
||||
},
|
||||
{
|
||||
"id": "fail to get http response writer from context",
|
||||
"message": "fail to get http response writer from context",
|
||||
"translation": "从上下文中获取HTTP响应Writer失败",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:802:48"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:809:48"
|
||||
},
|
||||
{
|
||||
"id": "FetchCustomizeColumns returns incorrect results",
|
||||
"message": "FetchCustomizeColumns returns incorrect results",
|
||||
"translation": "FetchCustomizeColumns返回值不正确",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:854:47"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:861:47"
|
||||
},
|
||||
{
|
||||
"id": "reflect call %s fail %s",
|
||||
"message": "reflect call %s fail %s",
|
||||
"translation": "反射调用%s出错:%s",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:885:49"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:892:49"
|
||||
},
|
||||
{
|
||||
"id": "Invald %s return value",
|
||||
"message": "Invald %s return value",
|
||||
"translation": "%s返回值无效",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:888:49"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:895:49"
|
||||
},
|
||||
{
|
||||
"id": "%s not allow to get property %s",
|
||||
"message": "%s not allow to get property %s",
|
||||
"translation": "%s不允许获取%s属性",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:891:44"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:898:44"
|
||||
},
|
||||
{
|
||||
"id": "No return value, so why query?",
|
||||
"message": "No return value, so why query?",
|
||||
"translation": "没有返回值",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:909:45"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:916:45"
|
||||
},
|
||||
{
|
||||
"id": "Not allow to get details",
|
||||
"message": "Not allow to get details",
|
||||
"translation": "不允许获取详情",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:940:43"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:947:43"
|
||||
},
|
||||
{
|
||||
"id": "%s %s %s not found",
|
||||
"message": "%s %s %s not found",
|
||||
"translation": "%s %s %s找不到",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:976:47"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:983:47"
|
||||
},
|
||||
{
|
||||
"id": "%s not allow to get spec %s",
|
||||
"message": "%s not allow to get spec %s",
|
||||
"translation": "%s不允许获取%s",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:987:44"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:994:44"
|
||||
},
|
||||
{
|
||||
"id": "Not allow to create item",
|
||||
"message": "Not allow to create item",
|
||||
"translation": "不允许创建对象",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1240:43"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1247:43"
|
||||
},
|
||||
{
|
||||
"id": "body is not a json?",
|
||||
"message": "body is not a json?",
|
||||
"translation": "请求体不是JSON对象?",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1282:48"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1289:48"
|
||||
},
|
||||
{
|
||||
"id": "Missing name or generate_name",
|
||||
"message": "Missing name or generate_name",
|
||||
"translation": "未指定name或者generate_name",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1288:49"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1295:49"
|
||||
},
|
||||
{
|
||||
"id": "not allow to perform %s",
|
||||
"message": "not allow to perform %s",
|
||||
"translation": "不允许执行%s",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1445:43"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1452:43"
|
||||
},
|
||||
{
|
||||
"id": "%s allow %s %s not found",
|
||||
"message": "%s allow %s %s not found",
|
||||
"translation": "找不到%s Allow %s %s方法",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1584:49"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1591:49"
|
||||
},
|
||||
{
|
||||
"id": "%s not allow to %s %s",
|
||||
"message": "%s not allow to %s %s",
|
||||
"translation": "%s不允许%s %s",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1597:44"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1604:44"
|
||||
},
|
||||
{
|
||||
"id": "Invalid data JSONObject",
|
||||
"message": "Invalid data JSONObject",
|
||||
"translation": "无效的JSON对象",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1633:48"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1640:48"
|
||||
},
|
||||
{
|
||||
"id": "Not allow to update item",
|
||||
"message": "Not allow to update item",
|
||||
"translation": "不允许更新对象",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1687:43"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1694:43"
|
||||
},
|
||||
{
|
||||
"id": "%s(%s) not allow to delete",
|
||||
"message": "%s(%s) not allow to delete",
|
||||
"translation": "不允许删除%s(%s)",
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1791:43"
|
||||
"position": "pkg/cloudcommon/db/db_dispatcher.go:1798:43"
|
||||
},
|
||||
{
|
||||
"id": "Not allow to attach",
|
||||
@@ -2267,7 +2267,7 @@
|
||||
"id": "no such snapshotpolicy %s",
|
||||
"message": "no such snapshotpolicy %s",
|
||||
"translation": "找不到快照策略%s",
|
||||
"position": "pkg/compute/models/disks.go:2612:48"
|
||||
"position": "pkg/compute/models/disks.go:2617:48"
|
||||
},
|
||||
{
|
||||
"id": "mx_priority range limited to [1,50]",
|
||||
@@ -2711,157 +2711,151 @@
|
||||
"id": "server %s not found",
|
||||
"message": "server %s not found",
|
||||
"translation": "找不到虚机%s",
|
||||
"position": "pkg/compute/models/elasticips.go:147:53"
|
||||
"position": "pkg/compute/models/elasticips.go:148:53"
|
||||
},
|
||||
{
|
||||
"id": "Not support associate type %s, only support %s",
|
||||
"message": "Not support associate type %s, only support %s",
|
||||
"translation": "不支持绑定类型%s,仅支持%s",
|
||||
"position": "pkg/compute/models/elasticips.go:173:49"
|
||||
},
|
||||
{
|
||||
"id": "Cloud provider %s not found",
|
||||
"message": "Cloud provider %s not found",
|
||||
"translation": "找不到cloudprovider %s",
|
||||
"position": "pkg/compute/models/elasticips.go:839:52"
|
||||
"position": "pkg/compute/models/elasticips.go:174:49"
|
||||
},
|
||||
{
|
||||
"id": "charge type %s not supported",
|
||||
"message": "charge type %s not supported",
|
||||
"translation": "不支持付费类型%s",
|
||||
"position": "pkg/compute/models/elasticips.go:854:48"
|
||||
"position": "pkg/compute/models/elasticips.go:824:50"
|
||||
},
|
||||
{
|
||||
"id": "eip has been associated with instance",
|
||||
"message": "eip has been associated with instance",
|
||||
"translation": "EIP已绑定到其它实例",
|
||||
"position": "pkg/compute/models/elasticips.go:955:42"
|
||||
"position": "pkg/compute/models/elasticips.go:940:42"
|
||||
},
|
||||
{
|
||||
"id": "eip cannot associate in status %s",
|
||||
"message": "eip cannot associate in status %s",
|
||||
"translation": "EIP状态为%s无法绑定",
|
||||
"position": "pkg/compute/models/elasticips.go:959:47"
|
||||
"position": "pkg/compute/models/elasticips.go:944:47"
|
||||
},
|
||||
{
|
||||
"id": "fixed eip cannot be associated",
|
||||
"message": "fixed eip cannot be associated",
|
||||
"translation": "固定EIP不可再被关联",
|
||||
"position": "pkg/compute/models/elasticips.go:963:52"
|
||||
"position": "pkg/compute/models/elasticips.go:948:52"
|
||||
},
|
||||
{
|
||||
"id": "Unsupported %s",
|
||||
"message": "Unsupported %s",
|
||||
"translation": "不支持%s",
|
||||
"position": "pkg/compute/models/elasticips.go:976:48"
|
||||
"position": "pkg/compute/models/elasticips.go:961:48"
|
||||
},
|
||||
{
|
||||
"id": "cannot associate pending delete server",
|
||||
"message": "cannot associate pending delete server",
|
||||
"translation": "无法与正在删除的虚机进行绑定",
|
||||
"position": "pkg/compute/models/elasticips.go:994:47"
|
||||
"position": "pkg/compute/models/elasticips.go:979:47"
|
||||
},
|
||||
{
|
||||
"id": "instance is already associated with eip",
|
||||
"message": "instance is already associated with eip",
|
||||
"translation": "实例已与其它EIP绑定",
|
||||
"position": "pkg/compute/models/elasticips.go:1001:47"
|
||||
"position": "pkg/compute/models/elasticips.go:986:47"
|
||||
},
|
||||
{
|
||||
"id": "cannot associate server in status %s",
|
||||
"message": "cannot associate server in status %s",
|
||||
"translation": "虚机状态%s无法进行EIP绑定操作",
|
||||
"position": "pkg/compute/models/elasticips.go:1005:47"
|
||||
"position": "pkg/compute/models/elasticips.go:990:47"
|
||||
},
|
||||
{
|
||||
"id": "cannot associate eip with same network",
|
||||
"message": "cannot associate eip with same network",
|
||||
"translation": "虚机与EIP在同一子网下不可关联",
|
||||
"position": "pkg/compute/models/elasticips.go:1015:50"
|
||||
"position": "pkg/compute/models/elasticips.go:1000:50"
|
||||
},
|
||||
{
|
||||
"id": "server region is not found???",
|
||||
"message": "server region is not found???",
|
||||
"translation": "找不到虚机所属region",
|
||||
"position": "pkg/compute/models/elasticips.go:1022:48"
|
||||
"position": "pkg/compute/models/elasticips.go:1007:48"
|
||||
},
|
||||
{
|
||||
"id": "eip region is not found???",
|
||||
"message": "eip region is not found???",
|
||||
"translation": "找不到EIP所属region",
|
||||
"position": "pkg/compute/models/elasticips.go:1027:48"
|
||||
"position": "pkg/compute/models/elasticips.go:1012:48"
|
||||
},
|
||||
{
|
||||
"id": "eip and server are not in the same region",
|
||||
"message": "eip and server are not in the same region",
|
||||
"translation": "EIP的虚机不在同一region",
|
||||
"position": "pkg/compute/models/elasticips.go:1031:48"
|
||||
"position": "pkg/compute/models/elasticips.go:1016:48"
|
||||
},
|
||||
{
|
||||
"id": "eip and server are not in the same zone",
|
||||
"message": "eip and server are not in the same zone",
|
||||
"translation": "EIP和虚机不在同一个zone",
|
||||
"position": "pkg/compute/models/elasticips.go:1038:49"
|
||||
"position": "pkg/compute/models/elasticips.go:1023:49"
|
||||
},
|
||||
{
|
||||
"id": "server host is not found???",
|
||||
"message": "server host is not found???",
|
||||
"translation": "虚机所在宿主机找不到",
|
||||
"position": "pkg/compute/models/elasticips.go:1044:48"
|
||||
"position": "pkg/compute/models/elasticips.go:1029:48"
|
||||
},
|
||||
{
|
||||
"id": "server and eip are not managed by the same provider",
|
||||
"message": "server and eip are not managed by the same provider",
|
||||
"translation": "虚机和EIP分属不同cloudprovider",
|
||||
"position": "pkg/compute/models/elasticips.go:1048:48"
|
||||
"position": "pkg/compute/models/elasticips.go:1033:48"
|
||||
},
|
||||
{
|
||||
"id": "eip cannot dissociate in status %s",
|
||||
"message": "eip cannot dissociate in status %s",
|
||||
"translation": "EIP状态为%s无法执行解绑操作",
|
||||
"position": "pkg/compute/models/elasticips.go:1096:47"
|
||||
"position": "pkg/compute/models/elasticips.go:1081:47"
|
||||
},
|
||||
{
|
||||
"id": "fixed public eip cannot be dissociated",
|
||||
"message": "fixed public eip cannot be dissociated",
|
||||
"translation": "固定的公网IP无法解绑",
|
||||
"position": "pkg/compute/models/elasticips.go:1100:52"
|
||||
"position": "pkg/compute/models/elasticips.go:1085:52"
|
||||
},
|
||||
{
|
||||
"id": "the associated natgateway has corresponding snat rules with eip %s, please delete them firstly",
|
||||
"message": "the associated natgateway has corresponding snat rules with eip %s, please delete them firstly",
|
||||
"translation": "EIP %s正被NAT网关的SNAT规则使用,请先删除它们",
|
||||
"position": "pkg/compute/models/elasticips.go:1116:53"
|
||||
"position": "pkg/compute/models/elasticips.go:1101:53"
|
||||
},
|
||||
{
|
||||
"id": "the associated natgateway has corresponding dnat rules with eip %s, please delete them firstly",
|
||||
"message": "the associated natgateway has corresponding dnat rules with eip %s, please delete them firstly",
|
||||
"translation": "EIP %s正被NAT网关的DNAT规则使用,请先删除它们",
|
||||
"position": "pkg/compute/models/elasticips.go:1126:53"
|
||||
"position": "pkg/compute/models/elasticips.go:1111:53"
|
||||
},
|
||||
{
|
||||
"id": "fixed eip cannot sync status",
|
||||
"message": "fixed eip cannot sync status",
|
||||
"translation": "固定公网IP无法执行同步状态操作",
|
||||
"position": "pkg/compute/models/elasticips.go:1181:52"
|
||||
"position": "pkg/compute/models/elasticips.go:1166:52"
|
||||
},
|
||||
{
|
||||
"id": "cannot change bandwidth in status %s",
|
||||
"message": "cannot change bandwidth in status %s",
|
||||
"translation": "EIP状态为%s无法变更带宽",
|
||||
"position": "pkg/compute/models/elasticips.go:1337:47"
|
||||
"position": "pkg/compute/models/elasticips.go:1327:47"
|
||||
},
|
||||
{
|
||||
"id": "Invalid bandwidth",
|
||||
"message": "Invalid bandwidth",
|
||||
"translation": "无效的带宽",
|
||||
"position": "pkg/compute/models/elasticips.go:1342:48"
|
||||
"position": "pkg/compute/models/elasticips.go:1332:48"
|
||||
},
|
||||
{
|
||||
"id": "Cannot purge elastic_ip on enabled cloud provider",
|
||||
"message": "Cannot purge elastic_ip on enabled cloud provider",
|
||||
"translation": "EIP所属cloudprovider为启用状态,无法执行purge操作",
|
||||
"position": "pkg/compute/models/elasticips.go:1463:48"
|
||||
"position": "pkg/compute/models/elasticips.go:1453:48"
|
||||
},
|
||||
{
|
||||
"id": "not allow change project across domain",
|
||||
@@ -4433,19 +4427,19 @@
|
||||
"id": "fetch disk size failed",
|
||||
"message": "fetch disk size failed",
|
||||
"translation": "获取磁盘大小失败",
|
||||
"position": "pkg/compute/models/guests.go:5269:63"
|
||||
"position": "pkg/compute/models/guests.go:5271:63"
|
||||
},
|
||||
{
|
||||
"id": "image %s do not belong to guest image %s",
|
||||
"message": "image %s do not belong to guest image %s",
|
||||
"translation": "镜像%s不在虚机镜像%s中",
|
||||
"position": "pkg/compute/models/guests.go:5335:41"
|
||||
"position": "pkg/compute/models/guests.go:5337:41"
|
||||
},
|
||||
{
|
||||
"id": "miss some subimage of guest image",
|
||||
"message": "miss some subimage of guest image",
|
||||
"translation": "部分虚机镜像的子镜像未指定",
|
||||
"position": "pkg/compute/models/guests.go:5341:39"
|
||||
"position": "pkg/compute/models/guests.go:5343:39"
|
||||
},
|
||||
{
|
||||
"id": "Baremetal %s not enabled",
|
||||
@@ -4985,85 +4979,85 @@
|
||||
"id": "host status %s can't exit maintenance",
|
||||
"message": "host status %s can't exit maintenance",
|
||||
"translation": "宿主机状态%s无法退出维护模式",
|
||||
"position": "pkg/compute/models/hosts.go:4901:47"
|
||||
"position": "pkg/compute/models/hosts.go:4903:47"
|
||||
},
|
||||
{
|
||||
"id": "host type %s can't do host maintenance",
|
||||
"message": "host type %s can't do host maintenance",
|
||||
"translation": "宿主机类型%s无法进入维护模式",
|
||||
"position": "pkg/compute/models/hosts.go:4919:44"
|
||||
"position": "pkg/compute/models/hosts.go:4921:44"
|
||||
},
|
||||
{
|
||||
"id": "unsupport on host status %s",
|
||||
"message": "unsupport on host status %s",
|
||||
"translation": "宿主机状态为%s不支持此操作",
|
||||
"position": "pkg/compute/models/hosts.go:4922:44"
|
||||
"position": "pkg/compute/models/hosts.go:4924:44"
|
||||
},
|
||||
{
|
||||
"id": "Host %s can't migrate guests %s in status %s",
|
||||
"message": "Host %s can't migrate guests %s in status %s",
|
||||
"translation": "宿主机%s无法迁移虚机%s,因虚机状态为%s",
|
||||
"position": "pkg/compute/models/hosts.go:4950:45"
|
||||
"position": "pkg/compute/models/hosts.go:4952:45"
|
||||
},
|
||||
{
|
||||
"id": "Cannot do insert-iso in status %s",
|
||||
"message": "Cannot do insert-iso in status %s",
|
||||
"translation": "因状态为%s无法执行insert-iso指令",
|
||||
"position": "pkg/compute/models/hosts.go:5226:46"
|
||||
"position": "pkg/compute/models/hosts.go:5228:46"
|
||||
},
|
||||
{
|
||||
"id": "Cannot do eject-iso in status %s",
|
||||
"message": "Cannot do eject-iso in status %s",
|
||||
"translation": "因状态为%s无法执行eject-iso指令",
|
||||
"position": "pkg/compute/models/hosts.go:5257:46"
|
||||
"position": "pkg/compute/models/hosts.go:5259:46"
|
||||
},
|
||||
{
|
||||
"id": "Cannot sync config a non-baremetal host",
|
||||
"message": "Cannot sync config a non-baremetal host",
|
||||
"translation": "非裸金属服务器中无法执行同步配置操作",
|
||||
"position": "pkg/compute/models/hosts.go:5282:44"
|
||||
"position": "pkg/compute/models/hosts.go:5284:44"
|
||||
},
|
||||
{
|
||||
"id": "reserved cpu must \u003e= 0",
|
||||
"message": "reserved cpu must \u003e= 0",
|
||||
"translation": "预留CPU数必须为非负整数",
|
||||
"position": "pkg/compute/models/hosts.go:5401:48"
|
||||
"position": "pkg/compute/models/hosts.go:5403:48"
|
||||
},
|
||||
{
|
||||
"id": "reserved memory must \u003e= 0",
|
||||
"message": "reserved memory must \u003e= 0",
|
||||
"translation": "预留内存大小必须为非负整数",
|
||||
"position": "pkg/compute/models/hosts.go:5404:48"
|
||||
"position": "pkg/compute/models/hosts.go:5406:48"
|
||||
},
|
||||
{
|
||||
"id": "reserved storage must \u003e= 0",
|
||||
"message": "reserved storage must \u003e= 0",
|
||||
"translation": "预留存储必须为非负整数",
|
||||
"position": "pkg/compute/models/hosts.go:5407:48"
|
||||
"position": "pkg/compute/models/hosts.go:5409:48"
|
||||
},
|
||||
{
|
||||
"id": "host %s can't reserve %d cpu for each isolated device, not enough",
|
||||
"message": "host %s can't reserve %d cpu for each isolated device, not enough",
|
||||
"translation": "宿主机%s无法为每个透传设备预留%d个CPU,因资源不够",
|
||||
"position": "pkg/compute/models/hosts.go:5414:44"
|
||||
"position": "pkg/compute/models/hosts.go:5416:44"
|
||||
},
|
||||
{
|
||||
"id": "host %s can't reserve %dM memory for each isolated device, not enough",
|
||||
"message": "host %s can't reserve %dM memory for each isolated device, not enough",
|
||||
"translation": "宿主机%s无法为每个透传设备预留%dM内存,因资源不够",
|
||||
"position": "pkg/compute/models/hosts.go:5418:44"
|
||||
"position": "pkg/compute/models/hosts.go:5420:44"
|
||||
},
|
||||
{
|
||||
"id": "host %s can't reserve %dM storage for each isolated device, not enough",
|
||||
"message": "host %s can't reserve %dM storage for each isolated device, not enough",
|
||||
"translation": "宿主机%s无法为每个透传设备预留%dM存储,因资源不够",
|
||||
"position": "pkg/compute/models/hosts.go:5423:44"
|
||||
"position": "pkg/compute/models/hosts.go:5425:44"
|
||||
},
|
||||
{
|
||||
"id": "Only system admin can assign host",
|
||||
"message": "Only system admin can assign host",
|
||||
"translation": "仅系统管理员可指定宿主机",
|
||||
"position": "pkg/compute/models/hosts.go:5494:51"
|
||||
"position": "pkg/compute/models/hosts.go:5496:51"
|
||||
},
|
||||
{
|
||||
"id": "StorageInUse",
|
||||
@@ -7687,12 +7681,6 @@
|
||||
"translation": "非http监听必须指定后端组",
|
||||
"position": "pkg/compute/regiondrivers/kvm.go:677:50"
|
||||
},
|
||||
{
|
||||
"id": "failed to found network %s",
|
||||
"message": "failed to found network %s",
|
||||
"translation": "查找子网%s时出错",
|
||||
"position": "pkg/compute/regiondrivers/kvm.go:907:46"
|
||||
},
|
||||
{
|
||||
"id": "bad network type %q, want %q",
|
||||
"message": "bad network type %q, want %q",
|
||||
@@ -7745,7 +7733,7 @@
|
||||
"id": "loadbalancer listener %s is already updating",
|
||||
"message": "loadbalancer listener %s is already updating",
|
||||
"translation": "负载均衡监听%s正在变更中",
|
||||
"position": "pkg/compute/regiondrivers/openstack.go:542:50"
|
||||
"position": "pkg/compute/regiondrivers/openstack.go:543:50"
|
||||
},
|
||||
{
|
||||
"id": "loadbalancer backendgroup aready associate with other %s listener",
|
||||
@@ -8159,7 +8147,7 @@
|
||||
"id": "No login secret found",
|
||||
"message": "No login secret found",
|
||||
"translation": "找不到登录密文信息",
|
||||
"position": "pkg/mcclient/modules/mod_cloudusers.go:67:42"
|
||||
"position": "pkg/mcclient/modules/mod_cloudusers.go:68:42"
|
||||
},
|
||||
{
|
||||
"id": "no totp for %s",
|
||||
@@ -8269,12 +8257,348 @@
|
||||
"translation": "不支持的动作%s",
|
||||
"position": "pkg/mcclient/modules/mod_users.go:139:48"
|
||||
},
|
||||
{
|
||||
"id": "url is empty",
|
||||
"message": "url is empty",
|
||||
"translation": "URL不应为空",
|
||||
"position": "pkg/monitor/alerting/notifiers/dingding.go:50:52"
|
||||
},
|
||||
{
|
||||
"id": "invalid url: %v",
|
||||
"message": "invalid url: %v",
|
||||
"translation": "无效的URL: %v",
|
||||
"position": "pkg/monitor/alerting/notifiers/dingding.go:53:52"
|
||||
},
|
||||
{
|
||||
"id": "unsupport type: %s",
|
||||
"message": "unsupport type: %s",
|
||||
"translation": "不支持的类型:%s",
|
||||
"position": "pkg/monitor/alerting/notifiers/dingding.go:63:52"
|
||||
},
|
||||
{
|
||||
"id": "app_id is empty",
|
||||
"message": "app_id is empty",
|
||||
"translation": "app_id为空",
|
||||
"position": "pkg/monitor/alerting/notifiers/feishu.go:43:52"
|
||||
},
|
||||
{
|
||||
"id": "app_secret is empty",
|
||||
"message": "app_secret is empty",
|
||||
"translation": "app_secret为空",
|
||||
"position": "pkg/monitor/alerting/notifiers/feishu.go:46:52"
|
||||
},
|
||||
{
|
||||
"id": "channel is empty",
|
||||
"message": "channel is empty",
|
||||
"translation": "channel为空",
|
||||
"position": "pkg/monitor/alerting/notifiers/onecloud.go:50:52"
|
||||
},
|
||||
{
|
||||
"id": "parameter %s is empty",
|
||||
"message": "parameter %s is empty",
|
||||
"translation": "参数%s为空",
|
||||
"position": "pkg/monitor/errors/error.go:8:42"
|
||||
},
|
||||
{
|
||||
"id": "unsupported no_data_state %s",
|
||||
"message": "unsupported no_data_state %s",
|
||||
"translation": "不支持的no_data_state:%s",
|
||||
"position": "pkg/monitor/models/alert.go:269:43"
|
||||
},
|
||||
{
|
||||
"id": "unsupported execution_error_state %s",
|
||||
"message": "unsupported execution_error_state %s",
|
||||
"translation": "不支持的execution_error_state:%s",
|
||||
"position": "pkg/monitor/models/alert.go:276:43"
|
||||
},
|
||||
{
|
||||
"id": "metric %s is invalid format, usage \u003cmeasurement\u003e.\u003cfield\u003e",
|
||||
"message": "metric %s is invalid format, usage \u003cmeasurement\u003e.\u003cfield\u003e",
|
||||
"translation": "指标%s的格式无效,应为\u003cmeasurement\u003e.\u003cfield\u003e",
|
||||
"position": "pkg/monitor/models/alert.go:380:51"
|
||||
},
|
||||
{
|
||||
"id": "Cannot change state on pause alert",
|
||||
"message": "Cannot change state on pause alert",
|
||||
"translation": "无法变更状态为暂停的告警状态",
|
||||
"position": "pkg/monitor/models/alert.go:436:2"
|
||||
},
|
||||
{
|
||||
"id": "alert already attached to notification",
|
||||
"message": "alert already attached to notification",
|
||||
"translation": "告警已绑定到通知",
|
||||
"position": "pkg/monitor/models/alert.go:557:47"
|
||||
},
|
||||
{
|
||||
"id": "Alert is already un-paused",
|
||||
"message": "Alert is already un-paused",
|
||||
"translation": "报警已非暂停状态",
|
||||
"position": "pkg/monitor/models/alert.go:674:47"
|
||||
},
|
||||
{
|
||||
"id": "Alert is already paused",
|
||||
"message": "Alert is already paused",
|
||||
"translation": "告警已是暂停状态",
|
||||
"position": "pkg/monitor/models/alert.go:678:47"
|
||||
},
|
||||
{
|
||||
"id": "Invalid refresh format: %s",
|
||||
"message": "Invalid refresh format: %s",
|
||||
"translation": "refresh参数格式无效:%s",
|
||||
"position": "pkg/monitor/models/alertdashboard.go:95:50"
|
||||
},
|
||||
{
|
||||
"id": "the Comparator is illegal:",
|
||||
"message": "the Comparator is illegal:",
|
||||
"translation": "参数comparator无效",
|
||||
"position": "pkg/monitor/models/alertdashboard.go:104:52"
|
||||
},
|
||||
{
|
||||
"id": "the reduce is illegal",
|
||||
"message": "the reduce is illegal",
|
||||
"translation": "参数reduce无效",
|
||||
"position": "pkg/monitor/models/alertdashboard.go:109:52"
|
||||
},
|
||||
{
|
||||
"id": "not find alert %s",
|
||||
"message": "not find alert %s",
|
||||
"translation": "找不到告警%s",
|
||||
"position": "pkg/monitor/models/alertnotification.go:135:51"
|
||||
},
|
||||
{
|
||||
"id": "not find notification %s",
|
||||
"message": "not find notification %s",
|
||||
"translation": "找不到通知%s",
|
||||
"position": "pkg/monitor/models/alertnotification.go:142:51"
|
||||
},
|
||||
{
|
||||
"id": "Invalid level format: %s",
|
||||
"message": "Invalid level format: %s",
|
||||
"translation": "参数level的格式无效:%s",
|
||||
"position": "pkg/monitor/models/commonalert.go:92:49"
|
||||
},
|
||||
{
|
||||
"id": "Invalid period format: %s",
|
||||
"message": "Invalid period format: %s",
|
||||
"translation": "参数period的格式无效:%s",
|
||||
"position": "pkg/monitor/models/commonalert.go:95:49"
|
||||
},
|
||||
{
|
||||
"id": "threshold is meaningless",
|
||||
"message": "threshold is meaningless",
|
||||
"translation": "参数threshold的值为效",
|
||||
"position": "pkg/monitor/models/commonalert.go:113:51"
|
||||
},
|
||||
{
|
||||
"id": "the AlertType is illegal:%s",
|
||||
"message": "the AlertType is illegal:%s",
|
||||
"translation": "参数AlertType无效:%s",
|
||||
"position": "pkg/monitor/models/commonalert.go:120:50"
|
||||
},
|
||||
{
|
||||
"id": "Cannot delete system alert",
|
||||
"message": "Cannot delete system alert",
|
||||
"translation": "不可删除系统告警",
|
||||
"position": "pkg/monitor/models/commonalert.go:388:42"
|
||||
},
|
||||
{
|
||||
"id": "Default data source not found",
|
||||
"message": "Default data source not found",
|
||||
"translation": "找不到默认数据源",
|
||||
"position": "pkg/monitor/models/datasource.go:61:2"
|
||||
},
|
||||
{
|
||||
"id": "not support database",
|
||||
"message": "not support database",
|
||||
"translation": "不支持此数据库",
|
||||
"position": "pkg/monitor/models/datasource.go:294:63"
|
||||
},
|
||||
{
|
||||
"id": "not support type %q",
|
||||
"message": "not support type %q",
|
||||
"translation": "不支持类型%q",
|
||||
"position": "pkg/monitor/models/meteralert.go:147:48"
|
||||
},
|
||||
{
|
||||
"id": "unsupported resource type %s",
|
||||
"message": "unsupported resource type %s",
|
||||
"translation": "不支持资源类型%s",
|
||||
"position": "pkg/monitor/models/nodealert.go:160:51"
|
||||
},
|
||||
{
|
||||
"id": "not found alert notification used by %s",
|
||||
"message": "not found alert notification used by %s",
|
||||
"translation": "找不到被%s使用的告警通知",
|
||||
"position": "pkg/monitor/models/nodealert.go:629:41"
|
||||
},
|
||||
{
|
||||
"id": "unsupported notification type %s",
|
||||
"message": "unsupported notification type %s",
|
||||
"translation": "不支持告警类型%s",
|
||||
"position": "pkg/monitor/models/notification.go:80:49"
|
||||
},
|
||||
{
|
||||
"id": "Alert notification used by %d alert",
|
||||
"message": "Alert notification used by %d alert",
|
||||
"translation": "通知被%d个告警使用",
|
||||
"position": "pkg/monitor/models/notification.go:216:37"
|
||||
},
|
||||
{
|
||||
"id": "not found res_id %q",
|
||||
"message": "not found res_id %q",
|
||||
"translation": "找不到res_id %q",
|
||||
"position": "pkg/monitor/models/suggestsysalert.go:200:49"
|
||||
},
|
||||
{
|
||||
"id": "not found type %q",
|
||||
"message": "not found type %q",
|
||||
"translation": "找不到类型%q",
|
||||
"position": "pkg/monitor/models/suggestsysalert.go:203:49"
|
||||
},
|
||||
{
|
||||
"id": "type %s rule already exists",
|
||||
"message": "type %s rule already exists",
|
||||
"translation": "类型为%s的规则已存在",
|
||||
"position": "pkg/monitor/models/suggestsysrule.go:167:53"
|
||||
},
|
||||
{
|
||||
"id": "no found rule setting",
|
||||
"message": "no found rule setting",
|
||||
"translation": "找不到规则设置",
|
||||
"position": "pkg/monitor/models/suggestsysrule.go:173:51"
|
||||
},
|
||||
{
|
||||
"id": "not found resource_type %q",
|
||||
"message": "not found resource_type %q",
|
||||
"translation": "找不到resource_type %q",
|
||||
"position": "pkg/monitor/models/suggestsysruleconfig.go:253:43"
|
||||
},
|
||||
{
|
||||
"id": "not found driver by type %q",
|
||||
"message": "not found driver by type %q",
|
||||
"translation": "找不到driver类型%q",
|
||||
"position": "pkg/monitor/models/suggestsysruleconfig.go:258:44"
|
||||
},
|
||||
{
|
||||
"id": "resource type %q of driver does not match input %q",
|
||||
"message": "resource type %q of driver does not match input %q",
|
||||
"translation": "driver %q的资源类型与输入参数的资源类型%q不匹配",
|
||||
"position": "pkg/monitor/models/suggestsysruleconfig.go:261:49"
|
||||
},
|
||||
{
|
||||
"id": "resource type must provided when resource_id specified",
|
||||
"message": "resource type must provided when resource_id specified",
|
||||
"translation": "当resource_id指定时,必须也指定资源类型",
|
||||
"position": "pkg/monitor/models/suggestsysruleconfig.go:266:47"
|
||||
},
|
||||
{
|
||||
"id": "type or resource_type must provided",
|
||||
"message": "type or resource_type must provided",
|
||||
"translation": "参数type或resource_type必须要指定",
|
||||
"position": "pkg/monitor/models/suggestsysruleconfig.go:269:47"
|
||||
},
|
||||
{
|
||||
"id": "not found rule by type %q",
|
||||
"message": "not found rule by type %q",
|
||||
"translation": "无法根据类型%q找到规则",
|
||||
"position": "pkg/monitor/models/suggestsysruleconfig.go:284:42"
|
||||
},
|
||||
{
|
||||
"id": "Invalid interval format: %s",
|
||||
"message": "Invalid interval format: %s",
|
||||
"translation": "参数interval的格式无效:%s",
|
||||
"position": "pkg/monitor/models/unifiedmonitor.go:255:43"
|
||||
},
|
||||
{
|
||||
"id": "Unsupported notification type",
|
||||
"message": "Unsupported notification type",
|
||||
"translation": "不支持的通知类型",
|
||||
"position": "pkg/monitor/notifydrivers/drivers.go:28:2"
|
||||
},
|
||||
{
|
||||
"id": "the evalType is illegal",
|
||||
"message": "the evalType is illegal",
|
||||
"translation": "evalType参数非法",
|
||||
"position": "pkg/monitor/suggestsysdrivers/influxdbbasedriver.go:58:44"
|
||||
},
|
||||
{
|
||||
"id": "Influxdb invalid status",
|
||||
"message": "Influxdb invalid status",
|
||||
"translation": "influxdb无效状态",
|
||||
"position": "pkg/monitor/tsdb/driver/influxdb/influxdb.go:36:2"
|
||||
},
|
||||
{
|
||||
"id": "Not find executor for data source",
|
||||
"message": "Not find executor for data source",
|
||||
"translation": "找不到数据源对应的执行器",
|
||||
"position": "pkg/monitor/tsdb/query_endpoint.go:36:2"
|
||||
},
|
||||
{
|
||||
"id": "Condition is missing the threshold parameter",
|
||||
"message": "Condition is missing the threshold parameter",
|
||||
"translation": "条件缺少threshold参数",
|
||||
"position": "pkg/monitor/validators/validators.go:30:2"
|
||||
},
|
||||
{
|
||||
"id": "Condition is missing the type parameter",
|
||||
"message": "Condition is missing the type parameter",
|
||||
"translation": "条件缺少type参数",
|
||||
"position": "pkg/monitor/validators/validators.go:31:2"
|
||||
},
|
||||
{
|
||||
"id": "Invalid condition evaluator type",
|
||||
"message": "Invalid condition evaluator type",
|
||||
"translation": "无效的求值类型",
|
||||
"position": "pkg/monitor/validators/validators.go:32:2"
|
||||
},
|
||||
{
|
||||
"id": "Unknown alert condition",
|
||||
"message": "Unknown alert condition",
|
||||
"translation": "未知的告警条件",
|
||||
"position": "pkg/monitor/validators/validators.go:33:2"
|
||||
},
|
||||
{
|
||||
"id": "Alert is missing conditions",
|
||||
"message": "Alert is missing conditions",
|
||||
"translation": "告警缺少告警条件",
|
||||
"position": "pkg/monitor/validators/validators.go:34:2"
|
||||
},
|
||||
{
|
||||
"id": "input condition is empty",
|
||||
"message": "input condition is empty",
|
||||
"translation": "输入条件为空",
|
||||
"position": "pkg/monitor/validators/validators.go:48:43"
|
||||
},
|
||||
{
|
||||
"id": "Unkown alert condition type: %s",
|
||||
"message": "Unkown alert condition type: %s",
|
||||
"translation": "未知的告警条件类型:%s",
|
||||
"position": "pkg/monitor/validators/validators.go:61:43"
|
||||
},
|
||||
{
|
||||
"id": "Unkown operator %s",
|
||||
"message": "Unkown operator %s",
|
||||
"translation": "未知的操作符%s",
|
||||
"position": "pkg/monitor/validators/validators.go:76:43"
|
||||
},
|
||||
{
|
||||
"id": "select for nothing in query",
|
||||
"message": "select for nothing in query",
|
||||
"translation": "查询内容为空",
|
||||
"position": "pkg/monitor/validators/validators.go:118:44"
|
||||
},
|
||||
{
|
||||
"id": "query duration err: from: %s, to:%s",
|
||||
"message": "query duration err: from: %s, to:%s",
|
||||
"translation": "查询区间无效:from:%s,to:%s",
|
||||
"position": "pkg/monitor/validators/validators.go:142:44"
|
||||
},
|
||||
{
|
||||
"id": "query duration `to` err: %s",
|
||||
"message": "query duration `to` err: %s",
|
||||
"translation": "查询区间参数to无效:%s",
|
||||
"position": "pkg/monitor/validators/validators.go:146:42"
|
||||
},
|
||||
{
|
||||
"id": "security group id should not be empty",
|
||||
"message": "security group id should not be empty",
|
||||
|
||||
@@ -258,6 +258,15 @@ func fetchUserInfoFromToken(ctx context.Context, req *http.Request, token mcclie
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func FetchProjectMetadata(ctx context.Context, req *http.Request, pid string) (jsonutils.JSONObject, error) {
|
||||
s := auth.GetAdminSession(ctx, FetchRegion(req), "")
|
||||
meta, err := modules.Projects.GetSpecific(s, pid, "metadata", nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetProjectMetadata")
|
||||
}
|
||||
return meta, nil
|
||||
}
|
||||
|
||||
func isUserEnableTotp(userInfo jsonutils.JSONObject) bool {
|
||||
return jsonutils.QueryBoolean(userInfo, "enable_mfa", false)
|
||||
}
|
||||
@@ -779,6 +788,14 @@ func getUserInfo(ctx context.Context, req *http.Request) (*jsonutils.JSONDict, e
|
||||
data.Add(jsonutils.NewString(token.GetProjectDomain()), "projectDomain")
|
||||
data.Add(jsonutils.NewString(token.GetProjectDomainId()), "projectDomainId")
|
||||
|
||||
pmeta, err := FetchProjectMetadata(ctx, req, token.GetProjectId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchProjectMetadata")
|
||||
}
|
||||
if pmeta != nil {
|
||||
data.Add(pmeta, "project_meta")
|
||||
}
|
||||
|
||||
log.Infof("getUserInfo modules.RoleAssignments.List")
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.JSONNull, "effective")
|
||||
|
||||
@@ -488,7 +488,17 @@ func (f *ResourceHandlers) batchUpdateHandler(ctx context.Context, w http.Respon
|
||||
return
|
||||
}
|
||||
|
||||
ret := module.BatchUpdate(req.Session(), idlist, body)
|
||||
var ret []modulebase.SubmitResult
|
||||
if jsonutils.QueryBoolean(query, "batch_params", false) {
|
||||
bodys, err := body.GetArray()
|
||||
if err != nil {
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
return
|
||||
}
|
||||
ret = module.BatchParamsUpdate(req.Session(), idlist, bodys)
|
||||
} else {
|
||||
ret = module.BatchUpdate(req.Session(), idlist, body)
|
||||
}
|
||||
w.WriteHeader(207)
|
||||
appsrv.SendJSON(w, modulebase.SubmitResults2JSON(ret))
|
||||
}
|
||||
|
||||
@@ -232,6 +232,9 @@ type CloudproviderListInput struct {
|
||||
|
||||
// 账号健康状态
|
||||
HealthStatus []string `json:"health_status"`
|
||||
|
||||
// filter by host schedtag
|
||||
HostSchedtagId string `json:"host_schedtag_id"`
|
||||
}
|
||||
|
||||
func (input *CapabilityListInput) AfterUnmarshal() {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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/i18n"
|
||||
)
|
||||
|
||||
const (
|
||||
CLOUD_PROVIDER_ONECLOUD_EN = "YunionCloud"
|
||||
CLOUD_PROVIDER_ONECLOUD_CN = "云联壹云"
|
||||
)
|
||||
|
||||
var ComputeI18nTable = i18n.Table{}
|
||||
|
||||
func init() {
|
||||
ComputeI18nTable.Set(CLOUD_PROVIDER_ONECLOUD, i18n.NewTableEntry().
|
||||
EN(CLOUD_PROVIDER_ONECLOUD_EN).
|
||||
CN(CLOUD_PROVIDER_ONECLOUD_CN),
|
||||
)
|
||||
}
|
||||
@@ -350,3 +350,8 @@ type DBInstanceFilterListInput struct {
|
||||
|
||||
VpcFilterListInput
|
||||
}
|
||||
|
||||
type DBInstanceNetworkListInput struct {
|
||||
apis.VirtualJointResourceBaseListInput
|
||||
DBInstanceFilterListInput
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ type DiskCreateInput struct {
|
||||
|
||||
*DiskConfig
|
||||
|
||||
// 调度使用指定的云账号
|
||||
PreferManager string `json:"prefer_manager_id"`
|
||||
|
||||
// 此参数仅适用于未指定storage时进行调度到指定区域创建磁盘
|
||||
// required: false
|
||||
PreferRegion string `json:"prefer_region_id"`
|
||||
@@ -51,12 +54,13 @@ type DiskCreateInput struct {
|
||||
func (req *DiskCreateInput) ToServerCreateInput() *ServerCreateInput {
|
||||
input := ServerCreateInput{
|
||||
ServerConfigs: &ServerConfigs{
|
||||
PreferRegion: req.PreferRegion,
|
||||
PreferZone: req.PreferZone,
|
||||
PreferWire: req.PreferWire,
|
||||
PreferHost: req.PreferHost,
|
||||
Hypervisor: req.Hypervisor,
|
||||
Disks: []*DiskConfig{req.DiskConfig},
|
||||
PreferManager: req.PreferManager,
|
||||
PreferRegion: req.PreferRegion,
|
||||
PreferZone: req.PreferZone,
|
||||
PreferWire: req.PreferWire,
|
||||
PreferHost: req.PreferHost,
|
||||
Hypervisor: req.Hypervisor,
|
||||
Disks: []*DiskConfig{req.DiskConfig},
|
||||
// Project: req.Project,
|
||||
// Domain: req.Domain,
|
||||
},
|
||||
|
||||
@@ -15,9 +15,14 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -47,7 +52,10 @@ type DnsRecordSetCreateInput struct {
|
||||
type DnsRecordSetUpdateInput struct {
|
||||
apis.EnabledStatusStandaloneResourceBaseUpdateInput
|
||||
|
||||
SDnsRecordSet
|
||||
DnsType string `json:"dns_type"`
|
||||
DnsValue string `json:"dns_value"`
|
||||
TTL *int64 `json:"ttl"`
|
||||
MxPriority *int64 `json:"mx_priority"`
|
||||
|
||||
TrafficPolicies []DnsRecordPolicy
|
||||
}
|
||||
@@ -76,3 +84,29 @@ type DnsRecordDisableInput struct {
|
||||
type DnsRecordSetTrafficPoliciesInput struct {
|
||||
TrafficPolicies []DnsRecordPolicy `json:"traffic_policies"`
|
||||
}
|
||||
|
||||
func (recordset *SDnsRecordSet) ValidateDnsrecordValue() error {
|
||||
domainReg := regexp.MustCompile(`^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$`)
|
||||
switch cloudprovider.TDnsType(recordset.DnsType) {
|
||||
case cloudprovider.DnsTypeMX:
|
||||
if recordset.MxPriority < 1 || recordset.MxPriority > 50 {
|
||||
return httperrors.NewOutOfRangeError("mx_priority range limited to [1,50]")
|
||||
}
|
||||
if !domainReg.MatchString(recordset.DnsValue) {
|
||||
return httperrors.NewInputParameterError("invalid domain %s for MX record", recordset.DnsValue)
|
||||
}
|
||||
case cloudprovider.DnsTypeA:
|
||||
if !regutils.MatchIP4Addr(recordset.DnsValue) {
|
||||
return httperrors.NewInputParameterError("invalid ipv4 %s for A record", recordset.DnsValue)
|
||||
}
|
||||
case cloudprovider.DnsTypeAAAA:
|
||||
if !regutils.MatchIP6Addr(recordset.DnsValue) {
|
||||
return httperrors.NewInputParameterError("invalid ipv6 %s for AAAA record", recordset.DnsValue)
|
||||
}
|
||||
case cloudprovider.DnsTypeCNAME:
|
||||
if !domainReg.MatchString(recordset.DnsValue) {
|
||||
return httperrors.NewInputParameterError("invalid domain %s for CNAME record", recordset.DnsValue)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -30,3 +30,7 @@ type ExternalProjectDetails struct {
|
||||
|
||||
SExternalProject
|
||||
}
|
||||
|
||||
type ExternalProjectChangeProjectInput struct {
|
||||
apis.ProjectizedResourceInput
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ type ServerListInput struct {
|
||||
// enum: asc,desc
|
||||
// OrderByDisk string `json:"order_by_disk"`
|
||||
|
||||
// 根据ip查找机器
|
||||
IpAddr string `json:"ip_addr"`
|
||||
|
||||
// 列出可以挂载指定EIP的主机
|
||||
UsableServerForEip string `json:"usable_server_for_eip"`
|
||||
|
||||
|
||||
@@ -114,6 +114,9 @@ type NetworkListInput struct {
|
||||
IsAutoAlloc *bool `json:"is_auto_alloc"`
|
||||
// 是否为基础网络(underlay)
|
||||
IsClassic *bool `json:"is_classic"`
|
||||
|
||||
// filter by Host schedtag
|
||||
HostSchedtagId string `json:"host_schedtag_id"`
|
||||
}
|
||||
|
||||
type NetworkResourceInfoBase struct {
|
||||
|
||||
@@ -106,8 +106,10 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
DISK_TYPES = []string{DISK_TYPE_ROTATE, DISK_TYPE_SSD, DISK_TYPE_HYBRID}
|
||||
STORAGE_LOCAL_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_UCLOUD_LOCAL_NORMAL, STORAGE_UCLOUD_LOCAL_SSD, STORAGE_UCLOUD_EXCLUSIVE_LOCAL_DISK}
|
||||
DISK_TYPES = []string{DISK_TYPE_ROTATE, DISK_TYPE_SSD, DISK_TYPE_HYBRID}
|
||||
STORAGE_LOCAL_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_UCLOUD_LOCAL_NORMAL, STORAGE_UCLOUD_LOCAL_SSD, STORAGE_UCLOUD_EXCLUSIVE_LOCAL_DISK,
|
||||
STORAGE_EPHEMERAL_SSD, STORAGE_LOCAL_BASIC, STORAGE_LOCAL_SSD, STORAGE_LOCAL_PRO, STORAGE_OPENSTACK_NOVA,
|
||||
STORAGE_ZSTACK_LOCAL_STORAGE, STORAGE_GOOGLE_LOCAL_SSD}
|
||||
STORAGE_SUPPORT_TYPES = STORAGE_LOCAL_TYPES
|
||||
STORAGE_ALL_TYPES = []string{
|
||||
STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_SHEEPDOG,
|
||||
|
||||
@@ -916,8 +916,7 @@ type SGuestTemplate struct {
|
||||
// 计费方式
|
||||
BillingType string `json:"billing_type"`
|
||||
// 其他配置信息
|
||||
Content interface{} `json:"content"`
|
||||
LastCheckTime time.Time `json:"last_check_time"`
|
||||
Content interface{} `json:"content"`
|
||||
}
|
||||
|
||||
// SGuestTemplateResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGuestTemplateResourceBase.
|
||||
@@ -926,6 +925,20 @@ type SGuestTemplateResourceBase struct {
|
||||
GuestTemplateId string `json:"guest_template_id"`
|
||||
}
|
||||
|
||||
// SGuestcdrom is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGuestcdrom.
|
||||
type SGuestcdrom struct {
|
||||
Id string `json:"id"`
|
||||
// = Column(VARCHAR(36, charset='ascii'), primary_key=True)
|
||||
ImageId string `json:"image_id"`
|
||||
// Column(VARCHAR(36, charset='ascii'), nullable=True)
|
||||
Name string `json:"name"`
|
||||
// Column(VARCHAR(64, charset='ascii'), nullable=True)
|
||||
Path string `json:"path"`
|
||||
// Column(VARCHAR(256, charset='ascii'), nullable=True)
|
||||
Size int64 `json:"size"`
|
||||
UpdateVersion int `json:"update_version"`
|
||||
}
|
||||
|
||||
// SGuestdisk is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGuestdisk.
|
||||
type SGuestdisk struct {
|
||||
SGuestJointsBase
|
||||
@@ -1045,11 +1058,10 @@ type SHost struct {
|
||||
OvnVersion string `json:"ovn_version"`
|
||||
IsBaremetal bool `json:"is_baremetal"`
|
||||
// 是否处于维护状态
|
||||
IsMaintenance bool `json:"is_maintenance"`
|
||||
LastPingAt time.Time `json:"last_ping_at"`
|
||||
EnableHealthCheck bool `json:"enable_health_check"`
|
||||
ResourceType string `json:"resource_type"`
|
||||
RealExternalId string `json:"real_external_id"`
|
||||
IsMaintenance bool `json:"is_maintenance"`
|
||||
EnableHealthCheck bool `json:"enable_health_check"`
|
||||
ResourceType string `json:"resource_type"`
|
||||
RealExternalId string `json:"real_external_id"`
|
||||
// 是否为导入的宿主机
|
||||
IsImport bool `json:"is_import"`
|
||||
// 是否允许PXE启动
|
||||
@@ -1305,12 +1317,9 @@ type SLoadbalancerAgentDeployment struct {
|
||||
|
||||
// SLoadbalancerAgentParams is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SLoadbalancerAgentParams.
|
||||
type SLoadbalancerAgentParams struct {
|
||||
KeepalivedConfTmpl string `json:"keepalived_conf_tmpl"`
|
||||
HaproxyConfTmpl string `json:"haproxy_conf_tmpl"`
|
||||
TelegrafConfTmpl string `json:"telegraf_conf_tmpl"`
|
||||
Vrrp SLoadbalancerAgentParamsVrrp `json:"vrrp"`
|
||||
Haproxy SLoadbalancerAgentParamsHaproxy `json:"haproxy"`
|
||||
Telegraf SLoadbalancerAgentParamsTelegraf `json:"telegraf"`
|
||||
KeepalivedConfTmpl string `json:"keepalived_conf_tmpl"`
|
||||
HaproxyConfTmpl string `json:"haproxy_conf_tmpl"`
|
||||
TelegrafConfTmpl string `json:"telegraf_conf_tmpl"`
|
||||
}
|
||||
|
||||
// SLoadbalancerAgentParamsHaproxy is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SLoadbalancerAgentParamsHaproxy.
|
||||
@@ -1552,6 +1561,16 @@ type SManagedResourceBase struct {
|
||||
ManagerId string `json:"manager_id"`
|
||||
}
|
||||
|
||||
// SNatDEntry is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNatDEntry.
|
||||
type SNatDEntry struct {
|
||||
SNatEntry
|
||||
ExternalIP string `json:"external_ip"`
|
||||
ExternalPort int `json:"external_port"`
|
||||
InternalIP string `json:"internal_ip"`
|
||||
InternalPort int `json:"internal_port"`
|
||||
IpProtocol string `json:"ip_protocol"`
|
||||
}
|
||||
|
||||
// SNatEntry is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNatEntry.
|
||||
type SNatEntry struct {
|
||||
apis.SStatusInfrasResourceBase
|
||||
@@ -1582,6 +1601,25 @@ type SNatgatewayResourceBase struct {
|
||||
NatgatewayId string `json:"natgateway_id"`
|
||||
}
|
||||
|
||||
// SNetInterface is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNetInterface.
|
||||
type SNetInterface struct {
|
||||
Mac string `json:"mac"`
|
||||
// Column(VARCHAR(36, charset='ascii'), primary_key=True)
|
||||
BaremetalId string `json:"baremetal_id"`
|
||||
// Column(VARCHAR(36, charset='ascii'), nullable=True)
|
||||
WireId string `json:"wire_id"`
|
||||
// Column(VARCHAR(36, charset='ascii'), nullable=True)
|
||||
Rate int `json:"rate"`
|
||||
// Column(Integer, nullable=True) # Mbps
|
||||
NicType string `json:"nic_type"`
|
||||
// Column(VARCHAR(36, charset='ascii'), nullable=True)
|
||||
Index byte `json:"index"`
|
||||
// Column(TINYINT, nullable=True)
|
||||
LinkUp bool `json:"link_up"`
|
||||
// Column(Boolean, nullable=True)
|
||||
Mtu int16 `json:"mtu"`
|
||||
}
|
||||
|
||||
// SNetwork is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNetwork.
|
||||
type SNetwork struct {
|
||||
apis.SSharableVirtualResourceBase
|
||||
@@ -1787,8 +1825,6 @@ type SScalingAlarm struct {
|
||||
Value float64 `json:"value"`
|
||||
// Real-time cumulate number
|
||||
RealCumulate int `json:"real_cumulate"`
|
||||
// Last trigger time
|
||||
LastTriggerTime time.Time `json:"last_trigger_time"`
|
||||
}
|
||||
|
||||
// SScalingGroup is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SScalingGroup.
|
||||
@@ -1819,10 +1855,6 @@ type SScalingGroup struct {
|
||||
HealthCheckGov int `json:"health_check_gov"`
|
||||
LoadbalancerBackendPort int `json:"loadbalancer_backend_port"`
|
||||
LoadbalancerBackendWeight int `json:"loadbalancer_backend_weight"`
|
||||
// Time to allow scale
|
||||
AllowScaleTime time.Time `json:"allow_scale_time"`
|
||||
// NextCheckTime descripe the next time to check instance's health
|
||||
NextCheckTime time.Time `json:"next_check_time"`
|
||||
}
|
||||
|
||||
// SScalingGroupGuest is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SScalingGroupGuest.
|
||||
@@ -2086,7 +2118,7 @@ type SStorage struct {
|
||||
Capacity int64 `json:"capacity"`
|
||||
// 实际容量大小,单位Mb
|
||||
// we always expect actual capacity great or equal than zero, otherwise something wrong
|
||||
ActualCapacity int64 `json:"actual_capacity"`
|
||||
ActualCapacityUsed int64 `json:"actual_capacity_used"`
|
||||
// 预留容量大小
|
||||
Reserved int64 `json:"reserved"`
|
||||
// 存储类型
|
||||
@@ -2164,13 +2196,7 @@ type STimer struct {
|
||||
WeekDays byte `json:"week_days"`
|
||||
// 0-31 0 is unlimited
|
||||
MonthDays uint32 `json:"month_days"`
|
||||
// StartTime represent the start time of this timer
|
||||
StartTime time.Time `json:"start_time"`
|
||||
// EndTime represent deadline of this timer
|
||||
EndTime time.Time `json:"end_time"`
|
||||
// NextTime represent the time timer should bell
|
||||
NextTime time.Time `json:"next_time"`
|
||||
IsExpired bool `json:"is_expired"`
|
||||
IsExpired bool `json:"is_expired"`
|
||||
}
|
||||
|
||||
// SVCenter is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SVCenter.
|
||||
|
||||
@@ -19,6 +19,8 @@ import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/pkg/trace"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/i18n"
|
||||
)
|
||||
|
||||
type AppContextKey string
|
||||
@@ -54,6 +56,10 @@ func AppContextServiceName(ctx context.Context) string {
|
||||
}
|
||||
}
|
||||
|
||||
func AppContextLang(ctx context.Context) string {
|
||||
return i18n.Lang(ctx).String()
|
||||
}
|
||||
|
||||
func AppContextCurrentPath(ctx context.Context) []string {
|
||||
val := ctx.Value(APP_CONTEXT_KEY_CUR_PATH)
|
||||
if val != nil {
|
||||
@@ -170,6 +176,7 @@ type AppContextData struct {
|
||||
TaskId string
|
||||
TaskNotifyUrl string
|
||||
ServiceName string
|
||||
Lang string
|
||||
}
|
||||
|
||||
func (self *AppContextData) IsZero() bool {
|
||||
@@ -184,6 +191,7 @@ func FetchAppContextData(ctx context.Context) AppContextData {
|
||||
taskId := AppContextTaskId(ctx)
|
||||
taskNotifyUrl := AppContextTaskNotifyUrl(ctx)
|
||||
serviceName := AppContextServiceName(ctx)
|
||||
lang := AppContextLang(ctx)
|
||||
|
||||
var trace trace.STrace
|
||||
if tracePtr != nil {
|
||||
@@ -196,6 +204,7 @@ func FetchAppContextData(ctx context.Context) AppContextData {
|
||||
TaskId: taskId,
|
||||
TaskNotifyUrl: taskNotifyUrl,
|
||||
ServiceName: serviceName,
|
||||
Lang: lang,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,5 +231,8 @@ func (self *AppContextData) GetContext() context.Context {
|
||||
if len(self.ServiceName) > 0 {
|
||||
ctx = context.WithValue(ctx, APP_CONTEXT_KEY_APPNAME, self.ServiceName)
|
||||
}
|
||||
if len(self.Lang) > 0 {
|
||||
ctx = i18n.WithLang(ctx, self.Lang)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
@@ -116,9 +116,33 @@ func (m *SScopedResourceBaseManager) FilterByOwner(q *sqlchemy.SQuery, userCred
|
||||
}
|
||||
switch scope {
|
||||
case rbacutils.ScopeDomain:
|
||||
q = q.Equals("domain_id", userCred.GetProjectDomainId())
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
// share to system
|
||||
sqlchemy.AND(
|
||||
sqlchemy.IsNullOrEmpty(q.Field("domain_id")),
|
||||
sqlchemy.IsNullOrEmpty(q.Field("tenant_id")),
|
||||
),
|
||||
// share to this domain or its sub-projects
|
||||
sqlchemy.Equals(q.Field("domain_id"), userCred.GetProjectDomainId()),
|
||||
))
|
||||
case rbacutils.ScopeProject:
|
||||
q = q.Equals("tenant_id", userCred.GetProjectId())
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
// share to system
|
||||
sqlchemy.AND(
|
||||
sqlchemy.IsNullOrEmpty(q.Field("domain_id")),
|
||||
sqlchemy.IsNullOrEmpty(q.Field("tenant_id")),
|
||||
),
|
||||
// share to project's parent domain
|
||||
sqlchemy.AND(
|
||||
sqlchemy.Equals(q.Field("domain_id"), userCred.GetProjectDomainId()),
|
||||
sqlchemy.IsNullOrEmpty(q.Field("tenant_id")),
|
||||
),
|
||||
// share to this project
|
||||
sqlchemy.AND(
|
||||
sqlchemy.Equals(q.Field("domain_id"), userCred.GetProjectDomainId()),
|
||||
sqlchemy.Equals(q.Field("tenant_id"), userCred.GetProjectId()),
|
||||
),
|
||||
))
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@ const (
|
||||
TASK_INIT_STAGE = "on_init"
|
||||
|
||||
CONVERT_TASK = "convert_task"
|
||||
|
||||
LANG = "lang"
|
||||
)
|
||||
|
||||
type STaskManager struct {
|
||||
|
||||
@@ -24,8 +24,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
@@ -46,24 +44,24 @@ var (
|
||||
|
||||
notifyAdminUsers []string
|
||||
notifyAdminGroups []string
|
||||
|
||||
notifyclientI18nTable = i18n.Table{}
|
||||
)
|
||||
|
||||
const (
|
||||
SUFFIX = "suffix"
|
||||
)
|
||||
|
||||
func init() {
|
||||
notifyClientWorkerMan = appsrv.NewWorkerManager("NotifyClientWorkerManager", 1, 50, false)
|
||||
templatesTableLock = &sync.Mutex{}
|
||||
templatesTable = make(map[string]*template.Template)
|
||||
|
||||
notifyclientI18nTable.Set(SUFFIX, i18n.NewTableEntry().EN("en").CN("cn"))
|
||||
}
|
||||
|
||||
func getLangSuffix(ctx context.Context) string {
|
||||
lang := i18n.Lang(ctx)
|
||||
switch lang {
|
||||
case language.English:
|
||||
return "en"
|
||||
case language.Chinese:
|
||||
return "cn"
|
||||
default:
|
||||
return "en"
|
||||
}
|
||||
return notifyclientI18nTable.Lookup(ctx, SUFFIX)
|
||||
}
|
||||
|
||||
func getTemplateString(ctx context.Context, topic string, contType string, channel npk.TNotifyChannel) ([]byte, error) {
|
||||
@@ -80,7 +78,7 @@ func getTemplateString(ctx context.Context, topic string, contType string, chann
|
||||
}
|
||||
|
||||
func getTemplate(ctx context.Context, topic string, contType string, channel npk.TNotifyChannel) (*template.Template, error) {
|
||||
key := fmt.Sprintf("%s.%s.%s", topic, contType, channel)
|
||||
key := fmt.Sprintf("%s.%s.%s@%s", topic, contType, channel, getLangSuffix(ctx))
|
||||
templatesTableLock.Lock()
|
||||
defer templatesTableLock.Unlock()
|
||||
|
||||
@@ -162,7 +160,10 @@ func rawNotify(ctx context.Context, recipientId []string, isGroup bool, channel
|
||||
// log.Debugf("send notification %s %s", topic, body)
|
||||
notifyClientWorkerMan.Run(func() {
|
||||
s := auth.GetAdminSession(context.Background(), consts.GetRegion(), "")
|
||||
npk.Notifications.Send(s, msg)
|
||||
err := npk.Notifications.Send(s, msg)
|
||||
if err != nil {
|
||||
log.Errorf("unable to send notification: %v", err)
|
||||
}
|
||||
}, nil, nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ func (manager *SCloudaccountManager) syncCloudaccounts(ctx context.Context, user
|
||||
result.AddError(err)
|
||||
continue
|
||||
}
|
||||
account.StartSyncCloudIdResourcesTask(ctx, userCred, "")
|
||||
localAccounts = append(localAccounts, *account)
|
||||
result.Add()
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package cloudprovider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
@@ -601,7 +602,7 @@ func (r DnsRecordSet) GetMxPriority() int64 {
|
||||
}
|
||||
|
||||
func (record DnsRecordSet) Equals(r DnsRecordSet) bool {
|
||||
if record.DnsName != r.DnsName {
|
||||
if strings.ToLower(record.DnsName) != strings.ToLower(r.DnsName) {
|
||||
return false
|
||||
}
|
||||
if record.DnsType != r.DnsType {
|
||||
|
||||
@@ -202,6 +202,7 @@ type ICloudStorage interface {
|
||||
GetStorageType() string
|
||||
GetMediumType() string
|
||||
GetCapacityMB() int64 // MB
|
||||
GetCapacityUsedMB() int64
|
||||
GetStorageConf() jsonutils.JSONObject
|
||||
GetEnabled() bool
|
||||
|
||||
@@ -248,6 +249,8 @@ type ICloudHost interface {
|
||||
|
||||
CreateVM(desc *SManagedVMCreateConfig) (ICloudVM, error)
|
||||
GetIHostNics() ([]ICloudHostNetInterface, error)
|
||||
|
||||
GetSchedtags() ([]string, error)
|
||||
}
|
||||
|
||||
type ICloudVM interface {
|
||||
|
||||
@@ -438,8 +438,8 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForCreate(ctx conte
|
||||
}
|
||||
|
||||
iVM, err := func() (cloudprovider.ICloudVM, error) {
|
||||
lockman.LockObject(ctx, host)
|
||||
defer lockman.ReleaseObject(ctx, host)
|
||||
lockman.LockObject(ctx, guest)
|
||||
defer lockman.ReleaseObject(ctx, guest)
|
||||
|
||||
iVM, err := ihost.CreateVM(&desc)
|
||||
if err != nil {
|
||||
@@ -669,7 +669,9 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
|
||||
}
|
||||
|
||||
for _, guestdisk := range guest.GetDisks() {
|
||||
if disk := guestdisk.GetDisk(); disk != nil && disk.AutoDelete {
|
||||
disk := guestdisk.GetDisk()
|
||||
storage := disk.GetStorage()
|
||||
if disk != nil && disk.AutoDelete && !utils.IsInStringArray(storage.StorageType, api.STORAGE_LOCAL_TYPES) {
|
||||
idisk, err := disk.GetIDisk()
|
||||
if err != nil {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
@@ -678,6 +680,9 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
|
||||
log.Errorf("disk.GetIDisk fail %s", err)
|
||||
return nil, err
|
||||
}
|
||||
if idisk.GetStatus() == api.DISK_DEALLOC {
|
||||
continue
|
||||
}
|
||||
err = idisk.Delete(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("idisk.Delete fail %s", err)
|
||||
|
||||
@@ -1019,7 +1019,7 @@ func (bucket *SBucket) PerformUpload(
|
||||
if inc.SizeBytes < 0 {
|
||||
inc.SizeBytes = 0
|
||||
}
|
||||
} else if err == cloudprovider.ErrNotFound {
|
||||
} else if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
// new upload
|
||||
inc.SizeBytes = sizeBytes
|
||||
inc.ObjectCount = 1
|
||||
@@ -1246,7 +1246,7 @@ func (bucket *SBucket) GetDetailsAcl(
|
||||
} else {
|
||||
object, err := cloudprovider.GetIObject(iBucket, objKey)
|
||||
if err != nil {
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
return output, httperrors.NewNotFoundError("object %s not found", objKey)
|
||||
} else {
|
||||
return output, httperrors.NewInternalServerError("iBucket.GetIObjects error %s", err)
|
||||
@@ -1455,7 +1455,7 @@ func (bucket *SBucket) processObjectsActionInput(input api.BucketObjectsActionIn
|
||||
} else {
|
||||
object, err := cloudprovider.GetIObject(iBucket, key)
|
||||
if err != nil {
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
return nil, nil, httperrors.NewResourceNotFoundError("object %s not found", key)
|
||||
} else {
|
||||
return nil, nil, httperrors.NewInternalServerError("iBucket.GetIObject error %s", err)
|
||||
|
||||
@@ -357,7 +357,11 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
|
||||
return output, httperrors.NewNotSupportedError("not support for cloudaccount with provider '%s'", input.Provider)
|
||||
}
|
||||
// validate first
|
||||
input.CloudaccountCreateInput, err = scm.ValidateCreateData(ctx, userCred, userCred, query, input.CloudaccountCreateInput)
|
||||
ownerId, err := scm.FetchOwnerId(ctx, jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return output, errors.Wrap(err, "FetchOwnerId in PerformPrepareNets")
|
||||
}
|
||||
input.CloudaccountCreateInput, err = scm.ValidateCreateData(ctx, userCred, ownerId, query, input.CloudaccountCreateInput)
|
||||
if err != nil {
|
||||
return output, err
|
||||
}
|
||||
|
||||
@@ -355,15 +355,20 @@ func createTenant(ctx context.Context, name, domainId, desc string) (string, str
|
||||
return domainId, projectId, nil
|
||||
}
|
||||
|
||||
func getOrCreateTenant(ctx context.Context, name, domainId, projectId, desc string) (string, string, error) {
|
||||
func (self *SCloudaccount) getOrCreateTenant(ctx context.Context, name, projectId, desc string) (string, string, error) {
|
||||
tenant, err := getTenant(ctx, projectId, name)
|
||||
if err != nil && errors.Cause(err) != sql.ErrNoRows {
|
||||
return "", "", err
|
||||
if err != nil {
|
||||
if errors.Cause(err) != sql.ErrNoRows {
|
||||
return "", "", errors.Wrapf(err, "getTenan")
|
||||
}
|
||||
return createTenant(ctx, name, self.DomainId, desc)
|
||||
}
|
||||
if err == sql.ErrNoRows || tenant.DomainId != domainId {
|
||||
return createTenant(ctx, name, domainId, desc)
|
||||
share := self.GetSharedInfo()
|
||||
if tenant.DomainId == self.DomainId || (share.PublicScope == rbacutils.ScopeSystem ||
|
||||
(share.PublicScope == rbacutils.ScopeDomain && utils.IsInStringArray(tenant.DomainId, share.SharedDomains))) {
|
||||
return tenant.DomainId, tenant.Id, nil
|
||||
}
|
||||
return tenant.DomainId, tenant.Id, nil
|
||||
return createTenant(ctx, name, self.DomainId, desc)
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) syncProject(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
@@ -373,7 +378,7 @@ func (self *SCloudprovider) syncProject(ctx context.Context, userCred mcclient.T
|
||||
}
|
||||
|
||||
desc := fmt.Sprintf("auto create from cloud provider %s (%s)", self.Name, self.Id)
|
||||
domainId, projectId, err := getOrCreateTenant(ctx, self.Name, account.DomainId, self.ProjectId, desc)
|
||||
domainId, projectId, err := account.getOrCreateTenant(ctx, self.Name, self.ProjectId, desc)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getOrCreateTenant")
|
||||
}
|
||||
@@ -1196,6 +1201,22 @@ func (manager *SCloudproviderManager) ListItemFilter(
|
||||
q = q.In("cloudaccount_id", subq)
|
||||
}
|
||||
|
||||
if len(query.HostSchedtagId) > 0 {
|
||||
schedTagObj, err := SchedtagManager.FetchByIdOrName(userCred, query.HostSchedtagId)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", SchedtagManager.Keyword(), query.HostSchedtagId)
|
||||
} else {
|
||||
return nil, errors.Wrap(err, "SchedtagManager.FetchByIdOrName")
|
||||
}
|
||||
}
|
||||
subq := HostManager.Query("manager_id")
|
||||
hostschedtags := HostschedtagManager.Query().Equals("schedtag_id", schedTagObj.GetId()).SubQuery()
|
||||
subq = subq.Join(hostschedtags, sqlchemy.Equals(hostschedtags.Field("host_id"), subq.Field("id")))
|
||||
log.Debugf("%s", subq.String())
|
||||
q = q.In("id", subq.SubQuery())
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -735,3 +735,21 @@ func (manager *SDBInstanceAccountManager) ListItemExportKeys(ctx context.Context
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SDBInstanceAccountManager) InitializeData() error {
|
||||
sq := DBInstanceManager.Query("id")
|
||||
q := manager.Query().NotIn("dbinstance_id", sq.SubQuery())
|
||||
accounts := []SDBInstanceAccount{}
|
||||
err := db.FetchModelObjects(manager, q, &accounts)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
for i := range accounts {
|
||||
err = accounts[i].Purge(context.Background(), nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "purge %s", accounts[i].Id)
|
||||
}
|
||||
}
|
||||
log.Debugf("SDBInstanceAccountManager cleaned %d dirty data.", len(accounts))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -487,3 +487,21 @@ func (manager *SDBInstanceDatabaseManager) ListItemExportKeys(ctx context.Contex
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SDBInstanceDatabaseManager) InitializeData() error {
|
||||
sq := DBInstanceManager.Query("id")
|
||||
q := manager.Query().NotIn("dbinstance_id", sq.SubQuery())
|
||||
databases := []SDBInstanceDatabase{}
|
||||
err := db.FetchModelObjects(manager, q, &databases)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
for i := range databases {
|
||||
err = databases[i].Purge(context.Background(), nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "purge %s", databases[i].Id)
|
||||
}
|
||||
}
|
||||
log.Debugf("SDBInstanceDatabaseManager cleaned %d dirty data.", len(databases))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
@@ -73,6 +74,24 @@ func (self *SDBInstanceNetwork) AllowDeleteItem(ctx context.Context, userCred mc
|
||||
return false
|
||||
}
|
||||
|
||||
// RDS网络列表
|
||||
func (manager *SDBInstanceNetworkManager) ListItemFilter(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
query api.DBInstanceNetworkListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SVirtualJointResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualJointResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualJointResourceBase.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SDBInstanceResourceBaseManager.ListItemFilter(ctx, q, userCred, query.DBInstanceFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SDBInstanceResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (self *SDBInstanceNetwork) GetNetwork() (*SNetwork, error) {
|
||||
network, err := NetworkManager.FetchById(self.NetworkId)
|
||||
if err != nil {
|
||||
@@ -221,3 +240,23 @@ func (manager *SDBInstanceNetworkManager) newFromCloudDBNetwork(ctx context.Cont
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SDBInstanceNetworkManager) InitializeData() error {
|
||||
sq := DBInstanceManager.Query("id")
|
||||
q := manager.Query().NotIn("dbinstance_id", sq.SubQuery())
|
||||
networks := []SDBInstanceNetwork{}
|
||||
err := db.FetchModelObjects(manager, q, &networks)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
for i := range networks {
|
||||
_, err := db.Update(&networks[i], func() error {
|
||||
return networks[i].MarkDelete()
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "db.Update.MarkDelete")
|
||||
}
|
||||
}
|
||||
log.Debugf("SDBInstanceNetworkManager cleaned %d dirty data.", len(networks))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1351,17 +1351,7 @@ func (manager *SDBInstanceManager) SyncDBInstances(ctx context.Context, userCred
|
||||
}
|
||||
|
||||
func (self *SDBInstance) syncRemoveCloudDBInstance(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
self.SetDisableDelete(userCred, false)
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil { // cannot delete
|
||||
self.SetStatus(userCred, api.VPC_STATUS_UNKNOWN, "sync to delete")
|
||||
return errors.Wrap(err, "ValidateDeleteCondition")
|
||||
}
|
||||
return self.RealDelete(ctx, userCred)
|
||||
return self.Purge(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SDBInstance) ValidateDeleteCondition(ctx context.Context) error {
|
||||
|
||||
+27
-22
@@ -443,12 +443,11 @@ func diskCreateInput2ComputeQuotaKeys(input api.DiskCreateInput, ownerId mcclien
|
||||
return keys
|
||||
}
|
||||
|
||||
func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, oinput api.DiskCreateInput) (*jsonutils.JSONDict, error) {
|
||||
input := &oinput
|
||||
func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.DiskCreateInput) (api.DiskCreateInput, error) {
|
||||
diskConfig := input.DiskConfig
|
||||
diskConfig, err := parseDiskInfo(ctx, userCred, diskConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return input, err
|
||||
}
|
||||
input.ProjectId = ownerId.GetProjectId()
|
||||
input.ProjectDomainId = ownerId.GetProjectDomainId()
|
||||
@@ -459,26 +458,18 @@ func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mc
|
||||
if storageID != "" {
|
||||
storageObj, err := StorageManager.FetchByIdOrName(nil, storageID)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Storage %s not found", storageID)
|
||||
return input, httperrors.NewResourceNotFoundError("Storage %s not found", storageID)
|
||||
}
|
||||
storage := storageObj.(*SStorage)
|
||||
|
||||
provider := storage.GetCloudprovider()
|
||||
if provider != nil {
|
||||
if !provider.GetEnabled() {
|
||||
return nil, httperrors.NewInputParameterError("provider %s(%s) is disabled, you need enable provider first", provider.Name, provider.Id)
|
||||
}
|
||||
if !utils.IsInStringArray(provider.Status, api.CLOUD_PROVIDER_VALID_STATUS) {
|
||||
return nil, httperrors.NewInputParameterError("invalid provider %s(%s) status %s, require status is %s", provider.Name, provider.Id, provider.Status, api.CLOUD_PROVIDER_VALID_STATUS)
|
||||
}
|
||||
if !utils.IsInStringArray(provider.HealthStatus, api.CLOUD_PROVIDER_VALID_HEALTH_STATUS) {
|
||||
return nil, httperrors.NewInputParameterError("invalid provider %s(%s) health status %s, require status is %s", provider.Name, provider.Id, provider.HealthStatus, api.CLOUD_PROVIDER_VALID_HEALTH_STATUS)
|
||||
}
|
||||
if provider != nil && !provider.IsAvailable() {
|
||||
return input, httperrors.NewResourceNotReadyError("cloudprovider %s not available", provider.Name)
|
||||
}
|
||||
|
||||
host := storage.GetMasterHost()
|
||||
if host == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("storage %s(%s) need online and attach host for create disk", storage.Name, storage.Id)
|
||||
return input, httperrors.NewResourceNotFoundError("storage %s(%s) need online and attach host for create disk", storage.Name, storage.Id)
|
||||
}
|
||||
input.Hypervisor = host.GetHostDriver().GetHypervisor()
|
||||
if len(diskConfig.Backend) == 0 {
|
||||
@@ -486,7 +477,7 @@ func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mc
|
||||
}
|
||||
err = manager.validateDiskOnStorage(diskConfig, storage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return input, err
|
||||
}
|
||||
input.Storage = storage.Id
|
||||
|
||||
@@ -501,25 +492,39 @@ func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mc
|
||||
if len(diskConfig.Backend) == 0 {
|
||||
diskConfig.Backend = api.STORAGE_LOCAL
|
||||
}
|
||||
if len(input.PreferManager) > 0 {
|
||||
_manager, err := CloudproviderManager.FetchByIdOrName(userCred, input.PreferManager)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return input, httperrors.NewResourceNotFoundError2("cloudprovider", input.PreferManager)
|
||||
}
|
||||
return input, httperrors.NewGeneralError(err)
|
||||
}
|
||||
manager := _manager.(*SCloudprovider)
|
||||
if !manager.IsAvailable() {
|
||||
return input, httperrors.NewResourceNotReadyError("cloudprovider %s not available", manager.Name)
|
||||
}
|
||||
input.PreferManager = manager.Id
|
||||
}
|
||||
serverInput, err := ValidateScheduleCreateData(ctx, userCred, input.ToServerCreateInput(), input.Hypervisor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return input, err
|
||||
}
|
||||
input = serverInput.ToDiskCreateInput()
|
||||
quotaKey = diskCreateInput2ComputeQuotaKeys(*input, ownerId)
|
||||
input = *serverInput.ToDiskCreateInput()
|
||||
quotaKey = diskCreateInput2ComputeQuotaKeys(input, ownerId)
|
||||
}
|
||||
|
||||
input.VirtualResourceCreateInput, err = manager.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.VirtualResourceCreateInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return input, err
|
||||
}
|
||||
|
||||
pendingUsage := SQuota{Storage: diskConfig.SizeMb}
|
||||
pendingUsage.SetKeys(quotaKey)
|
||||
if err := quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
|
||||
return nil, httperrors.NewOutOfQuotaError("%s", err)
|
||||
return input, httperrors.NewOutOfQuotaError("%s", err)
|
||||
}
|
||||
return input.JSON(input), nil
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (manager *SDiskManager) validateDiskOnStorage(diskConfig *api.DiskConfig, storage *SStorage) error {
|
||||
|
||||
@@ -18,13 +18,11 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
@@ -75,6 +73,44 @@ func (manager *SDnsRecordSetManager) EnableGenerateName() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type SDnsRecordSetValidateInfo struct {
|
||||
api.SDnsRecordSet
|
||||
TrafficPolicies []api.DnsRecordPolicy
|
||||
}
|
||||
|
||||
func validateDnsrecordPolicy(dnsType string, dnsZone *SDnsZone, trafficPolicies []api.DnsRecordPolicy) error {
|
||||
for _, policy := range trafficPolicies {
|
||||
if len(policy.Provider) == 0 {
|
||||
return httperrors.NewGeneralError(fmt.Errorf("missing traffic policy provider"))
|
||||
}
|
||||
factory, err := cloudprovider.GetProviderFactory(policy.Provider)
|
||||
if err != nil {
|
||||
return httperrors.NewGeneralError(errors.Wrapf(err, "invalid provider %s for traffic policy", policy.Provider))
|
||||
}
|
||||
_dnsTypes := factory.GetSupportedDnsTypes()
|
||||
dnsTypes, _ := _dnsTypes[cloudprovider.TDnsZoneType(dnsZone.ZoneType)]
|
||||
if ok, _ := utils.InArray(cloudprovider.TDnsType(dnsType), dnsTypes); !ok {
|
||||
return httperrors.NewNotSupportedError("%s %s not supported dns type %s", policy.Provider, dnsZone.ZoneType, dnsType)
|
||||
}
|
||||
_policyTypes := factory.GetSupportedDnsPolicyTypes()
|
||||
policyTypes, _ := _policyTypes[cloudprovider.TDnsZoneType(dnsZone.ZoneType)]
|
||||
if ok, _ := utils.InArray(cloudprovider.TDnsPolicyType(policy.PolicyType), policyTypes); !ok {
|
||||
return httperrors.NewNotSupportedError("%s %s not supported policy type %s", policy.Provider, dnsZone.ZoneType, policy.PolicyType)
|
||||
}
|
||||
_policyValues := factory.GetSupportedDnsPolicyValues()
|
||||
policyValues, _ := _policyValues[cloudprovider.TDnsPolicyType(policy.PolicyType)]
|
||||
if len(policyValues) > 0 {
|
||||
if len(policy.PolicyValue) == 0 {
|
||||
return httperrors.NewMissingParameterError(fmt.Sprintf("missing %s policy value", policy.Provider))
|
||||
}
|
||||
if isIn, _ := utils.InArray(cloudprovider.TDnsPolicyValue(policy.PolicyValue), policyValues); !isIn {
|
||||
return httperrors.NewNotSupportedError("%s %s %s not support %s", policy.Provider, dnsZone.ZoneType, policy.PolicyType, policy.PolicyValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建
|
||||
func (manager *SDnsRecordSetManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.DnsRecordSetCreateInput) (api.DnsRecordSetCreateInput, error) {
|
||||
var err error
|
||||
@@ -93,69 +129,36 @@ func (manager *SDnsRecordSetManager) ValidateCreateData(ctx context.Context, use
|
||||
}
|
||||
return input, httperrors.NewGeneralError(err)
|
||||
}
|
||||
domainReg := regexp.MustCompile(`^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$`)
|
||||
switch cloudprovider.TDnsType(input.DnsType) {
|
||||
case cloudprovider.DnsTypeMX:
|
||||
if input.MxPriority < 1 || input.MxPriority > 50 {
|
||||
return input, httperrors.NewOutOfRangeError("mx_priority range limited to [1,50]")
|
||||
}
|
||||
if !domainReg.MatchString(input.DnsValue) {
|
||||
return input, httperrors.NewInputParameterError("invalid domain %s for MX record", input.DnsValue)
|
||||
}
|
||||
case cloudprovider.DnsTypeA:
|
||||
if !regutils.MatchIP4Addr(input.DnsValue) {
|
||||
return input, httperrors.NewInputParameterError("invalid ipv4 %s for A record", input.DnsValue)
|
||||
}
|
||||
case cloudprovider.DnsTypeAAAA:
|
||||
if !regutils.MatchIP6Addr(input.DnsValue) {
|
||||
return input, httperrors.NewInputParameterError("invalid ipv6 %s for AAAA record", input.DnsValue)
|
||||
}
|
||||
case cloudprovider.DnsTypeCNAME:
|
||||
if !domainReg.MatchString(input.DnsValue) {
|
||||
return input, httperrors.NewInputParameterError("invalid domain %s for CNAME record", input.DnsValue)
|
||||
}
|
||||
default:
|
||||
input.MxPriority = 0
|
||||
dnsZone := _dnsZone.(*SDnsZone)
|
||||
|
||||
validateInfo := &SDnsRecordSetValidateInfo{}
|
||||
|
||||
validateInfo.TrafficPolicies = input.TrafficPolicies
|
||||
|
||||
recordset := api.SDnsRecordSet{}
|
||||
recordset.DnsZoneId = input.DnsZoneId
|
||||
recordset.DnsType = input.DnsType
|
||||
recordset.DnsValue = input.DnsValue
|
||||
recordset.TTL = input.TTL
|
||||
recordset.MxPriority = input.MxPriority
|
||||
|
||||
err = recordset.ValidateDnsrecordValue()
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
err = validateDnsrecordPolicy(input.DnsType, dnsZone, input.TrafficPolicies)
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
|
||||
dnsZone := _dnsZone.(*SDnsZone)
|
||||
for _, policy := range input.TrafficPolicies {
|
||||
if len(policy.Provider) == 0 {
|
||||
return input, httperrors.NewGeneralError(fmt.Errorf("missing traffic policy provider"))
|
||||
}
|
||||
factory, err := cloudprovider.GetProviderFactory(policy.Provider)
|
||||
if err != nil {
|
||||
return input, httperrors.NewGeneralError(errors.Wrapf(err, "invalid provider %s for traffic policy", policy.Provider))
|
||||
}
|
||||
_dnsTypes := factory.GetSupportedDnsTypes()
|
||||
dnsTypes, _ := _dnsTypes[cloudprovider.TDnsZoneType(dnsZone.ZoneType)]
|
||||
if ok, _ := utils.InArray(cloudprovider.TDnsType(input.DnsType), dnsTypes); !ok {
|
||||
return input, httperrors.NewNotSupportedError("%s %s not supported dns type %s", policy.Provider, dnsZone.ZoneType, input.DnsType)
|
||||
}
|
||||
_policyTypes := factory.GetSupportedDnsPolicyTypes()
|
||||
policyTypes, _ := _policyTypes[cloudprovider.TDnsZoneType(dnsZone.ZoneType)]
|
||||
if ok, _ := utils.InArray(cloudprovider.TDnsPolicyType(policy.PolicyType), policyTypes); !ok {
|
||||
return input, httperrors.NewNotSupportedError("%s %s not supported policy type %s", policy.Provider, dnsZone.ZoneType, policy.PolicyType)
|
||||
}
|
||||
_policyValues := factory.GetSupportedDnsPolicyValues()
|
||||
policyValues, _ := _policyValues[cloudprovider.TDnsPolicyType(policy.PolicyType)]
|
||||
if len(policyValues) > 0 {
|
||||
if len(policy.PolicyValue) == 0 {
|
||||
return input, httperrors.NewMissingParameterError(fmt.Sprintf("missing %s policy value", policy.Provider))
|
||||
}
|
||||
if isIn, _ := utils.InArray(cloudprovider.TDnsPolicyValue(policy.PolicyValue), policyValues); !isIn {
|
||||
return input, httperrors.NewNotSupportedError("%s %s %s not support %s", policy.Provider, dnsZone.ZoneType, policy.PolicyType, policy.PolicyValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理重复的记录
|
||||
dupedRecordsets := make([]SDnsRecordSet, 0)
|
||||
err = DnsRecordSetManager.Query().Equals("dns_zone_id", input.DnsZoneId).Equals("name", input.Name).Equals("dns_type", input.DnsType).All(&dupedRecordsets)
|
||||
if err != nil && errors.Cause(err) != sql.ErrNoRows {
|
||||
return input, httperrors.NewGeneralError(err)
|
||||
}
|
||||
// 检查dnsrecord 是否通过为policy重复
|
||||
// simple 不能重复,不能和其他policy重复
|
||||
// 检查dnsrecord 是否通过policy重复
|
||||
// simple类型不能重复,不能和其他policy重复
|
||||
// 不同类型policy不能重复
|
||||
// 同类型policy的dnsrecord重复时,需要通过policyvalue区别
|
||||
for i := range dupedRecordsets {
|
||||
@@ -167,28 +170,25 @@ func (manager *SDnsRecordSetManager) ValidateCreateData(ctx context.Context, use
|
||||
return input, httperrors.NewGeneralError(errors.Wrap(err, "db.FetchModelObjects"))
|
||||
}
|
||||
if len(policies) < 1 || len(input.TrafficPolicies) < 1 {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord not support")
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord with simple policy not support")
|
||||
}
|
||||
for j := range policies {
|
||||
for k := range input.TrafficPolicies {
|
||||
if strings.Contains(policies[j].Name, "MultiValueAnswer") &&
|
||||
input.TrafficPolicies[k].PolicyType == "MultiValueAnswer" {
|
||||
if dupedRecordsets[i].DnsValue == input.DnsValue {
|
||||
return input, httperrors.NewNotSupportedError("MultiValueAnswer policy not support duplicated recordset value")
|
||||
}
|
||||
if policies[j].Provider != input.TrafficPolicies[k].Provider {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(policies[j].Name, "Simple") ||
|
||||
strings.Contains(input.TrafficPolicies[k].PolicyType, "Simple") ||
|
||||
policies[j].Name != fmt.Sprintf("%s-%s", input.TrafficPolicies[k].Provider, input.TrafficPolicies[k].PolicyType) {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord not support")
|
||||
policies[j].PolicyType != input.TrafficPolicies[k].PolicyType {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord with different policyType not support")
|
||||
}
|
||||
if policies[j].PolicyValue == input.TrafficPolicies[k].PolicyValue {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord not support")
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord with same policyValue not support")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input.Status = api.DNS_RECORDSET_STATUS_AVAILABLE
|
||||
input.DnsZoneId = dnsZone.Id
|
||||
return input, nil
|
||||
@@ -324,12 +324,14 @@ func (self *SDnsRecordSet) Delete(ctx context.Context, userCred mcclient.TokenCr
|
||||
type sRecordUniqValues struct {
|
||||
DnsZoneId string
|
||||
DnsType string
|
||||
DnsName string
|
||||
DnsValue string
|
||||
}
|
||||
|
||||
func (self *SDnsRecordSet) GetUniqValues() jsonutils.JSONObject {
|
||||
return jsonutils.Marshal(sRecordUniqValues{
|
||||
DnsZoneId: self.DnsZoneId,
|
||||
DnsName: self.Name,
|
||||
DnsType: self.DnsType,
|
||||
DnsValue: self.DnsValue,
|
||||
})
|
||||
@@ -347,12 +349,19 @@ func (manager *SDnsRecordSetManager) FilterByUniqValues(q *sqlchemy.SQuery, valu
|
||||
if len(uniq.DnsZoneId) > 0 {
|
||||
q = q.Equals("dns_zone_id", uniq.DnsZoneId)
|
||||
}
|
||||
if len(uniq.DnsName) > 0 {
|
||||
q = q.Equals("name", uniq.DnsName)
|
||||
}
|
||||
if uniq.DnsType == "CNAME" {
|
||||
return q
|
||||
}
|
||||
if len(uniq.DnsType) > 0 {
|
||||
q = q.Equals("dns_type", uniq.DnsType)
|
||||
}
|
||||
if len(uniq.DnsValue) > 0 {
|
||||
q = q.Equals("dns_value", uniq.DnsValue)
|
||||
}
|
||||
|
||||
return q
|
||||
}
|
||||
|
||||
@@ -427,32 +436,90 @@ func (self *SDnsRecordSet) ValidateUpdateData(ctx context.Context, userCred mccl
|
||||
return input, httperrors.NewGeneralError(errors.Wrapf(err, "GetDnsZone"))
|
||||
}
|
||||
|
||||
for _, policy := range input.TrafficPolicies {
|
||||
if len(policy.Provider) == 0 {
|
||||
return input, httperrors.NewGeneralError(fmt.Errorf("missing traffic policy provider"))
|
||||
}
|
||||
factory, err := cloudprovider.GetProviderFactory(policy.Provider)
|
||||
recordset := api.SDnsRecordSet{}
|
||||
recordset.DnsType = input.DnsType
|
||||
recordset.DnsValue = input.DnsValue
|
||||
if len(recordset.DnsType) == 0 {
|
||||
recordset.DnsType = self.DnsType
|
||||
}
|
||||
if len(recordset.DnsValue) == 0 {
|
||||
recordset.DnsValue = self.DnsValue
|
||||
}
|
||||
if input.TTL != nil {
|
||||
recordset.TTL = *input.TTL
|
||||
} else {
|
||||
recordset.TTL = self.TTL
|
||||
}
|
||||
if input.MxPriority != nil {
|
||||
recordset.MxPriority = *input.MxPriority
|
||||
} else {
|
||||
recordset.MxPriority = self.MxPriority
|
||||
}
|
||||
|
||||
err = recordset.ValidateDnsrecordValue()
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
err = validateDnsrecordPolicy(input.DnsType, dnsZone, input.TrafficPolicies)
|
||||
if err != nil {
|
||||
return input, err
|
||||
}
|
||||
|
||||
// 处理重复的记录
|
||||
dupedRecordsets := make([]SDnsRecordSet, 0)
|
||||
q := DnsRecordSetManager.Query().Equals("dns_zone_id", dnsZone.Id).Equals("name", input.Name).Equals("dns_type", input.DnsType).NotEquals("id", self.Id)
|
||||
err = q.All(&dupedRecordsets)
|
||||
if err != nil && errors.Cause(err) != sql.ErrNoRows {
|
||||
return input, httperrors.NewGeneralError(err)
|
||||
}
|
||||
// 检查dnsrecord 是否通过policy重复
|
||||
// simple类型不能重复,不能和其他policy重复
|
||||
// 不同类型policy不能重复
|
||||
// 同类型policy的dnsrecord重复时,需要通过policyvalue区别
|
||||
|
||||
oldPolicies, err := self.GetDnsTrafficPolicies()
|
||||
if err != nil {
|
||||
return input, httperrors.NewGeneralError(err)
|
||||
}
|
||||
for i := range dupedRecordsets {
|
||||
sq := DnsRecordSetTrafficPolicyManager.Query("dns_traffic_policy_id").Equals("dns_recordset_id", dupedRecordsets[i].Id)
|
||||
q := DnsTrafficPolicyManager.Query().In("id", sq.SubQuery())
|
||||
policies := []SDnsTrafficPolicy{}
|
||||
err := db.FetchModelObjects(DnsTrafficPolicyManager, q, &policies)
|
||||
if err != nil {
|
||||
return input, httperrors.NewGeneralError(errors.Wrapf(err, "invalid provider %s for traffic policy", policy.Provider))
|
||||
return input, httperrors.NewGeneralError(errors.Wrap(err, "db.FetchModelObjects"))
|
||||
}
|
||||
_dnsTypes := factory.GetSupportedDnsTypes()
|
||||
dnsTypes, _ := _dnsTypes[cloudprovider.TDnsZoneType(dnsZone.ZoneType)]
|
||||
if ok, _ := utils.InArray(cloudprovider.TDnsType(input.DnsType), dnsTypes); !ok {
|
||||
return input, httperrors.NewNotSupportedError("%s %s not supported dns type %s", policy.Provider, dnsZone.ZoneType, input.DnsType)
|
||||
if len(policies) < 1 || (len(input.TrafficPolicies) < 1 && len(oldPolicies) < 1) {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord with simple policy not support")
|
||||
}
|
||||
_policyTypes := factory.GetSupportedDnsPolicyTypes()
|
||||
policyTypes, _ := _policyTypes[cloudprovider.TDnsZoneType(dnsZone.ZoneType)]
|
||||
if ok, _ := utils.InArray(cloudprovider.TDnsPolicyType(policy.PolicyType), policyTypes); !ok {
|
||||
return input, httperrors.NewNotSupportedError("%s %s not supported policy type %s", policy.Provider, dnsZone.ZoneType, policy.PolicyType)
|
||||
}
|
||||
_policyValues := factory.GetSupportedDnsPolicyValues()
|
||||
policyValues, _ := _policyValues[cloudprovider.TDnsPolicyType(policy.PolicyType)]
|
||||
if len(policyValues) > 0 {
|
||||
if len(policy.PolicyValue) == 0 {
|
||||
return input, httperrors.NewMissingParameterError(fmt.Sprintf("missing %s policy value", policy.Provider))
|
||||
for j := range policies {
|
||||
for k := range input.TrafficPolicies {
|
||||
if policies[j].Provider != input.TrafficPolicies[k].Provider {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(policies[j].Name, "Simple") ||
|
||||
strings.Contains(input.TrafficPolicies[k].PolicyType, "Simple") ||
|
||||
policies[j].PolicyType != input.TrafficPolicies[k].PolicyType {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord with different policyType not support")
|
||||
}
|
||||
if policies[j].PolicyValue == input.TrafficPolicies[k].PolicyValue {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord with same policyValue not support")
|
||||
}
|
||||
}
|
||||
if isIn, _ := utils.InArray(cloudprovider.TDnsPolicyValue(policy.PolicyValue), policyValues); !isIn {
|
||||
return input, httperrors.NewNotSupportedError("%s %s %s not support %s", policy.Provider, dnsZone.ZoneType, policy.PolicyType, policy.PolicyValue)
|
||||
if len(input.TrafficPolicies) < 1 {
|
||||
for k := range oldPolicies {
|
||||
if policies[j].Provider != input.TrafficPolicies[k].Provider {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(policies[j].Name, "Simple") ||
|
||||
strings.Contains(oldPolicies[k].PolicyType, "Simple") ||
|
||||
policies[j].PolicyType != oldPolicies[k].PolicyType {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord with different policyType not support")
|
||||
}
|
||||
if policies[j].PolicyValue == oldPolicies[k].PolicyValue {
|
||||
return input, httperrors.NewNotSupportedError("duplicated dnsrecord with same policyValue not support")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
@@ -72,6 +73,36 @@ func (manager *SDnsZoneCacheManager) ValidateCreateData(ctx context.Context, use
|
||||
return input, httperrors.NewNotSupportedError("Not support")
|
||||
}
|
||||
|
||||
func (manager *SDnsZoneCacheManager) ResourceScope() rbacutils.TRbacScope {
|
||||
return rbacutils.ScopeDomain
|
||||
}
|
||||
|
||||
func (manager *SDnsZoneCacheManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
|
||||
dnsZoneId, _ := data.GetString("dns_zone_id")
|
||||
if len(dnsZoneId) > 0 {
|
||||
dnsZone, err := db.FetchById(DnsZoneManager, dnsZoneId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.FetchById(DnsZoneManager, %s)", dnsZoneId)
|
||||
}
|
||||
return dnsZone.(*SDnsZone).GetOwnerId(), nil
|
||||
}
|
||||
return db.FetchProjectInfo(ctx, data)
|
||||
}
|
||||
|
||||
func (self *SDnsZoneCache) GetOwnerId() mcclient.IIdentityProvider {
|
||||
dnsZone, err := self.GetDnsZone()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return dnsZone.GetOwnerId()
|
||||
}
|
||||
|
||||
func (manager *SDnsZoneCacheManager) FilterByOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery {
|
||||
sq := DnsZoneManager.Query("id")
|
||||
sq = db.SharableManagerFilterByOwner(DnsZoneManager, sq, userCred, scope)
|
||||
return q.In("dns_zone_id", sq.SubQuery())
|
||||
}
|
||||
|
||||
func (manager *SDnsZoneCacheManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return db.IsDomainAllowList(userCred, manager)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
@@ -245,12 +246,35 @@ func (manager *SDnsZoneManager) FetchCustomizeColumns(
|
||||
return rows
|
||||
}
|
||||
|
||||
ownedVpcs := []SVpc{}
|
||||
q := VpcManager.Query()
|
||||
ownerId, queryScope, err := db.FetchCheckQueryOwnerScope(ctx, userCred, query, VpcManager, policy.PolicyActionList, true)
|
||||
if err != nil {
|
||||
log.Errorf("FetchCheckQueryOwnerScope error: %v", err)
|
||||
return rows
|
||||
}
|
||||
q = VpcManager.FilterByOwner(q, ownerId, queryScope)
|
||||
err = db.FetchModelObjects(VpcManager, q, &ownedVpcs)
|
||||
if err != nil {
|
||||
log.Errorf("db.FetchModelObjects error: %v", err)
|
||||
return rows
|
||||
}
|
||||
ownedVpcIds := map[string]bool{}
|
||||
for i := range ownedVpcs {
|
||||
ownedVpcIds[ownedVpcs[i].Id] = true
|
||||
}
|
||||
|
||||
for i := range rows {
|
||||
records, _ := recordMaps[dnsZoneIds[i]]
|
||||
rows[i].DnsRecordsetCount = len(records)
|
||||
|
||||
vpcs, _ := vpcMaps[dnsZoneIds[i]]
|
||||
rows[i].VpcCount = len(vpcs)
|
||||
rows[i].VpcCount = 0
|
||||
for j := range vpcs {
|
||||
if _, ok := ownedVpcIds[vpcs[j]]; ok {
|
||||
rows[i].VpcCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
@@ -509,6 +509,8 @@ func (self *SElasticcache) syncRemoveCloudElasticcache(ctx context.Context, user
|
||||
|
||||
self.SetDisableDelete(userCred, false)
|
||||
|
||||
self.DeleteSubResources(ctx, userCred)
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
self.SetStatus(userCred, api.ELASTIC_CACHE_STATUS_ERROR, "sync to delete")
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
||||
@@ -1252,8 +1253,9 @@ func (manager *SElasticipManager) NewEipForVMOnHost(ctx context.Context, userCre
|
||||
hostq := HostManager.Query().SubQuery()
|
||||
wireq := WireManager.Query().SubQuery()
|
||||
hostwireq := HostwireManager.Query().SubQuery()
|
||||
scope := policy.PolicyManager.AllowScope(userCred, consts.GetServiceType(), NetworkManager.KeywordPlural(), policy.PolicyActionList)
|
||||
q := NetworkManager.Query()
|
||||
q = NetworkManager.FilterByOwner(q, userCred, NetworkManager.NamespaceScope())
|
||||
q = NetworkManager.FilterByOwner(q, userCred, scope)
|
||||
q = q.Join(wireq, sqlchemy.Equals(wireq.Field("id"), q.Field("wire_id")))
|
||||
q = q.Join(hostwireq, sqlchemy.Equals(hostwireq.Field("wire_id"), wireq.Field("id")))
|
||||
q = q.Join(hostq, sqlchemy.Equals(hostq.Field("id"), host.Id))
|
||||
@@ -1263,17 +1265,21 @@ func (manager *SElasticipManager) NewEipForVMOnHost(ctx context.Context, userCre
|
||||
return nil, errors.Wrapf(err, "fetch eip networks usable in host %s(%s)",
|
||||
host.Name, host.Id)
|
||||
}
|
||||
var net *SNetwork
|
||||
for i := range nets {
|
||||
net := &nets[i]
|
||||
net = &nets[i]
|
||||
cnt, err := net.GetFreeAddressCount()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if cnt > 0 {
|
||||
eip.NetworkId = net.Id
|
||||
break
|
||||
}
|
||||
}
|
||||
if net == nil {
|
||||
return nil, errors.Error("no usable eip network")
|
||||
}
|
||||
eip.NetworkId = net.Id
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
@@ -36,6 +37,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
@@ -202,29 +204,55 @@ func (self *SExternalProject) SyncWithCloudProject(ctx context.Context, userCred
|
||||
self.Name = ext.GetName()
|
||||
self.IsEmulated = ext.IsEmulated()
|
||||
self.Status = ext.GetStatus()
|
||||
if self.DomainId == account.DomainId && account.AutoCreateProject && options.Options.EnableAutoRenameProject {
|
||||
share := account.GetSharedInfo()
|
||||
if self.DomainId != account.DomainId && !(share.PublicScope == rbacutils.ScopeSystem ||
|
||||
(share.PublicScope == rbacutils.ScopeDomain && utils.IsInStringArray(self.DomainId, share.SharedDomains))) {
|
||||
self.ProjectId = account.ProjectId
|
||||
self.DomainId = account.DomainId
|
||||
if account.AutoCreateProject {
|
||||
desc := fmt.Sprintf("auto create from cloud project %s (%s)", self.Name, self.ExternalId)
|
||||
domainId, projectId, err := account.getOrCreateTenant(ctx, self.Name, "", desc)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get or create tenant %s(%s) %v", self.Name, self.ExternalId, err)
|
||||
} else {
|
||||
self.ProjectId = projectId
|
||||
self.DomainId = domainId
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if account.AutoCreateProject && options.Options.EnableAutoRenameProject {
|
||||
tenant, err := db.TenantCacheManager.FetchTenantById(ctx, self.ProjectId)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "TenantCacheManager.FetchTenantById(%s)", self.ProjectId)
|
||||
}
|
||||
if tenant.Name != self.Name {
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion(), "v1")
|
||||
params := map[string]string{"name": self.Name}
|
||||
_, err := modules.Projects.Update(s, tenant.Id, jsonutils.Marshal(params))
|
||||
proj, err := db.TenantCacheManager.FetchTenantByName(ctx, self.Name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "update project name from %s -> %s", tenant.Name, self.Name)
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion(), "v1")
|
||||
params := map[string]string{"name": self.Name}
|
||||
_, err := modules.Projects.Update(s, tenant.Id, jsonutils.Marshal(params))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "update project name from %s -> %s", tenant.Name, self.Name)
|
||||
}
|
||||
_, err = db.Update(tenant, func() error {
|
||||
tenant.Name = self.Name
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
return errors.Wrapf(err, "FetchTenantByName(%s)", self.Name)
|
||||
}
|
||||
_, err = db.Update(tenant, func() error {
|
||||
tenant.Name = self.Name
|
||||
if proj.DomainId == account.DomainId ||
|
||||
share.PublicScope == rbacutils.ScopeSystem ||
|
||||
(share.PublicScope == rbacutils.ScopeDomain && utils.IsInStringArray(proj.DomainId, share.SharedDomains)) {
|
||||
self.ProjectId = proj.Id
|
||||
self.DomainId = proj.DomainId
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.DomainId != account.DomainId {
|
||||
self.ProjectId = account.ProjectId
|
||||
self.DomainId = account.DomainId
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -250,7 +278,7 @@ func (manager *SExternalProjectManager) newFromCloudProject(ctx context.Context,
|
||||
project.ProjectId = localProject.Id
|
||||
} else if account.AutoCreateProject {
|
||||
desc := fmt.Sprintf("auto create from cloud project %s (%s)", project.Name, project.ExternalId)
|
||||
domainId, projectId, err := getOrCreateTenant(ctx, project.Name, account.DomainId, "", desc)
|
||||
domainId, projectId, err := account.getOrCreateTenant(ctx, project.Name, "", desc)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get or create tenant %s(%s) %v", project.Name, project.ExternalId, err)
|
||||
} else {
|
||||
@@ -261,8 +289,7 @@ func (manager *SExternalProjectManager) newFromCloudProject(ctx context.Context,
|
||||
|
||||
err := manager.TableSpec().Insert(ctx, &project)
|
||||
if err != nil {
|
||||
log.Errorf("newFromCloudProject fail %s", err)
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "Insert")
|
||||
}
|
||||
|
||||
db.OpsLog.LogEvent(&project, db.ACT_CREATE, project.GetShortDesc(ctx), userCred)
|
||||
@@ -273,23 +300,38 @@ func (self *SExternalProject) AllowPerformChangeProject(ctx context.Context, use
|
||||
return db.IsAdminAllowPerform(userCred, self, "change-project")
|
||||
}
|
||||
|
||||
func (self *SExternalProject) PerformChangeProject(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
project, err := data.GetString("project")
|
||||
func (self *SExternalProject) GetCloudaccount() (*SCloudaccount, error) {
|
||||
account, err := CloudaccountManager.FetchById(self.CloudaccountId)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("project")
|
||||
return nil, errors.Wrapf(err, "CloudaccountManager.FetchById(%s)", self.CloudaccountId)
|
||||
}
|
||||
return account.(*SCloudaccount), nil
|
||||
}
|
||||
|
||||
// 切换本地项目
|
||||
func (self *SExternalProject) PerformChangeProject(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ExternalProjectChangeProjectInput) (jsonutils.JSONObject, error) {
|
||||
if len(input.ProjectId) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("project_id")
|
||||
}
|
||||
|
||||
tenant, err := db.TenantCacheManager.FetchTenantByIdOrName(ctx, project)
|
||||
tenant, err := db.TenantCacheManager.FetchTenantByIdOrName(ctx, input.ProjectId)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("project %s not found", project)
|
||||
return nil, httperrors.NewNotFoundError("project %s not found", input.ProjectId)
|
||||
}
|
||||
|
||||
if self.ProjectId == tenant.Id {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if self.DomainId != tenant.DomainId {
|
||||
return nil, httperrors.NewForbiddenError("not allow change project across domain")
|
||||
account, err := self.GetCloudaccount()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "GetCloudaccount"))
|
||||
}
|
||||
share := account.GetSharedInfo()
|
||||
|
||||
if self.DomainId != tenant.DomainId && !(tenant.DomainId == account.DomainId || share.PublicScope == rbacutils.ScopeSystem ||
|
||||
(share.PublicScope == rbacutils.ScopeDomain && utils.IsInStringArray(tenant.DomainId, share.SharedDomains))) {
|
||||
return nil, httperrors.NewForbiddenError("account %s not share for domain %s", account.Name, tenant.DomainId)
|
||||
}
|
||||
|
||||
notes := struct {
|
||||
@@ -310,11 +352,11 @@ func (self *SExternalProject) PerformChangeProject(ctx context.Context, userCred
|
||||
|
||||
_, err = db.Update(self, func() error {
|
||||
self.ProjectId = tenant.Id
|
||||
self.DomainId = tenant.DomainId
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("Update external project error: %v", err)
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "db.Update"))
|
||||
}
|
||||
|
||||
logclient.AddSimpleActionLog(self, logclient.ACT_CHANGE_OWNER, notes, userCred, true)
|
||||
|
||||
@@ -836,7 +836,11 @@ func (self *SGuest) NotifyServerEvent(
|
||||
kwargs.Add(jsonutils.NewString(self.Hypervisor), "hypervisor")
|
||||
host := self.GetHost()
|
||||
if host != nil {
|
||||
kwargs.Add(jsonutils.NewString(host.GetBrand()), "brand")
|
||||
brand := host.GetBrand()
|
||||
if brand == api.CLOUD_PROVIDER_ONECLOUD {
|
||||
brand = api.ComputeI18nTable.Lookup(ctx, brand)
|
||||
}
|
||||
kwargs.Add(jsonutils.NewString(brand), "brand")
|
||||
}
|
||||
if loginInfo {
|
||||
kwargs.Add(jsonutils.NewString(self.getNotifyIps()), "ips")
|
||||
@@ -3656,6 +3660,53 @@ func (self *SGuest) PerformRenew(ctx context.Context, userCred mcclient.TokenCre
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) GetStorages() []*SStorage {
|
||||
disks := self.GetDisks()
|
||||
storageMap := make(map[string]*SStorage)
|
||||
for i := range disks {
|
||||
storage := disks[i].GetStorage()
|
||||
if _, ok := storageMap[storage.GetId()]; !ok {
|
||||
storageMap[storage.GetId()] = storage
|
||||
}
|
||||
}
|
||||
ret := make([]*SStorage, 0, len(storageMap))
|
||||
for _, s := range storageMap {
|
||||
ret = append(ret, s)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SGuest) SyncCapacityUsedForStorage(ctx context.Context, storageIds []string) error {
|
||||
if self.Hypervisor != api.HYPERVISOR_ESXI {
|
||||
return nil
|
||||
}
|
||||
var storages []*SStorage
|
||||
if len(storageIds) == 0 {
|
||||
storages = self.GetStorages()
|
||||
} else {
|
||||
q := StorageManager.Query()
|
||||
if len(storageIds) == 1 {
|
||||
q = q.Equals("id", storageIds[0])
|
||||
} else {
|
||||
q = q.In("id", storageIds[0])
|
||||
}
|
||||
ss := make([]SStorage, 0, len(storageIds))
|
||||
err := db.FetchModelObjects(StorageManager, q, &ss)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
storages = make([]*SStorage, len(ss))
|
||||
for i := range ss {
|
||||
storages[i] = &ss[i]
|
||||
}
|
||||
}
|
||||
for _, s := range storages {
|
||||
err := s.SyncCapacityUsed(ctx)
|
||||
return errors.Wrapf(err, "unable to SyncCapacityUsed for storage %q", s.GetId())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) startGuestRenewTask(ctx context.Context, userCred mcclient.TokenCredential, duration string, parentTaskId string) error {
|
||||
self.SetStatus(userCred, api.VM_RENEWING, "")
|
||||
data := jsonutils.NewDict()
|
||||
|
||||
@@ -355,6 +355,17 @@ func (manager *SGuestManager) ListItemFilter(
|
||||
q = q.In("host_id", sq)
|
||||
}
|
||||
|
||||
if len(query.IpAddr) > 0 {
|
||||
gn := GuestnetworkManager.Query("guest_id").Contains("ip_addr", query.IpAddr).SubQuery()
|
||||
guestEip := ElasticipManager.Query("associate_id").Equals("associate_type", api.EIP_ASSOCIATE_TYPE_SERVER).Contains("ip_addr", query.IpAddr).SubQuery()
|
||||
q = q.LeftJoin(gn, sqlchemy.Equals(q.Field("id"), gn.Field("guest_id")))
|
||||
q = q.LeftJoin(guestEip, sqlchemy.Equals(q.Field("id"), guestEip.Field("associate_id")))
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsNotNull(gn.Field("guest_id")),
|
||||
sqlchemy.IsNotNull(guestEip.Field("associate_id")),
|
||||
))
|
||||
}
|
||||
|
||||
diskFilter := query.AttachableServersForDisk
|
||||
if len(diskFilter) > 0 {
|
||||
diskI, _ := DiskManager.FetchByIdOrName(userCred, diskFilter)
|
||||
|
||||
+139
-7
@@ -33,6 +33,7 @@ import (
|
||||
"yunion.io/x/pkg/util/fileutils"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/util/sets"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
@@ -1142,8 +1143,8 @@ func (self *SHost) GetSpec(statusCheck bool) *jsonutils.JSONDict {
|
||||
if model == "" {
|
||||
model = "Unknown"
|
||||
}
|
||||
specInfo.Manufacture = manufacture
|
||||
specInfo.Model = model
|
||||
specInfo.Manufacture = strings.ReplaceAll(manufacture, " ", "_")
|
||||
specInfo.Model = strings.ReplaceAll(model, " ", "_")
|
||||
devices := IsolatedDeviceManager.FindByHost(self.Id)
|
||||
if len(devices) > 0 {
|
||||
specInfo.IsolatedDevices = make([]api.IsolatedDeviceSpec, len(devices))
|
||||
@@ -1735,6 +1736,11 @@ func (self *SHost) syncWithCloudHost(ctx context.Context, userCred mcclient.Toke
|
||||
self.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
|
||||
}
|
||||
|
||||
if err := self.syncSchedtags(ctx, userCred, extHost); err != nil {
|
||||
log.Errorf("syncSchedtags fail: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := HostManager.ClearSchedDescCache(self.Id); err != nil {
|
||||
log.Errorf("ClearSchedDescCache for host %s error %v", self.Name, err)
|
||||
}
|
||||
@@ -1766,6 +1772,131 @@ func (self *SHost) syncWithCloudPrepaidVM(extVM cloudprovider.ICloudVM, host *SH
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
METADATA_EXT_SCHEDTAG_KEY = "ext:schedtag"
|
||||
)
|
||||
|
||||
func (s *SHost) getAllSchedtagsWithExtSchedtagKey(ctx context.Context, userCred mcclient.TokenCredential) (map[string]*SSchedtag, error) {
|
||||
q := SchedtagManager.Query().Equals("resource_type", HostManager.KeywordPlural())
|
||||
sts := make([]SSchedtag, 0, 5)
|
||||
err := db.FetchModelObjects(SchedtagManager, q, &sts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stMap := make(map[string]*SSchedtag)
|
||||
for i := range sts {
|
||||
extTagName := sts[i].GetMetadata(METADATA_EXT_SCHEDTAG_KEY, userCred)
|
||||
if len(extTagName) == 0 {
|
||||
continue
|
||||
}
|
||||
stMap[extTagName] = &sts[i]
|
||||
}
|
||||
return stMap, nil
|
||||
}
|
||||
|
||||
func (s *SHost) syncSchedtags(ctx context.Context, userCred mcclient.TokenCredential, extHost cloudprovider.ICloudHost) error {
|
||||
stq := SchedtagManager.Query()
|
||||
subq := HostschedtagManager.Query("schedtag_id").Equals("host_id", s.Id).SubQuery()
|
||||
stq = stq.Join(subq, sqlchemy.Equals(stq.Field("id"), subq.Field("schedtag_id")))
|
||||
schedtags := make([]SSchedtag, 0)
|
||||
err := db.FetchModelObjects(SchedtagManager, stq, &schedtags)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
extSchedtagStrs, err := extHost.GetSchedtags()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "extHost.GetSchedtags")
|
||||
}
|
||||
extStStrSet := sets.NewString(extSchedtagStrs...)
|
||||
removed := make([]*SSchedtag, 0)
|
||||
removedIds := make([]string, 0)
|
||||
for i := range schedtags {
|
||||
stag := &schedtags[i]
|
||||
extTagName := stag.GetMetadata(METADATA_EXT_SCHEDTAG_KEY, userCred)
|
||||
if len(extTagName) == 0 {
|
||||
continue
|
||||
}
|
||||
if !extStStrSet.Has(extTagName) {
|
||||
removed = append(removed, stag)
|
||||
removedIds = append(removedIds, stag.GetId())
|
||||
} else {
|
||||
extStStrSet.Delete(extTagName)
|
||||
}
|
||||
}
|
||||
added := extStStrSet.UnsortedList()
|
||||
|
||||
var stagMap map[string]*SSchedtag
|
||||
if len(added) > 0 {
|
||||
stagMap, err = s.getAllSchedtagsWithExtSchedtagKey(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getAllSchedtagsWithExtSchedtagKey")
|
||||
}
|
||||
}
|
||||
|
||||
for _, stStr := range added {
|
||||
st, ok := stagMap[stStr]
|
||||
if !ok {
|
||||
st = &SSchedtag{
|
||||
ResourceType: HostManager.KeywordPlural(),
|
||||
}
|
||||
st.DomainId = s.DomainId
|
||||
st.Name = stStr
|
||||
st.Description = "Sync from cloud"
|
||||
err := SchedtagManager.TableSpec().Insert(ctx, st)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to create schedtag %q", stStr)
|
||||
}
|
||||
st.SetModelManager(SchedtagManager, st)
|
||||
st.SetMetadata(ctx, METADATA_EXT_SCHEDTAG_KEY, stStr, userCred)
|
||||
}
|
||||
// attach
|
||||
hostschedtag := &SHostschedtag{
|
||||
HostId: s.GetId(),
|
||||
}
|
||||
hostschedtag.SchedtagId = st.GetId()
|
||||
err = HostschedtagManager.TableSpec().Insert(ctx, hostschedtag)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to create hostschedtag for tag %q host %q", stStr, s.GetId())
|
||||
}
|
||||
}
|
||||
|
||||
if len(removedIds) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
q := HostschedtagManager.Query().Equals("host_id", s.GetId()).In("schedtag_id", removedIds)
|
||||
hostschedtags := make([]SHostschedtag, 0, len(removedIds))
|
||||
err = db.FetchModelObjects(HostschedtagManager, q, &hostschedtags)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "db.FetchModelObject")
|
||||
}
|
||||
for i := range hostschedtags {
|
||||
err = hostschedtags[i].Detach(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to detach host %q and schedtag %q", hostschedtags[i].HostId, hostschedtags[i].SchedtagId)
|
||||
}
|
||||
}
|
||||
|
||||
// try to clean
|
||||
for _, tag := range removed {
|
||||
cnt, err := tag.GetObjectCount()
|
||||
if err != nil {
|
||||
log.Errorf("unable to GetObjectCount for schedtag %q: %v", tag.GetName(), err)
|
||||
continue
|
||||
}
|
||||
if cnt > 0 {
|
||||
continue
|
||||
}
|
||||
err = tag.Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
log.Errorf("unable to delete schedtag %q: %v", tag.GetName(), err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SHostManager) newFromCloudHost(ctx context.Context, userCred mcclient.TokenCredential, extHost cloudprovider.ICloudHost, provider *SCloudprovider, izone *SZone) (*SHost, error) {
|
||||
host := SHost{}
|
||||
host.SetModelManager(manager, &host)
|
||||
@@ -1844,6 +1975,11 @@ func (manager *SHostManager) newFromCloudHost(ctx context.Context, userCred mccl
|
||||
|
||||
SyncCloudDomain(userCred, &host, provider.GetOwnerId())
|
||||
|
||||
if err := host.syncSchedtags(ctx, userCred, extHost); err != nil {
|
||||
log.Errorf("newFromCloudHost fail in syncSchedtags %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if provider != nil {
|
||||
host.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
|
||||
}
|
||||
@@ -2536,11 +2672,7 @@ func (self *SHost) GetIHostAndProvider() (cloudprovider.ICloudHost, cloudprovide
|
||||
}
|
||||
ihost, err := iregion.GetIHostById(self.ExternalId)
|
||||
if err != nil {
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
return nil, nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
log.Errorf("fail to find ihost by id %s %s", self.ExternalId, err)
|
||||
return nil, nil, fmt.Errorf("fail to find ihost by id %s", err)
|
||||
return nil, nil, errors.Wrapf(err, "iregion.GetIHostById(%s)", self.ExternalId)
|
||||
}
|
||||
return ihost, provider, nil
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ func init() {
|
||||
"schedtaghost",
|
||||
"schedtaghosts",
|
||||
HostManager,
|
||||
SchedtagManager,
|
||||
),
|
||||
}
|
||||
HostschedtagManager.SetVirtualObject(HostschedtagManager)
|
||||
@@ -57,7 +56,7 @@ type SHostschedtag struct {
|
||||
HostId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"admin_required"` // Column(VARCHAR(36, charset='ascii'), nullable=False)
|
||||
}
|
||||
|
||||
func (manager *SHostschedtagManager) GetSlaveFieldName() string {
|
||||
func (manager *SHostschedtagManager) GetMasterFieldName() string {
|
||||
return "host_id"
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,10 @@ func InitDB() error {
|
||||
ExternalProjectManager,
|
||||
CachedimageManager,
|
||||
StoragecachedimageManager,
|
||||
NetworkinterfacenetworkManager,
|
||||
DBInstanceNetworkManager,
|
||||
DBInstanceAccountManager,
|
||||
DBInstanceDatabaseManager,
|
||||
} {
|
||||
err := manager.InitializeData()
|
||||
if err != nil {
|
||||
|
||||
@@ -75,6 +75,12 @@ func (self *SLoadbalancerResourceBase) GetCloudprovider() *SCloudprovider {
|
||||
if vpc != nil {
|
||||
return vpc.GetCloudprovider()
|
||||
}
|
||||
|
||||
lb := self.GetLoadbalancer()
|
||||
if lb != nil {
|
||||
return lb.GetCloudprovider()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -436,10 +436,7 @@ func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.IClou
|
||||
ChargeType: lb.ChargeType,
|
||||
LoadbalancerSpec: lb.LoadbalancerSpec,
|
||||
}
|
||||
iRegion, err := lb.GetIRegion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(lb.ZoneId) > 0 {
|
||||
zone := lb.GetZone()
|
||||
if zone == nil {
|
||||
@@ -447,7 +444,7 @@ func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.IClou
|
||||
}
|
||||
iZone, err := iRegion.GetIZoneById(zone.ExternalId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "GetIZoneById")
|
||||
}
|
||||
params.ZoneID = iZone.GetId()
|
||||
}
|
||||
@@ -462,7 +459,7 @@ func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.IClou
|
||||
}
|
||||
iVpc, err := iRegion.GetIVpcById(vpc.ExternalId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "GetIVpcById")
|
||||
}
|
||||
params.VpcID = iVpc.GetId()
|
||||
}
|
||||
@@ -476,7 +473,7 @@ func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.IClou
|
||||
for i := range networks {
|
||||
iNetwork, err := networks[i].GetINetwork()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "GetINetwork")
|
||||
}
|
||||
params.NetworkIDs = append(params.NetworkIDs, iNetwork.GetId())
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
@@ -228,3 +229,23 @@ func (self *SNetworkinterfacenetwork) GetDetailJson() (jsonutils.JSONObject, err
|
||||
"network": network.Name,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkinterfacenetworkManager) InitializeData() error {
|
||||
sq := NetworkInterfaceManager.Query("id")
|
||||
q := manager.Query().NotIn("networkinterface_id", sq.SubQuery())
|
||||
networks := []SNetworkinterfacenetwork{}
|
||||
err := db.FetchModelObjects(manager, q, &networks)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
for i := range networks {
|
||||
_, err = db.Update(&networks[i], func() error {
|
||||
return networks[i].MarkDelete()
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Delete %d", networks[i].RowId)
|
||||
}
|
||||
}
|
||||
log.Debugf("SNetworkinterfacenetworkManager cleaned %d deprecated networkinterface ipAddrs.", len(networks))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -286,8 +286,21 @@ func (self *SNetworkInterface) syncRemoveCloudNetworkInterface(ctx context.Conte
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return self.SetStatus(userCred, api.NETWORK_INTERFACE_STATUS_UNKNOWN, "sync to delete")
|
||||
self.SetStatus(userCred, api.NETWORK_INTERFACE_STATUS_UNKNOWN, "sync to delete")
|
||||
return errors.Wrapf(err, "ValidateDeleteCondition")
|
||||
}
|
||||
|
||||
networks, err := self.GetNetworks()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetNetworks")
|
||||
}
|
||||
for i := range networks {
|
||||
err = networks[i].Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Delete networkinterfacenetwork %d", networks[i].RowId)
|
||||
}
|
||||
}
|
||||
|
||||
return self.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
|
||||
@@ -159,17 +159,18 @@ func (self *SNetwork) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return httperrors.NewInternalServerError("GetAllocatedNicCount fail %s", err)
|
||||
}
|
||||
if cnt > 0 {
|
||||
return httperrors.NewNotEmptyError("not an empty network")
|
||||
if cnt.Total > 0 {
|
||||
return httperrors.NewNotEmptyError("not an empty network %s", jsonutils.Marshal(cnt).String())
|
||||
}
|
||||
return self.SSharableVirtualResourceBase.ValidateDeleteCondition(ctx)
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetTotalNicCount() (int, error) {
|
||||
total, err := self.GetAllocatedNicCount()
|
||||
count, err := self.GetAllocatedNicCount()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
total := count.Total
|
||||
cnt, err := self.GetReservedNicsCount()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
@@ -183,39 +184,50 @@ func (self *SNetwork) GetTotalNicCount() (int, error) {
|
||||
return total, nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetAllocatedNicCount() (int, error) {
|
||||
total := 0
|
||||
cnt, err := self.GetGuestnicsCount()
|
||||
type sNicCount struct {
|
||||
GuestNicCount int
|
||||
GroupNicCount int
|
||||
BaremetalNicCount int
|
||||
LoadbalancerNicCount int
|
||||
DBInstanceNicCount int
|
||||
EipNicCount int
|
||||
Total int
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetAllocatedNicCount() (*sNicCount, error) {
|
||||
cnt := &sNicCount{Total: 0}
|
||||
var err error
|
||||
cnt.GuestNicCount, err = self.GetGuestnicsCount()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return nil, errors.Wrapf(err, "GetGuestnicsCount")
|
||||
}
|
||||
total += cnt
|
||||
cnt, err = self.GetGroupNicsCount()
|
||||
cnt.Total += cnt.GuestNicCount
|
||||
cnt.GroupNicCount, err = self.GetGroupNicsCount()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return nil, errors.Wrapf(err, "GetGroupNicsCount")
|
||||
}
|
||||
total += cnt
|
||||
cnt, err = self.GetBaremetalNicsCount()
|
||||
cnt.Total += cnt.GroupNicCount
|
||||
cnt.BaremetalNicCount, err = self.GetBaremetalNicsCount()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return nil, errors.Wrapf(err, "GetBaremetalNicsCount")
|
||||
}
|
||||
total += cnt
|
||||
cnt, err = self.GetLoadbalancerIpsCount()
|
||||
cnt.Total += cnt.BaremetalNicCount
|
||||
cnt.LoadbalancerNicCount, err = self.GetLoadbalancerIpsCount()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return nil, errors.Wrapf(err, "GetLoadbalancerIpsCount")
|
||||
}
|
||||
total += cnt
|
||||
cnt, err = self.GetDBInstanceIpsCount()
|
||||
cnt.Total += cnt.LoadbalancerNicCount
|
||||
cnt.DBInstanceNicCount, err = self.GetDBInstanceIpsCount()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return nil, errors.Wrapf(err, "GetDBInstanceIpsCount")
|
||||
}
|
||||
total += cnt
|
||||
cnt, err = self.GetEipsCount()
|
||||
cnt.Total += cnt.DBInstanceNicCount
|
||||
cnt.EipNicCount, err = self.GetEipsCount()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return nil, errors.Wrapf(err, "GetEipsCount")
|
||||
}
|
||||
total += cnt
|
||||
return total, nil
|
||||
cnt.Total += cnt.EipNicCount
|
||||
return cnt, nil
|
||||
}
|
||||
|
||||
/*验证elb network可用,并返回关联的region, zone,vpc, wire*/
|
||||
@@ -298,6 +310,16 @@ func (self *SNetwork) GetLoadbalancerIpsCount() (int, error) {
|
||||
return LoadbalancernetworkManager.Query().Equals("network_id", self.Id).CountWithError()
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetDBInstanceNetworks() ([]SDBInstanceNetwork, error) {
|
||||
q := DBInstanceNetworkManager.Query().Equals("network_id", self.Id)
|
||||
networks := []SDBInstanceNetwork{}
|
||||
err := db.FetchModelObjects(DBInstanceNetworkManager, q, &networks)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetDBInstanceIpsCount() (int, error) {
|
||||
return DBInstanceNetworkManager.Query().Equals("network_id", self.Id).CountWithError()
|
||||
}
|
||||
@@ -1988,6 +2010,21 @@ func (manager *SNetworkManager) ListItemFilter(
|
||||
q = q.In("id", subq.SubQuery())
|
||||
}
|
||||
|
||||
if len(input.HostSchedtagId) > 0 {
|
||||
schedTagObj, err := SchedtagManager.FetchByIdOrName(userCred, input.HostSchedtagId)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", SchedtagManager.Keyword(), input.HostSchedtagId)
|
||||
} else {
|
||||
return nil, errors.Wrap(err, "SchedtagManager.FetchByIdOrName")
|
||||
}
|
||||
}
|
||||
subq := HostwireManager.Query("wire_id")
|
||||
hostschedtags := HostschedtagManager.Query().Equals("schedtag_id", schedTagObj.GetId()).SubQuery()
|
||||
subq = subq.Join(hostschedtags, sqlchemy.Equals(hostschedtags.Field("host_id"), subq.Field("host_id")))
|
||||
q = q.In("wire_id", subq.SubQuery())
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ func init() {
|
||||
"schedtagnetwork",
|
||||
"schedtagnetworks",
|
||||
NetworkManager,
|
||||
SchedtagManager,
|
||||
),
|
||||
}
|
||||
NetworkschedtagManager.SetVirtualObject(NetworkschedtagManager)
|
||||
@@ -57,7 +56,7 @@ type SNetworkschedtag struct {
|
||||
NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"admin_required"` // Column(VARCHAR(36, charset='ascii'), nullable=False)
|
||||
}
|
||||
|
||||
func (manager *SNetworkschedtagManager) GetSlaveFieldName() string {
|
||||
func (manager *SNetworkschedtagManager) GetMasterFieldName() string {
|
||||
return "network_id"
|
||||
}
|
||||
|
||||
|
||||
+38
-15
@@ -16,6 +16,7 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/log"
|
||||
@@ -881,6 +882,20 @@ func (nic *SNetworkInterface) purge(ctx context.Context, userCred mcclient.Token
|
||||
return nic.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (net *SNetwork) purgeDBInstanceNetworks(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
dbNets, err := net.GetDBInstanceNetworks()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetDBInstanceNetworks")
|
||||
}
|
||||
for i := range dbNets {
|
||||
err = dbNets[i].Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Delete %d", dbNets[i].RowId)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (net *SNetwork) purgeNetworkInterfaces(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
networkinterfaceIds := NetworkinterfacenetworkManager.Query("networkinterface_id").Equals("network_id", net.Id).Distinct().SubQuery()
|
||||
q := NetworkInterfaceManager.Query().In("id", networkinterfaceIds)
|
||||
@@ -904,37 +919,42 @@ func (net *SNetwork) purge(ctx context.Context, userCred mcclient.TokenCredentia
|
||||
|
||||
err := net.purgeGuestnetworks(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeGuestnetworks")
|
||||
}
|
||||
err = net.purgeHostnetworks(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeHostnetworks")
|
||||
}
|
||||
err = net.purgeGroupnetworks(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeGroupnetworks")
|
||||
}
|
||||
err = net.purgeLoadbalancernetworks(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeLoadbalancernetworks")
|
||||
}
|
||||
err = net.purgeEipnetworks(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeEipnetworks")
|
||||
}
|
||||
err = net.purgeReservedIps(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeReservedIps")
|
||||
}
|
||||
|
||||
err = net.purgeNetworkInterfaces(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeNetworkInterfaces")
|
||||
}
|
||||
|
||||
err = net.purgeDBInstanceNetworks(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "purgeDBInstanceNetworks")
|
||||
}
|
||||
|
||||
err = net.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "ValidateDeleteCondition")
|
||||
}
|
||||
return net.RealDelete(ctx, userCred)
|
||||
}
|
||||
@@ -1334,13 +1354,16 @@ func (network *SDBInstanceNetwork) purge(ctx context.Context, userCred mcclient.
|
||||
|
||||
err := network.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "ValidateDeleteCondition")
|
||||
}
|
||||
return network.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (instance *SDBInstance) purgeNetwork(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
network, _ := instance.GetDBNetwork()
|
||||
network, err := instance.GetDBNetwork()
|
||||
if err != nil && errors.Cause(err) != sql.ErrNoRows {
|
||||
return errors.Wrapf(err, "GetDBNetwork")
|
||||
}
|
||||
if network != nil {
|
||||
return network.purge(ctx, userCred)
|
||||
}
|
||||
@@ -1369,22 +1392,22 @@ func (instance *SDBInstance) Purge(ctx context.Context, userCred mcclient.TokenC
|
||||
|
||||
err := instance.purgeAccounts(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeAccounts")
|
||||
}
|
||||
|
||||
err = instance.purgeDatabases(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeDatabases")
|
||||
}
|
||||
|
||||
err = instance.purgeParameters(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeParameters")
|
||||
}
|
||||
|
||||
err = instance.purgeNetwork(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "purgeNetwork")
|
||||
}
|
||||
|
||||
err = instance.PurgeBackups(ctx, userCred, api.BACKUP_MODE_AUTOMATED)
|
||||
@@ -1394,7 +1417,7 @@ func (instance *SDBInstance) Purge(ctx context.Context, userCred mcclient.TokenC
|
||||
|
||||
err = instance.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "ValidateDeleteCondition")
|
||||
}
|
||||
|
||||
return instance.RealDelete(ctx, userCred)
|
||||
|
||||
@@ -55,6 +55,10 @@ type SScalingGroupGuest struct {
|
||||
Manual tristate.TriState `nullable:"false" default:"false"`
|
||||
}
|
||||
|
||||
func (sggm *SScalingGroupGuestManager) GetSlaveFieldName() string {
|
||||
return "scaling_group_id"
|
||||
}
|
||||
|
||||
func (sggm *SScalingGroupGuestManager) Attach(ctx context.Context, scaligGroupId, guestId string, manual bool) error {
|
||||
sgg := &SScalingGroupGuest{
|
||||
SGuestJointsBase: SGuestJointsBase{
|
||||
|
||||
@@ -44,7 +44,6 @@ func NewSchedtagJointsManager(
|
||||
keyword string,
|
||||
keywordPlural string,
|
||||
master db.IStandaloneModelManager,
|
||||
slave db.IStandaloneModelManager,
|
||||
) *SSchedtagJointsManager {
|
||||
return &SSchedtagJointsManager{
|
||||
SJointResourceBaseManager: db.NewJointResourceBaseManager(
|
||||
@@ -53,7 +52,7 @@ func NewSchedtagJointsManager(
|
||||
keyword,
|
||||
keywordPlural,
|
||||
master,
|
||||
slave,
|
||||
SchedtagManager,
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -64,7 +63,7 @@ type SSchedtagJointsBase struct {
|
||||
SchedtagId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"admin_required"` // =Column(VARCHAR(36, charset='ascii'), nullable=False)
|
||||
}
|
||||
|
||||
func (manager *SSchedtagJointsManager) GetMasterFieldName() string {
|
||||
func (manager *SSchedtagJointsManager) GetSlaveFieldName() string {
|
||||
return "schedtag_id"
|
||||
}
|
||||
|
||||
@@ -118,7 +117,7 @@ func (man *SSchedtagJointsManager) AllowListDescendent(ctx context.Context, user
|
||||
return db.IsAdminAllowList(userCred, man)
|
||||
}
|
||||
|
||||
func (man *SSchedtagJointsManager) GetMasterIdKey(m db.IJointModelManager) string {
|
||||
func (man *SSchedtagJointsManager) GetResourceIdKey(m db.IJointModelManager) string {
|
||||
return fmt.Sprintf("%s_id", m.GetMasterManager().Keyword())
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ var STRATEGY_LIST = api.STRATEGY_LIST
|
||||
|
||||
type ISchedtagJointManager interface {
|
||||
db.IJointModelManager
|
||||
GetMasterIdKey(db.IJointModelManager) string
|
||||
GetResourceIdKey(db.IJointModelManager) string
|
||||
}
|
||||
|
||||
type ISchedtagJointModel interface {
|
||||
@@ -367,7 +367,7 @@ func (self *SSchedtag) GetObjectQuery() *sqlchemy.SQuery {
|
||||
objs := masterMan.Query().SubQuery()
|
||||
objschedtags := jointMan.Query().SubQuery()
|
||||
q := objs.Query()
|
||||
q = q.Join(objschedtags, sqlchemy.AND(sqlchemy.Equals(objschedtags.Field(jointMan.GetMasterIdKey(jointMan)), objs.Field("id")),
|
||||
q = q.Join(objschedtags, sqlchemy.AND(sqlchemy.Equals(objschedtags.Field(jointMan.GetResourceIdKey(jointMan)), objs.Field("id")),
|
||||
sqlchemy.IsFalse(objschedtags.Field("deleted"))))
|
||||
// q = q.Filter(sqlchemy.IsTrue(objs.Field("enabled")))
|
||||
q = q.Filter(sqlchemy.Equals(objschedtags.Field("schedtag_id"), self.Id))
|
||||
@@ -469,7 +469,7 @@ func (self *SSchedtag) GetShortDescV2(ctx context.Context) api.SchedtagShortDesc
|
||||
|
||||
func GetResourceJointSchedtags(obj IModelWithSchedtag) ([]ISchedtagJointModel, error) {
|
||||
jointMan := obj.GetSchedtagJointManager()
|
||||
q := jointMan.Query().Equals(jointMan.GetMasterIdKey(jointMan), obj.GetId())
|
||||
q := jointMan.Query().Equals(jointMan.GetResourceIdKey(jointMan), obj.GetId())
|
||||
jointTags := make([]ISchedtagJointModel, 0)
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
@@ -501,7 +501,7 @@ func GetSchedtags(jointMan ISchedtagJointManager, masterId string) []SSchedtag {
|
||||
q := schedtags.Query()
|
||||
q = q.Join(objschedtags, sqlchemy.AND(sqlchemy.Equals(objschedtags.Field("schedtag_id"), schedtags.Field("id")),
|
||||
sqlchemy.IsFalse(objschedtags.Field("deleted"))))
|
||||
q = q.Filter(sqlchemy.Equals(objschedtags.Field(jointMan.GetMasterIdKey(jointMan)), masterId))
|
||||
q = q.Filter(sqlchemy.Equals(objschedtags.Field(jointMan.GetResourceIdKey(jointMan)), masterId))
|
||||
err := db.FetchModelObjects(SchedtagManager, q, &tags)
|
||||
if err != nil {
|
||||
log.Errorf("GetSchedtags error: %s", err)
|
||||
@@ -553,7 +553,7 @@ func PerformSetResourceSchedtag(obj IModelWithSchedtag, ctx context.Context, use
|
||||
if newTagObj, err := db.NewModelObject(jointMan); err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
} else {
|
||||
objectKey := jointMan.GetMasterIdKey(jointMan)
|
||||
objectKey := jointMan.GetResourceIdKey(jointMan)
|
||||
createData := jsonutils.NewDict()
|
||||
createData.Add(jsonutils.NewString(setTagId), "schedtag_id")
|
||||
createData.Add(jsonutils.NewString(obj.GetId()), objectKey)
|
||||
|
||||
@@ -484,7 +484,7 @@ func (spc *SSnapshotPolicyCache) DeleteCloudSnapshotPolicy() error {
|
||||
return err
|
||||
}
|
||||
cloudSp, err := iregion.GetISnapshotPolicyById(spc.ExternalId)
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -74,7 +74,7 @@ type SStorage struct {
|
||||
Capacity int64 `nullable:"false" list:"domain" update:"domain" create:"domain_required"`
|
||||
// 实际容量大小,单位Mb
|
||||
// we always expect actual capacity great or equal than zero, otherwise something wrong
|
||||
ActualCapacity int64 `nullable:"true" list:"domain" update:"domain" create:"domain_optional"`
|
||||
ActualCapacityUsed int64 `nullable:"true" list:"domain" update:"domain" create:"domain_optional"`
|
||||
// 预留容量大小
|
||||
Reserved int64 `nullable:"true" default:"0" list:"domain" update:"domain"`
|
||||
// 存储类型
|
||||
@@ -412,7 +412,7 @@ func (self *SStorage) getStorageCapacity() SStorageCapacity {
|
||||
capa.Used = self.GetUsedCapacity(tristate.True)
|
||||
capa.Wasted = self.GetUsedCapacity(tristate.False)
|
||||
capa.VCapacity = int64(float32(self.GetCapacity()) * self.GetOvercommitBound())
|
||||
capa.ActualUsed = self.ActualCapacity
|
||||
capa.ActualUsed = self.ActualCapacityUsed
|
||||
|
||||
return capa
|
||||
}
|
||||
@@ -758,6 +758,58 @@ func (self *SStorage) syncRemoveCloudStorage(ctx context.Context, userCred mccli
|
||||
return err
|
||||
}
|
||||
|
||||
var CapacityUsedCloudStorageProvider = []string{
|
||||
api.CLOUD_PROVIDER_VMWARE,
|
||||
}
|
||||
|
||||
func (sm *SStorageManager) SyncCapacityUsedForStorage(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
cpSubQ := CloudproviderManager.Query("id").In("provider", CapacityUsedCloudStorageProvider).SubQuery()
|
||||
sQ := sm.Query()
|
||||
sQ = sQ.Join(cpSubQ, sqlchemy.Equals(sQ.Field("manager_id"), cpSubQ.Field("id")))
|
||||
storages := make([]SStorage, 0, 5)
|
||||
err := db.FetchModelObjects(sm, sQ, &storages)
|
||||
if err != nil {
|
||||
log.Errorf("unable to fetch storages with sql %q: %v", sQ.String(), err)
|
||||
}
|
||||
for i := range storages {
|
||||
err := storages[i].SyncCapacityUsed(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("unable to sync CapacityUsed for storage %q: %v", storages[i].Id, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SStorage) SyncCapacityUsed(ctx context.Context) error {
|
||||
cp := s.GetCloudprovider()
|
||||
if cp == nil {
|
||||
return errors.Wrapf(errors.ErrNotFound, "no cloudprovider for storage %s", s.Id)
|
||||
}
|
||||
if !utils.IsInStringArray(cp.Provider, CapacityUsedCloudStorageProvider) {
|
||||
return nil
|
||||
}
|
||||
icp, err := cp.GetProvider()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetProvider")
|
||||
}
|
||||
iregion, err := icp.GetOnPremiseIRegion()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetOnPremiseIRegion")
|
||||
}
|
||||
cloudStorage, err := iregion.GetIStorageById(s.ExternalId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetIStorageById")
|
||||
}
|
||||
capacityUsed := cloudStorage.GetCapacityUsedMB()
|
||||
if s.ActualCapacityUsed == capacityUsed {
|
||||
return nil
|
||||
}
|
||||
_, err = db.UpdateWithLock(ctx, s, func() error {
|
||||
s.ActualCapacityUsed = capacityUsed
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SStorage) syncWithCloudStorage(ctx context.Context, userCred mcclient.TokenCredential, extStorage cloudprovider.ICloudStorage, provider *SCloudprovider) error {
|
||||
diff, err := db.UpdateWithLock(ctx, self, func() error {
|
||||
// self.Name = extStorage.GetName()
|
||||
@@ -767,6 +819,9 @@ func (self *SStorage) syncWithCloudStorage(ctx context.Context, userCred mcclien
|
||||
if capacity := extStorage.GetCapacityMB(); capacity != 0 {
|
||||
self.Capacity = capacity
|
||||
}
|
||||
if capacity := extStorage.GetCapacityUsedMB(); capacity != 0 {
|
||||
self.ActualCapacityUsed = capacity
|
||||
}
|
||||
self.StorageConf = extStorage.GetStorageConf()
|
||||
|
||||
self.Enabled = tristate.NewFromBool(extStorage.GetEnabled())
|
||||
@@ -807,6 +862,7 @@ func (manager *SStorageManager) newFromCloudStorage(ctx context.Context, userCre
|
||||
storage.MediumType = extStorage.GetMediumType()
|
||||
storage.StorageConf = extStorage.GetStorageConf()
|
||||
storage.Capacity = extStorage.GetCapacityMB()
|
||||
storage.ActualCapacityUsed = extStorage.GetCapacityUsedMB()
|
||||
storage.Cmtbound = 1.0
|
||||
|
||||
storage.Enabled = tristate.NewFromBool(extStorage.GetEnabled())
|
||||
|
||||
@@ -44,7 +44,6 @@ func init() {
|
||||
"schedtagstorage",
|
||||
"schedtagstorages",
|
||||
StorageManager,
|
||||
SchedtagManager,
|
||||
),
|
||||
}
|
||||
StorageschedtagManager.SetVirtualObject(StorageschedtagManager)
|
||||
@@ -57,7 +56,7 @@ type SStorageschedtag struct {
|
||||
StorageId string `width:"36" charset:"ascii" nullable:"false" list:"admin" create:"admin_required"` // Column(VARCHAR(36, charset='ascii'), nullable=False)
|
||||
}
|
||||
|
||||
func (manager *SStorageschedtagManager) GetSlaveFieldName() string {
|
||||
func (manager *SStorageschedtagManager) GetMasterFieldName() string {
|
||||
return "storage_id"
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +143,8 @@ type ComputeOptions struct {
|
||||
|
||||
EnableAutoRenameProject bool `help:"when it set true, auto create project will rename when cloud project name changed" default:"false"`
|
||||
|
||||
SyncStorageCapacityUsedIntervalMinutes int `help:"interval sync storage capacity used" default:"10"`
|
||||
|
||||
SCapabilityOptions
|
||||
SASControllerOptions
|
||||
common_options.CommonOptions
|
||||
|
||||
@@ -1914,7 +1914,7 @@ func (self *SHuaWeiRegionDriver) RequestCreateLoadbalancer(ctx context.Context,
|
||||
}
|
||||
|
||||
eip, err := db.FetchByExternalIdAndManagerId(models.ElasticipManager, ieip.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", lb.MarkUnDelete)
|
||||
return q.Equals("manager_id", lb.ManagerId)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Huawei.RequestCreateLoadbalancer.FetchByExternalId")
|
||||
|
||||
@@ -135,6 +135,8 @@ func StartService() {
|
||||
cron.AddJobAtIntervalsWithStartRun("AutoSyncCloudaccountTask", time.Duration(opts.CloudAutoSyncIntervalSeconds)*time.Second, models.CloudaccountManager.AutoSyncCloudaccountTask, true)
|
||||
cron.AddJobAtIntervalsWithStartRun("ReconcileBackupGuests", time.Duration(opts.ReconcileGuestBackupIntervalSeconds)*time.Second, models.GuestManager.ReconcileBackupGuests, true)
|
||||
|
||||
cron.AddJobAtIntervalsWithStartRun("SyncCapacityUsedForStorage", time.Duration(opts.SyncStorageCapacityUsedIntervalMinutes)*time.Minute, models.StorageManager.SyncCapacityUsedForStorage, true)
|
||||
|
||||
cron.AddJobEveryFewHour("AutoDiskSnapshot", 1, 5, 0, models.DiskManager.AutoDiskSnapshot, false)
|
||||
cron.AddJobEveryFewHour("SnapshotsCleanup", 1, 35, 0, models.SnapshotManager.CleanupSnapshots, false)
|
||||
cron.AddJobEveryFewHour("AutoSyncExtDiskSnapshot", 1, 10, 0, models.DiskManager.AutoSyncExtDiskSnapshot, false)
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/sets"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/appctx"
|
||||
@@ -200,7 +201,7 @@ func handleQueryModel(
|
||||
return nil, err
|
||||
}
|
||||
objs := QueryObjects(manager, objects, specKeys, isOkF, statusCheck)
|
||||
return QueryObjectsToJson(objs, ctx, userCred, query)
|
||||
return QueryObjectsToJson(manager, objs, ctx, userCred, query)
|
||||
}
|
||||
|
||||
func QueryObjects(
|
||||
@@ -231,15 +232,23 @@ func QueryObjects(
|
||||
return selectedObjs
|
||||
}
|
||||
|
||||
func QueryObjectsToJson(objs []models.ISpecModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
func QueryObjectsToJson(manager models.ISpecModelManager, objs []models.ISpecModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
iObjs := make([]interface{}, len(objs))
|
||||
for i := range objs {
|
||||
iObjs[i] = objs[i]
|
||||
}
|
||||
details, err := db.FetchCustomizeColumns(manager, ctx, userCred, query, iObjs, nil, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "get %s details", manager.KeywordPlural())
|
||||
}
|
||||
ret := jsonutils.NewArray()
|
||||
for _, obj := range objs {
|
||||
for idx, obj := range objs {
|
||||
jsonData := jsonutils.Marshal(obj)
|
||||
jsonDict, ok := jsonData.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Invalid model data structure, not a dict")
|
||||
}
|
||||
extraDict, _ := db.GetExtraDetails(obj, ctx, userCred, query, false)
|
||||
extraDict := details[idx]
|
||||
if extraDict != nil {
|
||||
jsonDict.Update(extraDict)
|
||||
}
|
||||
|
||||
@@ -157,5 +157,5 @@ func (self *SnapshotCleanupTask) OnDeleteSnapshot(ctx context.Context, obj db.IS
|
||||
|
||||
func (self *SnapshotCleanupTask) OnDeleteSnapshotFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
log.Errorf("snapshot delete faield %s", data)
|
||||
self.OnDeleteSnapshot(ctx, obj, data)
|
||||
self.SetStageFailed(ctx, data)
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ func (self *DnsZoneCacheCreateTask) taskFailed(ctx context.Context, cache *model
|
||||
cache.SetStatus(self.GetUserCred(), api.DNS_ZONE_CACHE_STATUS_CREATE_FAILED, err.Error())
|
||||
db.OpsLog.LogEvent(cache, db.ACT_CREATE, cache.GetShortDesc(ctx), self.GetUserCred())
|
||||
logclient.AddActionLogWithContext(ctx, cache, logclient.ACT_CREATE, err, self.UserCred, false)
|
||||
dnsZone, err := cache.GetDnsZone()
|
||||
if err == nil {
|
||||
dnsZone, err2 := cache.GetDnsZone()
|
||||
if err2 == nil {
|
||||
dnsZone.SetStatus(self.GetUserCred(), api.DNS_ZONE_CACHE_STATUS_CREATE_FAILED, "")
|
||||
logclient.AddActionLogWithContext(ctx, dnsZone, logclient.ACT_CREATE, err, self.UserCred, false)
|
||||
}
|
||||
|
||||
@@ -109,6 +109,11 @@ func (self *GuestCreateTask) StartDeployGuest(ctx context.Context, guest *models
|
||||
|
||||
func (self *GuestCreateTask) OnDeployGuestDescComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
// sync capacityUsed for storage
|
||||
err := guest.SyncCapacityUsedForStorage(ctx, nil)
|
||||
if err != nil {
|
||||
log.Errorf("unable to SyncCapacityUsedForStorage: %v", err)
|
||||
}
|
||||
|
||||
// bind eip
|
||||
{
|
||||
|
||||
@@ -36,6 +36,10 @@ type GuestDeleteTask struct {
|
||||
SGuestBaseTask
|
||||
}
|
||||
|
||||
var (
|
||||
STORAGEIDS = "storage_ids"
|
||||
)
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(GuestDeleteTask{})
|
||||
}
|
||||
@@ -251,6 +255,15 @@ func (self *GuestDeleteTask) OnPendingDeleteCompleteFailed(ctx context.Context,
|
||||
}
|
||||
|
||||
func (self *GuestDeleteTask) StartDeleteGuest(ctx context.Context, guest *models.SGuest) {
|
||||
// Temporary storageids to sync capacityUsed after delete
|
||||
{
|
||||
storages := guest.GetStorages()
|
||||
storageIds := make([]string, len(storages))
|
||||
for i := range storages {
|
||||
storageIds[i] = storages[i].GetId()
|
||||
}
|
||||
self.Params.Set(STORAGEIDS, jsonutils.NewStringArray(storageIds))
|
||||
}
|
||||
// No snapshot
|
||||
self.SetStage("OnGuestDetachDisksComplete", nil)
|
||||
guest.GetDriver().RequestDetachDisksFromGuestForDelete(ctx, guest, self)
|
||||
@@ -303,6 +316,18 @@ func (self *GuestDeleteTask) OnGuestDeleteComplete(ctx context.Context, obj db.I
|
||||
guest.EjectIso(self.UserCred)
|
||||
guest.DeleteEip(ctx, self.UserCred)
|
||||
guest.GetDriver().OnDeleteGuestFinalCleanup(ctx, guest, self.UserCred)
|
||||
// sync capacity used for storage
|
||||
ja, err := self.Params.GetArray(STORAGEIDS)
|
||||
if err == nil {
|
||||
storageIds := make([]string, len(ja))
|
||||
for i := range ja {
|
||||
storageIds[i], _ = ja[i].GetString()
|
||||
}
|
||||
err = guest.SyncCapacityUsedForStorage(ctx, storageIds)
|
||||
if err != nil {
|
||||
log.Errorf("unable to SyncCapacityUsedForStoarage: %v", err)
|
||||
}
|
||||
}
|
||||
self.DeleteGuest(ctx, guest)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -64,7 +65,7 @@ func (self *SNatDEntryDeleteTask) OnInit(ctx context.Context, obj db.IStandalone
|
||||
}
|
||||
|
||||
cloudNatDEntry, err := cloudNatGateway.GetINatDEntryByID(dnatEntry.ExternalId)
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
// already delete
|
||||
} else if err != nil {
|
||||
self.TaskFailed(ctx, dnatEntry, jsonutils.NewString(fmt.Sprintf("Get DNat Entry by ID '%s' failed", dnatEntry.ExternalId)))
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -64,7 +65,7 @@ func (self *SNatSEntryDeleteTask) OnInit(ctx context.Context, obj db.IStandalone
|
||||
return
|
||||
}
|
||||
cloudNatSEntry, err := cloudNatGateway.GetINatSEntryByID(snatEntry.ExternalId)
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
//already delete
|
||||
} else if err != nil {
|
||||
self.TaskFailed(ctx, snatEntry, jsonutils.NewString(fmt.Sprintf("Get SNat Entry by ID '%s' failed: %s", snatEntry.ExternalId, err)))
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -57,7 +58,7 @@ func (self *NetworkDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneMod
|
||||
self.taskFailed(ctx, network, jsonutils.NewString(err.Error()))
|
||||
return
|
||||
}
|
||||
} else if err == cloudprovider.ErrNotFound {
|
||||
} else if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
// already deleted, do nothing
|
||||
} else {
|
||||
self.taskFailed(ctx, network, jsonutils.NewString(err.Error()))
|
||||
|
||||
@@ -126,6 +126,7 @@ type IStorage interface {
|
||||
disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool, diskDesc jsonutils.JSONObject) error
|
||||
|
||||
Accessible() error
|
||||
Detach() error
|
||||
}
|
||||
|
||||
type SBaseStorage struct {
|
||||
|
||||
@@ -87,7 +87,7 @@ func (s *SLocalStorage) GetComposedName() string {
|
||||
|
||||
func (s *SLocalStorage) SyncStorageSize() error {
|
||||
content := jsonutils.NewDict()
|
||||
content.Set("actual_capacity", jsonutils.NewInt(int64(s.GetUsedSizeMb())))
|
||||
content.Set("actual_capacity_used", jsonutils.NewInt(int64(s.GetUsedSizeMb())))
|
||||
_, err := modules.Storages.Put(
|
||||
hostutils.GetComputeSession(context.Background()),
|
||||
s.StorageId, content)
|
||||
@@ -98,7 +98,7 @@ func (s *SLocalStorage) SyncStorageInfo() (jsonutils.JSONObject, error) {
|
||||
content := jsonutils.NewDict()
|
||||
content.Set("name", jsonutils.NewString(s.GetName(s.GetComposedName)))
|
||||
content.Set("capacity", jsonutils.NewInt(int64(s.GetAvailSizeMb())))
|
||||
content.Set("actual_capacity", jsonutils.NewInt(int64(s.GetUsedSizeMb())))
|
||||
content.Set("actual_capacity_used", jsonutils.NewInt(int64(s.GetUsedSizeMb())))
|
||||
content.Set("storage_type", jsonutils.NewString(s.StorageType()))
|
||||
content.Set("medium_type", jsonutils.NewString(s.GetMediumType()))
|
||||
content.Set("zone", jsonutils.NewString(s.GetZoneName()))
|
||||
@@ -184,6 +184,10 @@ func (s *SLocalStorage) Accessible() error {
|
||||
|
||||
}
|
||||
|
||||
func (s *SLocalStorage) Detach() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SLocalStorage) DeleteDiskfile(diskpath string) error {
|
||||
log.Infof("Start Delete %s", diskpath)
|
||||
if options.HostOptions.RecycleDiskfile {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user