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  }