diff --git a/go.mod b/go.mod index b9a7276611..adb6aac8eb 100644 --- a/go.mod +++ b/go.mod @@ -81,7 +81,7 @@ require ( k8s.io/client-go v0.19.3 k8s.io/cluster-bootstrap v0.19.3 moul.io/http2curl/v2 v2.3.0 - yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230131095206-0d758294026e + yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230206033907-593ed22677c6 yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 yunion.io/x/jsonutils v1.0.1-0.20220819091305-3bab322ab4fd yunion.io/x/log v1.0.0 diff --git a/go.sum b/go.sum index 96d99e794e..3344981107 100644 --- a/go.sum +++ b/go.sum @@ -1158,8 +1158,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230131095206-0d758294026e h1:5YrzMsfD+p+wWvmHCWxIrwRqCJDpz8uliRAuY7hieT8= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230131095206-0d758294026e/go.mod h1:yEMFtIKPyIdIfPzsw7oTcH41JXc8G5StUAQw3ZoGj5I= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230206033907-593ed22677c6 h1:S3ZxAAae4qmlWYLDKJCQCUeUEOT3LhdvDB18h0oPqQI= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230206033907-593ed22677c6/go.mod h1:yEMFtIKPyIdIfPzsw7oTcH41JXc8G5StUAQw3ZoGj5I= yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 h1:0zlZD5uhZoIHgLVAWCz2aHaYk2ZrNsACCYD7R6EIBII= yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634= diff --git a/pkg/compute/models/cdn_domains.go b/pkg/compute/models/cdn_domains.go index d4dd684c2d..04ea5e1fb0 100644 --- a/pkg/compute/models/cdn_domains.go +++ b/pkg/compute/models/cdn_domains.go @@ -75,6 +75,20 @@ type SCDNDomain struct { ServiceType string `list:"user" width:"32" create:"domain_required"` // 加速区域 Area string `list:"user" width:"32" update:"domain" create:"domain_required"` + // 是否忽略参数 + CacheKeys *cloudprovider.SCDNCacheKeys `list:"user" create:"domain_optional"` + // 是否分片回源 + RangeOriginPull *cloudprovider.SCDNRangeOriginPull `list:"user" create:"domain_optional"` + // 缓存配置 + Cache *cloudprovider.SCDNCache `list:"user" create:"domain_optional"` + // https配置 + HTTPS *cloudprovider.SCDNHttps `list:"user" create:"domain_optional"` + // 强制跳转 + ForceRedirect *cloudprovider.SCDNForceRedirect `list:"user" create:"domain_optional"` + // 防盗链配置 + Referer *cloudprovider.SCDNReferer `list:"user" create:"domain_optional"` + // 浏览器缓存配置 + MaxAge *cloudprovider.SCDNMaxAge `list:"user" create:"domain_optional"` } func (manager *SCDNDomainManager) GetContextManagers() [][]db.IModelManager { @@ -215,6 +229,28 @@ func (self *SCDNDomain) SyncWithCloudCDNDomain(ctx context.Context, userCred mcc self.ServiceType = ext.GetServiceType() self.Cname = ext.GetCname() self.Origins = ext.GetOrigins() + cacheKeys, err := ext.GetCacheKeys() + if err == nil { + self.CacheKeys = cacheKeys + } + if rangeOrigin, err := ext.GetRangeOriginPull(); err == nil { + self.RangeOriginPull = rangeOrigin + } + if cache, err := ext.GetCache(); err == nil { + self.Cache = cache + } + if https, err := ext.GetHTTPS(); err == nil { + self.HTTPS = https + } + if fr, err := ext.GetForceRedirect(); err == nil { + self.ForceRedirect = fr + } + if referer, err := ext.GetReferer(); err == nil { + self.Referer = referer + } + if maxAge, err := ext.GetMaxAge(); err == nil { + self.MaxAge = maxAge + } return nil }) if err != nil { @@ -249,6 +285,13 @@ func (self *SCloudprovider) newFromCloudCDNDomain(ctx context.Context, userCred domain.ServiceType = ext.GetServiceType() domain.Cname = ext.GetCname() domain.Origins = ext.GetOrigins() + domain.CacheKeys, _ = ext.GetCacheKeys() + domain.RangeOriginPull, _ = ext.GetRangeOriginPull() + domain.Cache, _ = ext.GetCache() + domain.HTTPS, _ = ext.GetHTTPS() + domain.ForceRedirect, _ = ext.GetForceRedirect() + domain.Referer, _ = ext.GetReferer() + domain.MaxAge, _ = ext.GetMaxAge() err := CDNDomainManager.TableSpec().Insert(ctx, &domain) if err != nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index 98177f3963..3f514f1e6d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1439,7 +1439,7 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230131095206-0d758294026e +# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230206033907-593ed22677c6 ## explicit; go 1.18 yunion.io/x/cloudmux/pkg/apis yunion.io/x/cloudmux/pkg/apis/billing diff --git a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/cdn.go b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/cdn.go index 7402038c7f..d6b73d9a5b 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/cdn.go +++ b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/cdn.go @@ -57,6 +57,14 @@ type SCdnOrigin struct { Priority int } +type CdnCreateOptions struct { + Domain string + ServiceType string + Area string + + Origins SCdnOrigins +} + // +onecloud:model-api-gen type SCdnOrigins []SCdnOrigin @@ -68,16 +76,226 @@ func (self SCdnOrigins) String() string { return jsonutils.Marshal(self).String() } +// 是否忽略参数 +type SCDNCacheKeys struct { + // 开启关闭忽略参数 + Enabled *bool + // 是否忽略大小 + IgnoreCase *bool + // 分路径缓存键配置 + KeyRules []CacheKeyRule +} + +type CacheKeyRule struct { + RulePaths []string + RuleType string + FullUrlCache bool + IgnoreCase bool + QueryString CacheKeyRuleQueryString + RuleTag string +} + +type CacheKeyRuleQueryString struct { + Enabled bool + Action string + Value string +} + +func (self SCDNCacheKeys) IsZero() bool { + return jsonutils.Marshal(self) == jsonutils.Marshal(&SCDNCacheKeys{}) +} + +func (self SCDNCacheKeys) String() string { + return jsonutils.Marshal(self).String() +} + +// 是否分片回源 +type SCDNRangeOriginPull struct { + Enabled *bool + RangeOriginPullRules []SRangeOriginPullRule +} + +type SRangeOriginPullRule struct { + Enabled bool + RuleType string + RulePaths []string +} + +func (self SCDNRangeOriginPull) IsZero() bool { + return jsonutils.Marshal(self) == jsonutils.Marshal(&SCDNRangeOriginPull{}) +} + +func (self SCDNRangeOriginPull) String() string { + return jsonutils.Marshal(self).String() +} + +type CacheRule struct { + // 规则类型: + // all:所有文件生效 + // file:指定文件后缀生效 + // directory:指定路径生效 + // path:指定绝对路径生效 + // index:首页 + CacheType string + // CacheType 对应类型下的匹配内容 + CacheContents []string + // 过期时间: 秒 + CacheTime int +} + +type SCDNCache struct { + RuleCache []SCacheRuleCache +} + +type SCacheRuleCache struct { + RulePaths []string + RuleType string + Priority int + CacheConfig *RuleCacheConfig +} + +type RuleCacheConfig struct { + Cache *struct { + Enabled bool + CacheTime int + CompareMaxAge bool + IgnoreCacheControl bool + IgnoreSetCookie bool + } + NoCache *struct { + Enabled bool + Revalidate bool + } + FollowOrigin *struct { + Enabled bool + HeuristicCache struct { + Enabled bool + CacheConfig struct { + HeuristicCacheTimeSwitch bool + HeuristicCacheTime int + } + } + } +} + +func (self SCDNCache) IsZero() bool { + return jsonutils.Marshal(self) == jsonutils.Marshal(&SCDNCache{}) +} + +func (self SCDNCache) String() string { + return jsonutils.Marshal(self).String() +} + +type SCDNHttps struct { + // https 配置开关 + Enabled *bool + // http2 配置开关 + Http2 *bool +} + +func (self SCDNHttps) IsZero() bool { + return jsonutils.Marshal(self) == jsonutils.Marshal(&SCDNHttps{}) +} + +func (self SCDNHttps) String() string { + return jsonutils.Marshal(self).String() +} + +type SCDNForceRedirect struct { + // 访问强制跳转配置开关 + Enabled *bool + // 访问强制跳转类型 + // enmu: http, https + RedirectType string +} + +func (self SCDNForceRedirect) IsZero() bool { + return jsonutils.Marshal(self) == jsonutils.Marshal(&SCDNForceRedirect{}) +} + +func (self SCDNForceRedirect) String() string { + return jsonutils.Marshal(self).String() +} + +type RefererRule struct { + // 规则类型: + // all:所有文件生效 + // file:指定文件后缀生效 + // directory:指定路径生效 + // path:指定绝对路径生效 + RuleType string + RulePaths []string + RefererType string + Referers []string + AllowEmpty *bool +} + +type SCDNReferer struct { + // 是否开启防盗链 + Enabled *bool + + RefererRules []RefererRule +} + +func (self SCDNReferer) IsZero() bool { + return jsonutils.Marshal(self) == jsonutils.Marshal(&SCDNReferer{}) +} + +func (self SCDNReferer) String() string { + return jsonutils.Marshal(self).String() +} + +type SMaxAgeRule struct { + MaxAgeType string + MaxAgeContents []string + MaxAgeTime int + FollowOrigin bool +} + +// 浏览器缓存配置 +type SCDNMaxAge struct { + Enabled *bool + MaxAgeRules []SMaxAgeRule +} + +func (self SCDNMaxAge) IsZero() bool { + return jsonutils.Marshal(self) == jsonutils.Marshal(&SCDNMaxAge{}) +} + +func (self SCDNMaxAge) String() string { + return jsonutils.Marshal(self).String() +} + func init() { gotypes.RegisterSerializable(reflect.TypeOf(&SCdnOrigins{}), func() gotypes.ISerializable { return &SCdnOrigins{} }) -} -type CdnCreateOptions struct { - Domain string - ServiceType string - Area string + gotypes.RegisterSerializable(reflect.TypeOf(&SCDNCacheKeys{}), func() gotypes.ISerializable { + return &SCDNCacheKeys{} + }) - Origins SCdnOrigins + gotypes.RegisterSerializable(reflect.TypeOf(&SCDNRangeOriginPull{}), func() gotypes.ISerializable { + return &SCDNRangeOriginPull{} + }) + + gotypes.RegisterSerializable(reflect.TypeOf(&SCDNCache{}), func() gotypes.ISerializable { + return &SCDNCache{} + }) + + gotypes.RegisterSerializable(reflect.TypeOf(&SCDNHttps{}), func() gotypes.ISerializable { + return &SCDNHttps{} + }) + + gotypes.RegisterSerializable(reflect.TypeOf(&SCDNForceRedirect{}), func() gotypes.ISerializable { + return &SCDNForceRedirect{} + }) + + gotypes.RegisterSerializable(reflect.TypeOf(&SCDNReferer{}), func() gotypes.ISerializable { + return &SCDNReferer{} + }) + + gotypes.RegisterSerializable(reflect.TypeOf(&SCDNMaxAge{}), func() gotypes.ISerializable { + return &SCDNMaxAge{} + }) } diff --git a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/errors.go b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/errors.go index 5aa1bed3e2..0e8d0abeab 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/errors.go +++ b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/errors.go @@ -37,4 +37,6 @@ const ( ErrNotImplemented = errors.ErrNotImplemented ErrNotSupported = errors.ErrNotSupported ErrAccountReadOnly = errors.ErrAccountReadOnly + + ErrUnknown = errors.Error("UnknownError") ) diff --git a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go index 8f201f580b..0d2d5a49b6 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go +++ b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go @@ -1585,6 +1585,21 @@ type ICloudCDNDomain interface { GetCname() string GetOrigins() *SCdnOrigins + // 是否忽略参数 + GetCacheKeys() (*SCDNCacheKeys, error) + // 是否分片回源 + GetRangeOriginPull() (*SCDNRangeOriginPull, error) + // 缓存配置 + GetCache() (*SCDNCache, error) + // https配置 + GetHTTPS() (*SCDNHttps, error) + // 强制跳转 + GetForceRedirect() (*SCDNForceRedirect, error) + // 防盗链配置 + GetReferer() (*SCDNReferer, error) + // 浏览器缓存配置 + GetMaxAge() (*SCDNMaxAge, error) + Delete() error } diff --git a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/securitygroup.go b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/securitygroup.go index 248d6429ef..55ab35c42d 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/securitygroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/securitygroup.go @@ -132,6 +132,11 @@ type SecurityGroupCreateInput struct { Rules []secrules.SecurityRule } +type SecurityGroupCreateOutput struct { + Return bool + GroupId string +} + type SecurityRule struct { minPriority int maxPriority int diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/cdn.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/cdn.go index 4568e03b72..8eb17fcce8 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/cdn.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/cdn.go @@ -65,7 +65,7 @@ type SCdnSources struct { } type SCdnDomain struct { - multicloud.SResourceBase + multicloud.SCDNDomainBase client *SAliyunClient diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/bingo.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/bingo.go index 00b1463dec..819d9cdc60 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/bingo.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/bingo.go @@ -21,7 +21,7 @@ import ( "crypto/sha256" "encoding/base64" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "sort" @@ -236,14 +236,14 @@ func (self *SBingoCloudClient) invoke(action string, params map[string]string) ( query += "&" + encode("SignatureVersion", "2") query += "&" + encode("SignatureMethod", "HmacSHA256") query += "&" + encode("Signature", self.sign(query)) - client := self.getDefaultClient(0) + client := self.getDefaultClient(time.Minute * 5) resp, err := httputils.Request(client, context.Background(), httputils.POST, self.endpoint, nil, strings.NewReader(query), self.debug) if err != nil { return nil, err } defer resp.Body.Close() - data, err := ioutil.ReadAll(resp.Body) + data, err := io.ReadAll(resp.Body) if err != nil { return nil, err } @@ -265,7 +265,7 @@ func (self *SBingoCloudClient) invoke(action string, params map[string]string) ( } be := &sBingoError{} - obj.Unmarshal(be) + _ = obj.Unmarshal(be) if len(be.Response.Errors.Error.Code) > 0 { return nil, be } @@ -293,7 +293,7 @@ func (self *SBingoCloudClient) GetSubAccounts() ([]cloudprovider.SSubAccount, er } func (self *SBingoCloudClient) GetIRegions() []cloudprovider.ICloudRegion { - ret := []cloudprovider.ICloudRegion{} + var ret []cloudprovider.ICloudRegion for i := range self.regions { self.regions[i].client = self ret = append(ret, &self.regions[i]) diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/cluster.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/cluster.go index 991fe4be87..e3946eb6c4 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/cluster.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/cluster.go @@ -74,7 +74,7 @@ func (self *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { if err != nil { return nil, errors.Wrapf(err, "GetClusters") } - ret := []cloudprovider.ICloudZone{} + var ret []cloudprovider.ICloudZone for i := range clusters { clusters[i].region = self ret = append(ret, &clusters[i]) @@ -100,6 +100,6 @@ func (self *SRegion) GetClusters() ([]SCluster, error) { if err != nil { return nil, err } - ret := []SCluster{} + var ret []SCluster return ret, resp.Unmarshal(&ret, "clusterSet") } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/disk.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/disk.go index 4dabadeee2..548dddce0a 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/disk.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/disk.go @@ -61,6 +61,19 @@ type SDisk struct { VolumeName string `json:"volumeName"` } +func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { + snapshots, err := self.storage.cluster.region.getSnapshots("", "") + if err != nil { + return nil, err + } + iSnapshots := make([]cloudprovider.ICloudSnapshot, len(snapshots)) + for i := 0; i < len(snapshots); i++ { + snapshots[i].region = self.storage.cluster.region + iSnapshots[i] = &snapshots[i] + } + return iSnapshots, nil +} + type AttachmentSet struct { AttachTime string `json:"attachTime"` Cache string `json:"cache"` @@ -142,15 +155,19 @@ func (self *SDisk) GetAccessPath() string { } func (self *SDisk) Delete(ctx context.Context) error { - return cloudprovider.ErrNotImplemented + params := map[string]string{} + params["VolumeId"] = self.VolumeId + + _, err := self.storage.cluster.region.invoke("DeleteVolume", params) + return err } func (self *SDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) { - return nil, cloudprovider.ErrNotImplemented -} - -func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { - return nil, cloudprovider.ErrNotImplemented + snapshotId, err := self.storage.cluster.region.createSnapshot(self.VolumeId, name, desc) + if err != nil { + return nil, err + } + return self.storage.cluster.region.GetISnapshotById(snapshotId) } func (self *SDisk) GetExtSnapshotPolicyIds() ([]string, error) { @@ -188,11 +205,12 @@ func (self *SRegion) GetDisks(id string, maxResult int, nextToken string) ([]SDi } if len(nextToken) > 0 { - params["nextToken"] = nextToken + params["NextToken"] = nextToken } if maxResult > 0 { - params["maxRecords"] = fmt.Sprintf("%d", maxResult) + params["MaxRecords"] = fmt.Sprintf("%d", maxResult) } + resp, err := self.invoke("DescribeVolumes", params) if err != nil { return nil, "", err @@ -201,7 +219,8 @@ func (self *SRegion) GetDisks(id string, maxResult int, nextToken string) ([]SDi NextToken string VolumeSet []SDisk }{} - resp.Unmarshal(&ret) + _ = resp.Unmarshal(&ret) + return ret.VolumeSet, ret.NextToken, nil } @@ -210,7 +229,7 @@ func (self *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) { if err != nil { return nil, err } - disks := []SDisk{} + var disks []SDisk disks = append(disks, part...) for len(nextToken) > 0 { part, nextToken, err = self.cluster.region.GetDisks("", MAX_RESULT, nextToken) @@ -219,7 +238,7 @@ func (self *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) { } disks = append(disks, part...) } - ret := []cloudprovider.ICloudDisk{} + var ret []cloudprovider.ICloudDisk for i := range disks { if disks[i].StorageId == self.StorageId { disks[i].storage = self diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/eip.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/eip.go index ed3891838c..499feeffdc 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/eip.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/eip.go @@ -90,11 +90,20 @@ func (self *SEip) Delete() error { } func (self *SEip) Associate(conf *cloudprovider.AssociateConfig) error { - return cloudprovider.ErrNotImplemented + params := map[string]string{} + params["PublicIp"] = self.PublicIp + params["InstanceId"] = conf.InstanceId + + _, err := self.region.invoke("AssociateAddress", params) + return err } func (self *SEip) Dissociate() error { - return cloudprovider.ErrNotImplemented + params := map[string]string{} + params["PublicIp"] = self.PublicIp + + _, err := self.region.invoke("DisassociateAddress", params) + return err } func (self *SEip) ChangeBandwidth(bw int) error { @@ -112,10 +121,10 @@ func (self *SEip) GetStatus() string { func (self *SRegion) GetEips(ip, instanceId, nextToken string) ([]SEip, string, error) { params := map[string]string{} if len(ip) > 0 { - params["publicIp"] = ip + params["PublicIp"] = ip } if len(nextToken) > 0 { - params["nextToken"] = nextToken + params["NextToken"] = nextToken } idx := 1 @@ -133,7 +142,8 @@ func (self *SRegion) GetEips(ip, instanceId, nextToken string) ([]SEip, string, AddressesSet []SEip NextToken string }{} - resp.Unmarshal(&ret) + _ = resp.Unmarshal(&ret) + return ret.AddressesSet, ret.NextToken, nil } @@ -142,7 +152,7 @@ func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { if err != nil { return nil, err } - eips := []SEip{} + var eips []SEip eips = append(eips, part...) for len(nextToken) > 0 { part, nextToken, err = self.GetEips("", "", nextToken) @@ -151,7 +161,7 @@ func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) { } eips = append(eips, part...) } - ret := []cloudprovider.ICloudEIP{} + var ret []cloudprovider.ICloudEIP for i := range eips { eips[i].region = self ret = append(ret, &eips[i]) diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/host.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/host.go index 6bc6baf250..a70ee1bf35 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/host.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/host.go @@ -55,7 +55,7 @@ type SHost struct { func (self *SRegion) GetHosts(nextToken string) ([]SHost, string, error) { params := map[string]string{} if len(nextToken) > 0 { - params["nextToken"] = nextToken + params["NextToken"] = nextToken } resp, err := self.invoke("DescribePhysicalHosts", params) if err != nil { @@ -67,6 +67,7 @@ func (self *SRegion) GetHosts(nextToken string) ([]SHost, string, error) { } NextToken string }{} - resp.Unmarshal(&ret) + _ = resp.Unmarshal(&ret) + return ret.DescribePhysicalHostsResult.PhysicalHostSet, ret.NextToken, nil } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/image.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/image.go index 05d831a183..1433c66ab3 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/image.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/image.go @@ -94,6 +94,10 @@ func (self *SImage) GetSizeByte() int64 { return self.ImageSize } +func (self *SImage) GetSizeGB() int64 { + return self.ImageSize / 1073741824 +} + func (self *SImage) GetImageType() cloudprovider.TImageType { if self.IsPublic { return cloudprovider.ImageTypeSystem @@ -102,7 +106,7 @@ func (self *SImage) GetImageType() cloudprovider.TImageType { } func (self *SImage) GetImageStatus() string { - return "" + return "active" } func (i *SImage) getNormalizedImageInfo() *imagetools.ImageInfo { @@ -142,11 +146,11 @@ func (i *SImage) GetBios() cloudprovider.TBiosType { } func (self *SImage) GetMinOsDiskSizeGb() int { - return 0 + return 4 } func (self *SImage) GetMinRamSizeMb() int { - return 0 + return 1024 } func (self *SImage) GetImageFormat() string { @@ -188,10 +192,10 @@ func (self *SImage) GetStatus() string { func (self *SRegion) GetImages(id, nextToken string) ([]SImage, string, error) { params := map[string]string{} if len(id) > 0 { - params["imageId"] = id + params["ImageId.1"] = id } if len(nextToken) > 0 { - params["nextToken"] = nextToken + params["NextToken"] = nextToken } resp, err := self.invoke("DescribeImages", params) if err != nil { @@ -201,16 +205,27 @@ func (self *SRegion) GetImages(id, nextToken string) ([]SImage, string, error) { NextToken string ImagesSet []SImage }{} - resp.Unmarshal(&ret) + _ = resp.Unmarshal(&ret) return ret.ImagesSet, ret.NextToken, nil } +func (self *SRegion) GetImageById(id string) (*SImage, error) { + imgs, _, err := self.GetImages(id, "") + if err != nil { + return nil, err + } + if len(imgs) == 0 { + return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) + } + return &imgs[0], nil +} + func (self *SStoragecache) GetICloudImages() ([]cloudprovider.ICloudImage, error) { part, nextToken, err := self.region.GetImages("", "") if err != nil { return nil, err } - images := []SImage{} + var images []SImage images = append(images, part...) for len(nextToken) > 0 { part, nextToken, err = self.region.GetImages("", nextToken) @@ -219,7 +234,7 @@ func (self *SStoragecache) GetICloudImages() ([]cloudprovider.ICloudImage, error } images = append(images, part...) } - ret := []cloudprovider.ICloudImage{} + var ret []cloudprovider.ICloudImage for i := range images { if images[i].StorageId == self.storageId { images[i].cache = self @@ -240,6 +255,5 @@ func (self *SStoragecache) GetIImageById(id string) (cloudprovider.ICloudImage, return &images[i], nil } } - return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance.go index 3368437c72..2e1dd7d3c3 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance.go @@ -144,7 +144,7 @@ func (self *SInstance) GetName() string { } func (self *SInstance) GetSecurityGroupIds() ([]string, error) { - ret := []string{} + var ret []string for _, sec := range self.GroupSet { ret = append(ret, sec.GroupId) } @@ -152,19 +152,19 @@ func (self *SInstance) GetSecurityGroupIds() ([]string, error) { } func (self *SInstance) AssignSecurityGroup(secgroupId string) error { - return cloudprovider.ErrNotImplemented + return nil } func (self *SInstance) SetSecurityGroups(secgroupIds []string) error { - return cloudprovider.ErrNotImplemented + return nil } func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error { - return cloudprovider.ErrNotImplemented + return nil } func (self *SInstance) DetachDisk(ctx context.Context, diskId string) error { - return cloudprovider.ErrNotImplemented + return nil } func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error { @@ -176,7 +176,11 @@ func (self *SInstance) DeployVM(ctx context.Context, name string, username strin } func (self *SInstance) DeleteVM(ctx context.Context) error { - return cloudprovider.ErrNotImplemented + params := map[string]string{} + params["InstanceId.1"] = self.InstancesSet.InstanceId + + _, err := self.node.cluster.region.invoke("TerminateInstances", params) + return err } func (self *SInstance) GetVcpuCount() int { @@ -271,7 +275,7 @@ func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) { for i := range storages { storageMaps[storages[i].StorageId] = storages[i] } - ret := []cloudprovider.ICloudDisk{} + var ret []cloudprovider.ICloudDisk for _, _disk := range self.InstancesSet.BlockDeviceMapping { disk, err := self.node.cluster.region.GetDisk(_disk.Ebs.VolumeId) if err != nil { @@ -292,7 +296,7 @@ func (self *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) { if err != nil { return nil, err } - ret := []cloudprovider.ICloudNic{} + var ret []cloudprovider.ICloudNic for i := range nics { ret = append(ret, &nics[i]) } @@ -316,14 +320,14 @@ func (self *SInstance) GetProjectId() string { } func (self *SInstance) Refresh() error { - new, _, err := self.node.cluster.region.GetInstances(self.InstancesSet.InstanceId, self.node.NodeId, MAX_RESULT, "") + newInstances, _, err := self.node.cluster.region.GetInstances(self.InstancesSet.InstanceId, self.node.NodeId, MAX_RESULT, "") if err != nil { return err } - if len(new) == 1 { - return jsonutils.Update(self, &new[0]) + if len(newInstances) == 1 { + return jsonutils.Update(self, &newInstances[0]) } - return nil + return cloudprovider.ErrNotFound } func (self *SInstance) GetStatus() string { @@ -337,7 +341,7 @@ func (self *SInstance) GetStatus() string { func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) { params := map[string]string{} - params["instanceId"] = self.InstancesSet.InstanceId + params["InstanceId"] = self.InstancesSet.InstanceId resp, err := self.node.cluster.region.invoke("GetVncInfo", params) if err != nil { @@ -347,10 +351,7 @@ func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudpr result := struct { GetVncInfoResult *cloudprovider.ServerVncOutput `json:"getVncInfoResult"` }{} - err = resp.Unmarshal(&result) - if err != nil { - return nil, err - } + _ = resp.Unmarshal(&result) result.GetVncInfoResult.InstanceId = self.InstancesSet.InstanceId result.GetVncInfoResult.Hypervisor = self.GetHypervisor() @@ -384,13 +385,52 @@ func (self *SInstance) UpdateVM(ctx context.Context, name string) error { return cloudprovider.ErrNotImplemented } +func (self *SInstance) CreateInstanceSnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudInstanceSnapshot, error) { + newId, err := self.node.cluster.region.createInstanceSnapshot(self.InstancesSet.InstanceId, name, desc) + if err != nil { + return nil, err + } + return self.GetInstanceSnapshot(newId) +} + +func (self *SInstance) GetInstanceSnapshot(id string) (cloudprovider.ICloudInstanceSnapshot, error) { + snapshots, err := self.node.cluster.region.getInstanceSnapshots(self.InstancesSet.InstanceId, id) + if err != nil { + return nil, err + } + for i := range snapshots { + if snapshots[i].GetGlobalId() == id { + snapshots[i].region = self.node.cluster.region + return &snapshots[i], nil + } + } + return nil, cloudprovider.ErrNotFound +} + +func (self *SInstance) GetInstanceSnapshots() ([]cloudprovider.ICloudInstanceSnapshot, error) { + snapshots, err := self.node.cluster.region.getInstanceSnapshots(self.InstancesSet.InstanceId, "") + if err != nil { + return nil, err + } + var ret []cloudprovider.ICloudInstanceSnapshot + for i := range snapshots { + snapshots[i].region = self.node.cluster.region + ret = append(ret, &snapshots[i]) + } + return ret, nil +} + +func (self *SInstance) ResetToInstanceSnapshot(ctx context.Context, idStr string) error { + return self.node.cluster.region.revertInstanceSnapshot(idStr) +} + func (self *SRegion) GetInstances(id, nodeId string, maxResult int, nextToken string) ([]SInstance, string, error) { params := map[string]string{} if maxResult > 0 { - params["maxRecords"] = fmt.Sprintf("%d", maxResult) + params["MaxRecords"] = fmt.Sprintf("%d", maxResult) } if len(nextToken) > 0 { - params["nextToken"] = nextToken + params["NextToken"] = nextToken } idx := 1 @@ -414,9 +454,7 @@ func (self *SRegion) GetInstances(id, nodeId string, maxResult int, nextToken st NextToken string ReservationSet []SInstance }{} - err = resp.Unmarshal(&result) - if err != nil { - return nil, "", err - } + _ = resp.Unmarshal(&result) + return result.ReservationSet, result.NextToken, nil } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance_snapshot.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance_snapshot.go new file mode 100644 index 0000000000..4ff61c42d3 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance_snapshot.go @@ -0,0 +1,132 @@ +package bingocloud + +import ( + "time" + + "yunion.io/x/jsonutils" + + "yunion.io/x/cloudmux/pkg/cloudprovider" +) + +type SInstanceSnapshot struct { + region *SRegion + InstanceSnapshotId string + InstanceSnapshotName string + InstanceId string + DiskOnly bool + Size int64 + Status string + StatusReason string + CreateTime string +} + +func (self SInstanceSnapshot) GetId() string { + return self.InstanceSnapshotId +} + +func (self SInstanceSnapshot) GetName() string { + return self.InstanceSnapshotName +} + +func (self SInstanceSnapshot) GetGlobalId() string { + return self.InstanceSnapshotId +} + +func (self SInstanceSnapshot) GetCreatedAt() time.Time { + ct, _ := time.Parse("2006-01-02T15:04:05.000Z", self.CreateTime) + return ct +} + +func (self SInstanceSnapshot) GetStatus() string { + return self.Status +} + +func (self SInstanceSnapshot) Refresh() error { + newSnapshot, err := self.region.getInstanceSnapshots(self.InstanceId, self.InstanceSnapshotId) + if err != nil { + return err + } + if len(newSnapshot) == 1 { + return jsonutils.Update(self, &newSnapshot[0]) + } + return cloudprovider.ErrNotFound +} + +func (self SInstanceSnapshot) IsEmulated() bool { + return false +} + +func (self SInstanceSnapshot) GetSysTags() map[string]string { + return nil +} + +func (self SInstanceSnapshot) GetTags() (map[string]string, error) { + return nil, nil +} + +func (self SInstanceSnapshot) SetTags(tags map[string]string, replace bool) error { + return nil +} + +func (self SInstanceSnapshot) GetProjectId() string { + return "" +} + +func (self SInstanceSnapshot) GetDescription() string { + return "" +} + +func (self SInstanceSnapshot) Delete() error { + return self.region.deleteInstanceSnapshot(self.InstanceSnapshotId) +} + +func (self *SRegion) createInstanceSnapshot(instanceId, name string, desc string) (string, error) { + params := map[string]string{} + params["InstanceId"] = instanceId + params["InstanceSnapshotName"] = name + params["Description"] = desc + params["DiskOnly"] = "false" + + resp, err := self.client.invoke("CreateInstanceSnapshot", params) + if err != nil { + return "", err + } + newId := "" + err = resp.Unmarshal(&newId, "instanceSnapshotId") + + return newId, err +} + +func (self *SRegion) getInstanceSnapshots(instanceId, snapshotId string) ([]SInstanceSnapshot, error) { + params := map[string]string{} + if instanceId != "" { + params["InstanceId"] = instanceId + } + if snapshotId != "" { + params["InstanceSnapshotId.1"] = snapshotId + } + + resp, err := self.client.invoke("DescribeInstanceSnapshots", params) + if err != nil { + return nil, err + } + + var ret []SInstanceSnapshot + _ = resp.Unmarshal(&ret, "instanceSnapshotSet") + + return ret, err +} + +func (self *SRegion) deleteInstanceSnapshot(id string) error { + params := map[string]string{} + params["InstanceSnapshotId"] = id + _, err := self.client.invoke("DeleteInstanceSnapshots", params) + return err +} + +func (self *SRegion) revertInstanceSnapshot(id string) error { + params := map[string]string{} + params["InstanceSnapshotId"] = id + _, err := self.client.invoke("RevertInstanceSnapshot", params) + return err +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance_type.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance_type.go new file mode 100644 index 0000000000..54b58f8719 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instance_type.go @@ -0,0 +1,209 @@ +package bingocloud + +import ( + "strings" + "time" + + "yunion.io/x/cloudmux/pkg/apis" + "yunion.io/x/cloudmux/pkg/cloudprovider" +) + +var INSTANCE_CATEGORY_MAP = map[string]string{ + "m1": "M1代", + "m2": "M2代", + "m3": "M3代", + "c1": "C1代", + "c2": "C2代", + "c3": "C3代", + "t1": "T1代", + "t2": "T2代", + "t3": "T3代", +} + +func getInstanceCategory(family string) string { + ret, ok := INSTANCE_CATEGORY_MAP[family] + if ok { + return ret + } + + return family +} + +type SInstanceType struct { + cloudprovider.SServerSku + + region *SRegion + + InstanceType string + DisplayName string + Cpu int + Ram int + Max int + Available int + Description string +} + +func (self *SInstanceType) GetCreatedAt() time.Time { + return time.Time{} +} + +func (self *SInstanceType) GetId() string { + return self.InstanceType +} + +func (self *SInstanceType) GetName() string { + return self.InstanceType +} + +func (self *SInstanceType) GetGlobalId() string { + return self.InstanceType +} + +func (self *SInstanceType) GetStatus() string { + return "" +} + +func (self *SInstanceType) Refresh() error { + return nil +} + +func (self *SInstanceType) IsEmulated() bool { + return false +} + +func (self *SInstanceType) GetSysTags() map[string]string { + return nil +} + +func (self *SInstanceType) GetTags() (map[string]string, error) { + return nil, nil +} + +func (self *SInstanceType) SetTags(tags map[string]string, replace bool) error { + return nil +} + +func (self *SInstanceType) GetInstanceTypeFamily() string { + return strings.Split(self.InstanceType, ".")[0] +} + +func (self *SInstanceType) GetInstanceTypeCategory() string { + return getInstanceCategory(self.GetInstanceTypeFamily()) +} + +func (self *SInstanceType) GetPrepaidStatus() string { + return "available" +} + +func (self *SInstanceType) GetPostpaidStatus() string { + return "available" +} + +// https://support.huaweicloud.com/productdesc-ecs/ecs_01_0066.html +// https://support.huaweicloud.com/ecs_faq/ecs_faq_0105.html +func (self *SInstanceType) GetCpuArch() string { + return apis.OS_ARCH_X86 +} + +func (self *SInstanceType) GetCpuCoreCount() int { + return self.Cpu +} + +func (self *SInstanceType) GetMemorySizeMB() int { + return self.Ram +} + +func (self *SInstanceType) GetOsName() string { + return "" +} + +func (self *SInstanceType) GetSysDiskResizable() bool { + return false +} + +func (self *SInstanceType) GetSysDiskType() string { + return "" +} + +func (self *SInstanceType) GetSysDiskMinSizeGB() int { + return 0 +} + +func (self *SInstanceType) GetSysDiskMaxSizeGB() int { + return 0 +} + +func (self *SInstanceType) GetAttachedDiskType() string { + return "" +} + +func (self *SInstanceType) GetAttachedDiskSizeGB() int { + return 0 +} + +func (self *SInstanceType) GetAttachedDiskCount() int { + return 0 +} + +func (self *SInstanceType) GetDataDiskTypes() string { + return "" +} + +func (self *SInstanceType) GetDataDiskMaxCount() int { + return 0 +} + +func (self *SInstanceType) GetNicType() string { + return "" +} + +func (self *SInstanceType) GetNicMaxCount() int { + return 0 +} + +func (self *SInstanceType) GetGpuAttachable() bool { + return false +} + +func (self *SInstanceType) GetGpuSpec() string { + return "" +} + +func (self *SInstanceType) GetGpuCount() int { + return 0 +} + +func (self *SInstanceType) GetGpuMaxCount() int { + return 0 +} + +func (self *SInstanceType) Delete() error { + return nil +} + +func (self *SRegion) GetInstanceTypes() ([]SInstanceType, error) { + resp, err := self.invoke("DescribeInstanceTypes", nil) + if err != nil { + return nil, err + } + + result := struct { + InstanceTypeInfo []SInstanceType + }{} + _ = resp.Unmarshal(&result) + + return result.InstanceTypeInfo, err +} + +func (self *SRegion) GetISkus() ([]cloudprovider.ICloudSku, error) { + instanceTypes, err := self.GetInstanceTypes() + if err != nil { + return nil, err + } + iskus := make([]cloudprovider.ICloudSku, len(instanceTypes)) + for i := 0; i < len(instanceTypes); i++ { + instanceTypes[i].region = self + iskus[i] = &instanceTypes[i] + } + return iskus, nil +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instancenic.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instancenic.go index 5fa7d48b78..1b2d2b9903 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instancenic.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/instancenic.go @@ -75,7 +75,7 @@ func (self *SInstanceNic) GetINetworkId() string { } func (self *SInstanceNic) GetSubAddress() ([]string, error) { - ret := []string{} + var ret []string for _, ip := range self.PrivateIPAddressesSet { if ip.PrivateIPAddress != self.PrivateIPAddress { ret = append(ret, ip.PrivateIPAddress) @@ -99,15 +99,18 @@ func (self *SInstanceNic) UnassignAddress(ipAddrs []string) error { func (self *SRegion) GetInstanceNics(insId string) ([]SInstanceNic, error) { params := map[string]string{} if len(insId) > 0 { - params["instanceId"] = insId + params["InstanceId"] = insId } + resp, err := self.invoke("DescribeNetworkInterfaces", params) if err != nil { return nil, err } + ret := struct { NetworkInterfaceSet []SInstanceNic }{} - resp.Unmarshal(&ret) + _ = resp.Unmarshal(&ret) + return ret.NetworkInterfaceSet, nil } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/monitor.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/monitor.go index 65796d83d1..7db788e999 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/monitor.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/monitor.go @@ -81,10 +81,10 @@ func (self *SBingoCloudClient) GetMetrics(opts *cloudprovider.MetricListOptions) } func (self *SBingoCloudClient) GetEcsMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) { - ret := []cloudprovider.MetricValues{} + var ret []cloudprovider.MetricValues for metricType, metricName := range map[cloudprovider.TMetricType]string{ cloudprovider.VM_METRIC_TYPE_CPU_USAGE: "CPUUtilization", - cloudprovider.VM_METRIC_TYPE_MEM_USAGE: "MemeryUsage", + cloudprovider.VM_METRIC_TYPE_MEM_USAGE: "MemoryUsage", cloudprovider.VM_METRIC_TYPE_NET_BPS_RX: "NetworkIn", cloudprovider.VM_METRIC_TYPE_NET_BPS_TX: "NetworkOut", cloudprovider.VM_METRIC_TYPE_DISK_IO_READ_BPS: "DiskReadBytes", @@ -112,10 +112,10 @@ func (self *SBingoCloudClient) GetEcsMetrics(opts *cloudprovider.MetricListOptio } func (self *SBingoCloudClient) GetHostMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) { - ret := []cloudprovider.MetricValues{} + var ret []cloudprovider.MetricValues for metricType, metricName := range map[cloudprovider.TMetricType]string{ cloudprovider.VM_METRIC_TYPE_CPU_USAGE: "CPUUtilization", - cloudprovider.VM_METRIC_TYPE_MEM_USAGE: "MemeryUsage", + cloudprovider.VM_METRIC_TYPE_MEM_USAGE: "MemoryUsage", cloudprovider.VM_METRIC_TYPE_NET_BPS_RX: "NetworkIn", cloudprovider.VM_METRIC_TYPE_NET_BPS_TX: "NetworkOut", cloudprovider.VM_METRIC_TYPE_DISK_IO_READ_BPS: "DiskReadBytes", diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/network.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/network.go index e305aa1201..d026316c4f 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/network.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/network.go @@ -153,7 +153,7 @@ func (self *SWire) GetINetworks() ([]cloudprovider.ICloudNetwork, error) { if err != nil { return nil, err } - ret := []cloudprovider.ICloudNetwork{} + var ret []cloudprovider.ICloudNetwork for i := range networks { networks[i].wire = self ret = append(ret, &networks[i]) @@ -177,7 +177,7 @@ func (self *SWire) GetINetworkById(id string) (cloudprovider.ICloudNetwork, erro func (self *SRegion) GetNetworks(id, clusterId, vpcId string) ([]SNetwork, error) { params := map[string]string{} if len(id) > 0 { - params["subnetId"] = id + params["SubnetId"] = id } idx := 1 if len(clusterId) > 0 { @@ -194,6 +194,6 @@ func (self *SRegion) GetNetworks(id, clusterId, vpcId string) ([]SNetwork, error if err != nil { return nil, err } - networks := []SNetwork{} + var networks []SNetwork return networks, resp.Unmarshal(&networks, "subnetSet") } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/node.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/node.go index e37afd1bf2..96da92419d 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/node.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/node.go @@ -15,9 +15,12 @@ package bingocloud import ( + "fmt" + "strconv" "strings" "yunion.io/x/jsonutils" + "yunion.io/x/log" "yunion.io/x/pkg/errors" api "yunion.io/x/cloudmux/pkg/apis/compute" @@ -53,16 +56,16 @@ type SNode struct { func (self *SRegion) GetNodes(clusterId, nodeId string) ([]SNode, error) { params := map[string]string{} if len(clusterId) > 0 { - params["clusterId"] = clusterId + params["ClusterId"] = clusterId } if len(clusterId) > 0 { - params["nodeId"] = nodeId + params["NodeId"] = nodeId } resp, err := self.invoke("DescribeNodes", params) if err != nil { return nil, err } - ret := []SNode{} + var ret []SNode return ret, resp.Unmarshal(&ret, "nodeSet") } @@ -151,10 +154,6 @@ func (self *SNode) GetNodeType() string { return api.HOST_TYPE_BINGO_CLOUD } -func (self *SNode) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { - return nil, cloudprovider.ErrNotImplemented -} - func (self *SNode) GetIStorages() ([]cloudprovider.ICloudStorage, error) { return self.cluster.GetIStorages() } @@ -179,7 +178,7 @@ func (self *SNode) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error } func (self *SNode) GetIVMs() ([]cloudprovider.ICloudVM, error) { - vms := []SInstance{} + var vms []SInstance part, nextToken, err := self.cluster.region.GetInstances("", self.NodeId, MAX_RESULT, "") vms = append(vms, part...) for len(nextToken) > 0 { @@ -189,7 +188,7 @@ func (self *SNode) GetIVMs() ([]cloudprovider.ICloudVM, error) { } vms = append(vms, part...) } - ret := []cloudprovider.ICloudVM{} + var ret []cloudprovider.ICloudVM for i := range vms { vms[i].node = self ret = append(ret, &vms[i]) @@ -212,7 +211,19 @@ func (self *SNode) GetIVMById(id string) (cloudprovider.ICloudVM, error) { } func (self *SNode) GetIWires() ([]cloudprovider.ICloudWire, error) { - return nil, cloudprovider.ErrNotImplemented + vpcs, err := self.cluster.region.GetIVpcs() + if err != nil { + return nil, err + } + var ret []cloudprovider.ICloudWire + for _, vpc := range vpcs { + wires, err := vpc.GetIWires() + if err != nil { + return nil, err + } + ret = append(ret, wires...) + } + return ret, nil } func (self *SNode) GetSchedtags() ([]string, error) { @@ -261,10 +272,101 @@ func (self *SCluster) GetIHosts() ([]cloudprovider.ICloudHost, error) { if err != nil { return nil, err } - ret := []cloudprovider.ICloudHost{} + var ret []cloudprovider.ICloudHost for i := range nodes { nodes[i].cluster = self ret = append(ret, &nodes[i]) } return ret, nil } + +func (self *SNode) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) { + var err error + log.Debugf("Try instancetype : %s", desc.InstanceType) + + img, err := self.cluster.region.GetImageById(desc.ExternalImageId) + if err != nil { + log.Errorf("get image %s fail %s", desc.ExternalImageId, err) + return nil, err + } + + params := map[string]string{} + params["InstanceName"] = desc.Name + params["ImageId"] = desc.ExternalImageId + params["MinCount"] = "1" + params["MaxCount"] = "1" + + if len(desc.ExternalSecgroupIds) > 0 { + for i := range desc.ExternalSecgroupIds { + secGroup, err := self.cluster.region.GetISecurityGroupById(desc.ExternalSecgroupIds[i]) + if err != nil { + return nil, err + } + params[fmt.Sprintf("SecurityGroup.%v", i+1)] = secGroup.GetName() + } + } + + disks := make([]SDisk, len(desc.DataDisks)+1) + disks[0].Size = int(img.GetSizeGB()) + if desc.SysDisk.SizeGB > 0 && desc.SysDisk.SizeGB > int(img.GetSizeGB()) { + disks[0].Size = desc.SysDisk.SizeGB + } + for i, dataDisk := range desc.DataDisks { + disks[i+1].Size = dataDisk.SizeGB + } + + for i, disk := range disks { + var deviceName string + var err error + + if i == 0 { + params[fmt.Sprintf("BlockDeviceMapping.%v.Ebs.DeleteOnTermination", i+1)] = "true" + params[fmt.Sprintf("BlockDeviceMapping.%v.Ebs.VolumeSize", i+1)] = strconv.Itoa(disk.Size) + if len(img.RootDeviceName) > 0 { + deviceName = img.RootDeviceName + } else { + deviceName = fmt.Sprintf("/dev/vda") + } + } else { + params[fmt.Sprintf("BlockDeviceMapping.%v.Ebs.DeleteOnTermination", i+1)] = "true" + params[fmt.Sprintf("BlockDeviceMapping.%v.Ebs.VolumeSize", i+1)] = strconv.Itoa(disk.Size) + deviceName, err = nextDeviceName([]string{deviceName}) + if err != nil { + return nil, errors.Wrap(err, "nextDeviceName") + } + } + params[fmt.Sprintf("BlockDeviceMapping.%v.DeviceName", i+1)] = deviceName + } + + params["InstanceType"] = desc.InstanceType + params["Password"] = desc.Password + params["NetworkInterface.1.VpcId"] = desc.ExternalVpcId + params["NetworkInterface.1.SubnetId"] = desc.ExternalNetworkId + params["AllowNodes.1"] = self.NodeId + + resp, err := self.cluster.region.invoke("RunInstances", params) + if err != nil { + return nil, err + } + if err != nil { + return nil, errors.Wrap(err, "CreateVM") + } + + var tmpInst = struct { + InstancesSet struct { + InstanceId string + } + }{} + + _ = resp.Unmarshal(&tmpInst) + insets, _, err := self.cluster.region.GetInstances(tmpInst.InstancesSet.InstanceId, "", MAX_RESULT, "") + if err != nil { + log.Errorf("GetInstance %s: %s", "", err) + return nil, errors.Wrap(err, "CreateVM") + } + if len(insets) > 0 { + insets[0].node = self + return &insets[0], nil + } + return nil, errors.Wrap(cloudprovider.ErrUnknown, "CreateVM") +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/region.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/region.go index af81b2ce0e..3b2cad1880 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/region.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/region.go @@ -92,16 +92,26 @@ func (self *SBingoCloudClient) GetRegions() ([]SRegion, error) { if err != nil { return nil, err } - ret := []SRegion{} - err = resp.Unmarshal(&ret, "regionInfo") + var ret []SRegion + return ret, resp.Unmarshal(&ret, "regionInfo") +} + +func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, error) { + storages, err := self.getStorages() if err != nil { return nil, err } - return ret, nil + for i := range storages { + if storages[i].GetGlobalId() == id { + storages[i].cluster = &SCluster{region: self} + return &storages[i], nil + } + } + return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) } func (self *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) { - storages := []SStorage{} + var storages []SStorage part, nextToken, err := self.GetStorages("") if err != nil { return nil, err @@ -114,7 +124,7 @@ func (self *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, er } storages = append(storages, part...) } - ret := []cloudprovider.ICloudStoragecache{} + var ret []cloudprovider.ICloudStoragecache for i := range storages { cache := SStoragecache{ region: self, @@ -144,7 +154,7 @@ func (self *SRegion) GetIHosts() ([]cloudprovider.ICloudHost, error) { if err != nil { return nil, err } - ret := []cloudprovider.ICloudHost{} + var ret []cloudprovider.ICloudHost for i := range zones { hosts, err := zones[i].GetIHosts() if err != nil { @@ -173,3 +183,30 @@ func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) { } return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) } + +func (self *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) { + snapshots, err := self.getSnapshots("", "") + if err != nil { + return nil, err + } + iSnapshots := make([]cloudprovider.ICloudSnapshot, len(snapshots)) + for i := 0; i < len(snapshots); i++ { + snapshots[i].region = self + iSnapshots[i] = snapshots[i] + } + return iSnapshots, nil +} + +func (self *SRegion) GetISnapshotById(id string) (cloudprovider.ICloudSnapshot, error) { + snapshots, err := self.getSnapshots(id, "") + if err != nil { + return nil, err + } + for i := range snapshots { + if snapshots[i].GetGlobalId() == id { + snapshots[i].region = self + return &snapshots[i], nil + } + } + return nil, cloudprovider.ErrNotFound +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/secgroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/securitygroup.go similarity index 52% rename from vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/secgroup.go rename to vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/securitygroup.go index fa8aa200ef..41868f6dcb 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/secgroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/securitygroup.go @@ -15,6 +15,10 @@ package bingocloud import ( + "encoding/json" + "strings" + + "yunion.io/x/log" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/secrules" @@ -28,19 +32,19 @@ type SSecurityGroup struct { BingoTags region *SRegion - ComplexIPPermissions string `json:"complexIpPermissions"` - ComplexIPPermissionsEgress string `json:"complexIpPermissionsEgress"` - DisplayName string `json:"displayName"` - GroupDescription string `json:"groupDescription"` - GroupId string `json:"groupId"` - GroupName string `json:"groupName"` - IPPermissionType string `json:"ipPermissionType"` - IPPermissions string `json:"ipPermissions"` - IPPermissionsEgress []IPPermissionsEgress `json:"ipPermissionsEgress"` - OwnerId string `json:"ownerId"` + ComplexIPPermissions string `json:"complexIpPermissions"` + ComplexIPPermissionsEgress string `json:"complexIpPermissionsEgress"` + DisplayName string `json:"displayName"` + GroupDescription string `json:"groupDescription"` + GroupId string `json:"groupId"` + GroupName string `json:"groupName"` + IPPermissionType string `json:"ipPermissionType"` + IPPermissions []IPPermissions `json:"ipPermissions"` + IPPermissionsEgress []IPPermissions `json:"ipPermissionsEgress"` + OwnerId string `json:"ownerId"` } -type IPPermissionsEgress struct { +type IPPermissions struct { BoundType string `json:"boundType"` Description string `json:"description"` FromPort int `json:"fromPort"` @@ -70,10 +74,6 @@ func (self *SSecurityGroup) GetName() string { return self.GroupName } -func (self *SSecurityGroup) Delete() error { - return cloudprovider.ErrNotImplemented -} - func (self *SSecurityGroup) GetDescription() string { return self.GroupDescription } @@ -87,8 +87,8 @@ func (self *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupRefere } func (self *SSecurityGroup) GetRules() ([]cloudprovider.SecurityRule, error) { - ret := []cloudprovider.SecurityRule{} - for _, _rule := range self.IPPermissionsEgress { + var ret []cloudprovider.SecurityRule + for _, _rule := range append(self.IPPermissionsEgress, self.IPPermissions...) { if len(_rule.Groups) > 0 { continue } @@ -135,20 +135,82 @@ func (self *SSecurityGroup) GetStatus() string { } func (self *SSecurityGroup) SyncRules(common, inAdds, outAdds, inDels, outDels []cloudprovider.SecurityRule) error { - return cloudprovider.ErrNotImplemented + for _, r := range append(inDels, outDels...) { + err := self.region.deleteSecurityGroupRule(self.GroupId, r) + if err != nil { + if strings.Contains(err.Error(), "InvalidPermission.NotFound") { + continue + } + return errors.Wrapf(err, "deleteSecurityGroupRule %s %d %s", r.Name, r.Priority, r.String()) + } + } + for _, r := range append(inAdds, outAdds...) { + err := self.region.addSecurityGroupRules(self.GroupId, r) + if err != nil { + return errors.Wrapf(err, "addSecurityGroupRules %d %s", r.Priority, r.String()) + } + } + return nil +} + +func (self *SSecurityGroup) Delete() error { + return self.region.deleteSecurityGroup(self.GroupId) +} + +func (self *SRegion) deleteSecurityGroupRule(secGrpId string, rule cloudprovider.SecurityRule) error { + allInputs := securityRuleToBingoCloud(secGrpId, rule) + + for _, input := range allInputs { + data, _ := json.Marshal(&input) + params := make(map[string]string) + _ = json.Unmarshal(data, ¶ms) + + _, err := self.invoke("RevokeSecurityGroupIngress", params) + if err != nil { + log.Debugf("deleteSecurityGroupRule %s %s", rule.Direction, err.Error()) + return err + } + } + + return nil +} + +func (self *SRegion) addSecurityGroupRules(secGrpId string, rule cloudprovider.SecurityRule) error { + allInputs := securityRuleToBingoCloud(secGrpId, rule) + + for _, input := range allInputs { + data, _ := json.Marshal(&input) + params := make(map[string]string) + _ = json.Unmarshal(data, ¶ms) + + _, err := self.invoke("AuthorizeSecurityGroupIngress", params) + if err == nil { + continue + } + if err != nil && strings.Contains(err.Error(), "InvalidPermission.Duplicate") { + log.Debugf("addSecurityGroupRule %s %s", rule.Direction, err.Error()) + continue + } else { + return err + } + } + + return nil } func (self *SRegion) GetSecurityGroups(id, name, nextToken string) ([]SSecurityGroup, string, error) { params := map[string]string{} if len(id) > 0 { - params["groupId"] = id + params["GroupId.1"] = id } if len(name) > 0 { - params["groupName"] = name + params["Filter.1.Name"] = "group-name" + params["Filter.1.Value.1"] = name } if len(nextToken) > 0 { - params["nextToken"] = nextToken + params["NextToken"] = nextToken } + resp, err := self.invoke("DescribeSecurityGroups", params) if err != nil { return nil, "", err @@ -157,7 +219,7 @@ func (self *SRegion) GetSecurityGroups(id, name, nextToken string) ([]SSecurityG SecurityGroupInfo []SSecurityGroup NextToken string }{} - resp.Unmarshal(&ret) + _ = resp.Unmarshal(&ret) return ret.SecurityGroupInfo, ret.NextToken, nil } @@ -188,3 +250,49 @@ func (self *SRegion) GetISecurityGroupByName(opts *cloudprovider.SecurityGroupFi } return nil, cloudprovider.ErrNotFound } + +func (self *SRegion) deleteSecurityGroup(id string) error { + params := map[string]string{} + params["GroupId"] = id + + _, err := self.invoke("DeleteSecurityGroup", params) + return err +} + +func (self *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCreateInput) (cloudprovider.ICloudSecurityGroup, error) { + params := map[string]string{} + if len(conf.Name) > 0 { + params["GroupName"] = conf.Name + } + resp, err := self.invoke("CreateSecurityGroup", params) + if err != nil { + return nil, err + } + + ret := &cloudprovider.SecurityGroupCreateOutput{} + _ = resp.Unmarshal(&ret) + + if ret.Return { + //rule := cloudprovider.SecurityRule{ + // ExternalId: ret.GroupId, + // SecurityRule: secrules.SecurityRule{ + // Action: secrules.SecurityRuleAllow, + // Protocol: secrules.PROTO_ANY, + // Direction: secrules.DIR_IN, + // Priority: 1, + // Ports: []int{}, + // PortStart: 1, + // PortEnd: 65535, + // }, + //} + //rule.ParseCIDR("0.0.0.0/0") + //err = self.addSecurityGroupRules(ret.GroupId, rule) + //if err != nil { + // _ = self.deleteSecurityGroup(ret.GroupId) + // return nil, err + //} + return self.GetISecurityGroupById(ret.GroupId) + } + + return nil, errors.Wrap(cloudprovider.ErrUnknown, "CreateSecurityGroup") +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/snapshot.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/snapshot.go new file mode 100644 index 0000000000..d32271e4b3 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/snapshot.go @@ -0,0 +1,135 @@ +package bingocloud + +import ( + "strconv" + "time" + + "yunion.io/x/jsonutils" + + "yunion.io/x/cloudmux/pkg/cloudprovider" +) + +type SSnapshot struct { + region *SRegion + SnapshotId string + SnapshotName string + VolumeId string + Status string + StartTime string + Progress string + OwnerId string + VolumeSize string + Description string +} + +func (self SSnapshot) GetId() string { + return self.SnapshotId +} + +func (self SSnapshot) GetName() string { + return self.SnapshotName +} + +func (self SSnapshot) GetGlobalId() string { + return self.SnapshotId +} + +func (self SSnapshot) GetCreatedAt() time.Time { + ct, _ := time.Parse("2006-01-02T15:04:05.000Z", self.StartTime) + return ct +} + +func (self SSnapshot) GetStatus() string { + return self.Status +} + +func (self SSnapshot) Refresh() error { + newSnapshot, err := self.region.getSnapshots(self.SnapshotId, "") + if err != nil { + return err + } + if len(newSnapshot) == 1 { + return jsonutils.Update(self, &newSnapshot[0]) + } + return cloudprovider.ErrNotFound +} + +func (self SSnapshot) IsEmulated() bool { + return false +} + +func (self SSnapshot) GetSysTags() map[string]string { + return nil +} + +func (self SSnapshot) GetTags() (map[string]string, error) { + return nil, nil +} + +func (self SSnapshot) SetTags(tags map[string]string, replace bool) error { + return nil +} + +func (self SSnapshot) GetProjectId() string { + return "" +} + +func (self SSnapshot) GetSizeMb() int32 { + size, _ := strconv.Atoi(self.VolumeSize) + return int32(size * 1024) +} + +func (self SSnapshot) GetDiskId() string { + return self.VolumeId +} + +func (self SSnapshot) GetDiskType() string { + return "" +} + +func (self SSnapshot) Delete() error { + return self.region.deleteSnapshot(self.SnapshotId) +} + +func (self *SRegion) createSnapshot(volumeId, name string, desc string) (string, error) { + params := map[string]string{} + params["VolumeId"] = volumeId + params["SnapshotName"] = name + params["Description"] = desc + + resp, err := self.client.invoke("CreateSnapshot", params) + if err != nil { + return "", err + } + newId := "" + err = resp.Unmarshal(&newId, "snapshotId") + + return newId, err +} + +func (self *SRegion) getSnapshots(id, name string) ([]SSnapshot, error) { + params := map[string]string{} + if id != "" { + params["SnapshotId.1"] = id + } + if name != "" { + params["Filter.1.Name"] = name + } + + resp, err := self.client.invoke("DescribeSnapshots", params) + if err != nil { + return nil, err + } + + var ret []SSnapshot + _ = resp.Unmarshal(&ret, "snapshotSet") + + return ret, err +} + +func (self *SRegion) deleteSnapshot(id string) error { + params := map[string]string{} + params["SnapshotId"] = id + _, err := self.client.invoke("DeleteSnapshot", params) + return err +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/storage.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/storage.go index 3281aafe89..fb69319db4 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/storage.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/storage.go @@ -115,8 +115,9 @@ func (self *SStorage) IsSysDiskStore() bool { func (self *SRegion) GetStorages(nextToken string) ([]SStorage, string, error) { params := map[string]string{} if len(nextToken) > 0 { - params["nextToken"] = nextToken + params["NextToken"] = nextToken } + resp, err := self.invoke("DescribeStorages", params) if err != nil { return nil, "", err @@ -125,7 +126,8 @@ func (self *SRegion) GetStorages(nextToken string) ([]SStorage, string, error) { NextToken string StorageSet []SStorage }{} - resp.Unmarshal(&ret) + _ = resp.Unmarshal(&ret) + return ret.StorageSet, ret.NextToken, nil } @@ -147,7 +149,7 @@ func (self *SCluster) GetIStorages() ([]cloudprovider.ICloudStorage, error) { if err != nil { return nil, err } - ret := []cloudprovider.ICloudStorage{} + var ret []cloudprovider.ICloudStorage for i := range storages { storages[i].cluster = self ret = append(ret, &storages[i]) @@ -156,7 +158,7 @@ func (self *SCluster) GetIStorages() ([]cloudprovider.ICloudStorage, error) { } func (self *SRegion) getStorages() ([]SStorage, error) { - storages := []SStorage{} + var storages []SStorage part, nextToken, err := self.GetStorages("") if err != nil { return nil, err diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/utils.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/utils.go new file mode 100644 index 0000000000..0f6cfb292c --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/utils.go @@ -0,0 +1,113 @@ +package bingocloud + +import ( + "fmt" + "strconv" + "strings" + + "yunion.io/x/pkg/util/secrules" + + "yunion.io/x/cloudmux/pkg/cloudprovider" +) + +type portRange struct { + Start int64 + End int64 +} + +type securityGroupInput struct { + GroupId string `json:"GroupId,omitempty"` + IpProtocol string `json:"IpProtocol,omitempty"` + CidrIp string `json:"CidrIp,omitempty"` + FromPort string `json:"FromPort,omitempty"` + ToPort string `json:"ToPort,omitempty"` + BoundType string `json:"BoundType,omitempty"` + SourceSecurityGroupOwnerId string `json:"SourceSecurityGroupOwnerId,omitempty"` + SourceSecurityGroupName string `json:"SourceSecurityGroupName,omitempty"` + Policy string `json:"Policy,omitempty"` +} + +func securityRuleToBingoCloud(secGroupId string, rule cloudprovider.SecurityRule) []securityGroupInput { + var portRanges []portRange + if len(rule.Ports) == 0 { + var start, end = 0, 0 + if rule.PortStart <= 0 { + start = 1 + } else { + start = rule.PortStart + } + + if rule.PortEnd <= 0 { + end = 65535 + } else { + end = rule.PortEnd + } + + portRanges = append(portRanges, portRange{int64(start), int64(end)}) + } + + for i := range rule.Ports { + port := rule.Ports[i] + if port <= 0 { + portRanges = append(portRanges, portRange{1, 65535}) + } else { + portRanges = append(portRanges, portRange{int64(port), int64(port)}) + } + } + + protocol := "" + if rule.Protocol == secrules.PROTO_ANY { + protocol = "all" + } else { + protocol = rule.Protocol + } + + var boundType = "In" + var policy = "DROP" + var allInputs []securityGroupInput + + if rule.Direction == secrules.SecurityRuleEgress { + boundType = "Out" + } + if rule.Action == secrules.SecurityRuleAllow { + policy = "ACCEPT" + } + + for _, port := range portRanges { + input := securityGroupInput{ + GroupId: secGroupId, + IpProtocol: protocol, + CidrIp: rule.IPNet.String(), + FromPort: strconv.FormatInt(port.Start, 10), + ToPort: strconv.FormatInt(port.End, 10), + BoundType: boundType, + Policy: policy, + } + allInputs = append(allInputs, input) + } + + return allInputs +} + +func nextDeviceName(curDeviceNames []string) (string, error) { + var currents []string + for _, item := range curDeviceNames { + currents = append(currents, strings.ToLower(item)) + } + + for i := 0; i < 25; i++ { + device := fmt.Sprintf("/dev/vd%c", byte(98+i)) + found := false + for _, item := range currents { + if strings.HasPrefix(item, device) { + found = true + } + } + + if !found { + return device, nil + } + } + + return "", fmt.Errorf("disk devicename out of index, current deivces: %s", currents) +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/vpc.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/vpc.go index c1dff8caed..6f33035e80 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/vpc.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/vpc.go @@ -81,7 +81,7 @@ func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, err if err != nil { return nil, err } - groups := []SSecurityGroup{} + var groups []SSecurityGroup groups = append(groups, part...) for len(nextToken) > 0 { part, nextToken, err = self.region.GetSecurityGroups("", "", nextToken) @@ -90,7 +90,7 @@ func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, err } groups = append(groups, part...) } - ret := []cloudprovider.ICloudSecurityGroup{} + var ret []cloudprovider.ICloudSecurityGroup for i := range groups { groups[i].region = self.region ret = append(ret, &groups[i]) @@ -118,13 +118,15 @@ func (self *SVpc) GetStatus() string { func (self *SRegion) GetVpcs(id string) ([]SVpc, error) { params := map[string]string{} if len(id) > 0 { - params["vpcId"] = id + params["VpcId"] = id } + resp, err := self.invoke("DescribeVpcs", params) if err != nil { return nil, err } - vpcs := []SVpc{} + var vpcs []SVpc + return vpcs, resp.Unmarshal(&vpcs, "vpcSet") } @@ -133,7 +135,7 @@ func (self *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { if err != nil { return nil, errors.Wrapf(err, "GetVpcs") } - ret := []cloudprovider.ICloudVpc{} + var ret []cloudprovider.ICloudVpc for i := range vpcs { vpcs[i].region = self ret = append(ret, &vpcs[i]) diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/wire.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/wire.go index 68533aafdb..47f3adb674 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/wire.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/wire.go @@ -82,7 +82,7 @@ func (self *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) { if err != nil { return nil, err } - ret := []cloudprovider.ICloudWire{} + var ret []cloudprovider.ICloudWire for i := range clusters { wire := &SWire{ vpc: self, diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/zone.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/zone.go index ab3068282c..9dd2f16a8b 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/zone.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/bingocloud/zone.go @@ -25,6 +25,6 @@ func (self *SRegion) GetZones() ([]SZone, error) { if err != nil { return nil, err } - ret := []SZone{} + var ret []SZone return ret, resp.Unmarshal(&ret, "availabilityZoneInfo") } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/cdn_domain_base.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cdn_domain_base.go new file mode 100644 index 0000000000..403dd7e2ac --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cdn_domain_base.go @@ -0,0 +1,52 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package multicloud + +import ( + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/pkg/errors" +) + +type SCDNDomainBase struct { + SResourceBase +} + +func (self *SCDNDomainBase) GetCacheKeys() (*cloudprovider.SCDNCacheKeys, error) { + return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetCacheKeys") +} + +func (self *SCDNDomainBase) GetRangeOriginPull() (*cloudprovider.SCDNRangeOriginPull, error) { + return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetRangeOriginPull") +} + +func (self *SCDNDomainBase) GetCache() (*cloudprovider.SCDNCache, error) { + return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetCache") +} + +func (self *SCDNDomainBase) GetHTTPS() (*cloudprovider.SCDNHttps, error) { + return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetHTTPS") +} + +func (self *SCDNDomainBase) GetForceRedirect() (*cloudprovider.SCDNForceRedirect, error) { + return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetForceRedirect") +} + +func (self *SCDNDomainBase) GetReferer() (*cloudprovider.SCDNReferer, error) { + return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetReferer") +} + +func (self *SCDNDomainBase) GetMaxAge() (*cloudprovider.SCDNMaxAge, error) { + return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetMaxAge") +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/cdn.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/cdn.go index 4a5faba5f4..cf21deab78 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/cdn.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/cdn.go @@ -55,6 +55,134 @@ type SCdnDomain struct { ServiceType string `json:"ServiceType"` Status string `json:"Status"` UpdateTime string `json:"UpdateTime"` + + config *SCdnConfig +} + +func (self *SCdnDomain) GetConfig() (*SCdnConfig, error) { + var err error = nil + if self.config == nil { + self.config, err = self.client.GetCdnConfig(self.ResourceID) + } + return self.config, err +} + +type SCacheKey struct { + FullUrlCache string + IgnoreCase string + KeyRules []struct { + RulePaths []string + RuleType string + FullUrlCache string + IgnoreCase string + QueryString struct { + Switch string + Action string + Value string + } + RuleTag string + } +} + +type SCache struct { + RuleCache []CdnCache +} + +type CdnCache struct { + CdnCacheCacheConfig CdnCacheCacheConfig `json:"CacheConfig"` + RulePaths []string `json:"RulePaths"` + RuleType string `json:"RuleType"` +} + +type CdnCacheCacheConfig struct { + CdnCacheCacheConfigCache CdnCacheCacheConfigCache `json:"Cache"` + CdnCacheCacheConfigFollowOrigin CdnCacheCacheConfigFollowOrigin `json:"FollowOrigin"` + CdnCacheCacheConfigNoCache CdnCacheCacheConfigNoCache `json:"NoCache"` +} + +type CdnCacheCacheConfigFollowOrigin struct { + CdnCacheCacheConfigFollowOriginHeuristicCache CdnCacheCacheConfigFollowOriginHeuristicCache `json:"HeuristicCache"` + Switch string `json:"Switch"` +} + +type CdnCacheCacheConfigFollowOriginHeuristicCache struct { + CdnCacheCacheConfigFollowOriginHeuristicCacheCacheConfig CdnCacheCacheConfigFollowOriginHeuristicCacheCacheConfig `json:"CacheConfig"` + Switch string `json:"Switch"` +} + +type CdnCacheCacheConfigFollowOriginHeuristicCacheCacheConfig struct { + HeuristicCacheTime int `json:"HeuristicCacheTime"` + HeuristicCacheTimeSwitch string `json:"HeuristicCacheTimeSwitch"` +} + +type CdnCacheCacheConfigNoCache struct { + Revalidate string `json:"Revalidate"` + Switch string `json:"Switch"` +} + +type CdnCacheCacheConfigCache struct { + CacheTime int `json:"CacheTime"` + CompareMaxAge string `json:"CompareMaxAge"` + IgnoreCacheControl string `json:"IgnoreCacheControl"` + IgnoreSetCookie string `json:"IgnoreSetCookie"` + Switch string `json:"Switch"` +} + +type SRangeOriginPull struct { + Switch string + RangeRules []struct { + Switch string + RuleType string + RulePaths []string + } + Cache *SCache +} + +type SCdnHttps struct { + Switch string + Http2 string +} + +type SForceRedirect struct { + Switch string + RedirectType string +} + +type SCdnReferer struct { + Switch string + RefererRules []struct { + RuleType string + RulePaths []string + RefererType string + Referers []string + AllowEmpty bool + } +} + +type SMaxAge struct { + Switch string + MaxAgeRules []struct { + MaxAgeType string + MaxAgeContents []string + MaxAgeTime int + FollowOrigin string + } +} + +type SCdnConfig struct { + CacheKey *SCacheKey + + RangeOriginPull *SRangeOriginPull + + Cache *SCache + + Https *SCdnHttps + + ForceRedirect *SForceRedirect + + Referer *SCdnReferer + + MaxAge *SMaxAge } func (self *SCdnDomain) GetName() string { @@ -319,3 +447,252 @@ func (self *SQcloudClient) CreateCDNDomain(opts *cloudprovider.CdnCreateOptions) } return self.GetCdnDomain(opts.Domain) } + +func (self *SQcloudClient) GetCdnConfig(resourceId string) (*SCdnConfig, error) { + params := map[string]string{ + "Filters.0.Name": "resourceId", + "Filters.0.Value.0": resourceId, + "Limit": "1", + } + resp, err := self.cdnRequest("DescribeDomainsConfig", params) + if err != nil { + return nil, errors.Wrapf(err, "DescribeDomainsConfig") + } + result := struct { + Domains []SCdnConfig + TotalNumber int + }{} + err = resp.Unmarshal(&result) + if err != nil { + return nil, errors.Wrapf(err, "resp.Unmarshal") + } + for i := range result.Domains { + return &result.Domains[i], nil + } + return nil, errors.Wrapf(cloudprovider.ErrNotFound, resourceId) +} + +func (self *SCdnDomain) GetCacheKeys() (*cloudprovider.SCDNCacheKeys, error) { + config, err := self.GetConfig() + if err != nil { + return nil, err + } + if config.CacheKey == nil { + return nil, nil + } + enabled, ignoreCase := false, false + ret := &cloudprovider.SCDNCacheKeys{ + KeyRules: []cloudprovider.CacheKeyRule{}, + } + if config.CacheKey.FullUrlCache == "on" { + enabled = true + } + if config.CacheKey.IgnoreCase == "on" { + ignoreCase = true + } + ret.Enabled, ret.IgnoreCase = &enabled, &ignoreCase + for _, r := range config.CacheKey.KeyRules { + rule := cloudprovider.CacheKeyRule{ + RulePaths: r.RulePaths, + RuleType: r.RuleType, + FullUrlCache: r.FullUrlCache == "on", + IgnoreCase: r.IgnoreCase == "on", + RuleTag: r.RuleTag, + QueryString: cloudprovider.CacheKeyRuleQueryString{ + Enabled: r.QueryString.Switch == "on", + Action: r.QueryString.Action, + Value: r.QueryString.Value, + }, + } + ret.KeyRules = append(ret.KeyRules, rule) + } + return ret, nil +} + +func (self *SCdnDomain) GetRangeOriginPull() (*cloudprovider.SCDNRangeOriginPull, error) { + config, err := self.GetConfig() + if err != nil { + return nil, err + } + if config.RangeOriginPull == nil { + return nil, nil + } + ret := &cloudprovider.SCDNRangeOriginPull{RangeOriginPullRules: []cloudprovider.SRangeOriginPullRule{}} + enabled := false + if config.RangeOriginPull.Switch == "on" { + enabled = true + } + ret.Enabled = &enabled + for _, obj := range config.RangeOriginPull.RangeRules { + rule := cloudprovider.SRangeOriginPullRule{ + Enabled: false, + RuleType: obj.RuleType, + RulePaths: obj.RulePaths, + } + if obj.Switch == "on" { + rule.Enabled = true + } + ret.RangeOriginPullRules = append(ret.RangeOriginPullRules, rule) + } + return ret, nil +} + +func (self *SCdnDomain) GetCache() (*cloudprovider.SCDNCache, error) { + config, err := self.GetConfig() + if err != nil { + return nil, err + } + if config.Cache == nil { + return nil, nil + } + ret := &cloudprovider.SCDNCache{ + RuleCache: []cloudprovider.SCacheRuleCache{}, + } + for i, r := range config.Cache.RuleCache { + rule := cloudprovider.SCacheRuleCache{ + Priority: i + 1, + RulePaths: r.RulePaths, + RuleType: r.RuleType, + CacheConfig: &cloudprovider.RuleCacheConfig{}, + } + if r.CdnCacheCacheConfig.CdnCacheCacheConfigCache.Switch == "on" { + rule.CacheConfig.Cache = &struct { + Enabled bool + CacheTime int + CompareMaxAge bool + IgnoreCacheControl bool + IgnoreSetCookie bool + }{ + Enabled: true, + CacheTime: r.CdnCacheCacheConfig.CdnCacheCacheConfigCache.CacheTime, + CompareMaxAge: r.CdnCacheCacheConfig.CdnCacheCacheConfigCache.CompareMaxAge == "on", + IgnoreCacheControl: r.CdnCacheCacheConfig.CdnCacheCacheConfigCache.IgnoreCacheControl == "on", + IgnoreSetCookie: r.CdnCacheCacheConfig.CdnCacheCacheConfigCache.IgnoreSetCookie == "on", + } + } else if r.CdnCacheCacheConfig.CdnCacheCacheConfigNoCache.Switch == "on" { + rule.CacheConfig.NoCache = &struct { + Enabled bool + Revalidate bool + }{ + Enabled: true, + Revalidate: r.CdnCacheCacheConfig.CdnCacheCacheConfigNoCache.Revalidate == "on", + } + } else if r.CdnCacheCacheConfig.CdnCacheCacheConfigFollowOrigin.Switch == "on" { + follow := r.CdnCacheCacheConfig.CdnCacheCacheConfigFollowOrigin + rule.CacheConfig.FollowOrigin = &struct { + Enabled bool + HeuristicCache struct { + Enabled bool + CacheConfig struct { + HeuristicCacheTimeSwitch bool + HeuristicCacheTime int + } + } + }{ + Enabled: true, + } + rule.CacheConfig.FollowOrigin.HeuristicCache.Enabled = follow.Switch == "on" + rule.CacheConfig.FollowOrigin.HeuristicCache.CacheConfig.HeuristicCacheTimeSwitch = follow.CdnCacheCacheConfigFollowOriginHeuristicCache.Switch == "on" + rule.CacheConfig.FollowOrigin.HeuristicCache.CacheConfig.HeuristicCacheTime = follow.CdnCacheCacheConfigFollowOriginHeuristicCache.CdnCacheCacheConfigFollowOriginHeuristicCacheCacheConfig.HeuristicCacheTime + } + ret.RuleCache = append(ret.RuleCache, rule) + } + return ret, nil +} + +func (self *SCdnDomain) GetHTTPS() (*cloudprovider.SCDNHttps, error) { + config, err := self.GetConfig() + if err != nil { + return nil, err + } + if config.Https == nil { + return nil, nil + } + ret := &cloudprovider.SCDNHttps{} + enabled, enableHttp2 := false, false + if config.Https.Switch == "on" { + enabled = true + } + if config.Https.Http2 == "on" { + enableHttp2 = true + } + ret.Enabled, ret.Http2 = &enabled, &enableHttp2 + return ret, nil +} + +func (self *SCdnDomain) GetForceRedirect() (*cloudprovider.SCDNForceRedirect, error) { + config, err := self.GetConfig() + if err != nil { + return nil, err + } + if config.ForceRedirect == nil { + return nil, nil + } + ret := &cloudprovider.SCDNForceRedirect{ + RedirectType: config.ForceRedirect.RedirectType, + } + enabled := false + if config.ForceRedirect.Switch == "on" { + enabled = true + } + ret.Enabled = &enabled + return ret, nil +} + +func (self *SCdnDomain) GetReferer() (*cloudprovider.SCDNReferer, error) { + config, err := self.GetConfig() + if err != nil { + return nil, err + } + if config.Referer == nil { + return nil, nil + } + ret := &cloudprovider.SCDNReferer{ + RefererRules: []cloudprovider.RefererRule{}, + } + enabled := false + if config.Referer.Switch == "on" { + enabled = true + } + ret.Enabled = &enabled + for _, r := range config.Referer.RefererRules { + rule := cloudprovider.RefererRule{ + RuleType: r.RuleType, + RulePaths: r.RulePaths, + RefererType: r.RuleType, + Referers: r.Referers, + AllowEmpty: &r.AllowEmpty, + } + ret.RefererRules = append(ret.RefererRules, rule) + } + return ret, nil +} + +func (self *SCdnDomain) GetMaxAge() (*cloudprovider.SCDNMaxAge, error) { + config, err := self.GetConfig() + if err != nil { + return nil, err + } + if config.MaxAge == nil { + return nil, nil + } + ret := &cloudprovider.SCDNMaxAge{} + enabled := false + if config.MaxAge.Switch == "on" { + enabled = true + } + ret.Enabled = &enabled + for _, r := range config.MaxAge.MaxAgeRules { + rule := cloudprovider.SMaxAgeRule{ + MaxAgeType: r.MaxAgeType, + MaxAgeContents: r.MaxAgeContents, + MaxAgeTime: r.MaxAgeTime, + FollowOrigin: false, + } + if r.FollowOrigin == "on" { + rule.FollowOrigin = true + } + ret.MaxAgeRules = append(ret.MaxAgeRules, rule) + } + return ret, nil +}