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 }