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  }