yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/hcso/modelarts.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 hcso 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 84 type SNodeFlavor struct { 85 Flavor string `json:"flavor"` 86 Count int `json:"count"` 87 } 88 89 type SModelartsPoolStatus struct { 90 Phase string `json:"phase"` 91 Message string `json:"message"` 92 Resource SNodeStatus `json:"resources"` 93 } 94 95 type SModelartsPoolNetwork struct { 96 Metadata SModelartsPoolNetworkMetadata `json:"metadata"` 97 } 98 99 type SModelartsPoolNetworkMetadata struct { 100 Name string `json:"name"` 101 CreationTimestamp string `json:"creationTimestamp"` 102 } 103 104 func (self *SRegion) GetIModelartsPools() ([]cloudprovider.ICloudModelartsPool, error) { 105 pools := make([]SModelartsPool, 0) 106 resObj, err := self.client.modelartsPoolList(nil) 107 if err != nil { 108 return nil, errors.Wrap(err, "region.GetPools") 109 } 110 err = resObj.Unmarshal(&pools, "items") 111 if err != nil { 112 return nil, errors.Wrap(err, "resObj unmarshal") 113 } 114 res := make([]cloudprovider.ICloudModelartsPool, len(pools)) 115 for i := 0; i < len(pools); i++ { 116 pools[i].region = self 117 res[i] = &pools[i] 118 } 119 120 return res, nil 121 } 122 123 func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreateOption) (cloudprovider.ICloudModelartsPool, error) { 124 netObj, err := self.client.modelartsPoolNetworkList(nil) 125 if err != nil { 126 return nil, errors.Wrap(err, "SHuaweiClient.GetPools") 127 } 128 netRes := make([]SModelartsPoolNetwork, 0) 129 netObj.Unmarshal(&netRes, "items") 130 netId := "" 131 if len(netRes) != 0 { 132 netId = netRes[0].Metadata.Name 133 } else { 134 createNetObj, err := self.client.CreatePoolNetworks() 135 if err != nil { 136 return nil, errors.Wrap(err, "SHuaweiClient.CreatePoolNetworks") 137 } 138 netId, _ = createNetObj.GetString("metadata", "name") 139 } 140 141 scopeArr := strings.Split(args.WorkType, ",") 142 params := map[string]interface{}{ 143 "apiVersion": "v2", 144 "kind": "Pool", 145 "metadata": map[string]interface{}{ 146 "labels": map[string]interface{}{ 147 "os.modelarts/name": args.Name, 148 "os.modelarts/workspace.id": "0", 149 }, 150 }, 151 "spec": map[string]interface{}{ 152 "type": "Dedicate", 153 "scope": scopeArr, 154 "network": map[string]interface{}{ 155 "name": netId, 156 }, 157 158 "resources": []map[string]interface{}{ 159 { 160 "flavor": args.InstanceType, 161 "count": args.NodeCount, 162 }, 163 }, 164 }, 165 } 166 obj, err := self.client.modelartsPoolCreate(params) 167 if err != nil { 168 return nil, errors.Wrap(err, "SHuaweiClient.CreatePools") 169 } 170 pool := &SModelartsPool{} 171 obj.Unmarshal(&pool) 172 res := []cloudprovider.ICloudModelartsPool{} 173 for i := 0; i < 1; i++ { 174 pool.region = self 175 res = append(res, pool) 176 } 177 178 return res[0], nil 179 } 180 181 func (self *SRegion) DeletePool(poolName string) (jsonutils.JSONObject, error) { 182 return self.client.modelartsPoolDelete(poolName, nil) 183 } 184 185 func (self *SRegion) GetIModelartsPoolById(poolId string) (cloudprovider.ICloudModelartsPool, error) { 186 obj, err := self.client.modelartsPoolById(poolId) 187 if err != nil { 188 if strings.Contains(err.Error(), "not found") { 189 return nil, errors.Wrapf(cloudprovider.ErrNotFound, "") 190 } 191 return nil, errors.Wrap(err, "region.modelartsPoolByName") 192 } 193 pool := &SModelartsPool{} 194 obj.Unmarshal(&pool) 195 res := []cloudprovider.ICloudModelartsPool{} 196 for i := 0; i < 1; i++ { 197 pool.region = self 198 res = append(res, pool) 199 } 200 return res[0], nil 201 } 202 203 func (self *SRegion) MonitorPool(poolId string) (*SModelartsMetrics, error) { 204 resObj, err := self.client.modelartsPoolMonitor(poolId, nil) 205 if err != nil { 206 return nil, errors.Wrapf(err, "send request error") 207 } 208 metrics := SModelartsMetrics{} 209 err = resObj.Unmarshal(&metrics) 210 if err != nil { 211 return nil, errors.Wrapf(err, "unmarsh error") 212 } 213 return &metrics, nil 214 } 215 216 type SModelartsMetrics struct { 217 Metrics []SModelartsMetric `json:"metrics"` 218 } 219 220 type SModelartsMetric struct { 221 Metric SModelartsMetricInfo `json:"metric"` 222 Datapoints []SModelartsDataPoints `json:"dataPoints"` 223 } 224 225 type SModelartsMetricInfo struct { 226 Dimensions []SModelartsDimensions `json:"dimensions"` 227 MetricName string 228 Namespace string 229 } 230 231 type SModelartsDimensions struct { 232 Name string 233 Value string 234 } 235 236 type SModelartsDataPoints struct { 237 Timestamp int64 238 Unit string 239 Statistics []ModelartsStatistics 240 } 241 242 type ModelartsStatistics struct { 243 Statistic string 244 Value float64 245 } 246 247 func (self *SHuaweiClient) GetPoolNetworks(poolName string) (jsonutils.JSONObject, error) { 248 return self.modelartsPoolNetworkList(nil) 249 } 250 251 func (self *SHuaweiClient) CreatePoolNetworks() (jsonutils.JSONObject, error) { 252 params := map[string]interface{}{ 253 "apiVersion": "v1", 254 "kind": "Network", 255 "metadata": map[string]interface{}{ 256 "labels": map[string]interface{}{ 257 "os.modelarts/name": "test", 258 "os.modelarts/workspace.id": "0", 259 }, 260 }, 261 "spec": map[string]interface{}{ 262 "cidr": "192.168.20.0/24", 263 }, 264 } 265 return self.modelartsPoolNetworkCreate(params) 266 } 267 268 func (self *SModelartsPool) GetCreatedAt() time.Time { 269 ret, _ := time.Parse("2006-01-02T15:04:05CST", self.Metadata.CreationTimestamp) 270 if !ret.IsZero() { 271 ret = ret.Add(time.Hour * 8) 272 } 273 return ret 274 } 275 276 func (self *SModelartsPool) GetGlobalId() string { 277 return self.Metadata.Name 278 } 279 280 func (self *SModelartsPool) GetId() string { 281 return self.Metadata.Name 282 } 283 284 func (self *SModelartsPool) GetName() string { 285 return self.Metadata.Labels.Name 286 } 287 288 func (self *SModelartsPool) GetStatus() string { 289 res := strings.ToLower(self.Status.Phase) 290 switch { 291 case res == compute.MODELARTS_POOL_STATUS_RUNNING && len(self.Status.Resource.Creating) != 0: 292 res = compute.MODELARTS_POOL_STATUS_CREATING 293 } 294 return res 295 } 296 297 func (self *SModelartsPool) GetSysTags() map[string]string { 298 return nil 299 } 300 301 func (self *SModelartsPool) GetTags() (map[string]string, error) { 302 return nil, nil 303 } 304 305 func (self *SModelartsPool) IsEmulated() bool { 306 return false 307 } 308 309 func (self *SModelartsPool) GetBillingType() string { 310 if self.Metadata.Annotations.BillingType == "1" { 311 return billing_api.BILLING_TYPE_PREPAID 312 } else { 313 return billing_api.BILLING_TYPE_POSTPAID 314 } 315 } 316 317 // 获取资源归属项目Id 318 func (self *SModelartsPool) GetProjectId() string { 319 return self.Metadata.Name 320 } 321 322 func (self *SModelartsPool) GetExpiredAt() time.Time { 323 ret, _ := time.Parse("2006-01-02T15:04:05CST", self.Metadata.CreationTimestamp) 324 if !ret.IsZero() { 325 ret = ret.Add(time.Hour * 8) 326 } 327 return ret 328 } 329 330 func (self *SModelartsPool) IsAutoRenew() bool { 331 return false 332 } 333 334 func (self *SModelartsPool) Renew(bc billing.SBillingCycle) error { 335 return nil 336 } 337 338 func (self *SModelartsPool) SetAutoRenew(bc billing.SBillingCycle) error { 339 return nil 340 } 341 342 func (self *SModelartsPool) Refresh() error { 343 pool, err := self.region.client.modelartsPoolById(self.GetId()) 344 if err != nil { 345 return errors.Wrapf(err, "GetModelartsPool(%s)", self.GetId()) 346 } 347 return jsonutils.Update(self, pool) 348 } 349 350 func (self *SModelartsPool) SetTags(tags map[string]string, replace bool) error { 351 return nil 352 } 353 354 func (self *SModelartsPool) Delete() error { 355 _, err := self.region.DeletePool(self.GetId()) 356 if err != nil { 357 return err 358 } 359 return nil 360 } 361 362 func (self *SModelartsPool) GetInstanceType() string { 363 return self.Spec.Resource[0].Flavor 364 365 } 366 367 func (self *SModelartsPool) GetWorkType() string { 368 return strings.Join(self.Spec.Scope, ",") 369 } 370 371 func (self *SModelartsPool) GetNodeCount() int { 372 if len(self.Spec.Resource) < 1 { 373 return 0 374 } 375 return self.Spec.Resource[0].Count 376 } 377 378 func (self *SModelartsPool) ChangeConfig(opts *cloudprovider.ModelartsPoolChangeConfigOptions) error { 379 //{"spec":{"resources":[{"flavor":"modelarts.kat1.8xlarge","count":2}]}} 380 res := []map[string]interface{}{} 381 for _, re := range self.Spec.Resource { 382 res = append(res, map[string]interface{}{ 383 "flavor": re.Flavor, 384 "count": opts.NodeCount, 385 }) 386 } 387 params := map[string]interface{}{ 388 "spec": map[string]interface{}{ 389 "resources": res, 390 }, 391 } 392 _, err := self.region.client.modelartsPoolUpdate(self.Metadata.Name, params) 393 return err 394 }