fix(region): vendor update for aliyun alb and nlb (#22761)

This commit is contained in:
屈轩
2025-06-23 10:30:18 +08:00
committed by GitHub
parent 064c23040e
commit 39d5d57545
15 changed files with 2902 additions and 11 deletions
+1 -1
View File
@@ -96,7 +96,7 @@ require (
k8s.io/cri-api v0.22.17
k8s.io/klog/v2 v2.20.0
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250620092920-5cf87c1f27fd
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250623020750-d1f03ea14cc5
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
+2 -2
View File
@@ -1412,8 +1412,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.20250620092920-5cf87c1f27fd h1:FvsOvo2KpO8eSrz/amhKV6WZBgvOFOWZrtxrqIm+Z4s=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250620092920-5cf87c1f27fd/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250623020750-d1f03ea14cc5 h1:BIbMRsvXq0WZY7LYjzKOxzhazD7Rusm/JRda0mZ53WM=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250623020750-d1f03ea14cc5/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ=
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0 h1:msG4SiDSVU7CrXH06WuHlNEZXIooTcmNbfrIGHuIHBU=
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
+1 -1
View File
@@ -1852,7 +1852,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.20250620092920-5cf87c1f27fd
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250623020750-d1f03ea14cc5
## explicit; go 1.21
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
+337
View File
@@ -0,0 +1,337 @@
// 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 aliyun
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SAlb struct {
multicloud.SLoadbalancerBase
AliyunTags
region *SRegion
LoadBalancerId string `json:"LoadBalancerId"`
LoadBalancerName string `json:"LoadBalancerName"`
LoadBalancerStatus string `json:"LoadBalancerStatus"`
LoadBalancerBizStatus string `json:"LoadBalancerBizStatus"`
LoadBalancerEdition string `json:"LoadBalancerEdition"`
LoadBalancerPayType string `json:"LoadBalancerPayType"`
AddressType string `json:"AddressType"`
AddressAllocatedMode string `json:"AddressAllocatedMode"`
Ipv6AddressType string `json:"Ipv6AddressType"`
DNSName string `json:"DNSName"`
VpcId string `json:"VpcId"`
LoadBalancerBussinessStatus string `json:"LoadBalancerBussinessStatus"`
CreateTime time.Time `json:"CreateTime"`
ResourceGroupId string `json:"ResourceGroupId"`
CanBeDeleted bool `json:"CanBeDeleted"`
ModificationProtectionConfig map[string]interface{} `json:"ModificationProtectionConfig"`
DeletionProtectionConfig map[string]interface{} `json:"DeletionProtectionConfig"`
AccessLogConfig map[string]interface{} `json:"AccessLogConfig"`
LoadBalancerOperationLocks []map[string]interface{} `json:"LoadBalancerOperationLocks"`
ZoneMappings []ZoneMapping `json:"ZoneMappings"`
RegionId string `json:"RegionId"`
}
type ZoneMapping struct {
ZoneId string `json:"ZoneId"`
VSwitchId string `json:"VSwitchId"`
AllocationId string `json:"AllocationId"`
EipType string `json:"EipType"`
LoadBalancerAddresses []LoadBalancerAddress `json:"LoadBalancerAddresses"`
}
type LoadBalancerAddress struct {
Address string `json:"Address"`
AddressType string `json:"AddressType"`
AllocationId string `json:"AllocationId"`
EipType string `json:"EipType"`
IntranetAddress string `json:"IntranetAddress"`
InternetAddress string `json:"InternetAddress"`
Ipv6Address string `json:"Ipv6Address"`
}
func (alb *SAlb) GetName() string {
return alb.LoadBalancerName
}
func (alb *SAlb) GetId() string {
return alb.LoadBalancerId
}
func (alb *SAlb) GetGlobalId() string {
return alb.LoadBalancerId
}
func (alb *SAlb) GetStatus() string {
switch alb.LoadBalancerStatus {
case "Active":
return api.LB_STATUS_ENABLED
case "Provisioning", "Configuring":
return api.LB_STATUS_UNKNOWN
case "Stopped":
return api.LB_STATUS_DISABLED
default:
return api.LB_STATUS_UNKNOWN
}
}
func (alb *SAlb) GetAddress() string {
return alb.DNSName
}
func (alb *SAlb) GetAddressType() string {
return alb.AddressType
}
func (alb *SAlb) GetNetworkType() string {
return "vpc"
}
func (alb *SAlb) GetNetworkIds() []string {
ret := []string{}
for _, zone := range alb.ZoneMappings {
if len(zone.VSwitchId) > 0 {
ret = append(ret, zone.VSwitchId)
}
}
return ret
}
func (alb *SAlb) GetZoneId() string {
if len(alb.ZoneMappings) > 0 {
zone, err := alb.region.getZoneById(alb.ZoneMappings[0].ZoneId)
if err != nil {
log.Errorf("failed to find zone for alb %s error: %v", alb.LoadBalancerName, err)
return ""
}
return zone.GetGlobalId()
}
return ""
}
func (alb *SAlb) GetZone1Id() string {
if len(alb.ZoneMappings) > 1 {
zone, err := alb.region.getZoneById(alb.ZoneMappings[1].ZoneId)
if err != nil {
log.Errorf("failed to find zone for alb %s error: %v", alb.LoadBalancerName, err)
return ""
}
return zone.GetGlobalId()
}
return ""
}
func (alb *SAlb) IsEmulated() bool {
return false
}
func (alb *SAlb) GetVpcId() string {
return alb.VpcId
}
func (alb *SAlb) Refresh() error {
loadbalancer, err := alb.region.GetAlbDetail(alb.LoadBalancerId)
if err != nil {
return err
}
return jsonutils.Update(alb, loadbalancer)
}
func (alb *SAlb) Delete(ctx context.Context) error {
return alb.region.DeleteAlb(alb.LoadBalancerId)
}
func (alb *SAlb) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
groups, err := alb.region.GetAlbServerGroups()
if err != nil {
return nil, err
}
igroups := []cloudprovider.ICloudLoadbalancerBackendGroup{}
for i := 0; i < len(groups); i++ {
// 过滤出属于当前负载均衡器的服务器组
for _, lbId := range groups[i].RelatedLoadBalancerIds {
if lbId == alb.LoadBalancerId {
groups[i].alb = alb
igroups = append(igroups, &groups[i])
break
}
}
}
return igroups, nil
}
func (alb *SAlb) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbalancerBackendGroup) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
serverGroup, err := alb.region.CreateAlbServerGroup(group, alb.VpcId)
if err != nil {
return nil, err
}
serverGroup.alb = alb
return serverGroup, nil
}
func (alb *SAlb) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
groups, err := alb.GetILoadBalancerBackendGroups()
if err != nil {
return nil, err
}
for i := 0; i < len(groups); i++ {
if groups[i].GetGlobalId() == groupId {
return groups[i], nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (alb *SAlb) CreateILoadBalancerListener(ctx context.Context, listener *cloudprovider.SLoadbalancerListenerCreateOptions) (cloudprovider.ICloudLoadbalancerListener, error) {
return alb.region.CreateAlbListener(alb, listener)
}
func (alb *SAlb) GetILoadBalancerListenerById(listenerId string) (cloudprovider.ICloudLoadbalancerListener, error) {
listeners, err := alb.GetILoadBalancerListeners()
if err != nil {
return nil, err
}
for i := 0; i < len(listeners); i++ {
if listeners[i].GetGlobalId() == listenerId {
return listeners[i], nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (alb *SAlb) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
listeners, err := alb.region.GetAlbListeners(alb.LoadBalancerId)
if err != nil {
return nil, err
}
ilisteners := []cloudprovider.ICloudLoadbalancerListener{}
for i := 0; i < len(listeners); i++ {
listeners[i].alb = alb
ilisteners = append(ilisteners, &listeners[i])
}
return ilisteners, nil
}
func (alb *SAlb) GetChargeType() string {
return api.LB_CHARGE_TYPE_BY_TRAFFIC
}
func (alb *SAlb) GetCreatedAt() time.Time {
return alb.CreateTime
}
func (alb *SAlb) GetEgressMbps() int {
return 0
}
func (alb *SAlb) GetIEIPs() ([]cloudprovider.ICloudEIP, error) {
return []cloudprovider.ICloudEIP{}, nil
}
func (alb *SAlb) Start() error {
return cloudprovider.ErrNotSupported
}
func (alb *SAlb) Stop() error {
return cloudprovider.ErrNotSupported
}
func (alb *SAlb) GetLoadbalancerSpec() string {
return alb.LoadBalancerEdition
}
func (alb *SAlb) GetProjectId() string {
return alb.ResourceGroupId
}
// region methods
func (region *SRegion) GetAlbs() ([]SAlb, error) {
params := map[string]string{
"RegionId": region.RegionId,
"MaxResults": "100",
}
albs := []SAlb{}
nextToken := ""
for {
if nextToken != "" {
params["NextToken"] = nextToken
}
body, err := region.albRequest("ListLoadBalancers", params)
if err != nil {
return nil, err
}
pageAlbs := []SAlb{}
err = body.Unmarshal(&pageAlbs, "LoadBalancers")
if err != nil {
return nil, err
}
for i := 0; i < len(pageAlbs); i++ {
pageAlbs[i].region = region
}
albs = append(albs, pageAlbs...)
nextToken, _ = body.GetString("NextToken")
if nextToken == "" {
break
}
}
return albs, nil
}
func (region *SRegion) GetAlbDetail(albId string) (*SAlb, error) {
params := map[string]string{
"RegionId": region.RegionId,
"LoadBalancerId": albId,
}
body, err := region.albRequest("GetLoadBalancerAttribute", params)
if err != nil {
return nil, err
}
alb := &SAlb{region: region}
err = body.Unmarshal(alb)
if err != nil {
return nil, err
}
return alb, nil
}
func (region *SRegion) DeleteAlb(albId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"LoadBalancerId": albId,
}
_, err := region.albRequest("DeleteLoadBalancer", params)
return err
}
+503
View File
@@ -0,0 +1,503 @@
// 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 aliyun
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SAlbListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
AliyunTags
alb *SAlb
ListenerId string `json:"ListenerId"`
ListenerDescription string `json:"ListenerDescription"`
ListenerProtocol string `json:"ListenerProtocol"`
ListenerPort int `json:"ListenerPort"`
ListenerStatus string `json:"ListenerStatus"`
LoadBalancerId string `json:"LoadBalancerId"`
RequestTimeout int `json:"RequestTimeout"`
IdleTimeout int `json:"IdleTimeout"`
SecurityPolicyId string `json:"SecurityPolicyId"`
GzipEnabledField bool `json:"GzipEnabled"`
Http2Enabled bool `json:"Http2Enabled"`
QuicEnabled bool `json:"QuicEnabled"`
ProxyProtocolEnabled bool `json:"ProxyProtocolEnabled"`
Certificates []AlbCertificate `json:"Certificates"`
CaCertificates []AlbCertificate `json:"CaCertificates"`
DefaultActions []AlbAction `json:"DefaultActions"`
XForwardedForConfig map[string]interface{} `json:"XForwardedForConfig"`
AccessLogTracingConfig map[string]interface{} `json:"AccessLogTracingConfig"`
// LogConfig map[string]interface{} `json:"LogConfig"`
CreateTime string `json:"CreateTime"`
RegionId string `json:"RegionId"`
}
type AlbCertificate struct {
CertificateId string `json:"CertificateId"`
IsDefault bool `json:"IsDefault"`
}
type AlbAction struct {
Type string `json:"Type"`
Order int `json:"Order"`
ForwardGroupConfig ForwardGroupConfig `json:"ForwardGroupConfig"`
FixedResponseConfig FixedResponseConfig `json:"FixedResponseConfig"`
RedirectConfig RedirectConfig `json:"RedirectConfig"`
RewriteConfig RewriteConfig `json:"RewriteConfig"`
InsertHeaderConfig InsertHeaderConfig `json:"InsertHeaderConfig"`
RemoveHeaderConfig RemoveHeaderConfig `json:"RemoveHeaderConfig"`
TrafficLimitConfig TrafficLimitConfig `json:"TrafficLimitConfig"`
TrafficMirrorConfig TrafficMirrorConfig `json:"TrafficMirrorConfig"`
CorsConfig CorsConfig `json:"CorsConfig"`
}
type ForwardGroupConfig struct {
ServerGroupTuples []ServerGroupTuple `json:"ServerGroupTuples"`
}
type ServerGroupTuple struct {
ServerGroupId string `json:"ServerGroupId"`
Weight int `json:"Weight"`
}
type FixedResponseConfig struct {
Content string `json:"Content"`
ContentType string `json:"ContentType"`
HttpCode string `json:"HttpCode"`
}
type RedirectConfig struct {
Host string `json:"Host"`
HttpCode string `json:"HttpCode"`
Path string `json:"Path"`
Port string `json:"Port"`
Protocol string `json:"Protocol"`
Query string `json:"Query"`
}
type RewriteConfig struct {
Host string `json:"Host"`
Path string `json:"Path"`
Query string `json:"Query"`
}
type InsertHeaderConfig struct {
Key string `json:"Key"`
Value string `json:"Value"`
ValueType string `json:"ValueType"`
}
type RemoveHeaderConfig struct {
Key string `json:"Key"`
}
type TrafficLimitConfig struct {
QPS int `json:"QPS"`
}
type TrafficMirrorConfig struct {
MirrorGroupConfig MirrorGroupConfig `json:"MirrorGroupConfig"`
TargetType string `json:"TargetType"`
}
type MirrorGroupConfig struct {
ServerGroupTuples []ServerGroupTuple `json:"ServerGroupTuples"`
}
type CorsConfig struct {
AllowCredentials string `json:"AllowCredentials"`
AllowHeaders []string `json:"AllowHeaders"`
AllowMethods []string `json:"AllowMethods"`
AllowOrigin []string `json:"AllowOrigin"`
ExposeHeaders []string `json:"ExposeHeaders"`
MaxAge int `json:"MaxAge"`
}
func (listener *SAlbListener) GetName() string {
if len(listener.ListenerDescription) > 0 {
return listener.ListenerDescription
}
return fmt.Sprintf("%s:%d", listener.ListenerProtocol, listener.ListenerPort)
}
func (listener *SAlbListener) GetId() string {
return listener.ListenerId
}
func (listener *SAlbListener) GetGlobalId() string {
return listener.ListenerId
}
func (listener *SAlbListener) GetStatus() string {
switch listener.ListenerStatus {
case "Running":
return api.LB_STATUS_ENABLED
case "Stopped":
return api.LB_STATUS_DISABLED
case "Provisioning", "Configuring":
return api.LB_STATUS_UNKNOWN
default:
return api.LB_STATUS_UNKNOWN
}
}
func (listener *SAlbListener) IsEmulated() bool {
return false
}
func (listener *SAlbListener) GetEgressMbps() int {
return 0
}
func (listener *SAlbListener) Refresh() error {
lis, err := listener.alb.region.GetAlbListener(listener.ListenerId)
if err != nil {
return err
}
return jsonutils.Update(listener, lis)
}
func (listener *SAlbListener) GetListenerType() string {
switch listener.ListenerProtocol {
case "HTTP":
return api.LB_LISTENER_TYPE_HTTP
case "HTTPS":
return api.LB_LISTENER_TYPE_HTTPS
case "QUIC":
return "QUIC"
default:
return listener.ListenerProtocol
}
}
func (listener *SAlbListener) GetListenerPort() int {
return listener.ListenerPort
}
func (listener *SAlbListener) GetBackendGroupId() string {
if len(listener.DefaultActions) > 0 {
for _, action := range listener.DefaultActions {
if action.Type == "ForwardGroup" && len(action.ForwardGroupConfig.ServerGroupTuples) > 0 {
return action.ForwardGroupConfig.ServerGroupTuples[0].ServerGroupId
}
}
}
return ""
}
func (listener *SAlbListener) GetBackendServerPort() int {
return 0
}
func (listener *SAlbListener) GetScheduler() string {
return ""
}
func (listener *SAlbListener) GetAclStatus() string {
return ""
}
func (listener *SAlbListener) GetAclType() string {
return ""
}
func (listener *SAlbListener) GetAclId() string {
return ""
}
func (listener *SAlbListener) GetHealthCheck() string {
return ""
}
func (listener *SAlbListener) GetHealthCheckType() string {
return ""
}
func (listener *SAlbListener) GetHealthCheckDomain() string {
return ""
}
func (listener *SAlbListener) GetHealthCheckURI() string {
return ""
}
func (listener *SAlbListener) GetHealthCheckCode() string {
return ""
}
func (listener *SAlbListener) GetHealthCheckRise() int {
return 0
}
func (listener *SAlbListener) GetHealthCheckFail() int {
return 0
}
func (listener *SAlbListener) GetHealthCheckTimeout() int {
return 0
}
func (listener *SAlbListener) GetHealthCheckInterval() int {
return 0
}
func (listener *SAlbListener) GetHealthCheckReq() string {
return ""
}
func (listener *SAlbListener) GetHealthCheckExp() string {
return ""
}
func (listener *SAlbListener) GetStickySession() string {
return ""
}
func (listener *SAlbListener) GetStickySessionType() string {
return ""
}
func (listener *SAlbListener) GetStickySessionCookie() string {
return ""
}
func (listener *SAlbListener) GetStickySessionCookieTimeout() int {
return 0
}
func (listener *SAlbListener) XForwardedForEnabled() bool {
return false
}
func (listener *SAlbListener) GzipEnabled() bool {
return listener.GzipEnabledField
}
func (listener *SAlbListener) GetCertificateId() string {
for _, cert := range listener.Certificates {
if cert.IsDefault {
return cert.CertificateId
}
}
if len(listener.Certificates) > 0 {
return listener.Certificates[0].CertificateId
}
return ""
}
func (listener *SAlbListener) GetTLSCipherPolicy() string {
return listener.SecurityPolicyId
}
func (listener *SAlbListener) HTTP2Enabled() bool {
return listener.Http2Enabled
}
func (listener *SAlbListener) ChangeCertificate(ctx context.Context, opts *cloudprovider.ListenerCertificateOptions) error {
return cloudprovider.ErrNotSupported
}
func (listener *SAlbListener) SetAcl(ctx context.Context, opts *cloudprovider.ListenerAclOptions) error {
return cloudprovider.ErrNotSupported
}
func (listener *SAlbListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) {
rules, err := listener.alb.region.GetAlbRules(listener.ListenerId)
if err != nil {
return nil, err
}
iRules := []cloudprovider.ICloudLoadbalancerListenerRule{}
for i := 0; i < len(rules); i++ {
rules[i].albListener = listener
iRules = append(iRules, &rules[i])
}
return iRules, nil
}
func (listener *SAlbListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
listenerRule, err := listener.alb.region.CreateAlbRule(listener.ListenerId, rule)
if err != nil {
return nil, err
}
listenerRule.albListener = listener
return listenerRule, nil
}
func (listener *SAlbListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
rule, err := listener.alb.region.GetAlbRule(ruleId)
if err != nil {
return nil, err
}
rule.albListener = listener
return rule, nil
}
func (listener *SAlbListener) Delete(ctx context.Context) error {
return listener.alb.region.DeleteAlbListener(listener.ListenerId)
}
func (listener *SAlbListener) Start() error {
return listener.alb.region.StartAlbListener(listener.ListenerId)
}
func (listener *SAlbListener) Stop() error {
return listener.alb.region.StopAlbListener(listener.ListenerId)
}
func (listener *SAlbListener) ChangeScheduler(ctx context.Context, opts *cloudprovider.ChangeListenerSchedulerOptions) error {
return cloudprovider.ErrNotSupported
}
func (listener *SAlbListener) SetHealthCheck(ctx context.Context, opts *cloudprovider.ListenerHealthCheckOptions) error {
return cloudprovider.ErrNotSupported
}
func (listener *SAlbListener) GetProjectId() string {
return listener.alb.GetProjectId()
}
func (listener *SAlbListener) GetClientIdleTimeout() int {
return listener.IdleTimeout
}
func (listener *SAlbListener) GetBackendConnectTimeout() int {
return listener.RequestTimeout
}
// region methods
func (region *SRegion) GetAlbListeners(loadBalancerId string) ([]SAlbListener, error) {
params := map[string]string{
"RegionId": region.RegionId,
"MaxResults": "100",
}
if len(loadBalancerId) > 0 {
params["LoadBalancerIds.1"] = loadBalancerId
}
listeners := []SAlbListener{}
nextToken := ""
for {
if nextToken != "" {
params["NextToken"] = nextToken
}
body, err := region.albRequest("ListListeners", params)
if err != nil {
return nil, err
}
pageListeners := []SAlbListener{}
err = body.Unmarshal(&pageListeners, "Listeners")
if err != nil {
return nil, err
}
listeners = append(listeners, pageListeners...)
nextToken, _ = body.GetString("NextToken")
if nextToken == "" {
break
}
}
return listeners, nil
}
func (region *SRegion) GetAlbListener(listenerId string) (*SAlbListener, error) {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
}
body, err := region.albRequest("GetListenerAttribute", params)
if err != nil {
return nil, err
}
listener := &SAlbListener{}
err = body.Unmarshal(listener)
if err != nil {
return nil, err
}
return listener, nil
}
func (region *SRegion) CreateAlbListener(alb *SAlb, listener *cloudprovider.SLoadbalancerListenerCreateOptions) (*SAlbListener, error) {
params := map[string]string{
"RegionId": region.RegionId,
"LoadBalancerId": alb.LoadBalancerId,
"ListenerProtocol": listener.ListenerType,
"ListenerPort": fmt.Sprintf("%d", listener.ListenerPort),
}
if len(listener.Name) > 0 {
params["ListenerDescription"] = listener.Name
}
body, err := region.albRequest("CreateListener", params)
if err != nil {
return nil, err
}
listenerId, err := body.GetString("ListenerId")
if err != nil {
return nil, err
}
return region.GetAlbListener(listenerId)
}
func (region *SRegion) DeleteAlbListener(listenerId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
}
_, err := region.albRequest("DeleteListener", params)
return err
}
func (region *SRegion) StartAlbListener(listenerId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
}
_, err := region.albRequest("StartListener", params)
return err
}
func (region *SRegion) StopAlbListener(listenerId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
}
_, err := region.albRequest("StopListener", params)
return err
}
+300
View File
@@ -0,0 +1,300 @@
// 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 aliyun
import (
"context"
"yunion.io/x/jsonutils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SAlbRule struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
AliyunTags
albListener *SAlbListener
RuleId string `json:"RuleId"`
RuleName string `json:"RuleName"`
RuleStatus string `json:"RuleStatus"`
Priority int `json:"Priority"`
ListenerId string `json:"ListenerId"`
LoadBalancerId string `json:"LoadBalancerId"`
RuleConditions []RuleCondition `json:"RuleConditions"`
RuleActions []AlbRuleAction `json:"RuleActions"`
Direction string `json:"Direction"`
CreateTime string `json:"CreateTime"`
RegionId string `json:"RegionId"`
}
type RuleCondition struct {
Type string `json:"Type"`
HostConfig HostConfig `json:"HostConfig"`
PathConfig PathConfig `json:"PathConfig"`
MethodConfig MethodConfig `json:"MethodConfig"`
QueryStringConfig QueryStringConfig `json:"QueryStringConfig"`
HeaderConfig HeaderConfig `json:"HeaderConfig"`
CookieConfig CookieConfig `json:"CookieConfig"`
SourceIpConfig SourceIpConfig `json:"SourceIpConfig"`
ResponseHeaderConfig ResponseHeaderConfig `json:"ResponseHeaderConfig"`
ResponseStatusCodeConfig ResponseStatusCodeConfig `json:"ResponseStatusCodeConfig"`
}
type AlbRuleAction struct {
Type string `json:"Type"`
Order int `json:"Order"`
ForwardGroupConfig ForwardGroupConfig `json:"ForwardGroupConfig"`
}
type HostConfig struct {
Values []string `json:"Values"`
}
type PathConfig struct {
Values []string `json:"Values"`
}
type MethodConfig struct {
Values []string `json:"Values"`
}
type QueryStringConfig struct {
Values []QueryStringValue `json:"Values"`
}
type QueryStringValue struct {
Key string `json:"Key"`
Value string `json:"Value"`
}
type HeaderConfig struct {
Key string `json:"Key"`
Values []string `json:"Values"`
}
type CookieConfig struct {
Values []CookieValue `json:"Values"`
}
type CookieValue struct {
Key string `json:"Key"`
Value string `json:"Value"`
}
type SourceIpConfig struct {
Values []string `json:"Values"`
}
type ResponseHeaderConfig struct {
Key string `json:"Key"`
Values []string `json:"Values"`
}
type ResponseStatusCodeConfig struct {
Values []string `json:"Values"`
}
func (rule *SAlbRule) GetName() string {
return rule.RuleName
}
func (rule *SAlbRule) GetId() string {
return rule.RuleId
}
func (rule *SAlbRule) GetGlobalId() string {
return rule.RuleId
}
func (rule *SAlbRule) GetStatus() string {
switch rule.RuleStatus {
case "Available":
return api.LB_STATUS_ENABLED
case "Configuring":
return api.LB_STATUS_UNKNOWN
default:
return api.LB_STATUS_UNKNOWN
}
}
func (rule *SAlbRule) IsDefault() bool {
return false
}
func (rule *SAlbRule) IsEmulated() bool {
return false
}
func (rule *SAlbRule) Refresh() error {
r, err := rule.albListener.alb.region.GetAlbRule(rule.RuleId)
if err != nil {
return err
}
return jsonutils.Update(rule, r)
}
func (rule *SAlbRule) GetCondition() string {
return ""
}
func (rule *SAlbRule) GetDomain() string {
for _, condition := range rule.RuleConditions {
if condition.Type == "Host" && len(condition.HostConfig.Values) > 0 {
return condition.HostConfig.Values[0]
}
}
return ""
}
func (rule *SAlbRule) GetPath() string {
for _, condition := range rule.RuleConditions {
if condition.Type == "Path" && len(condition.PathConfig.Values) > 0 {
return condition.PathConfig.Values[0]
}
}
return ""
}
func (rule *SAlbRule) GetProjectId() string {
return rule.albListener.GetProjectId()
}
func (rule *SAlbRule) GetBackendGroupId() string {
for _, action := range rule.RuleActions {
if action.Type == "ForwardGroup" && len(action.ForwardGroupConfig.ServerGroupTuples) > 0 {
return action.ForwardGroupConfig.ServerGroupTuples[0].ServerGroupId
}
}
return ""
}
func (rule *SAlbRule) Delete(ctx context.Context) error {
return rule.albListener.alb.region.DeleteAlbRule(rule.RuleId)
}
// region methods
func (region *SRegion) GetAlbRules(listenerId string) ([]SAlbRule, error) {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerIds.1": listenerId,
}
body, err := region.albRequest("ListRules", params)
if err != nil {
return nil, err
}
rules := []SAlbRule{}
err = body.Unmarshal(&rules, "Rules")
if err != nil {
return nil, err
}
return rules, nil
}
func (region *SRegion) GetAlbRule(ruleId string) (*SAlbRule, error) {
rules, err := region.GetAlbRules("")
if err != nil {
return nil, err
}
for _, rule := range rules {
if rule.RuleId == ruleId {
return &rule, nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (region *SRegion) CreateAlbRule(listenerId string, rule *cloudprovider.SLoadbalancerListenerRule) (*SAlbRule, error) {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
"RuleName": rule.Name,
"Priority": "100",
}
// 构建规则条件
conditions := jsonutils.NewArray()
if len(rule.Domain) > 0 {
condition := jsonutils.Marshal(map[string]interface{}{
"Type": "Host",
"HostConfig": map[string]interface{}{
"Values": []string{rule.Domain},
},
})
conditions.Add(condition)
}
if len(rule.Path) > 0 {
condition := jsonutils.Marshal(map[string]interface{}{
"Type": "Path",
"PathConfig": map[string]interface{}{
"Values": []string{rule.Path},
},
})
conditions.Add(condition)
}
params["RuleConditions"] = conditions.String()
// 构建规则动作
actions := jsonutils.NewArray()
if len(rule.BackendGroupId) > 0 {
action := jsonutils.Marshal(map[string]interface{}{
"Type": "ForwardGroup",
"Order": 1,
"ForwardGroupConfig": map[string]interface{}{
"ServerGroupTuples": []map[string]interface{}{
{
"ServerGroupId": rule.BackendGroupId,
"Weight": 100,
},
},
},
})
actions.Add(action)
}
params["RuleActions"] = actions.String()
body, err := region.albRequest("CreateRule", params)
if err != nil {
return nil, err
}
ruleId, err := body.GetString("RuleId")
if err != nil {
return nil, err
}
return region.GetAlbRule(ruleId)
}
func (region *SRegion) DeleteAlbRule(ruleId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"RuleId": ruleId,
}
_, err := region.albRequest("DeleteRule", params)
return err
}
+319
View File
@@ -0,0 +1,319 @@
// 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 aliyun
import (
"context"
"yunion.io/x/jsonutils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SAlbServerGroup struct {
multicloud.SResourceBase
AliyunTags
alb *SAlb
ServerGroupId string `json:"ServerGroupId"`
ServerGroupName string `json:"ServerGroupName"`
ServerGroupType string `json:"ServerGroupType"`
Protocol string `json:"Protocol"`
Scheduler string `json:"Scheduler"`
VpcId string `json:"VpcId"`
ServerGroupStatus string `json:"ServerGroupStatus"`
StickySessionConfig map[string]interface{} `json:"StickySessionConfig"`
HealthCheckConfig map[string]interface{} `json:"HealthCheckConfig"`
UchConfig map[string]interface{} `json:"UchConfig"`
SlowStartConfig map[string]interface{} `json:"SlowStartConfig"`
ConnectionDrainConfig map[string]interface{} `json:"ConnectionDrainConfig"`
RelatedLoadBalancerIds []string `json:"RelatedLoadBalancerIds"`
Servers []AlbServer `json:"Servers"`
CreateTime string `json:"CreateTime"`
RegionId string `json:"RegionId"`
ResourceGroupId string `json:"ResourceGroupId"`
}
type AlbServer struct {
ServerId string `json:"ServerId"`
ServerType string `json:"ServerType"`
ServerIp string `json:"ServerIp"`
Port int `json:"Port"`
Weight int `json:"Weight"`
Description string `json:"Description"`
Status string `json:"Status"`
}
func (group *SAlbServerGroup) GetILoadbalancer() cloudprovider.ICloudLoadbalancer {
return group.alb
}
func (group *SAlbServerGroup) GetLoadbalancerId() string {
return group.alb.GetId()
}
func (group *SAlbServerGroup) GetProtocolType() string {
return group.Protocol
}
func (group *SAlbServerGroup) GetScheduler() string {
return group.Scheduler
}
func (group *SAlbServerGroup) GetHealthCheck() (*cloudprovider.SLoadbalancerHealthCheck, error) {
return nil, nil
}
func (group *SAlbServerGroup) GetStickySession() (*cloudprovider.SLoadbalancerStickySession, error) {
return nil, nil
}
func (group *SAlbServerGroup) GetName() string {
return group.ServerGroupName
}
func (group *SAlbServerGroup) GetId() string {
return group.ServerGroupId
}
func (group *SAlbServerGroup) GetGlobalId() string {
return group.ServerGroupId
}
func (group *SAlbServerGroup) GetStatus() string {
switch group.ServerGroupStatus {
case "Available":
return api.LB_STATUS_ENABLED
case "Configuring":
return api.LB_STATUS_UNKNOWN
default:
return api.LB_STATUS_UNKNOWN
}
}
func (group *SAlbServerGroup) IsDefault() bool {
return false
}
func (group *SAlbServerGroup) GetType() string {
return api.LB_BACKENDGROUP_TYPE_NORMAL
}
func (group *SAlbServerGroup) IsEmulated() bool {
return false
}
func (group *SAlbServerGroup) Refresh() error {
serverGroup, err := group.alb.region.GetAlbServerGroup(group.ServerGroupId)
if err != nil {
return err
}
return jsonutils.Update(group, serverGroup)
}
func (group *SAlbServerGroup) GetILoadbalancerBackends() ([]cloudprovider.ICloudLoadbalancerBackend, error) {
backends := []cloudprovider.ICloudLoadbalancerBackend{}
for i := 0; i < len(group.Servers); i++ {
server := &SAlbServerGroupServer{
albServerGroup: group,
AlbServer: group.Servers[i],
}
backends = append(backends, server)
}
return backends, nil
}
func (group *SAlbServerGroup) GetILoadbalancerBackendById(backendId string) (cloudprovider.ICloudLoadbalancerBackend, error) {
backends, err := group.GetILoadbalancerBackends()
if err != nil {
return nil, err
}
for i := 0; i < len(backends); i++ {
if backends[i].GetGlobalId() == backendId {
return backends[i], nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (group *SAlbServerGroup) Sync(ctx context.Context, group2 *cloudprovider.SLoadbalancerBackendGroup) error {
return nil
}
func (group *SAlbServerGroup) Delete(ctx context.Context) error {
return group.alb.region.DeleteAlbServerGroup(group.ServerGroupId)
}
func (group *SAlbServerGroup) AddBackendServer(serverId string, weight, port int) (cloudprovider.ICloudLoadbalancerBackend, error) {
err := group.alb.region.AddServersToAlbServerGroup(group.ServerGroupId, []cloudprovider.SLoadbalancerBackend{
{
ExternalID: serverId,
Weight: weight,
Port: port,
},
})
if err != nil {
return nil, err
}
return &SAlbServerGroupServer{
albServerGroup: group,
AlbServer: AlbServer{
ServerId: serverId,
Weight: weight,
Port: port,
},
}, nil
}
func (group *SAlbServerGroup) RemoveBackendServer(serverId string, weight, port int) error {
return group.alb.region.RemoveServersFromAlbServerGroup(group.ServerGroupId, []string{serverId})
}
func (group *SAlbServerGroup) GetProjectId() string {
return group.ResourceGroupId
}
// region methods
func (region *SRegion) GetAlbServerGroups() ([]SAlbServerGroup, error) {
params := map[string]string{
"RegionId": region.RegionId,
"MaxResults": "100",
}
groups := []SAlbServerGroup{}
nextToken := ""
for {
if nextToken != "" {
params["NextToken"] = nextToken
}
body, err := region.albRequest("ListServerGroups", params)
if err != nil {
return nil, err
}
pageGroups := []SAlbServerGroup{}
err = body.Unmarshal(&pageGroups, "ServerGroups")
if err != nil {
return nil, err
}
groups = append(groups, pageGroups...)
nextToken, _ = body.GetString("NextToken")
if nextToken == "" {
break
}
}
return groups, nil
}
func (region *SRegion) GetAlbServerGroup(serverGroupId string) (*SAlbServerGroup, error) {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
body, err := region.albRequest("ListServerGroupServers", params)
if err != nil {
return nil, err
}
group := &SAlbServerGroup{}
err = body.Unmarshal(group)
if err != nil {
return nil, err
}
return group, nil
}
func (region *SRegion) CreateAlbServerGroup(group *cloudprovider.SLoadbalancerBackendGroup, vpcId string) (*SAlbServerGroup, error) {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupName": group.Name,
"ServerGroupType": "Instance",
"VpcId": vpcId,
"Protocol": "HTTP",
"Scheduler": "Wrr",
}
body, err := region.albRequest("CreateServerGroup", params)
if err != nil {
return nil, err
}
serverGroupId, err := body.GetString("ServerGroupId")
if err != nil {
return nil, err
}
return region.GetAlbServerGroup(serverGroupId)
}
func (region *SRegion) DeleteAlbServerGroup(serverGroupId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
_, err := region.albRequest("DeleteServerGroup", params)
return err
}
func (region *SRegion) AddServersToAlbServerGroup(serverGroupId string, backends []cloudprovider.SLoadbalancerBackend) error {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
servers := jsonutils.NewArray()
for _, backend := range backends {
servers.Add(jsonutils.Marshal(map[string]interface{}{
"ServerId": backend.ExternalID,
"ServerType": "Ecs",
"Port": backend.Port,
"Weight": backend.Weight,
}))
}
params["Servers"] = servers.String()
_, err := region.albRequest("AddServersToServerGroup", params)
return err
}
func (region *SRegion) RemoveServersFromAlbServerGroup(serverGroupId string, serverIds []string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
servers := jsonutils.NewArray()
for _, serverId := range serverIds {
servers.Add(jsonutils.Marshal(map[string]interface{}{
"ServerId": serverId,
"ServerType": "Ecs",
}))
}
params["Servers"] = servers.String()
_, err := region.albRequest("RemoveServersFromServerGroup", params)
return err
}
@@ -0,0 +1,131 @@
// 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 aliyun
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SAlbServerGroupServer struct {
multicloud.SResourceBase
AliyunTags
albServerGroup *SAlbServerGroup
AlbServer
}
func (server *SAlbServerGroupServer) GetName() string {
return server.ServerId
}
func (server *SAlbServerGroupServer) GetId() string {
return fmt.Sprintf("%s/%s/%d", server.albServerGroup.ServerGroupId, server.ServerId, server.Port)
}
func (server *SAlbServerGroupServer) GetGlobalId() string {
return server.GetId()
}
func (server *SAlbServerGroupServer) GetStatus() string {
switch server.Status {
case "Available":
return api.LB_STATUS_ENABLED
case "Configuring":
return api.LB_STATUS_UNKNOWN
default:
return api.LB_STATUS_ENABLED
}
}
func (server *SAlbServerGroupServer) IsEmulated() bool {
return false
}
func (server *SAlbServerGroupServer) Refresh() error {
serverGroup, err := server.albServerGroup.alb.region.GetAlbServerGroup(server.albServerGroup.ServerGroupId)
if err != nil {
return err
}
for _, s := range serverGroup.Servers {
if s.ServerId == server.ServerId && s.Port == server.Port {
return jsonutils.Update(server, &s)
}
}
return cloudprovider.ErrNotFound
}
func (server *SAlbServerGroupServer) GetWeight() int {
return server.Weight
}
func (server *SAlbServerGroupServer) GetPort() int {
return server.Port
}
func (server *SAlbServerGroupServer) GetBackendType() string {
return api.LB_BACKEND_GUEST
}
func (server *SAlbServerGroupServer) GetBackendRole() string {
return api.LB_BACKEND_ROLE_DEFAULT
}
func (server *SAlbServerGroupServer) GetBackendId() string {
return server.ServerId
}
func (server *SAlbServerGroupServer) GetIpAddress() string {
return server.ServerIp
}
func (server *SAlbServerGroupServer) GetProjectId() string {
return server.albServerGroup.GetProjectId()
}
func (server *SAlbServerGroupServer) SyncConf(ctx context.Context, port, weight int) error {
return server.albServerGroup.alb.region.UpdateAlbServerGroupServerAttribute(
server.albServerGroup.ServerGroupId,
server.ServerId,
port,
weight,
)
}
// region methods for ALB server group server operations
func (region *SRegion) UpdateAlbServerGroupServerAttribute(serverGroupId, serverId string, port, weight int) error {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
servers := jsonutils.NewArray()
servers.Add(jsonutils.Marshal(map[string]interface{}{
"ServerId": serverId,
"ServerType": "Ecs",
"Port": port,
"Weight": weight,
}))
params["Servers"] = servers.String()
_, err := region.albRequest("UpdateServerGroupServersAttribute", params)
return err
}
+24
View File
@@ -94,6 +94,30 @@ const (
ALIYUN_SERVICE_MONGO_DB = "mongodb"
DefaultAssumeRoleName = "ResourceDirectoryAccountAccessRole"
ALIYUN_API_VERSION_ECS = "2014-05-26"
ALIYUN_API_VERSION_EIP = "2016-04-28"
ALIYUN_API_VERSION_ELB = "2016-04-28"
ALIYUN_API_VERSION_VGW = "2016-04-28"
ALIYUN_API_VERSION_NAS = "2017-06-26"
ALIYUN_API_VERSION_CON = "2018-12-01"
ALIYUN_API_VERSION_VHH = "2019-06-01"
ALIYUN_API_VERSION_BSS = "2017-12-14"
ALIYUN_API_VERSION_FC = "2021-04-06"
ALIYUN_API_VERSION_NLB = "2022-04-30"
ALIYUN_API_VERSION_ALB = "2020-06-16"
ALIYUN_BSS_BILLING_METHOD_PREPAID = "Subscription"
ALIYUN_BSS_BILLING_METHOD_POSTPAID = "PayAsYouGo"
ALIYUN_API_INTERVAL = 5 * time.Second
DEFAULT_SESSION_DURATION_SECONDS = 3600
ALIYUN_SERVICE_ALB = "alb"
ALIYUN_SERVICE_NLB = "nlb"
ALIYUN_SERVICE_OSS = "oss"
ALIYUN_SERVICE_EIP = "eip"
)
var (
+341
View File
@@ -0,0 +1,341 @@
// 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 aliyun
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SNlb struct {
multicloud.SLoadbalancerBase
AliyunTags
region *SRegion
LoadBalancerId string `json:"LoadBalancerId"`
LoadBalancerName string `json:"LoadBalancerName"`
LoadBalancerStatus string `json:"LoadBalancerStatus"`
LoadBalancerBusinessStatus string `json:"LoadBalancerBusinessStatus"`
LoadBalancerType string `json:"LoadBalancerType"`
AddressType string `json:"AddressType"`
AddressIpVersion string `json:"AddressIpVersion"`
Ipv6AddressType string `json:"Ipv6AddressType"`
VpcId string `json:"VpcId"`
RegionId string `json:"RegionId"`
ZoneId string `json:"ZoneId"`
DNSName string `json:"DNSName"`
NetworkType string `json:"NetworkType"`
InternetChargeType string `json:"InternetChargeType"`
LoadBalancerBillingConfig map[string]interface{} `json:"LoadBalancerBillingConfig"`
ModificationProtectionConfig map[string]interface{} `json:"ModificationProtectionConfig"`
DeletionProtectionConfig map[string]interface{} `json:"DeletionProtectionConfig"`
LoadBalancerOperationLocks []map[string]interface{} `json:"LoadBalancerOperationLocks"`
ZoneMappings []NlbZoneMapping `json:"ZoneMappings"`
CreateTime time.Time `json:"CreateTime"`
ResourceGroupId string `json:"ResourceGroupId"`
CpsEnabled bool `json:"CpsEnabled"`
CrossZoneEnabled bool `json:"CrossZoneEnabled"`
TrafficAffinityEnabled bool `json:"TrafficAffinityEnabled"`
BandwidthPackageId string `json:"BandwidthPackageId"`
}
type NlbZoneMapping struct {
ZoneId string `json:"ZoneId"`
VSwitchId string `json:"VSwitchId"`
AllocationId string `json:"AllocationId"`
PrivateIPv4Address string `json:"PrivateIPv4Address"`
IPv6Address string `json:"IPv6Address"`
LoadBalancerAddresses []NlbLoadBalancerAddress `json:"LoadBalancerAddresses"`
}
type NlbLoadBalancerAddress struct {
AllocationId string `json:"AllocationId"`
EipType string `json:"EipType"`
PrivateIPv4Address string `json:"PrivateIPv4Address"`
PrivateIPv6Address string `json:"PrivateIPv6Address"`
PublicIPv4Address string `json:"PublicIPv4Address"`
PublicIPv6Address string `json:"PublicIPv6Address"`
}
func (nlb *SNlb) GetName() string {
return nlb.LoadBalancerName
}
func (nlb *SNlb) GetId() string {
return nlb.LoadBalancerId
}
func (nlb *SNlb) GetGlobalId() string {
return nlb.LoadBalancerId
}
func (nlb *SNlb) GetStatus() string {
switch nlb.LoadBalancerStatus {
case "Active":
return api.LB_STATUS_ENABLED
case "Provisioning", "Configuring":
return api.LB_STATUS_UNKNOWN
case "Stopped":
return api.LB_STATUS_DISABLED
default:
return api.LB_STATUS_UNKNOWN
}
}
func (nlb *SNlb) GetAddress() string {
return nlb.DNSName
}
func (nlb *SNlb) GetAddressType() string {
return nlb.AddressType
}
func (nlb *SNlb) GetNetworkType() string {
return "vpc"
}
func (nlb *SNlb) GetNetworkIds() []string {
ret := []string{}
for _, zone := range nlb.ZoneMappings {
if len(zone.VSwitchId) > 0 {
ret = append(ret, zone.VSwitchId)
}
}
return ret
}
func (nlb *SNlb) GetZoneId() string {
if len(nlb.ZoneMappings) > 0 {
zone, err := nlb.region.getZoneById(nlb.ZoneMappings[0].ZoneId)
if err != nil {
log.Errorf("failed to find zone for nlb %s error: %v", nlb.LoadBalancerName, err)
return ""
}
return zone.GetGlobalId()
}
return ""
}
func (nlb *SNlb) GetZone1Id() string {
if len(nlb.ZoneMappings) > 1 {
zone, err := nlb.region.getZoneById(nlb.ZoneMappings[1].ZoneId)
if err != nil {
log.Errorf("failed to find zone for nlb %s error: %v", nlb.LoadBalancerName, err)
return ""
}
return zone.GetGlobalId()
}
return ""
}
func (nlb *SNlb) IsEmulated() bool {
return false
}
func (nlb *SNlb) GetVpcId() string {
return nlb.VpcId
}
func (nlb *SNlb) Refresh() error {
loadbalancer, err := nlb.region.GetNlbDetail(nlb.LoadBalancerId)
if err != nil {
return err
}
return jsonutils.Update(nlb, loadbalancer)
}
func (nlb *SNlb) Delete(ctx context.Context) error {
return nlb.region.DeleteNlb(nlb.LoadBalancerId)
}
func (nlb *SNlb) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
groups, err := nlb.region.GetNlbServerGroups()
if err != nil {
return nil, err
}
igroups := []cloudprovider.ICloudLoadbalancerBackendGroup{}
for i := 0; i < len(groups); i++ {
// 过滤出属于当前负载均衡器的服务器组
for _, lbId := range groups[i].RelatedLoadBalancerIds {
if lbId == nlb.LoadBalancerId {
groups[i].nlb = nlb
igroups = append(igroups, &groups[i])
break
}
}
}
return igroups, nil
}
func (nlb *SNlb) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbalancerBackendGroup) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
serverGroup, err := nlb.region.CreateNlbServerGroup(group, nlb.VpcId)
if err != nil {
return nil, err
}
serverGroup.nlb = nlb
return serverGroup, nil
}
func (nlb *SNlb) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
groups, err := nlb.GetILoadBalancerBackendGroups()
if err != nil {
return nil, err
}
for i := 0; i < len(groups); i++ {
if groups[i].GetGlobalId() == groupId {
return groups[i], nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (nlb *SNlb) CreateILoadBalancerListener(ctx context.Context, listener *cloudprovider.SLoadbalancerListenerCreateOptions) (cloudprovider.ICloudLoadbalancerListener, error) {
return nlb.region.CreateNlbListener(nlb, listener)
}
func (nlb *SNlb) GetILoadBalancerListenerById(listenerId string) (cloudprovider.ICloudLoadbalancerListener, error) {
listeners, err := nlb.GetILoadBalancerListeners()
if err != nil {
return nil, err
}
for i := 0; i < len(listeners); i++ {
if listeners[i].GetGlobalId() == listenerId {
return listeners[i], nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (nlb *SNlb) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
listeners, err := nlb.region.GetNlbListeners(nlb.LoadBalancerId)
if err != nil {
return nil, err
}
ilisteners := []cloudprovider.ICloudLoadbalancerListener{}
for i := 0; i < len(listeners); i++ {
listeners[i].nlb = nlb
ilisteners = append(ilisteners, &listeners[i])
}
return ilisteners, nil
}
func (nlb *SNlb) GetChargeType() string {
return api.LB_CHARGE_TYPE_BY_TRAFFIC
}
func (nlb *SNlb) GetCreatedAt() time.Time {
return nlb.CreateTime
}
func (nlb *SNlb) GetEgressMbps() int {
return 0
}
func (nlb *SNlb) GetIEIPs() ([]cloudprovider.ICloudEIP, error) {
return []cloudprovider.ICloudEIP{}, nil
}
func (nlb *SNlb) Start() error {
return cloudprovider.ErrNotSupported
}
func (nlb *SNlb) Stop() error {
return cloudprovider.ErrNotSupported
}
func (nlb *SNlb) GetLoadbalancerSpec() string {
return nlb.LoadBalancerType
}
func (nlb *SNlb) GetProjectId() string {
return nlb.ResourceGroupId
}
// region methods
func (region *SRegion) GetNlbs() ([]SNlb, error) {
params := map[string]string{
"RegionId": region.RegionId,
"MaxResults": "100",
}
nlbs := []SNlb{}
nextToken := ""
for {
if nextToken != "" {
params["NextToken"] = nextToken
}
body, err := region.nlbRequest("ListLoadBalancers", params)
if err != nil {
return nil, err
}
pageNlbs := []SNlb{}
err = body.Unmarshal(&pageNlbs, "LoadBalancers")
if err != nil {
return nil, err
}
for i := 0; i < len(pageNlbs); i++ {
pageNlbs[i].region = region
}
nlbs = append(nlbs, pageNlbs...)
nextToken, _ = body.GetString("NextToken")
if nextToken == "" {
break
}
}
return nlbs, nil
}
func (region *SRegion) GetNlbDetail(nlbId string) (*SNlb, error) {
params := map[string]string{
"RegionId": region.RegionId,
"LoadBalancerId": nlbId,
}
body, err := region.nlbRequest("GetLoadBalancerAttribute", params)
if err != nil {
return nil, err
}
nlb := &SNlb{region: region}
err = body.Unmarshal(nlb)
if err != nil {
return nil, err
}
return nlb, nil
}
func (region *SRegion) DeleteNlb(nlbId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"LoadBalancerId": nlbId,
}
_, err := region.nlbRequest("DeleteLoadBalancer", params)
return err
}
+392
View File
@@ -0,0 +1,392 @@
// 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 aliyun
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SNlbListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
AliyunTags
nlb *SNlb
ListenerId string `json:"ListenerId"`
ListenerDescription string `json:"ListenerDescription"`
ListenerProtocol string `json:"ListenerProtocol"`
ListenerPort int `json:"ListenerPort"`
ListenerStatus string `json:"ListenerStatus"`
LoadBalancerId string `json:"LoadBalancerId"`
ServerGroupId string `json:"ServerGroupId"`
IdleTimeout int `json:"IdleTimeout"`
SecurityPolicyId string `json:"SecurityPolicyId"`
CaEnabled bool `json:"CaEnabled"`
CaCertificateIds []string `json:"CaCertificateIds"`
CertificateIds []string `json:"CertificateIds"`
Cps int `json:"Cps"`
Mss int `json:"Mss"`
ProxyProtocolEnabled bool `json:"ProxyProtocolEnabled"`
SecSensorEnabled bool `json:"SecSensorEnabled"`
ProxyProtocolV2Config map[string]interface{} `json:"ProxyProtocolV2Config"`
AlpnEnabled bool `json:"AlpnEnabled"`
AlpnPolicy string `json:"AlpnPolicy"`
StartPort string `json:"StartPort"`
EndPort string `json:"EndPort"`
RegionId string `json:"RegionId"`
}
func (listener *SNlbListener) GetName() string {
if len(listener.ListenerDescription) > 0 {
return listener.ListenerDescription
}
return fmt.Sprintf("%s:%d", listener.ListenerProtocol, listener.ListenerPort)
}
func (listener *SNlbListener) GetId() string {
return listener.ListenerId
}
func (listener *SNlbListener) GetGlobalId() string {
return listener.ListenerId
}
func (listener *SNlbListener) GetStatus() string {
switch listener.ListenerStatus {
case "Running":
return api.LB_STATUS_ENABLED
case "Stopped":
return api.LB_STATUS_DISABLED
case "Provisioning", "Configuring":
return api.LB_STATUS_UNKNOWN
default:
return api.LB_STATUS_UNKNOWN
}
}
func (listener *SNlbListener) IsEmulated() bool {
return false
}
func (listener *SNlbListener) GetEgressMbps() int {
return 0
}
func (listener *SNlbListener) Refresh() error {
lis, err := listener.nlb.region.GetNlbListener(listener.ListenerId)
if err != nil {
return err
}
return jsonutils.Update(listener, lis)
}
func (listener *SNlbListener) GetListenerType() string {
switch listener.ListenerProtocol {
case "TCP":
return api.LB_LISTENER_TYPE_TCP
case "UDP":
return api.LB_LISTENER_TYPE_UDP
case "TCPSSL":
return "TCPSSL"
default:
return listener.ListenerProtocol
}
}
func (listener *SNlbListener) GetListenerPort() int {
return listener.ListenerPort
}
func (listener *SNlbListener) GetBackendGroupId() string {
return listener.ServerGroupId
}
func (listener *SNlbListener) GetBackendServerPort() int {
return 0
}
func (listener *SNlbListener) GetScheduler() string {
return ""
}
func (listener *SNlbListener) GetAclStatus() string {
return ""
}
func (listener *SNlbListener) GetAclType() string {
return ""
}
func (listener *SNlbListener) GetAclId() string {
return ""
}
func (listener *SNlbListener) GetHealthCheck() string {
return ""
}
func (listener *SNlbListener) GetHealthCheckType() string {
return ""
}
func (listener *SNlbListener) GetHealthCheckDomain() string {
return ""
}
func (listener *SNlbListener) GetHealthCheckURI() string {
return ""
}
func (listener *SNlbListener) GetHealthCheckCode() string {
return ""
}
func (listener *SNlbListener) GetHealthCheckRise() int {
return 0
}
func (listener *SNlbListener) GetHealthCheckFail() int {
return 0
}
func (listener *SNlbListener) GetHealthCheckTimeout() int {
return 0
}
func (listener *SNlbListener) GetHealthCheckInterval() int {
return 0
}
func (listener *SNlbListener) GetHealthCheckReq() string {
return ""
}
func (listener *SNlbListener) GetHealthCheckExp() string {
return ""
}
func (listener *SNlbListener) GetStickySession() string {
return ""
}
func (listener *SNlbListener) GetStickySessionType() string {
return ""
}
func (listener *SNlbListener) GetStickySessionCookie() string {
return ""
}
func (listener *SNlbListener) GetStickySessionCookieTimeout() int {
return 0
}
func (listener *SNlbListener) XForwardedForEnabled() bool {
return false
}
func (listener *SNlbListener) GzipEnabled() bool {
return false
}
func (listener *SNlbListener) GetCertificateId() string {
if len(listener.CertificateIds) > 0 {
return listener.CertificateIds[0]
}
return ""
}
func (listener *SNlbListener) GetTLSCipherPolicy() string {
return listener.SecurityPolicyId
}
func (listener *SNlbListener) HTTP2Enabled() bool {
return false
}
func (listener *SNlbListener) ChangeCertificate(ctx context.Context, opts *cloudprovider.ListenerCertificateOptions) error {
return cloudprovider.ErrNotSupported
}
func (listener *SNlbListener) SetAcl(ctx context.Context, opts *cloudprovider.ListenerAclOptions) error {
return cloudprovider.ErrNotSupported
}
func (listener *SNlbListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) {
return []cloudprovider.ICloudLoadbalancerListenerRule{}, nil
}
func (listener *SNlbListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
return nil, cloudprovider.ErrNotSupported
}
func (listener *SNlbListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
return nil, cloudprovider.ErrNotFound
}
func (listener *SNlbListener) Delete(ctx context.Context) error {
return listener.nlb.region.DeleteNlbListener(listener.ListenerId)
}
func (listener *SNlbListener) Start() error {
return listener.nlb.region.StartNlbListener(listener.ListenerId)
}
func (listener *SNlbListener) Stop() error {
return listener.nlb.region.StopNlbListener(listener.ListenerId)
}
func (listener *SNlbListener) ChangeScheduler(ctx context.Context, opts *cloudprovider.ChangeListenerSchedulerOptions) error {
return cloudprovider.ErrNotSupported
}
func (listener *SNlbListener) SetHealthCheck(ctx context.Context, opts *cloudprovider.ListenerHealthCheckOptions) error {
return cloudprovider.ErrNotSupported
}
func (listener *SNlbListener) GetProjectId() string {
return listener.nlb.GetProjectId()
}
func (listener *SNlbListener) GetClientIdleTimeout() int {
return listener.IdleTimeout
}
func (listener *SNlbListener) GetBackendConnectTimeout() int {
return 0
}
// region methods
func (region *SRegion) GetNlbListeners(loadBalancerId string) ([]SNlbListener, error) {
params := map[string]string{
"RegionId": region.RegionId,
"MaxResults": "100",
}
if len(loadBalancerId) > 0 {
params["LoadBalancerIds.1"] = loadBalancerId
}
listeners := []SNlbListener{}
nextToken := ""
for {
if nextToken != "" {
params["NextToken"] = nextToken
}
body, err := region.nlbRequest("ListListeners", params)
if err != nil {
return nil, err
}
pageListeners := []SNlbListener{}
err = body.Unmarshal(&pageListeners, "Listeners")
if err != nil {
return nil, err
}
listeners = append(listeners, pageListeners...)
nextToken, _ = body.GetString("NextToken")
if nextToken == "" {
break
}
}
return listeners, nil
}
func (region *SRegion) GetNlbListener(listenerId string) (*SNlbListener, error) {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
}
body, err := region.nlbRequest("GetListenerAttribute", params)
if err != nil {
return nil, err
}
listener := &SNlbListener{}
err = body.Unmarshal(listener)
if err != nil {
return nil, err
}
return listener, nil
}
func (region *SRegion) CreateNlbListener(nlb *SNlb, listener *cloudprovider.SLoadbalancerListenerCreateOptions) (*SNlbListener, error) {
params := map[string]string{
"RegionId": region.RegionId,
"LoadBalancerId": nlb.LoadBalancerId,
"ListenerProtocol": listener.ListenerType,
"ListenerPort": fmt.Sprintf("%d", listener.ListenerPort),
}
if len(listener.Name) > 0 {
params["ListenerDescription"] = listener.Name
}
body, err := region.nlbRequest("CreateListener", params)
if err != nil {
return nil, err
}
listenerId, err := body.GetString("ListenerId")
if err != nil {
return nil, err
}
return region.GetNlbListener(listenerId)
}
func (region *SRegion) DeleteNlbListener(listenerId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
}
_, err := region.nlbRequest("DeleteListener", params)
return err
}
func (region *SRegion) StartNlbListener(listenerId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
}
_, err := region.nlbRequest("StartListener", params)
return err
}
func (region *SRegion) StopNlbListener(listenerId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ListenerId": listenerId,
}
_, err := region.nlbRequest("StopListener", params)
return err
}
+323
View File
@@ -0,0 +1,323 @@
// 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 aliyun
import (
"context"
"yunion.io/x/jsonutils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SNlbServerGroup struct {
multicloud.SResourceBase
AliyunTags
nlb *SNlb
ServerGroupId string `json:"ServerGroupId"`
ServerGroupName string `json:"ServerGroupName"`
ServerGroupType string `json:"ServerGroupType"`
Protocol string `json:"Protocol"`
Scheduler string `json:"Scheduler"`
VpcId string `json:"VpcId"`
ServerGroupStatus string `json:"ServerGroupStatus"`
AddressIPVersion string `json:"AddressIPVersion"`
AnyPortEnabled bool `json:"AnyPortEnabled"`
ConnectionDrainEnabled bool `json:"ConnectionDrainEnabled"`
ConnectionDrainTimeout int `json:"ConnectionDrainTimeout"`
PreserveClientIpEnabled bool `json:"PreserveClientIpEnabled"`
PersistenceEnabled bool `json:"PersistenceEnabled"`
PersistenceTimeout int `json:"PersistenceTimeout"`
HealthCheckConfig map[string]interface{} `json:"HealthCheckConfig"`
RelatedLoadBalancerIds []string `json:"RelatedLoadBalancerIds"`
Servers []NlbServer `json:"Servers"`
CreateTime string `json:"CreateTime"`
RegionId string `json:"RegionId"`
ResourceGroupId string `json:"ResourceGroupId"`
}
type NlbServer struct {
ServerId string `json:"ServerId"`
ServerType string `json:"ServerType"`
ServerIp string `json:"ServerIp"`
Port int `json:"Port"`
Weight int `json:"Weight"`
Description string `json:"Description"`
Status string `json:"Status"`
ZoneId string `json:"ZoneId"`
}
func (group *SNlbServerGroup) GetILoadbalancer() cloudprovider.ICloudLoadbalancer {
return group.nlb
}
func (group *SNlbServerGroup) GetLoadbalancerId() string {
return group.nlb.GetId()
}
func (group *SNlbServerGroup) GetProtocolType() string {
return group.Protocol
}
func (group *SNlbServerGroup) GetScheduler() string {
return group.Scheduler
}
func (group *SNlbServerGroup) GetHealthCheck() (*cloudprovider.SLoadbalancerHealthCheck, error) {
return nil, nil
}
func (group *SNlbServerGroup) GetStickySession() (*cloudprovider.SLoadbalancerStickySession, error) {
return nil, nil
}
func (group *SNlbServerGroup) GetName() string {
return group.ServerGroupName
}
func (group *SNlbServerGroup) GetId() string {
return group.ServerGroupId
}
func (group *SNlbServerGroup) GetGlobalId() string {
return group.ServerGroupId
}
func (group *SNlbServerGroup) GetStatus() string {
switch group.ServerGroupStatus {
case "Available":
return api.LB_STATUS_ENABLED
case "Configuring":
return api.LB_STATUS_UNKNOWN
default:
return api.LB_STATUS_UNKNOWN
}
}
func (group *SNlbServerGroup) IsDefault() bool {
return false
}
func (group *SNlbServerGroup) GetType() string {
return api.LB_BACKENDGROUP_TYPE_NORMAL
}
func (group *SNlbServerGroup) IsEmulated() bool {
return false
}
func (group *SNlbServerGroup) Refresh() error {
serverGroup, err := group.nlb.region.GetNlbServerGroup(group.ServerGroupId)
if err != nil {
return err
}
return jsonutils.Update(group, serverGroup)
}
func (group *SNlbServerGroup) GetILoadbalancerBackends() ([]cloudprovider.ICloudLoadbalancerBackend, error) {
backends := []cloudprovider.ICloudLoadbalancerBackend{}
for i := 0; i < len(group.Servers); i++ {
server := &SNlbServerGroupServer{
nlbServerGroup: group,
NlbServer: group.Servers[i],
}
backends = append(backends, server)
}
return backends, nil
}
func (group *SNlbServerGroup) GetILoadbalancerBackendById(backendId string) (cloudprovider.ICloudLoadbalancerBackend, error) {
backends, err := group.GetILoadbalancerBackends()
if err != nil {
return nil, err
}
for i := 0; i < len(backends); i++ {
if backends[i].GetGlobalId() == backendId {
return backends[i], nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (group *SNlbServerGroup) Sync(ctx context.Context, group2 *cloudprovider.SLoadbalancerBackendGroup) error {
return nil
}
func (group *SNlbServerGroup) Delete(ctx context.Context) error {
return group.nlb.region.DeleteNlbServerGroup(group.ServerGroupId)
}
func (group *SNlbServerGroup) AddBackendServer(serverId string, weight, port int) (cloudprovider.ICloudLoadbalancerBackend, error) {
err := group.nlb.region.AddServersToNlbServerGroup(group.ServerGroupId, []cloudprovider.SLoadbalancerBackend{
{
ExternalID: serverId,
Weight: weight,
Port: port,
},
})
if err != nil {
return nil, err
}
return &SNlbServerGroupServer{
nlbServerGroup: group,
NlbServer: NlbServer{
ServerId: serverId,
Weight: weight,
Port: port,
},
}, nil
}
func (group *SNlbServerGroup) RemoveBackendServer(serverId string, weight, port int) error {
return group.nlb.region.RemoveServersFromNlbServerGroup(group.ServerGroupId, []string{serverId})
}
func (group *SNlbServerGroup) GetProjectId() string {
return group.ResourceGroupId
}
// region methods
func (region *SRegion) GetNlbServerGroups() ([]SNlbServerGroup, error) {
params := map[string]string{
"RegionId": region.RegionId,
"MaxResults": "100",
}
groups := []SNlbServerGroup{}
nextToken := ""
for {
if nextToken != "" {
params["NextToken"] = nextToken
}
body, err := region.nlbRequest("ListServerGroups", params)
if err != nil {
return nil, err
}
pageGroups := []SNlbServerGroup{}
err = body.Unmarshal(&pageGroups, "ServerGroups")
if err != nil {
return nil, err
}
groups = append(groups, pageGroups...)
nextToken, _ = body.GetString("NextToken")
if nextToken == "" {
break
}
}
return groups, nil
}
func (region *SRegion) GetNlbServerGroup(serverGroupId string) (*SNlbServerGroup, error) {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
body, err := region.nlbRequest("ListServerGroupServers", params)
if err != nil {
return nil, err
}
group := &SNlbServerGroup{}
err = body.Unmarshal(group)
if err != nil {
return nil, err
}
return group, nil
}
func (region *SRegion) CreateNlbServerGroup(group *cloudprovider.SLoadbalancerBackendGroup, vpcId string) (*SNlbServerGroup, error) {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupName": group.Name,
"ServerGroupType": "Instance",
"VpcId": vpcId,
"Protocol": "TCP",
"Scheduler": "Wrr",
}
body, err := region.nlbRequest("CreateServerGroup", params)
if err != nil {
return nil, err
}
serverGroupId, err := body.GetString("ServerGroupId")
if err != nil {
return nil, err
}
return region.GetNlbServerGroup(serverGroupId)
}
func (region *SRegion) DeleteNlbServerGroup(serverGroupId string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
_, err := region.nlbRequest("DeleteServerGroup", params)
return err
}
func (region *SRegion) AddServersToNlbServerGroup(serverGroupId string, backends []cloudprovider.SLoadbalancerBackend) error {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
servers := jsonutils.NewArray()
for _, backend := range backends {
servers.Add(jsonutils.Marshal(map[string]interface{}{
"ServerId": backend.ExternalID,
"ServerType": "Ecs",
"Port": backend.Port,
"Weight": backend.Weight,
}))
}
params["Servers"] = servers.String()
_, err := region.nlbRequest("AddServersToServerGroup", params)
return err
}
func (region *SRegion) RemoveServersFromNlbServerGroup(serverGroupId string, serverIds []string) error {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
servers := jsonutils.NewArray()
for _, serverId := range serverIds {
servers.Add(jsonutils.Marshal(map[string]interface{}{
"ServerId": serverId,
"ServerType": "Ecs",
}))
}
params["Servers"] = servers.String()
_, err := region.nlbRequest("RemoveServersFromServerGroup", params)
return err
}
@@ -0,0 +1,131 @@
// 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 aliyun
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
api "yunion.io/x/cloudmux/pkg/apis/compute"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/cloudmux/pkg/multicloud"
)
type SNlbServerGroupServer struct {
multicloud.SResourceBase
AliyunTags
nlbServerGroup *SNlbServerGroup
NlbServer
}
func (server *SNlbServerGroupServer) GetName() string {
return server.ServerId
}
func (server *SNlbServerGroupServer) GetId() string {
return fmt.Sprintf("%s/%s/%d", server.nlbServerGroup.ServerGroupId, server.ServerId, server.Port)
}
func (server *SNlbServerGroupServer) GetGlobalId() string {
return server.GetId()
}
func (server *SNlbServerGroupServer) GetStatus() string {
switch server.Status {
case "Available":
return api.LB_STATUS_ENABLED
case "Configuring":
return api.LB_STATUS_UNKNOWN
default:
return api.LB_STATUS_ENABLED
}
}
func (server *SNlbServerGroupServer) IsEmulated() bool {
return false
}
func (server *SNlbServerGroupServer) Refresh() error {
serverGroup, err := server.nlbServerGroup.nlb.region.GetNlbServerGroup(server.nlbServerGroup.ServerGroupId)
if err != nil {
return err
}
for _, s := range serverGroup.Servers {
if s.ServerId == server.ServerId && s.Port == server.Port {
return jsonutils.Update(server, &s)
}
}
return cloudprovider.ErrNotFound
}
func (server *SNlbServerGroupServer) GetWeight() int {
return server.Weight
}
func (server *SNlbServerGroupServer) GetPort() int {
return server.Port
}
func (server *SNlbServerGroupServer) GetBackendType() string {
return api.LB_BACKEND_GUEST
}
func (server *SNlbServerGroupServer) GetBackendRole() string {
return api.LB_BACKEND_ROLE_DEFAULT
}
func (server *SNlbServerGroupServer) GetBackendId() string {
return server.ServerId
}
func (server *SNlbServerGroupServer) GetIpAddress() string {
return server.ServerIp
}
func (server *SNlbServerGroupServer) GetProjectId() string {
return server.nlbServerGroup.GetProjectId()
}
func (server *SNlbServerGroupServer) SyncConf(ctx context.Context, port, weight int) error {
return server.nlbServerGroup.nlb.region.UpdateNlbServerGroupServerAttribute(
server.nlbServerGroup.ServerGroupId,
server.ServerId,
port,
weight,
)
}
// region methods for NLB server group server operations
func (region *SRegion) UpdateNlbServerGroupServerAttribute(serverGroupId, serverId string, port, weight int) error {
params := map[string]string{
"RegionId": region.RegionId,
"ServerGroupId": serverGroupId,
}
servers := jsonutils.NewArray()
servers.Add(jsonutils.Marshal(map[string]interface{}{
"ServerId": serverId,
"ServerType": "Ecs",
"Port": port,
"Weight": weight,
}))
params["Servers"] = servers.String()
_, err := region.nlbRequest("UpdateServerGroupServersAttribute", params)
return err
}
+41
View File
@@ -319,6 +319,26 @@ func (self *SRegion) _lbRequest(client *sdk.Client, apiName string, domain strin
return jsonRequest(client, domain, ALIYUN_API_VERSION_LB, apiName, params, self.client.debug)
}
func (self *SRegion) albRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
client, err := self.getSdkClient()
if err != nil {
return nil, err
}
params = self.client.SetResourceGropuId(params)
domain := fmt.Sprintf("alb.%s.aliyuncs.com", self.RegionId)
return jsonRequest(client, domain, ALIYUN_API_VERSION_ALB, apiName, params, self.client.debug)
}
func (self *SRegion) nlbRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
client, err := self.getSdkClient()
if err != nil {
return nil, err
}
params = self.client.SetResourceGropuId(params)
domain := fmt.Sprintf("nlb.%s.aliyuncs.com", self.RegionId)
return jsonRequest(client, domain, ALIYUN_API_VERSION_NLB, apiName, params, self.client.debug)
}
// ///////////////////////////////////////////////////////////////////////////
func (self *SRegion) GetId() string {
return self.RegionId
@@ -910,6 +930,27 @@ func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer,
lbs[i].region = region
ilbs = append(ilbs, &lbs[i])
}
// 获取ALB实例
albs, err := region.GetAlbs()
if err != nil {
return nil, err
}
for i := 0; i < len(albs); i++ {
albs[i].region = region
ilbs = append(ilbs, &albs[i])
}
// 获取NLB实例
nlbs, err := region.GetNlbs()
if err != nil {
return nil, err
}
for i := 0; i < len(nlbs); i++ {
nlbs[i].region = region
ilbs = append(ilbs, &nlbs[i])
}
return ilbs, nil
}
+56 -7
View File
@@ -15,6 +15,8 @@
package aliyun
import (
"encoding/json"
"yunion.io/x/pkg/errors"
"yunion.io/x/cloudmux/pkg/cloudprovider"
@@ -22,12 +24,12 @@ import (
)
type AliyunTags struct {
Tags struct {
Tag []multicloud.STag
// 使用RawMessage来延迟解析,兼容两种格式
TagsRaw json.RawMessage `json:"Tags"`
// Kafka
TagVO []multicloud.STag `json:"TagVO" yunion-deprecated-by:"Tag"`
}
// 缓存解析后的标签
parsedTags []multicloud.STag
parsed bool
}
var sysTags = []string{
@@ -41,9 +43,52 @@ var sysTags = []string{
"eas_resource_group_name", "eas_tenant_name", "managedby",
}
// 解析标签数据,兼容两种格式
func (self *AliyunTags) parseTags() error {
if self.parsed || len(self.TagsRaw) == 0 {
return nil
}
// 先尝试解析为直接数组格式(ALB格式)
var directTags []multicloud.STag
if err := json.Unmarshal(self.TagsRaw, &directTags); err == nil {
self.parsedTags = directTags
self.parsed = true
return nil
}
// 如果失败,尝试解析为嵌套格式(传统格式)
var nested struct {
Tag []multicloud.STag
TagVO []multicloud.STag `json:"TagVO"`
}
if err := json.Unmarshal(self.TagsRaw, &nested); err == nil {
// 合并Tag和TagVO
var allTags []multicloud.STag
allTags = append(allTags, nested.Tag...)
allTags = append(allTags, nested.TagVO...)
self.parsedTags = allTags
self.parsed = true
return nil
}
return errors.Errorf("failed to parse tags")
}
// 获取所有标签
func (self *AliyunTags) getAllTags() []multicloud.STag {
self.parseTags()
return self.parsedTags
}
func (self *AliyunTags) GetTags() (map[string]string, error) {
ret := map[string]string{}
for _, tag := range self.Tags.Tag {
// 获取所有标签(兼容两种格式)
allTags := self.getAllTags()
for _, tag := range allTags {
if tag.IsSysTagPrefix(sysTags) {
continue
}
@@ -59,7 +104,11 @@ func (self *AliyunTags) GetTags() (map[string]string, error) {
func (self *AliyunTags) GetSysTags() map[string]string {
ret := map[string]string{}
for _, tag := range self.Tags.Tag {
// 获取所有标签(兼容两种格式)
allTags := self.getAllTags()
for _, tag := range allTags {
if tag.IsSysTagPrefix(sysTags) {
if len(tag.TagKey) > 0 {
ret[tag.TagKey] = tag.TagValue