yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/qcloud/cdn.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 qcloud
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  
    21  	"yunion.io/x/jsonutils"
    22  	"yunion.io/x/pkg/errors"
    23  
    24  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    25  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    26  	"yunion.io/x/cloudmux/pkg/multicloud"
    27  )
    28  
    29  type SCdnOrigin struct {
    30  	Origins            []string `json:"Origins"`
    31  	OriginType         string   `json:"OriginType"`
    32  	ServerName         string   `json:"ServerName"`
    33  	CosPrivateAccess   string   `json:"CosPrivateAccess"`
    34  	OriginPullProtocol string   `json:"OriginPullProtocol"`
    35  	BackupOrigins      []string `json:"BackupOrigins"`
    36  	BackupOriginType   string   `json:"BackupOriginType"`
    37  	BackupServerName   string   `json:"BackupServerName"`
    38  }
    39  
    40  type SCdnDomain struct {
    41  	multicloud.SResourceBase
    42  	QcloudTags
    43  
    44  	client *SQcloudClient
    45  
    46  	Area        string     `json:"Area"`
    47  	Cname       string     `json:"Cname"`
    48  	CreateTime  string     `json:"CreateTime"`
    49  	Disable     string     `json:"Disable"`
    50  	Domain      string     `json:"Domain"`
    51  	Origin      SCdnOrigin `json:"Origin"`
    52  	ProjectID   int        `json:"ProjectId"`
    53  	Readonly    string     `json:"Readonly"`
    54  	ResourceID  string     `json:"ResourceId"`
    55  	ServiceType string     `json:"ServiceType"`
    56  	Status      string     `json:"Status"`
    57  	UpdateTime  string     `json:"UpdateTime"`
    58  }
    59  
    60  func (self *SCdnDomain) GetName() string {
    61  	return self.Domain
    62  }
    63  
    64  func (self *SCdnDomain) GetGlobalId() string {
    65  	return self.Domain
    66  }
    67  
    68  func (self *SCdnDomain) GetId() string {
    69  	return self.Domain
    70  }
    71  
    72  func (self *SCdnDomain) GetStatus() string {
    73  	return self.Status
    74  }
    75  
    76  func (self *SCdnDomain) GetEnabled() bool {
    77  	return self.Disable == "normal"
    78  }
    79  
    80  func (self *SCdnDomain) GetCname() string {
    81  	return self.Cname
    82  }
    83  
    84  func (self *SCdnDomain) GetOrigins() *cloudprovider.SCdnOrigins {
    85  	ret := cloudprovider.SCdnOrigins{}
    86  	if self.Origin.OriginType == "cos" {
    87  		self.Origin.OriginType = api.CDN_DOMAIN_ORIGIN_TYPE_BUCKET
    88  	}
    89  	for _, org := range self.Origin.Origins {
    90  		ret = append(ret, cloudprovider.SCdnOrigin{
    91  			Type:       self.Origin.OriginType,
    92  			ServerName: self.Origin.ServerName,
    93  			Protocol:   self.Origin.OriginPullProtocol,
    94  			Origin:     org,
    95  		})
    96  	}
    97  	for _, org := range self.Origin.BackupOrigins {
    98  		ret = append(ret, cloudprovider.SCdnOrigin{
    99  			Type:       self.Origin.BackupOriginType,
   100  			ServerName: self.Origin.BackupServerName,
   101  			Origin:     org,
   102  		})
   103  	}
   104  	return &ret
   105  }
   106  
   107  func (self *SCdnDomain) GetArea() string {
   108  	return self.Area
   109  }
   110  
   111  func (self *SCdnDomain) GetServiceType() string {
   112  	return self.ServiceType
   113  }
   114  
   115  func (self *SQcloudClient) GetCdnDomain(domain string) (*SCdnDomain, error) {
   116  	domains, _, err := self.DescribeCdnDomains([]string{domain}, nil, "", 0, 100)
   117  	if err != nil {
   118  		return nil, errors.Wrapf(err, "DescribeCdnDomains")
   119  	}
   120  	for i := range domains {
   121  		if domains[i].Domain == domain {
   122  			domains[i].client = self
   123  			return &domains[i], nil
   124  		}
   125  	}
   126  	return nil, errors.Wrapf(cloudprovider.ErrNotFound, domain)
   127  }
   128  
   129  func (self *SCdnDomain) Refresh() error {
   130  	domain, err := self.client.GetCdnDomain(self.Domain)
   131  	if err != nil {
   132  		return err
   133  	}
   134  	return jsonutils.Update(self, domain)
   135  }
   136  
   137  func (self *SCdnDomain) Delete() error {
   138  	err := self.client.StopCdnDomain(self.Domain)
   139  	if err != nil {
   140  		return errors.Wrapf(err, "StopCdnDomain")
   141  	}
   142  	return self.client.DeleteCdnDomain(self.Domain)
   143  }
   144  
   145  func (self *SCdnDomain) SetTags(tags map[string]string, replace bool) error {
   146  	region, err := self.client.getDefaultRegion()
   147  	if err != nil {
   148  		return errors.Wrapf(err, "getDefaultRegion")
   149  	}
   150  	return region.SetResourceTags("cdn", "domain", []string{self.Domain}, tags, replace)
   151  }
   152  
   153  func (self *SQcloudClient) StopCdnDomain(domain string) error {
   154  	params := map[string]string{
   155  		"Domain": domain,
   156  	}
   157  	_, err := self.cdnRequest("StopCdnDomain", params)
   158  	return errors.Wrapf(err, "StopCdnDomain")
   159  }
   160  
   161  func (self *SQcloudClient) StartCdnDomain(domain string) error {
   162  	params := map[string]string{
   163  		"Domain": domain,
   164  	}
   165  	_, err := self.cdnRequest("StartCdnDomain", params)
   166  	return errors.Wrapf(err, "StartCdnDomain")
   167  }
   168  
   169  func (self *SQcloudClient) DeleteCdnDomain(domain string) error {
   170  	params := map[string]string{
   171  		"Domain": domain,
   172  	}
   173  	_, err := self.cdnRequest("DeleteCdnDomain", params)
   174  	return errors.Wrapf(err, "DeleteCdnDomain")
   175  }
   176  
   177  type SDomains struct {
   178  	RequestID   string       `json:"RequestId"`
   179  	Domains     []SCdnDomain `json:"Domains"`
   180  	TotalNumber int          `json:"TotalNumber"`
   181  }
   182  
   183  func (self *SQcloudClient) GetICloudCDNDomains() ([]cloudprovider.ICloudCDNDomain, error) {
   184  	cdns, err := self.DescribeAllCdnDomains(nil, nil, "")
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  	ret := []cloudprovider.ICloudCDNDomain{}
   189  	for i := range cdns {
   190  		cdns[i].client = self
   191  		ret = append(ret, &cdns[i])
   192  	}
   193  	return ret, nil
   194  }
   195  
   196  func (self *SQcloudClient) GetICloudCDNDomainByName(name string) (cloudprovider.ICloudCDNDomain, error) {
   197  	domains, _, err := self.DescribeCdnDomains([]string{name}, nil, "", 0, 1)
   198  	if err != nil {
   199  		return nil, errors.Wrapf(err, "DescribeCdnDomains")
   200  	}
   201  	for i := range domains {
   202  		if domains[i].Domain == name {
   203  			domains[i].client = self
   204  			return &domains[i], nil
   205  		}
   206  	}
   207  	return nil, errors.Wrapf(cloudprovider.ErrNotFound, name)
   208  }
   209  
   210  func (client *SQcloudClient) AddCdnDomain(domain string, originType string, origins []string, cosPrivateAccess string) error {
   211  	params := map[string]string{}
   212  	params["Domain"] = domain
   213  	params["ServiceType"] = "web"
   214  	for i := range origins {
   215  		params[fmt.Sprintf("Origin.Origins.%d", i)] = origins[i]
   216  	}
   217  	params["Origin.OriginType"] = originType
   218  	params["Origin.CosPrivateAccess"] = cosPrivateAccess
   219  	_, err := client.cdnRequest("AddCdnDomain", params)
   220  	if err != nil {
   221  		return errors.Wrapf(err, `AddCdnDomain %s`, params)
   222  	}
   223  	return nil
   224  }
   225  
   226  func (client *SQcloudClient) DescribeCdnDomains(domains, origins []string, domainType string, offset int, limit int) ([]SCdnDomain, int, error) {
   227  	params := map[string]string{}
   228  	params["Offset"] = strconv.Itoa(offset)
   229  	params["Limit"] = strconv.Itoa(limit)
   230  	filterIndex := 0
   231  	if len(domains) > 0 {
   232  		params[fmt.Sprintf("Filters.%d.Name", filterIndex)] = "domain"
   233  		for i := range domains {
   234  			params[fmt.Sprintf("Filters.%d.Value.%d", filterIndex, i)] = domains[i]
   235  		}
   236  		filterIndex++
   237  	}
   238  	if len(origins) > 0 {
   239  		params[fmt.Sprintf("Filters.%d.Name", filterIndex)] = "origin"
   240  		for i := range origins {
   241  			params[fmt.Sprintf("Filters.%d.Value.%d", filterIndex, i)] = origins[i]
   242  		}
   243  		filterIndex++
   244  	}
   245  
   246  	if len(domainType) > 0 {
   247  		params[fmt.Sprintf("Filters.%d.Name", filterIndex)] = "domainType"
   248  		params[fmt.Sprintf("Filters.%d.Value.0", filterIndex)] = domainType
   249  		filterIndex++
   250  	}
   251  
   252  	resp, err := client.cdnRequest("DescribeDomainsConfig", params)
   253  	if err != nil {
   254  		return nil, 0, errors.Wrapf(err, "DescribeDomainsConfig %s", params)
   255  	}
   256  	cdnDomains := []SCdnDomain{}
   257  	err = resp.Unmarshal(&cdnDomains, "Domains")
   258  	if err != nil {
   259  		return nil, 0, errors.Wrapf(err, "resp.Unmarshal")
   260  	}
   261  	totalcount, _ := resp.Float("TotalNumber")
   262  	return cdnDomains, int(totalcount), nil
   263  }
   264  
   265  func (client *SQcloudClient) DescribeAllCdnDomains(domains, origins []string, domainType string) ([]SCdnDomain, error) {
   266  	cdnDomains := make([]SCdnDomain, 0)
   267  	for {
   268  		part, total, err := client.DescribeCdnDomains(domains, origins, domainType, len(cdnDomains), 50)
   269  		if err != nil {
   270  			return nil, errors.Wrap(err, "DescribeCdnDomains")
   271  		}
   272  		cdnDomains = append(cdnDomains, part...)
   273  		if len(cdnDomains) >= total {
   274  			break
   275  		}
   276  	}
   277  	return cdnDomains, nil
   278  }
   279  
   280  func (self *SQcloudClient) CreateCDNDomain(opts *cloudprovider.CdnCreateOptions) (*SCdnDomain, error) {
   281  	params := map[string]string{
   282  		"Domain":      opts.Domain,
   283  		"ServiceType": opts.ServiceType,
   284  	}
   285  	if len(opts.Area) > 0 {
   286  		params["Area"] = opts.Area
   287  	}
   288  	originTypes := map[string][]string{}
   289  	for _, origin := range opts.Origins {
   290  		_, ok := originTypes[origin.Type]
   291  		if !ok {
   292  			originTypes[origin.Type] = []string{}
   293  		}
   294  		originTypes[origin.Type] = append(originTypes[origin.Type], origin.Origin)
   295  	}
   296  	for _, origin := range opts.Origins {
   297  		params["Origin.OriginType"] = origin.Type
   298  		if origin.Type == api.CDN_DOMAIN_ORIGIN_TYPE_BUCKET {
   299  			params["Origin.OriginType"] = "cos"
   300  		}
   301  		if len(origin.ServerName) > 0 {
   302  			params["Origin.ServerName"] = origin.ServerName
   303  		} else {
   304  			params["Origin.ServerName"] = origin.Origin
   305  		}
   306  		if len(origin.Protocol) > 0 {
   307  			params["Origin.OriginPullProtocol"] = origin.Protocol
   308  		}
   309  		origins, ok := originTypes[origin.Type]
   310  		if ok {
   311  			for i, origin := range origins {
   312  				params[fmt.Sprintf("Origin.Origins.%d", i)] = origin
   313  			}
   314  		}
   315  	}
   316  	_, err := self.cdnRequest("AddCdnDomain", params)
   317  	if err != nil {
   318  		return nil, errors.Wrapf(err, "AddCdnDomain")
   319  	}
   320  	return self.GetCdnDomain(opts.Domain)
   321  }