From bac407a65cb88568922a0bdad5f07a1f414f14bd Mon Sep 17 00:00:00 2001 From: mhf Date: Wed, 21 Sep 2022 13:56:46 +0800 Subject: [PATCH] add hcso modelarts --- pkg/cloudprovider/endpoints.go | 2 + pkg/multicloud/hcso/hcso.go | 82 +++++ pkg/multicloud/hcso/modelarts.go | 357 +++++++++++++++++++++ pkg/multicloud/hcso/modelarts_sku.go | 130 ++++++++ pkg/multicloud/hcso/shell/modelarts.go | 75 +++++ pkg/multicloud/hcso/shell/modelarts_sku.go | 35 ++ 6 files changed, 681 insertions(+) create mode 100644 pkg/multicloud/hcso/modelarts.go create mode 100644 pkg/multicloud/hcso/modelarts_sku.go create mode 100644 pkg/multicloud/hcso/shell/modelarts.go create mode 100644 pkg/multicloud/hcso/shell/modelarts_sku.go diff --git a/pkg/cloudprovider/endpoints.go b/pkg/cloudprovider/endpoints.go index ce4762bafe..43e5b4134a 100644 --- a/pkg/cloudprovider/endpoints.go +++ b/pkg/cloudprovider/endpoints.go @@ -81,6 +81,8 @@ type SHCSOEndpoints struct { Eps string `default:"$HUAWEI_EPS_ENDPOINT"` // 文件系统 SfsTurbo string `default:"$HUAWEI_SFS_TURBO_ENDPOINT"` + // Modelarts + Modelarts string `default:"$HUAWEI_MODELARTS_ENDPOINT"` } func (self *SHCSOEndpoints) GetEndpoint(defaultRegion, serviceName string, region string) string { diff --git a/pkg/multicloud/hcso/hcso.go b/pkg/multicloud/hcso/hcso.go index a8cc217687..839ea04571 100644 --- a/pkg/multicloud/hcso/hcso.go +++ b/pkg/multicloud/hcso/hcso.go @@ -19,12 +19,14 @@ import ( "fmt" "net/http" "net/url" + "strconv" "strings" "github.com/huaweicloud/huaweicloud-sdk-go/auth/aksk" "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/gotypes" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/util/httputils" @@ -122,3 +124,83 @@ func (self *SHuaweiClient) deleteAKSK(accessKey string) (jsonutils.JSONObject, e uri := fmt.Sprintf("https://%s/v3.0/OS-CREDENTIAL/credentials/%s", self.endpoints.Iam, accessKey) return self.request(httputils.POST, uri, nil, nil) } + +func (self *SHuaweiClient) modelartsPoolNetworkList(params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://%s/v1/%s/networks", self.endpoints.Modelarts, self.projectId) + return self.request(httputils.GET, uri, url.Values{}, params) +} + +func (self *SHuaweiClient) modelartsPoolNetworkCreate(params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://%s/v1/%s/networks", self.endpoints.Modelarts, self.projectId) + return self.request(httputils.POST, uri, url.Values{}, params) +} + +func (self *SHuaweiClient) modelartsPoolById(poolName string, params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://modelarts.%s.myhuaweicloud.com/v2/%s/pools/%s", self.endpoints.Modelarts, self.projectId, poolName) + return self.request(httputils.GET, uri, url.Values{}, params) +} + +func (self *SHuaweiClient) modelartsPoolList(params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://%s/v2/%s/pools", self.endpoints.Modelarts, self.projectId) + return self.request(httputils.GET, uri, url.Values{}, params) +} + +func (self *SHuaweiClient) modelartsPoolCreate(params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://%s/v2/%s/pools", self.endpoints.Modelarts, self.projectId) + return self.request(httputils.POST, uri, url.Values{}, params) +} + +func (self *SHuaweiClient) modelartsPoolDelete(poolName string, params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://%s/v2/%s/pools/%s", self.endpoints.Modelarts, self.projectId, poolName) + return self.request(httputils.DELETE, uri, url.Values{}, params) +} + +func (self *SHuaweiClient) modelartsPoolUpdate(poolName string, params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://modelarts.%s.myhuaweicloud.com/v2/%s/pools/%s", self.endpoints.Modelarts, self.projectId, poolName) + urlValue := url.Values{} + urlValue.Add("time_range", "") + urlValue.Add("statistics", "") + urlValue.Add("period", "") + return self.patchRequest(httputils.PATCH, uri, urlValue, params) +} + +func (self *SHuaweiClient) modelartsPoolMonitor(poolName string, params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://modelarts.%s.myhuaweicloud.com/v2/%s/pools/%s/monitor", self.endpoints.Modelarts, self.projectId, poolName) + return self.request(httputils.GET, uri, url.Values{}, params) +} + +func (self *SHuaweiClient) modelartsResourceflavors(params map[string]interface{}) (jsonutils.JSONObject, error) { + uri := fmt.Sprintf("https://%s/v1/%s/resourceflavors", self.endpoints.Modelarts, self.projectId) + return self.request(httputils.GET, uri, url.Values{}, params) +} + +func (self *SHuaweiClient) patchRequest(method httputils.THttpMethod, url string, query url.Values, params map[string]interface{}) (jsonutils.JSONObject, error) { + client := self.getAkClient() + if len(query) > 0 { + url = fmt.Sprintf("%s?%s", url, query.Encode()) + } + var body jsonutils.JSONObject = nil + if len(params) > 0 { + body = jsonutils.Marshal(params) + } + header := http.Header{} + if len(self.projectId) > 0 { + header.Set("X-Project-Id", self.projectId) + } + var bodystr string + if !gotypes.IsNil(body) { + bodystr = body.String() + } + jbody := strings.NewReader(bodystr) + header.Set("Content-Length", strconv.FormatInt(int64(len(bodystr)), 10)) + header.Set("Content-Type", "application/merge-patch+json") + resp, err := httputils.Request(client, context.Background(), method, url, header, jbody, self.debug) + _, respValue, err := httputils.ParseJSONResponse(bodystr, resp, err, self.debug) + if err != nil { + if e, ok := err.(*httputils.JSONClientError); ok && e.Code == 404 { + return nil, errors.Wrapf(cloudprovider.ErrNotFound, err.Error()) + } + return nil, err + } + return respValue, err +} diff --git a/pkg/multicloud/hcso/modelarts.go b/pkg/multicloud/hcso/modelarts.go new file mode 100644 index 0000000000..8625209940 --- /dev/null +++ b/pkg/multicloud/hcso/modelarts.go @@ -0,0 +1,357 @@ +// 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 hcso + +import ( + "strings" + "time" + + "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/pkg/errors" + + billing_api "yunion.io/x/onecloud/pkg/apis/billing" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/multicloud" + "yunion.io/x/onecloud/pkg/util/billing" +) + +type SModelartsPool struct { + client *SHuaweiClient + region *SRegion + multicloud.SResourceBase + + Metadata SModelartsPoolMetadata `json:"metadata"` + Spec SModelartsPoolSpec `json:"spec"` + Status SModelartsPoolStatus `json:"status"` + InstanceType string + WorkType string +} + +type SModelartsPoolMetadata struct { + Name string `json:"name"` + CreationTimestamp string `json:"creationTimestamp"` + Labels SModelartsPoolMeatadataLabel + Annotations SModelartsPoolMetadataAnnotations `json:"annotations"` +} + +type SModelartsPoolMeatadataLabel struct { + WorkspaceId string `json:"os.modelarts/workspace.id"` + Name string `json:"os.modelarts/name"` + ResourceId string `json:"os.modelarts/resource.id"` +} + +type SModelartsPoolMetadataAnnotations struct { + Describe string `json:"os.modelarts/description"` + BillingType string `json:"os.modelarts/billing.mode"` + BillingCycle string `json:"os.modelarts/period.num"` + BillingPeriodType string `json:"os.modelarts/period.type"` + BillingMod string `json:"os.modelarts/charging.mode"` + BillingRenew string `json:"os.modelarts/auto.renew"` + OrderId string `json:"os.modelarts/order.id"` +} + +type SModelartsPoolSpec struct { + Type string `json:"type"` + Scope []string `json:"scope"` + Resource []SModelartsPoolResource `json:"resources"` +} + +type SModelartsPoolResource struct { + Flavor string `json:"flavor"` + Count int `json:"count"` + cloudprovider.Azs +} + +type SModelartsPoolStatus struct { + Phase string `json:"phase"` + Message string `json:"message"` +} + +type SModelartsPoolNetwork struct { + Metadata SModelartsPoolNetworkMetadata `json:"metadata"` +} + +type SModelartsPoolNetworkMetadata struct { + Name string `json:"name"` + CreationTimestamp string `json:"creationTimestamp"` +} + +func (self *SRegion) GetIModelartsPools() ([]cloudprovider.ICloudModelartsPool, error) { + pools := make([]SModelartsPool, 0) + log.Errorln("this is in GetIModelartsPools:", self.client.endpoints.Modelarts) + resObj, err := self.client.modelartsPoolList(nil) + if err != nil { + return nil, errors.Wrap(err, "region.GetPools") + } + err = resObj.Unmarshal(&pools, "items") + if err != nil { + return nil, errors.Wrap(err, "resObj unmarshal") + } + res := make([]cloudprovider.ICloudModelartsPool, len(pools)) + for i := 0; i < len(pools); i++ { + pools[i].region = self + pools[i].client = self.GetClient() + res[i] = &pools[i] + } + + return res, nil +} + +func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreateOption) (cloudprovider.ICloudModelartsPool, error) { + netObj, err := self.client.modelartsPoolNetworkList(nil) + if err != nil { + return nil, errors.Wrap(err, "SHuaweiClient.GetPools") + } + netRes := make([]SModelartsPoolNetwork, 0) + netObj.Unmarshal(&netRes, "items") + netId := "" + if len(netRes) != 0 { + netId = netRes[0].Metadata.Name + } else { + createNetObj, err := self.client.CreatePoolNetworks() + if err != nil { + return nil, errors.Wrap(err, "SHuaweiClient.CreatePoolNetworks") + } + netId, _ = createNetObj.GetString("metadata", "name") + } + + scopeArr := strings.Split(args.WorkType, ",") + params := map[string]interface{}{ + "apiVersion": "v2", + "kind": "Pool", + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "os.modelarts/name": args.Name, + "os.modelarts/workspace.id": "0", + }, + }, + "spec": map[string]interface{}{ + "type": "Dedicate", + "scope": scopeArr, + "network": map[string]interface{}{ + "name": netId, + }, + + "resources": []map[string]interface{}{ + { + "flavor": args.InstanceType, + "count": 1, + }, + }, + }, + } + obj, err := self.client.modelartsPoolCreate(params) + if err != nil { + return nil, errors.Wrap(err, "SHuaweiClient.CreatePools") + } + pool := &SModelartsPool{} + obj.Unmarshal(&pool) + res := []cloudprovider.ICloudModelartsPool{} + for i := 0; i < 1; i++ { + pool.region = self + pool.client = self.GetClient() + res = append(res, pool) + } + + return res[0], nil +} + +func (self *SRegion) DeletePool(poolName string) (jsonutils.JSONObject, error) { + return self.client.modelartsPoolDelete(poolName, nil) +} + +func (self *SRegion) GetIModelartsPoolById(poolId string) (cloudprovider.ICloudModelartsPool, error) { + obj, err := self.client.modelartsPoolById(poolId, nil) + if err != nil { + if strings.Contains(err.Error(), "not found") { + return nil, errors.Wrapf(cloudprovider.ErrNotFound, "") + } + return nil, errors.Wrap(err, "region.modelartsPoolByName") + } + pool := &SModelartsPool{} + obj.Unmarshal(&pool) + res := []cloudprovider.ICloudModelartsPool{} + for i := 0; i < 1; i++ { + pool.region = self + pool.client = self.GetClient() + res = append(res, pool) + } + return res[0], nil +} + +func (self *SRegion) MonitorPool(poolId string) (*SModelartsMetrics, error) { + resObj, err := self.client.modelartsPoolMonitor(poolId, nil) + if err != nil { + return nil, errors.Wrapf(err, "send request error") + } + metrics := SModelartsMetrics{} + err = resObj.Unmarshal(&metrics) + if err != nil { + return nil, errors.Wrapf(err, "unmarsh error") + } + return &metrics, nil +} + +type SModelartsMetrics struct { + Metrics []SModelartsMetric `json:"metrics"` +} + +type SModelartsMetric struct { + Metric SModelartsMetricInfo `json:"metric"` + Datapoints []SModelartsDataPoints `json:"dataPoints"` +} + +type SModelartsMetricInfo struct { + Dimensions []SModelartsDimensions `json:"dimensions"` + MetricName string + Namespace string +} + +type SModelartsDimensions struct { + Name string + Value string +} + +type SModelartsDataPoints struct { + Timestamp int64 + Unit string + Statistics []ModelartsStatistics +} + +type ModelartsStatistics struct { + Statistic string + Value float64 +} + +func (self *SHuaweiClient) GetPoolNetworks(poolName string) (jsonutils.JSONObject, error) { + return self.modelartsPoolNetworkList(nil) +} + +func (self *SHuaweiClient) CreatePoolNetworks() (jsonutils.JSONObject, error) { + params := map[string]interface{}{ + "apiVersion": "v1", + "kind": "Network", + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "os.modelarts/name": "test", + "os.modelarts/workspace.id": "0", + }, + }, + "spec": map[string]interface{}{ + "cidr": "192.168.20.0/24", + }, + } + return self.modelartsPoolNetworkCreate(params) +} + +func (self *SModelartsPool) GetCreatedAt() time.Time { + ret, _ := time.Parse("2006-01-02T15:04:05CST", self.Metadata.CreationTimestamp) + if !ret.IsZero() { + ret = ret.Add(time.Hour * 8) + } + return ret +} + +func (self *SModelartsPool) GetGlobalId() string { + return self.Metadata.Name +} + +func (self *SModelartsPool) GetId() string { + return self.Metadata.Name +} + +func (self *SModelartsPool) GetName() string { + return self.Metadata.Labels.Name +} + +func (self *SModelartsPool) GetStatus() string { + return strings.ToLower(self.Status.Phase) +} + +func (self *SModelartsPool) GetSysTags() map[string]string { + return nil +} + +func (self *SModelartsPool) GetTags() (map[string]string, error) { + return nil, nil +} + +func (self *SModelartsPool) IsEmulated() bool { + return false +} + +func (self *SModelartsPool) GetBillingType() string { + if self.Metadata.Annotations.BillingType == "1" { + return billing_api.BILLING_TYPE_PREPAID + } else { + return billing_api.BILLING_TYPE_POSTPAID + } + return self.Metadata.Annotations.BillingType +} + +// 获取资源归属项目Id +func (self *SModelartsPool) GetProjectId() string { + return self.Metadata.Name +} + +func (self *SModelartsPool) GetExpiredAt() time.Time { + ret, _ := time.Parse("2006-01-02T15:04:05CST", self.Metadata.CreationTimestamp) + if !ret.IsZero() { + ret = ret.Add(time.Hour * 8) + } + return ret +} + +func (self *SModelartsPool) IsAutoRenew() bool { + return false +} + +func (self *SModelartsPool) Renew(bc billing.SBillingCycle) error { + return nil +} + +func (self *SModelartsPool) SetAutoRenew(bc billing.SBillingCycle) error { + return nil +} + +func (self *SModelartsPool) Refresh() error { + pool, err := self.client.modelartsPoolById(self.GetId(), nil) + if err != nil { + return errors.Wrapf(err, "GetModelartsPool(%s)", self.GetId()) + } + return jsonutils.Update(self, pool) +} + +func (self *SModelartsPool) SetTags(tags map[string]string, replace bool) error { + return nil +} + +func (self *SModelartsPool) Delete() error { + _, err := self.region.DeletePool(self.GetId()) + if err != nil { + return err + } + return nil +} + +func (self *SModelartsPool) GetInstanceType() string { + return self.Spec.Resource[0].Flavor + +} + +func (self *SModelartsPool) GetWorkType() string { + return strings.Join(self.Spec.Scope, ",") +} diff --git a/pkg/multicloud/hcso/modelarts_sku.go b/pkg/multicloud/hcso/modelarts_sku.go new file mode 100644 index 0000000000..dbb05b07f0 --- /dev/null +++ b/pkg/multicloud/hcso/modelarts_sku.go @@ -0,0 +1,130 @@ +// 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 hcso + +import ( + "strconv" + "time" + + "yunion.io/x/pkg/errors" + + "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/multicloud" +) + +type SModelartsPoolSku struct { + multicloud.SResourceBase + multicloud.HuaweiTags + region *SRegion + + Kind string `json:"kind"` + Spec SModelartsResourceflavorsSpec `json:"spec"` + Status SModelartsResourceflavorsStatus `json:"status"` +} + +type SModelartsResourceflavorsSpec struct { + BillingCode string `json:"billingCode"` + BillingModes []int `json:"billingMods"` + Cpu int `json:"cpu"` + CpuArch string `json:"cpuArch"` + Gpu SModelartsResourceflavorsGpuSpec `json:"gpu"` + Npu SModelartsResourceflavorsGpuSpec `json:"npu"` + Memory string `json:"memory"` + Type string `json:"type"` +} + +type SModelartsResourceflavorsGpuSpec struct { + Size int `json:"size"` + Type string `json:"type"` +} + +type SModelartsResourceflavorsStatus struct { + Phase map[string]interface{} `json:"phase"` +} + +func (self *SRegion) GetIModelartsPoolSku() ([]cloudprovider.ICloudModelartsPoolSku, error) { + params := make(map[string]interface{}) + resourceflavors := make([]SModelartsPoolSku, 0) + obj, err := self.client.modelartsResourceflavors(params) + if err != nil { + return nil, errors.Wrap(err, "region.modelartsResourceflavors") + } + obj.Unmarshal(&resourceflavors, "items") + res := make([]cloudprovider.ICloudModelartsPoolSku, len(resourceflavors)) + for i := 0; i < len(resourceflavors); i++ { + res[i] = &resourceflavors[i] + } + return res, nil +} + +func (self *SModelartsPoolSku) GetCreatedAt() time.Time { + createdAt, _ := time.Parse("2006-01-02T15:04:05CST", time.Now().Format("2006-01-02T15:04:05CST")) + return createdAt +} + +func (self *SModelartsPoolSku) GetGlobalId() string { + return self.Spec.BillingCode +} + +func (self *SModelartsPoolSku) GetId() string { + return self.Spec.BillingCode +} + +func (self *SModelartsPoolSku) GetName() string { + return self.Spec.BillingCode +} + +func (self *SModelartsPoolSku) GetCpuArch() string { + return self.Spec.CpuArch +} + +func (self *SModelartsPoolSku) GetCpuCoreCount() int { + return self.Spec.Cpu +} + +func (self *SModelartsPoolSku) GetMemorySizeMB() int { + size, _ := strconv.Atoi(self.Spec.Memory[:len(self.Spec.Memory)-2]) + return size * 1024 +} + +func (self *SModelartsPoolSku) GetStatus() string { + for _, v := range self.Status.Phase { + if v == "normal" { + return compute.MODELARTS_POOL_SKU_AVAILABLE + } + } + return compute.MODELARTS_POOL_SKU_SOLDOUT +} + +func (self *SModelartsPoolSku) GetGpuSize() int { + return self.Spec.Gpu.Size +} + +func (self *SModelartsPoolSku) GetGpuType() string { + return self.Spec.Gpu.Type +} + +func (self *SModelartsPoolSku) GetNpuSize() int { + return self.Spec.Npu.Size +} + +func (self *SModelartsPoolSku) GetNpuType() string { + return self.Spec.Npu.Type +} + +func (self *SModelartsPoolSku) GetPoolType() string { + return self.Spec.Type +} diff --git a/pkg/multicloud/hcso/shell/modelarts.go b/pkg/multicloud/hcso/shell/modelarts.go new file mode 100644 index 0000000000..3d65525072 --- /dev/null +++ b/pkg/multicloud/hcso/shell/modelarts.go @@ -0,0 +1,75 @@ +// @@ -0,0 +1,46 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shell + +import ( + "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/cloudprovider" + huawei "yunion.io/x/onecloud/pkg/multicloud/hcso" + "yunion.io/x/onecloud/pkg/util/shellutils" +) + +func init() { + type ModelartsPoolListOption struct { + PoolId string `help:"Pool Id"` + } + + shellutils.R(&ModelartsPoolListOption{}, "modelarts-pool-list", "List Modelarts Pool", func(cli *huawei.SRegion, args *ModelartsPoolListOption) error { + log.Errorf("this is endpoints:%v,err:%s\n", cli.GetClient()) + pools, err := cli.GetIModelartsPools() + if err != nil { + return err + } + printList(pools, len(pools), 0, 0, nil) + return nil + }) + + shellutils.R(&ModelartsPoolListOption{}, "modelarts-pool-detail", "List pool", func(cli *huawei.SRegion, args *ModelartsPoolListOption) error { + pool, err := cli.GetIModelartsPoolById(args.PoolId) + if err != nil { + return err + } + printObject(pool) + return nil + }) + + shellutils.R(&cloudprovider.ModelartsPoolCreateOption{}, "modelarts-pool-create", "Create Modelarts Pool", func(cli *huawei.SRegion, args *cloudprovider.ModelartsPoolCreateOption) error { + res, err := cli.CreateIModelartsPool(args) + if err != nil { + return err + } + printObject(res) + return nil + }) + + shellutils.R(&ModelartsPoolListOption{}, "modelarts-pool-delete", "Delete Modelarts Pool", func(cli *huawei.SRegion, args *ModelartsPoolListOption) error { + res, err := cli.DeletePool(args.PoolId) + if err != nil { + return err + } + printObject(res) + return nil + }) + + shellutils.R(&ModelartsPoolListOption{}, "modelarts-pool-monitor", "Delete Modelarts Pool", func(cli *huawei.SRegion, args *ModelartsPoolListOption) error { + res, err := cli.MonitorPool(args.PoolId) + if err != nil { + return err + } + printList(res.Metrics, len(res.Metrics), 0, 0, nil) + return nil + }) +} diff --git a/pkg/multicloud/hcso/shell/modelarts_sku.go b/pkg/multicloud/hcso/shell/modelarts_sku.go new file mode 100644 index 0000000000..adddc35a46 --- /dev/null +++ b/pkg/multicloud/hcso/shell/modelarts_sku.go @@ -0,0 +1,35 @@ +// @@ -0,0 +1,46 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shell + +import ( + huawei "yunion.io/x/onecloud/pkg/multicloud/hcso" + "yunion.io/x/onecloud/pkg/util/shellutils" +) + +func init() { + type ModelartsResourceflavorsListOption struct { + PoolName string `help:"Pool Name"` + } + shellutils.R(&ModelartsResourceflavorsListOption{}, "modelarts-sku-list", "List Modelarts Pool", func(cli *huawei.SRegion, args *ModelartsResourceflavorsListOption) error { + resourceflavors, err := cli.GetIModelartsPoolSku() + if err != nil { + return err + } + printList(resourceflavors, len(resourceflavors), 0, 0, nil) + return nil + }) +}