yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/huawei/modelarts_pool.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package huawei 16 17 import ( 18 "strings" 19 "time" 20 21 "yunion.io/x/jsonutils" 22 "yunion.io/x/pkg/errors" 23 24 billing_api "yunion.io/x/cloudmux/pkg/apis/billing" 25 "yunion.io/x/cloudmux/pkg/apis/compute" 26 "yunion.io/x/cloudmux/pkg/cloudprovider" 27 "yunion.io/x/cloudmux/pkg/multicloud" 28 "yunion.io/x/onecloud/pkg/util/billing" 29 ) 30 31 type SModelartsPool struct { 32 region *SRegion 33 multicloud.SResourceBase 34 35 Metadata SModelartsPoolMetadata `json:"metadata"` 36 Spec SModelartsPoolSpec `json:"spec"` 37 Status SModelartsPoolStatus `json:"status"` 38 InstanceType string 39 WorkType string 40 } 41 42 type SModelartsPoolMetadata struct { 43 Name string `json:"name"` 44 CreationTimestamp string `json:"creationTimestamp"` 45 Labels SModelartsPoolMeatadataLabel 46 Annotations SModelartsPoolMetadataAnnotations `json:"annotations"` 47 } 48 49 type SModelartsPoolMeatadataLabel struct { 50 WorkspaceId string `json:"os.modelarts/workspace.id"` 51 Name string `json:"os.modelarts/name"` 52 ResourceId string `json:"os.modelarts/resource.id"` 53 } 54 55 type SModelartsPoolMetadataAnnotations struct { 56 Describe string `json:"os.modelarts/description"` 57 BillingType string `json:"os.modelarts/billing.mode"` 58 BillingCycle string `json:"os.modelarts/period.num"` 59 BillingPeriodType string `json:"os.modelarts/period.type"` 60 BillingMod string `json:"os.modelarts/charging.mode"` 61 BillingRenew string `json:"os.modelarts/auto.renew"` 62 OrderId string `json:"os.modelarts/order.id"` 63 } 64 65 type SModelartsPoolSpec struct { 66 Type string `json:"type"` 67 Scope []string `json:"scope"` 68 Resource []SModelartsPoolResource `json:"resources"` 69 } 70 71 type SModelartsPoolResource struct { 72 Flavor string `json:"flavor"` 73 Count int `json:"count"` 74 cloudprovider.Azs 75 } 76 77 type SNodeStatus struct { 78 Creating []SNodeFlavor `json:"creating"` 79 Available []SNodeFlavor `json:"available"` 80 Abnormal []SNodeFlavor `json:"abnormal"` 81 Deleting []SNodeFlavor `json:"deleting"` 82 } 83 type SNodeFlavor struct { 84 Flavor string `json:"flavor"` 85 Count int `json:"count"` 86 } 87 88 type SModelartsPoolStatus struct { 89 Phase string `json:"phase"` 90 Message string `json:"message"` 91 Resource SNodeStatus `json:"resources"` 92 } 93 94 type SModelartsPoolNetwork struct { 95 Metadata SModelartsPoolNetworkMetadata `json:"metadata"` 96 } 97 98 type SModelartsPoolNetworkMetadata struct { 99 Name string `json:"name"` 100 CreationTimestamp string `json:"creationTimestamp"` 101 } 102 103 func (self *SRegion) GetIModelartsPools() ([]cloudprovider.ICloudModelartsPool, error) { 104 pools := make([]SModelartsPool, 0) 105 resObj, err := self.client.modelartsPoolList("pools", nil) 106 if err != nil { 107 return nil, errors.Wrap(err, "region.GetPools") 108 } 109 err = resObj.Unmarshal(&pools, "items") 110 if err != nil { 111 return nil, errors.Wrap(err, "resObj unmarshal") 112 } 113 res := make([]cloudprovider.ICloudModelartsPool, len(pools)) 114 for i := 0; i < len(pools); i++ { 115 pools[i].region = self 116 res[i] = &pools[i] 117 } 118 119 return res, nil 120 } 121 122 func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreateOption) (cloudprovider.ICloudModelartsPool, error) { 123 netObj, err := self.client.modelartsPoolNetworkList("network", nil) 124 if err != nil { 125 return nil, errors.Wrap(err, "SHuaweiClient.GetPools") 126 } 127 netRes := make([]SModelartsPoolNetwork, 0) 128 netObj.Unmarshal(&netRes, "items") 129 netId := "" 130 if len(netRes) != 0 { 131 netId = netRes[0].Metadata.Name 132 } else { 133 createNetObj, err := self.client.CreatePoolNetworks() 134 if err != nil { 135 return nil, errors.Wrap(err, "SHuaweiClient.CreatePoolNetworks") 136 } 137 netId, _ = createNetObj.GetString("metadata", "name") 138 } 139 140 scopeArr := strings.Split(args.WorkType, ",") 141 params := map[string]interface{}{ 142 "apiVersion": "v2", 143 "kind": "Pool", 144 "metadata": map[string]interface{}{ 145 "labels": map[string]interface{}{ 146 "os.modelarts/name": args.Name, 147 "os.modelarts/workspace.id": "0", 148 }, 149 }, 150 "spec": map[string]interface{}{ 151 "type": "Dedicate", 152 "scope": scopeArr, 153 "network": map[string]interface{}{ 154 "name": netId, 155 }, 156 157 "resources": []map[string]interface{}{ 158 { 159 "flavor": args.InstanceType, 160 "count": args.NodeCount, 161 }, 162 }, 163 }, 164 } 165 obj, err := self.client.modelartsPoolCreate("pools", params) 166 if err != nil { 167 return nil, errors.Wrap(err, "SHuaweiClient.CreatePools") 168 } 169 pool := &SModelartsPool{} 170 obj.Unmarshal(&pool) 171 res := []cloudprovider.ICloudModelartsPool{} 172 for i := 0; i < 1; i++ { 173 pool.region = self 174 res = append(res, pool) 175 } 176 177 return res[0], nil 178 } 179 180 func (self *SRegion) DeletePool(poolName string) (jsonutils.JSONObject, error) { 181 return self.client.modelartsPoolDelete("pools", poolName, nil) 182 } 183 184 func (self *SRegion) GetIModelartsPoolById(poolId string) (cloudprovider.ICloudModelartsPool, error) { 185 obj, err := self.client.modelartsPoolById(poolId) 186 if err != nil { 187 if strings.Contains(err.Error(), "not found") { 188 return nil, errors.Wrapf(cloudprovider.ErrNotFound, "") 189 } 190 return nil, errors.Wrap(err, "region.modelartsPoolByName") 191 } 192 pool := &SModelartsPool{} 193 obj.Unmarshal(&pool) 194 res := []cloudprovider.ICloudModelartsPool{} 195 for i := 0; i < 1; i++ { 196 pool.region = self 197 res = append(res, pool) 198 } 199 return res[0], nil 200 } 201 202 func (self *SRegion) MonitorPool(poolId string) (*SModelartsMetrics, error) { 203 resObj, err := self.client.modelartsPoolMonitor(poolId, nil) 204 if err != nil { 205 return nil, errors.Wrapf(err, "send request error") 206 } 207 metrics := SModelartsMetrics{} 208 err = resObj.Unmarshal(&metrics) 209 if err != nil { 210 return nil, errors.Wrapf(err, "unmarsh error") 211 } 212 return &metrics, nil 213 } 214 215 type SModelartsMetrics struct { 216 Metrics []SModelartsMetric `json:"metrics"` 217 } 218 219 type SModelartsMetric struct { 220 Metric SModelartsMetricInfo `json:"metric"` 221 Datapoints []SModelartsDataPoints `json:"dataPoints"` 222 } 223 224 type SModelartsMetricInfo struct { 225 Dimensions []SModelartsDimensions `json:"dimensions"` 226 MetricName string 227 Namespace string 228 } 229 230 type SModelartsDimensions struct { 231 Name string 232 Value string 233 } 234 235 type SModelartsDataPoints struct { 236 Timestamp int64 237 Unit string 238 Statistics []ModelartsStatistics 239 } 240 241 type ModelartsStatistics struct { 242 Statistic string 243 Value float64 244 } 245 246 func (self *SHuaweiClient) GetPoolNetworks(poolName string) (jsonutils.JSONObject, error) { 247 return self.modelartsPoolNetworkList(poolName, nil) 248 } 249 250 func (self *SHuaweiClient) CreatePoolNetworks() (jsonutils.JSONObject, error) { 251 params := map[string]interface{}{ 252 "apiVersion": "v1", 253 "kind": "Network", 254 "metadata": map[string]interface{}{ 255 "labels": map[string]interface{}{ 256 "os.modelarts/name": "test", 257 "os.modelarts/workspace.id": "0", 258 }, 259 }, 260 "spec": map[string]interface{}{ 261 "cidr": "192.168.20.0/24", 262 }, 263 } 264 return self.modelartsPoolNetworkCreate(params) 265 } 266 267 func (self *SModelartsPool) GetCreatedAt() time.Time { 268 ret, _ := time.Parse("2006-01-02T15:04:05CST", self.Metadata.CreationTimestamp) 269 if !ret.IsZero() { 270 ret = ret.Add(time.Hour * 8) 271 } 272 return ret 273 } 274 275 func (self *SModelartsPool) GetGlobalId() string { 276 return self.Metadata.Name 277 } 278 279 func (self *SModelartsPool) GetId() string { 280 return self.Metadata.Name 281 } 282 283 func (self *SModelartsPool) GetName() string { 284 return self.Metadata.Labels.Name 285 } 286 287 func (self *SModelartsPool) GetStatus() string { 288 res := strings.ToLower(self.Status.Phase) 289 switch { 290 case res == compute.MODELARTS_POOL_STATUS_RUNNING && len(self.Status.Resource.Creating) != 0: 291 res = compute.MODELARTS_POOL_STATUS_CREATING 292 } 293 return res 294 } 295 296 func (self *SModelartsPool) GetSysTags() map[string]string { 297 return nil 298 } 299 300 func (self *SModelartsPool) GetTags() (map[string]string, error) { 301 return nil, nil 302 } 303 304 func (self *SModelartsPool) IsEmulated() bool { 305 return false 306 } 307 308 func (self *SModelartsPool) GetBillingType() string { 309 if self.Metadata.Annotations.BillingType == "1" { 310 return billing_api.BILLING_TYPE_PREPAID 311 } else { 312 return billing_api.BILLING_TYPE_POSTPAID 313 } 314 } 315 316 // 获取资源归属项目Id 317 func (self *SModelartsPool) GetProjectId() string { 318 return self.Metadata.Name 319 } 320 321 func (self *SModelartsPool) GetExpiredAt() time.Time { 322 ret, _ := time.Parse("2006-01-02T15:04:05CST", self.Metadata.CreationTimestamp) 323 if !ret.IsZero() { 324 ret = ret.Add(time.Hour * 8) 325 } 326 return ret 327 } 328 329 func (self *SModelartsPool) IsAutoRenew() bool { 330 return false 331 } 332 333 func (self *SModelartsPool) Renew(bc billing.SBillingCycle) error { 334 return nil 335 } 336 337 func (self *SModelartsPool) SetAutoRenew(bc billing.SBillingCycle) error { 338 return nil 339 } 340 341 func (self *SModelartsPool) Refresh() error { 342 pool, err := self.region.client.modelartsPoolById(self.GetId()) 343 if err != nil { 344 return errors.Wrapf(err, "GetModelartsPool(%s)", self.GetId()) 345 } 346 return jsonutils.Update(self, pool) 347 } 348 349 func (self *SModelartsPool) SetTags(tags map[string]string, replace bool) error { 350 return nil 351 } 352 353 func (self *SModelartsPool) Delete() error { 354 _, err := self.region.DeletePool(self.GetId()) 355 if err != nil { 356 return err 357 } 358 return nil 359 } 360 361 func (self *SModelartsPool) GetInstanceType() string { 362 return self.Spec.Resource[0].Flavor 363 364 } 365 366 func (self *SModelartsPool) GetWorkType() string { 367 return strings.Join(self.Spec.Scope, ",") 368 } 369 370 func (self *SModelartsPool) GetNodeCount() int { 371 if len(self.Spec.Resource) < 1 { 372 return 0 373 } 374 return self.Spec.Resource[0].Count 375 } 376 377 func (self *SModelartsPool) ChangeConfig(opts *cloudprovider.ModelartsPoolChangeConfigOptions) error { 378 //{"spec":{"resources":[{"flavor":"modelarts.kat1.8xlarge","count":2}]}} 379 res := []map[string]interface{}{} 380 for _, re := range self.Spec.Resource { 381 res = append(res, map[string]interface{}{ 382 "flavor": re.Flavor, 383 "count": opts.NodeCount, 384 }) 385 } 386 params := map[string]interface{}{ 387 "spec": map[string]interface{}{ 388 "resources": res, 389 }, 390 } 391 _, err := self.region.client.modelartsPoolUpdate(self.Metadata.Name, params) 392 return err 393 }