yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/filesystem.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 aliyun
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  	"time"
    21  
    22  	"yunion.io/x/jsonutils"
    23  	"yunion.io/x/pkg/errors"
    24  	"yunion.io/x/pkg/utils"
    25  
    26  	billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
    27  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    28  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    29  	"yunion.io/x/cloudmux/pkg/multicloud"
    30  )
    31  
    32  type SupportedFeatures struct {
    33  	SupportedFeature []string
    34  }
    35  
    36  type MountTargets struct {
    37  	MountTarget []SMountTarget
    38  }
    39  
    40  type Package struct {
    41  }
    42  
    43  type Packages struct {
    44  	Package []Package
    45  }
    46  
    47  type SFileSystem struct {
    48  	multicloud.SNasBase
    49  	AliyunTags
    50  	region *SRegion
    51  
    52  	Status                string
    53  	Description           string
    54  	StorageType           string
    55  	MountTargetCountLimit int
    56  	Ldap                  string
    57  	ZoneId                string
    58  	// 2021-03-22T10:08:15CST
    59  	CreateTime           string
    60  	MeteredIASize        int
    61  	SupportedFeatures    SupportedFeatures
    62  	MountTargets         MountTargets
    63  	AutoSnapshotPolicyId string
    64  	MeteredSize          int64
    65  	EncryptType          int
    66  	Capacity             int64
    67  	ProtocolType         string
    68  	ChargeType           string
    69  	Packages             Packages
    70  	ExpiredTime          string
    71  	FileSystemType       string
    72  	FileSystemId         string
    73  	RegionId             string
    74  }
    75  
    76  func (self *SFileSystem) GetId() string {
    77  	return self.FileSystemId
    78  }
    79  
    80  func (self *SFileSystem) GetGlobalId() string {
    81  	return self.FileSystemId
    82  }
    83  
    84  func (self *SFileSystem) GetName() string {
    85  	if len(self.Description) > 0 {
    86  		return self.Description
    87  	}
    88  	return self.FileSystemId
    89  }
    90  
    91  func (self *SFileSystem) GetFileSystemType() string {
    92  	return self.FileSystemType
    93  }
    94  
    95  func (self *SFileSystem) GetMountTargetCountLimit() int {
    96  	return self.MountTargetCountLimit
    97  }
    98  
    99  func (self *SFileSystem) GetStatus() string {
   100  	switch self.Status {
   101  	case "", "Running":
   102  		return api.NAS_STATUS_AVAILABLE
   103  	case "Extending":
   104  		return api.NAS_STATUS_EXTENDING
   105  	case "Stopping", "Stopped":
   106  		return api.NAS_STATUS_UNAVAILABLE
   107  	case "Pending":
   108  		return api.NAS_STATUS_CREATING
   109  	default:
   110  		return api.NAS_STATUS_UNKNOWN
   111  	}
   112  }
   113  
   114  func (self *SFileSystem) GetBillintType() string {
   115  	if self.ChargeType == "PayAsYouGo" {
   116  		return billing_api.BILLING_TYPE_POSTPAID
   117  	}
   118  	return billing_api.BILLING_TYPE_PREPAID
   119  }
   120  
   121  func (self *SFileSystem) GetStorageType() string {
   122  	return strings.ToLower(self.StorageType)
   123  }
   124  
   125  func (self *SFileSystem) GetProtocol() string {
   126  	return self.ProtocolType
   127  }
   128  
   129  func (self *SFileSystem) GetCapacityGb() int64 {
   130  	return self.Capacity
   131  }
   132  
   133  func (self *SFileSystem) GetUsedCapacityGb() int64 {
   134  	return self.MeteredSize
   135  }
   136  
   137  func (self *SFileSystem) GetZoneId() string {
   138  	return self.ZoneId
   139  }
   140  
   141  func (self *SFileSystem) Delete() error {
   142  	return self.region.DeleteFileSystem(self.FileSystemId)
   143  }
   144  
   145  func (self *SFileSystem) GetCreatedAt() time.Time {
   146  	ret, _ := time.Parse("2006-01-02T15:04:05CST", self.CreateTime)
   147  	if !ret.IsZero() {
   148  		ret = ret.Add(time.Hour * 8)
   149  	}
   150  	return ret
   151  }
   152  
   153  func (self *SFileSystem) GetExpiredAt() time.Time {
   154  	ret, _ := time.Parse("2006-01-02T15:04:05CST", self.ExpiredTime)
   155  	if !ret.IsZero() {
   156  		ret = ret.Add(time.Hour * 8)
   157  	}
   158  	return ret
   159  }
   160  
   161  func (self *SFileSystem) Refresh() error {
   162  	fs, err := self.region.GetFileSystem(self.FileSystemId)
   163  	if err != nil {
   164  		return errors.Wrapf(err, "GetFileSystem(%s)", self.FileSystemId)
   165  	}
   166  	return jsonutils.Update(self, fs)
   167  }
   168  
   169  func (self *SRegion) GetFileSystems(id string, pageSize, pageNum int) ([]SFileSystem, int, error) {
   170  	if pageSize < 1 || pageSize > 100 {
   171  		pageSize = 50
   172  	}
   173  	if pageNum < 1 {
   174  		pageNum = 1
   175  	}
   176  	params := map[string]string{
   177  		"RegionId":   self.RegionId,
   178  		"PageSize":   fmt.Sprintf("%d", pageSize),
   179  		"PageNumber": fmt.Sprintf("%d", pageNum),
   180  	}
   181  	if len(id) > 0 {
   182  		params["FileSystemId"] = id
   183  	}
   184  	resp, err := self.nasRequest("DescribeFileSystems", params)
   185  	if err != nil {
   186  		return nil, 0, errors.Wrapf(err, "DescribeFileSystems")
   187  	}
   188  	ret := struct {
   189  		TotalCount  int
   190  		FileSystems struct {
   191  			FileSystem []SFileSystem
   192  		}
   193  	}{}
   194  	err = resp.Unmarshal(&ret)
   195  	if err != nil {
   196  		return nil, 0, errors.Wrapf(err, "resp.Unmarshal")
   197  	}
   198  	return ret.FileSystems.FileSystem, ret.TotalCount, nil
   199  }
   200  
   201  func (self *SRegion) GetICloudFileSystems() ([]cloudprovider.ICloudFileSystem, error) {
   202  	nas := []SFileSystem{}
   203  	num := 1
   204  	for {
   205  		part, total, err := self.GetFileSystems("", 100, num)
   206  		if err != nil {
   207  			return nil, errors.Wrapf(err, "GetFileSystems")
   208  		}
   209  		nas = append(nas, part...)
   210  		if total <= len(nas) {
   211  			break
   212  		}
   213  		num++
   214  	}
   215  
   216  	ret := []cloudprovider.ICloudFileSystem{}
   217  	for i := range nas {
   218  		nas[i].region = self
   219  		ret = append(ret, &nas[i])
   220  	}
   221  	return ret, nil
   222  }
   223  
   224  func (self *SRegion) GetFileSystem(id string) (*SFileSystem, error) {
   225  	if len(id) == 0 {
   226  		return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty id")
   227  	}
   228  	nas, total, err := self.GetFileSystems(id, 1, 1)
   229  	if err != nil {
   230  		return nil, errors.Wrapf(err, "GetFileSystems")
   231  	}
   232  	if total == 1 {
   233  		nas[0].region = self
   234  		return &nas[0], nil
   235  	}
   236  	if total == 0 {
   237  		return nil, errors.Wrapf(cloudprovider.ErrNotFound, id)
   238  	}
   239  	return nil, errors.Wrapf(cloudprovider.ErrDuplicateId, id)
   240  }
   241  
   242  func (self *SRegion) GetICloudFileSystemById(id string) (cloudprovider.ICloudFileSystem, error) {
   243  	fs, err := self.GetFileSystem(id)
   244  	if err != nil {
   245  		return nil, errors.Wrapf(err, "self.GetFileSystem")
   246  	}
   247  	return fs, nil
   248  }
   249  
   250  func (self *SRegion) CreateMountTarget(opts *cloudprovider.SMountTargetCreateOptions) (*SMountTarget, error) {
   251  	params := map[string]string{
   252  		"RegionId":        self.RegionId,
   253  		"FileSystemId":    opts.FileSystemId,
   254  		"AccessGroupName": strings.TrimPrefix(strings.TrimPrefix(opts.AccessGroupId, "extreme/"), "standard/"),
   255  		"NetworkType":     utils.Capitalize(opts.NetworkType),
   256  		"VpcId":           opts.VpcId,
   257  		"VSwitchId":       opts.NetworkId,
   258  	}
   259  	resp, err := self.nasRequest("CreateMountTarget", params)
   260  	if err != nil {
   261  		return nil, errors.Wrapf(err, "CreateMountTarget")
   262  	}
   263  	ret := struct {
   264  		MountTargetDomain string
   265  	}{}
   266  	err = resp.Unmarshal(&ret)
   267  	if err != nil {
   268  		return nil, errors.Wrapf(err, "resp.Unmarshal")
   269  	}
   270  	mts, _, err := self.GetMountTargets(opts.FileSystemId, ret.MountTargetDomain, 10, 1)
   271  	if err != nil {
   272  		return nil, errors.Wrapf(err, "self.GetMountTargets")
   273  	}
   274  	for i := range mts {
   275  		if mts[i].MountTargetDomain == ret.MountTargetDomain {
   276  			return &mts[i], nil
   277  		}
   278  	}
   279  	return nil, errors.Wrapf(cloudprovider.ErrNotFound, "afeter create with mount domain %s", ret.MountTargetDomain)
   280  }
   281  
   282  func (self *SFileSystem) CreateMountTarget(opts *cloudprovider.SMountTargetCreateOptions) (cloudprovider.ICloudMountTarget, error) {
   283  	mt, err := self.region.CreateMountTarget(opts)
   284  	if err != nil {
   285  		return nil, errors.Wrapf(err, "CreateMountTarget")
   286  	}
   287  	mt.fs = self
   288  	return mt, nil
   289  }
   290  
   291  func (self *SRegion) DeleteFileSystem(id string) error {
   292  	params := map[string]string{
   293  		"RegionId":     self.RegionId,
   294  		"FileSystemId": id,
   295  	}
   296  	_, err := self.nasRequest("DeleteFileSystem", params)
   297  	return errors.Wrapf(err, "DeleteFileSystem")
   298  }
   299  
   300  func (self *SRegion) CreateICloudFileSystem(opts *cloudprovider.FileSystemCraeteOptions) (cloudprovider.ICloudFileSystem, error) {
   301  	fs, err := self.CreateFileSystem(opts)
   302  	if err != nil {
   303  		return nil, errors.Wrapf(err, "self.CreateFileSystem")
   304  	}
   305  	return fs, nil
   306  }
   307  
   308  func (self *SRegion) CreateFileSystem(opts *cloudprovider.FileSystemCraeteOptions) (*SFileSystem, error) {
   309  	params := map[string]string{
   310  		"RegionId":       self.RegionId,
   311  		"ProtocolType":   opts.Protocol,
   312  		"ZoneId":         opts.ZoneId,
   313  		"EncryptType":    "0",
   314  		"FileSystemType": opts.FileSystemType,
   315  		"StorageType":    opts.StorageType,
   316  		"ClientToken":    utils.GenRequestId(20),
   317  		"Description":    opts.Name,
   318  	}
   319  
   320  	if self.GetCloudEnv() == ALIYUN_FINANCE_CLOUDENV {
   321  		if opts.FileSystemType == "standard" {
   322  			opts.ZoneId = strings.Replace(opts.ZoneId, "cn-shanghai-finance-1", "jr-cn-shanghai-", 1)
   323  			opts.ZoneId = strings.Replace(opts.ZoneId, "cn-shenzhen-finance-1", "jr-cn-shenzhen-", 1)
   324  			params["ZoneId"] = opts.ZoneId
   325  		}
   326  	}
   327  
   328  	switch opts.FileSystemType {
   329  	case "standard":
   330  		params["StorageType"] = utils.Capitalize(opts.StorageType)
   331  	case "cpfs":
   332  		params["ProtocolType"] = "cpfs"
   333  		switch opts.StorageType {
   334  		case "advance_100":
   335  			params["Bandwidth"] = "100"
   336  		case "advance_200":
   337  			params["Bandwidth"] = "200"
   338  		}
   339  	case "extreme":
   340  		params["Capacity"] = fmt.Sprintf("%d", opts.Capacity)
   341  	}
   342  	if len(opts.VpcId) > 0 {
   343  		params["VpcId"] = opts.VpcId
   344  	}
   345  	if len(opts.NetworkId) > 0 {
   346  		params["VSwitchId"] = opts.NetworkId
   347  	}
   348  	if opts.BillingCycle != nil {
   349  		params["ChargeType"] = "Subscription"
   350  		params["Duration"] = fmt.Sprintf("%d", opts.BillingCycle.GetMonths())
   351  	}
   352  	resp, err := self.nasRequest("CreateFileSystem", params)
   353  	if err != nil {
   354  		return nil, errors.Wrapf(err, "CreateFileSystem")
   355  	}
   356  	fsId, _ := resp.GetString("FileSystemId")
   357  	return self.GetFileSystem(fsId)
   358  }
   359  
   360  func (self *SFileSystem) SetTags(tags map[string]string, replace bool) error {
   361  	return self.region.SetResourceTags(ALIYUN_SERVICE_NAS, "filesystem", self.FileSystemId, tags, replace)
   362  }