diff --git a/cmd/climc/shell/compute/storages.go b/cmd/climc/shell/compute/storages.go index 37a8889ac3..c67bcf9f11 100644 --- a/cmd/climc/shell/compute/storages.go +++ b/cmd/climc/shell/compute/storages.go @@ -15,268 +15,27 @@ package compute import ( - "fmt" - - "yunion.io/x/jsonutils" - - "yunion.io/x/onecloud/pkg/mcclient" - "yunion.io/x/onecloud/pkg/mcclient/modulebase" + "yunion.io/x/onecloud/cmd/climc/shell" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/mcclient/options" + "yunion.io/x/onecloud/pkg/mcclient/options/compute" ) func init() { - type StorageListOptions struct { - options.BaseListOptions - - Share *bool `help:"Share storage list"` - Local *bool `help:"Local storage list"` - Usable *bool `help:"Usable storage list"` - Zone string `help:"List storages in zone" json:"-"` - Region string `help:"List storages in region"` - Schedtag string `help:"filter storage by schedtag"` - - HostSchedtagId string `help:"filter storage by host schedtag"` - ImageId string `help:"filter storage by image"` - } - R(&StorageListOptions{}, "storage-list", "List storages", func(s *mcclient.ClientSession, opts *StorageListOptions) error { - params, err := options.ListStructToParams(opts) - if err != nil { - return err - } - var result *modulebase.ListResult - if len(opts.Zone) > 0 { - result, err = modules.Storages.ListInContext(s, params, &modules.Zones, opts.Zone) - } else { - result, err = modules.Storages.List(s, params) - } - if err != nil { - return err - } - printList(result, modules.Storages.GetColumns(s)) - return nil - }) - - type StorageUpdateOptions struct { - ID string `help:"ID or Name of storage to update"` - Name string `help:"New Name of storage"` - Desc string `help:"Description"` - CommitBound float64 `help:"Upper bound of storage overcommit rate" json:"cmtbound"` - MediumType string `help:"Medium type" choices:"ssd|rotate"` - RbdRadosMonOpTimeout int64 `help:"ceph rados_mon_op_timeout"` - RbdRadosOsdOpTimeout int64 `help:"ceph rados_osd_op_timeout"` - RbdClientMountTimeout int64 `help:"ceph client_mount_timeout"` - RbdKey string `help:"ceph rbd key"` - Reserved string `help:"Reserved storage space"` - Capacity int `help:"Capacity for storage"` - } - R(&StorageUpdateOptions{}, "storage-update", "Update a storage", func(s *mcclient.ClientSession, args *StorageUpdateOptions) error { - params, err := options.StructToParams(args) - if err != nil { - return err - } - - result, err := modules.Storages.Update(s, args.ID, params) - if err != nil { - return err - } - printObject(result) - return nil - }) - - type StorageCreateOptions struct { - NAME string `help:"Name of the Storage"` - ZONE string `help:"Zone id of storage"` - Capacity int64 `help:"Capacity of the Storage"` - MediumType string `help:"Medium type" choices:"ssd|rotate"` - StorageType string `help:"Storage type" choices:"local|nas|vsan|rbd|nfs|gpfs|baremetal"` - RbdMonHost string `help:"Ceph mon_host config"` - RbdRadosMonOpTimeout int64 `help:"ceph rados_mon_op_timeout"` - RbdRadosOsdOpTimeout int64 `help:"ceph rados_osd_op_timeout"` - RbdClientMountTimeout int64 `help:"ceph client_mount_timeout"` - RbdKey string `help:"Ceph key config"` - RbdPool string `help:"Ceph Pool Name"` - NfsHost string `help:"NFS host"` - NfsSharedDir string `help:"NFS shared dir"` - } - R(&StorageCreateOptions{}, "storage-create", "Create a Storage", func(s *mcclient.ClientSession, args *StorageCreateOptions) error { - params, err := options.StructToParams(args) - if err != nil { - return err - } - - if args.StorageType == "rbd" { - if args.RbdMonHost == "" || args.RbdKey == "" || args.RbdPool == "" { - return fmt.Errorf("Not enough arguments, missing mon_host、key or pool") - } - } else if args.StorageType == "nfs" { - if len(args.NfsHost) == 0 || len(args.NfsSharedDir) == 0 { - return fmt.Errorf("Storage type nfs missing conf host or shared dir") - } - } - storage, err := modules.Storages.Create(s, params) - if err != nil { - return err - } - printObject(storage) - return nil - }) - - type StorageShowOptions struct { - ID string `help:"ID or Name of the storage to show"` - } - R(&StorageShowOptions{}, "storage-show", "Show storage details", func(s *mcclient.ClientSession, args *StorageShowOptions) error { - result, err := modules.Storages.Get(s, args.ID, nil) - if err != nil { - return err - } - printObject(result) - return nil - }) - - R(&StorageShowOptions{}, "storage-delete", "Delete a storage", func(s *mcclient.ClientSession, args *StorageShowOptions) error { - result, err := modules.Storages.Delete(s, args.ID, nil) - if err != nil { - return err - } - printObject(result) - return nil - }) - - R(&StorageShowOptions{}, "storage-enable", "Enable a storage", func(s *mcclient.ClientSession, args *StorageShowOptions) error { - result, err := modules.Storages.PerformAction(s, args.ID, "enable", nil) - if err != nil { - return err - } - printObject(result) - return nil - }) - - R(&StorageShowOptions{}, "storage-disable", "Disable a storage", func(s *mcclient.ClientSession, args *StorageShowOptions) error { - result, err := modules.Storages.PerformAction(s, args.ID, "disable", nil) - if err != nil { - return err - } - printObject(result) - return nil - }) - - R(&StorageShowOptions{}, "storage-online", "Online a storage", func(s *mcclient.ClientSession, args *StorageShowOptions) error { - result, err := modules.Storages.PerformAction(s, args.ID, "online", nil) - if err != nil { - return err - } - printObject(result) - return nil - }) - - R(&StorageShowOptions{}, "storage-offline", "Offline a storage", func(s *mcclient.ClientSession, args *StorageShowOptions) error { - result, err := modules.Storages.PerformAction(s, args.ID, "offline", nil) - if err != nil { - return err - } - printObject(result) - return nil - }) - - type StorageCacheImageActionOptions struct { - ID string `help:"ID or name of storage"` - IMAGE string `help:"ID or name of image"` - Force bool `help:"Force refresh cache, even if the image exists in cache"` - Format string `help:"Image force" choices:"iso|vmdk|qcow2|vhd"` - } - R(&StorageCacheImageActionOptions{}, "storage-cache-image", "Ask a storage to cache a image", func(s *mcclient.ClientSession, args *StorageCacheImageActionOptions) error { - params := jsonutils.NewDict() - params.Add(jsonutils.NewString(args.IMAGE), "image") - if args.Force { - params.Add(jsonutils.JSONTrue, "is_force") - } - if len(args.Format) > 0 { - params.Add(jsonutils.NewString(args.Format), "format") - } - storage, err := modules.Storages.PerformAction(s, args.ID, "cache-image", params) - if err != nil { - return err - } - printObject(storage) - return nil - }) - - type StorageUncacheImageActionOptions struct { - ID string `help:"ID or name of storage"` - IMAGE string `help:"ID or name of image"` - Force bool `help:"Force uncache, even if the image exists in cache"` - } - R(&StorageUncacheImageActionOptions{}, "storage-uncache-image", "Ask a storage to remove image from its cache", func(s *mcclient.ClientSession, args *StorageUncacheImageActionOptions) error { - params := jsonutils.NewDict() - params.Add(jsonutils.NewString(args.IMAGE), "image") - if args.Force { - params.Add(jsonutils.JSONTrue, "is_force") - } - storage, err := modules.Storages.PerformAction(s, args.ID, "uncache-image", params) - if err != nil { - return err - } - printObject(storage) - return nil - }) - - type StorageChangeOwnerOptions struct { - ID string `help:"ID or name of storage" json:"-"` - ProjectDomain string `json:"project_domain" help:"target domain"` - } - R(&StorageChangeOwnerOptions{}, "storage-change-owner", "Change owner domain of storage", func(s *mcclient.ClientSession, args *StorageChangeOwnerOptions) error { - if len(args.ProjectDomain) == 0 { - return fmt.Errorf("empty project_domain") - } - params := jsonutils.Marshal(args) - ret, err := modules.Storages.PerformAction(s, args.ID, "change-owner", params) - if err != nil { - return err - } - printObject(ret) - return nil - }) - - type StorageForceDetachHost struct { - ID string `help:"ID or name of storage" json:"-"` - Host string `help:"ID or name of host"` - } - R(&StorageForceDetachHost{}, "storage-public", "Force detach host", func(s *mcclient.ClientSession, args *StorageForceDetachHost) error { - params := jsonutils.Marshal(args) - result, err := modules.Storages.PerformAction(s, args.ID, "force-detach-host", params) - if err != nil { - return err - } - printObject(result) - return nil - }) - - type StoragePublicOptions struct { - ID string `help:"ID or name of storage" json:"-"` - Scope string `help:"sharing scope" choices:"system|domain"` - SharedDomains []string `help:"share to domains"` - } - R(&StoragePublicOptions{}, "storage-public", "Make a storage public", func(s *mcclient.ClientSession, args *StoragePublicOptions) error { - params := jsonutils.Marshal(args) - result, err := modules.Storages.PerformAction(s, args.ID, "public", params) - if err != nil { - return err - } - printObject(result) - return nil - }) - - type StoragePrivateOptions struct { - ID string `help:"ID or name of storage" json:"-"` - } - R(&StoragePrivateOptions{}, "storage-private", "Make a storage private", func(s *mcclient.ClientSession, args *StoragePrivateOptions) error { - params := jsonutils.Marshal(args) - result, err := modules.Storages.PerformAction(s, args.ID, "private", params) - if err != nil { - return err - } - printObject(result) - return nil - }) + cmd := shell.NewResourceCmd(&modules.Storages).WithContextManager(&modules.Zones) + cmd.List(&compute.StorageListOptions{}) + cmd.Update(&compute.StorageUpdateOptions{}) + cmd.Create(&compute.StorageCreateOptions{}) + cmd.Show(&options.BaseShowOptions{}) + cmd.Delete(&options.BaseIdOptions{}) + cmd.Perform("enable", &options.BaseIdOptions{}) + cmd.Perform("disable", &options.BaseIdOptions{}) + cmd.Perform("online", &options.BaseIdOptions{}) + cmd.Perform("offline", &options.BaseIdOptions{}) + cmd.Perform("cache-image", &compute.StorageCacheImageActionOptions{}) + cmd.Perform("uncache-image", &compute.StorageUncacheImageActionOptions{}) + cmd.Perform("change-owner", &options.ChangeOwnerOptions{}) + cmd.Perform("force-detach-host", &compute.StorageForceDetachHost{}) + cmd.Perform("public", &options.BasePublicOptions{}) + cmd.Perform("private", &options.BaseIdOptions{}) } diff --git a/pkg/apis/compute/storage.go b/pkg/apis/compute/storage.go index 84d9ae40f2..cda37d11a5 100644 --- a/pkg/apis/compute/storage.go +++ b/pkg/apis/compute/storage.go @@ -47,6 +47,7 @@ type StorageCreateInput struct { // 存储介质类型 // enum: rotate, ssd, hybird // required: true + // default: ssd MediumType string `json:"medium_type"` ZoneResourceInput @@ -74,6 +75,24 @@ type StorageCreateInput struct { // swagger:ignore Key string + RbdTimeoutInput + + // swagger:ignore + ClientMountTimeout int + + // swagger:ignore + StorageConf *jsonutils.JSONDict + + // 网络文件系统主机, storage_type 为 nfs 时,此参数必传 + // example: 192.168.222.2 + NfsHost string `json:"nfs_host"` + + // 网络文件系统共享目录, storage_type 为 nfs 时, 此参数必传 + // example: /nfs_root/ + NfsSharedDir string `json:"nfs_shared_dir"` +} + +type RbdTimeoutInput struct { // ceph集群连接超时时间, 单位秒 // default: 3 RbdRadosMonOpTimeout int `json:"rbd_rados_mon_op_timeout"` @@ -91,20 +110,6 @@ type StorageCreateInput struct { // ceph CephFS挂载超时时间, 单位秒 // default: 120 RbdClientMountTimeout int `json:"rbd_client_mount_timeout"` - - // swagger:ignore - ClientMountTimeout int - - // swagger:ignore - StorageConf *jsonutils.JSONDict - - // 网络文件系统主机, storage_type 为 nfs 时,此参数必传 - // example: 192.168.222.2 - NfsHost string `json:"nfs_host"` - - // 网络文件系统共享目录, storage_type 为 nfs 时, 此参数必传 - // example: /nfs_root/ - NfsSharedDir string `json:"nfs_shared_dir"` } type SStorageCapacityInfo struct { @@ -134,8 +139,6 @@ type StorageDetails struct { SStorageCapacityInfo - SStorage - Hosts []StorageHost `json:"hosts"` Schedtags []SchedtagShortDescDetails `json:"schedtags"` @@ -167,3 +170,19 @@ type StorageResourceInfo struct { // 存储状态 StorageStatus string `json:"storage_status"` } + +type StorageUpdateInput struct { + apis.EnabledStatusInfrasResourceBaseUpdateInput + + // ceph集群密码,若ceph集群开启cephx认证,此参数必传 + // 可在ceph集群主机的/etc/ceph/ceph.client.admin.keyring文件中找到 + // example: AQDigB9dtnDAKhAAxS6X4zi4BPR/lIle4nf4Dw== + RbdKey string `json:"rbd_key"` + + RbdTimeoutInput + + // swagger:ignore + StorageConf *jsonutils.JSONDict + + UpdateStorageConf bool +} diff --git a/pkg/compute/models/storagedrivers.go b/pkg/compute/models/storagedrivers.go index f342d9c038..2b77102962 100644 --- a/pkg/compute/models/storagedrivers.go +++ b/pkg/compute/models/storagedrivers.go @@ -28,7 +28,7 @@ type IStorageDriver interface { GetStorageType() string ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, input *api.StorageCreateInput) error - ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, storage *SStorage) (*jsonutils.JSONDict, error) + ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, input api.StorageUpdateInput) (api.StorageUpdateInput, error) DoStorageUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, storage *SStorage, task taskman.ITask) error diff --git a/pkg/compute/models/storages.go b/pkg/compute/models/storages.go index 80cd39f01f..05a0c934fb 100644 --- a/pkg/compute/models/storages.go +++ b/pkg/compute/models/storages.go @@ -33,6 +33,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/options" "yunion.io/x/onecloud/pkg/httperrors" @@ -125,12 +126,22 @@ func (self *SStorage) AllowUpdateItem(ctx context.Context, userCred mcclient.Tok return db.IsAdminAllowUpdate(userCred, self) } -func (self *SStorage) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { +func (self *SStorage) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.StorageUpdateInput) (api.StorageUpdateInput, error) { + var err error + input.EnabledStatusInfrasResourceBaseUpdateInput, err = self.SEnabledStatusInfrasResourceBase.ValidateUpdateData(ctx, userCred, query, input.EnabledStatusInfrasResourceBaseUpdateInput) + if err != nil { + return input, err + } + if self.StorageConf != nil { + input.StorageConf = self.StorageConf.(*jsonutils.JSONDict) + } else { + input.StorageConf = jsonutils.NewDict() + } driver := GetStorageDriver(self.StorageType) if driver != nil { - return driver.ValidateUpdateData(ctx, userCred, data, self) + return driver.ValidateUpdateData(ctx, userCred, input) } - return data, nil + return input, nil } func (self *SStorage) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) { @@ -199,22 +210,22 @@ func (manager *SStorageManager) ValidateCreateData( query jsonutils.JSONObject, input api.StorageCreateInput, ) (api.StorageCreateInput, error) { - var err error - if !utils.IsInStringArray(input.StorageType, api.STORAGE_TYPES) { return input, httperrors.NewInputParameterError("Invalid storage type %s", input.StorageType) } + if len(input.MediumType) == 0 { + input.MediumType = api.DISK_TYPE_SSD + } if !utils.IsInStringArray(input.MediumType, api.DISK_TYPES) { return input, httperrors.NewInputParameterError("Invalid medium type %s", input.MediumType) } if len(input.ZoneId) == 0 { - return input, httperrors.NewMissingParameterError("zone") + return input, httperrors.NewMissingParameterError("zone_id") } - _, input.ZoneResourceInput, err = ValidateZoneResourceInput(userCred, input.ZoneResourceInput) + _, err := validators.ValidateModel(userCred, ZoneManager, &input.ZoneId) if err != nil { - return input, errors.Wrap(err, "ValidateZoneResourceInput") + return input, err } - storageDirver := GetStorageDriver(input.StorageType) if storageDirver == nil { return input, httperrors.NewUnsupportOperationError("Not support create %s storage", input.StorageType) diff --git a/pkg/compute/storagedrivers/base.go b/pkg/compute/storagedrivers/base.go index cd89f7919c..0610a7b7b8 100644 --- a/pkg/compute/storagedrivers/base.go +++ b/pkg/compute/storagedrivers/base.go @@ -43,8 +43,8 @@ func (self *SBaseStorageDriver) PostCreate(ctx context.Context, userCred mcclien } -func (self *SBaseStorageDriver) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, storage *models.SStorage) (*jsonutils.JSONDict, error) { - return data, nil +func (self *SBaseStorageDriver) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, input api.StorageUpdateInput) (api.StorageUpdateInput, error) { + return input, nil } func (self *SBaseStorageDriver) DoStorageUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, storage *models.SStorage, task taskman.ITask) error { diff --git a/pkg/compute/storagedrivers/rbd.go b/pkg/compute/storagedrivers/rbd.go index 5bc7fddfb0..2f471ed1d2 100644 --- a/pkg/compute/storagedrivers/rbd.go +++ b/pkg/compute/storagedrivers/rbd.go @@ -51,13 +51,13 @@ func (self *SRbdStorageDriver) ValidateCreateData(ctx context.Context, userCred if len(input.RbdMonHost) == 0 { return httperrors.NewMissingParameterError("rbd_mon_host") } - input.MonHost = input.RbdMonHost + input.MonHost = strings.ReplaceAll(input.RbdMonHost, " ", "") if len(input.RbdPool) == 0 { return httperrors.NewMissingParameterError("rbd_pool") } - input.Pool = input.RbdPool - input.Key = input.RbdKey + input.Pool = strings.Trim(input.RbdPool, " ") + input.Key = strings.Trim(input.RbdKey, " ") input.RadosMonOpTimeout = input.RbdRadosMonOpTimeout if input.RadosMonOpTimeout <= 0 { @@ -99,35 +99,23 @@ func (self *SRbdStorageDriver) ValidateCreateData(ctx context.Context, userCred return nil } -func (self *SRbdStorageDriver) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, storage *models.SStorage) (*jsonutils.JSONDict, error) { - conf, ok := storage.StorageConf.(*jsonutils.JSONDict) - if !ok { - conf = jsonutils.NewDict() - } - data.Set("update_storage_conf", jsonutils.JSONFalse) - for _, k := range []string{"rbd_rados_mon_op_timeout", "rbd_rados_osd_op_timeout", "rbd_client_mount_timeout"} { - if timeout, _ := data.Int(k); timeout > 0 { - conf.Set(strings.TrimPrefix(k, "rbd_"), jsonutils.NewInt(timeout)) - data.Set("update_storage_conf", jsonutils.JSONTrue) +func (self *SRbdStorageDriver) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, input api.StorageUpdateInput) (api.StorageUpdateInput, error) { + for k, v := range map[string]int{ + "rados_mon_op_timeout": input.RbdRadosMonOpTimeout, + "rados_osd_op_timeout": input.RbdRadosOsdOpTimeout, + "client_mount_timeout": input.RbdClientMountTimeout} { + if v > 0 { + input.StorageConf.Set(k, jsonutils.NewInt(int64(v))) + input.UpdateStorageConf = true } } - if key, _ := data.GetString("rbd_key"); len(key) > 0 { - conf.Set("key", jsonutils.NewString(key)) - data.Set("update_storage_conf", jsonutils.JSONTrue) + if len(input.RbdKey) > 0 { + input.StorageConf.Set("key", jsonutils.NewString(strings.Trim(input.RbdKey, " "))) + input.UpdateStorageConf = true } - if update, _ := data.Bool("update_storage_conf"); update { - _, err := storage.GetModelManager().TableSpec().Update(ctx, storage, func() error { - storage.StorageConf = conf - return nil - }) - if err != nil { - return nil, httperrors.NewGeneralError(err) - } - } - - return data, nil + return input, nil } func (self *SRbdStorageDriver) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, storage *models.SStorage, data jsonutils.JSONObject) { diff --git a/pkg/mcclient/options/base.go b/pkg/mcclient/options/base.go index 677878cfe8..28046e421a 100644 --- a/pkg/mcclient/options/base.go +++ b/pkg/mcclient/options/base.go @@ -406,3 +406,15 @@ type BaseShowOptions struct { func (o BaseShowOptions) Params() (jsonutils.JSONObject, error) { return StructToParams(o) } + +type ChangeOwnerOptions struct { + BaseIdOptions + ProjectDomain string `json:"project_domain" help:"target domain"` +} + +func (o ChangeOwnerOptions) Params() (jsonutils.JSONObject, error) { + if len(o.ProjectDomain) == 0 { + return nil, fmt.Errorf("empty project_domain") + } + return jsonutils.Marshal(map[string]string{"project_domain": o.ProjectDomain}), nil +} diff --git a/pkg/mcclient/options/compute/storage.go b/pkg/mcclient/options/compute/storage.go new file mode 100644 index 0000000000..5ba848c5e6 --- /dev/null +++ b/pkg/mcclient/options/compute/storage.go @@ -0,0 +1,120 @@ +// 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 ( + "fmt" + + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/mcclient/options" +) + +type StorageListOptions struct { + options.BaseListOptions + + Share *bool `help:"Share storage list"` + Local *bool `help:"Local storage list"` + Usable *bool `help:"Usable storage list"` + Zone string `help:"List storages in zone" json:"-"` + Region string `help:"List storages in region"` + Schedtag string `help:"filter storage by schedtag"` + + HostSchedtagId string `help:"filter storage by host schedtag"` + ImageId string `help:"filter storage by image"` +} + +func (opts *StorageListOptions) Params() (jsonutils.JSONObject, error) { + return options.ListStructToParams(opts) +} + +func (opts *StorageListOptions) GetContextId() string { + return opts.Zone +} + +type StorageUpdateOptions struct { + options.BaseUpdateOptions + CommitBound float64 `help:"Upper bound of storage overcommit rate" json:"cmtbound"` + MediumType string `help:"Medium type" choices:"ssd|rotate"` + RbdRadosMonOpTimeout int64 `help:"ceph rados_mon_op_timeout"` + RbdRadosOsdOpTimeout int64 `help:"ceph rados_osd_op_timeout"` + RbdClientMountTimeout int64 `help:"ceph client_mount_timeout"` + RbdKey string `help:"ceph rbd key"` + Reserved string `help:"Reserved storage space"` + Capacity int `help:"Capacity for storage"` +} + +func (opts *StorageUpdateOptions) Params() (jsonutils.JSONObject, error) { + return options.StructToParams(opts) +} + +type StorageCreateOptions struct { + NAME string `help:"Name of the Storage"` + ZONE string `help:"Zone id of storage"` + Capacity int64 `help:"Capacity of the Storage"` + MediumType string `help:"Medium type" choices:"ssd|rotate" default:"ssd"` + StorageType string `help:"Storage type" choices:"local|nas|vsan|rbd|nfs|gpfs|baremetal"` + RbdMonHost string `help:"Ceph mon_host config"` + RbdRadosMonOpTimeout int64 `help:"ceph rados_mon_op_timeout"` + RbdRadosOsdOpTimeout int64 `help:"ceph rados_osd_op_timeout"` + RbdClientMountTimeout int64 `help:"ceph client_mount_timeout"` + RbdKey string `help:"Ceph key config"` + RbdPool string `help:"Ceph Pool Name"` + NfsHost string `help:"NFS host"` + NfsSharedDir string `help:"NFS shared dir"` +} + +func (opts *StorageCreateOptions) Params() (jsonutils.JSONObject, error) { + if opts.StorageType == "rbd" { + if opts.RbdMonHost == "" || opts.RbdPool == "" { + return nil, fmt.Errorf("Not enough arguments, missing mon_hostor pool") + } + } else if opts.StorageType == "nfs" { + if len(opts.NfsHost) == 0 || len(opts.NfsSharedDir) == 0 { + return nil, fmt.Errorf("Storage type nfs missing conf host or shared dir") + } + } + return options.StructToParams(opts) +} + +type StorageCacheImageActionOptions struct { + options.BaseIdOptions + IMAGE string `help:"ID or name of image"` + Force bool `help:"Force refresh cache, even if the image exists in cache"` + Format string `help:"Image force" choices:"iso|vmdk|qcow2|vhd"` +} + +func (opts *StorageCacheImageActionOptions) Params() (jsonutils.JSONObject, error) { + return options.StructToParams(opts) +} + +type StorageUncacheImageActionOptions struct { + options.BaseIdOptions + IMAGE string `help:"ID or name of image"` + Force bool `help:"Force uncache, even if the image exists in cache"` +} + +func (opts *StorageUncacheImageActionOptions) Params() (jsonutils.JSONObject, error) { + return options.StructToParams(opts) +} + +type StorageForceDetachHost struct { + options.BaseIdOptions + HOST string `help:"ID or name of host"` +} + +func (opts *StorageForceDetachHost) Params() (jsonutils.JSONObject, error) { + return jsonutils.Marshal(map[string]string{"host": opts.HOST}), nil +}